Skip to content

Commit

Permalink
feat(spanner/spansql): add support for ALTER INDEX statement (#7287)
Browse files Browse the repository at this point in the history
  • Loading branch information
toga4 committed Jan 23, 2023
1 parent e528221 commit fbe1bd4
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 1 deletion.
49 changes: 49 additions & 0 deletions spanner/spansql/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,9 @@ func (p *parser) parseDDLStmt() (DDLStmt, *parseError) {
} else if p.sniff("ALTER", "STATISTICS") {
as, err := p.parseAlterStatistics()
return as, err
} else if p.sniff("ALTER", "INDEX") {
ai, err := p.parseAlterIndex()
return ai, err
}

return nil, p.errorf("unknown DDL statement")
Expand Down Expand Up @@ -2321,6 +2324,52 @@ func (p *parser) parseStatisticsOptions() (StatisticsOptions, *parseError) {
return opts, nil
}

func (p *parser) parseAlterIndex() (*AlterIndex, *parseError) {
debugf("parseAlterIndex: %v", p)

if err := p.expect("ALTER"); err != nil {
return nil, err
}
pos := p.Pos()
if err := p.expect("INDEX"); err != nil {
return nil, err
}
iname, err := p.parseTableOrIndexOrColumnName()
if err != nil {
return nil, err
}

a := &AlterIndex{Name: iname, Position: pos}
tok := p.next()
if tok.err != nil {
return nil, tok.err
}
switch {
case tok.caseEqual("ADD"):
if err := p.expect("STORED", "COLUMN"); err != nil {
return nil, err
}
cname, err := p.parseTableOrIndexOrColumnName()
if err != nil {
return nil, err
}
a.Alteration = AddStoredColumn{Name: cname}
return a, nil
case tok.caseEqual("DROP"):
if err := p.expect("STORED", "COLUMN"); err != nil {
return nil, err
}
cname, err := p.parseTableOrIndexOrColumnName()
if err != nil {
return nil, err
}
a.Alteration = DropStoredColumn{Name: cname}
return a, nil
}

return nil, p.errorf("got %q, expected ADD or DROP", tok.value)
}

var baseTypes = map[string]TypeBase{
"BOOL": Bool,
"INT64": Int64,
Expand Down
15 changes: 14 additions & 1 deletion spanner/spansql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,9 @@ func TestParseDDL(t *testing.T) {
ALTER TABLE DefaultCol ALTER COLUMN Age SET DEFAULT (0);
ALTER TABLE DefaultCol ALTER COLUMN Age STRING(MAX) DEFAULT ("0");
ALTER INDEX MyFirstIndex ADD STORED COLUMN UpdatedAt;
ALTER INDEX MyFirstIndex DROP STORED COLUMN UpdatedAt;
-- Trailing comment at end of file.
`, &DDL{Filename: "filename", List: []DDLStmt{
&CreateTable{
Expand Down Expand Up @@ -954,6 +957,16 @@ func TestParseDDL(t *testing.T) {
},
Position: line(83),
},
&AlterIndex{
Name: "MyFirstIndex",
Alteration: AddStoredColumn{Name: "UpdatedAt"},
Position: line(85),
},
&AlterIndex{
Name: "MyFirstIndex",
Alteration: DropStoredColumn{Name: "UpdatedAt"},
Position: line(86),
},
}, Comments: []*Comment{
{
Marker: "#", Start: line(2), End: line(2),
Expand Down Expand Up @@ -989,7 +1002,7 @@ func TestParseDDL(t *testing.T) {
{Marker: "--", Isolated: true, Start: line(75), End: line(75), Text: []string{"Table has a column with a default value."}},

// Comment after everything else.
{Marker: "--", Isolated: true, Start: line(85), End: line(85), Text: []string{"Trailing comment at end of file."}},
{Marker: "--", Isolated: true, Start: line(88), End: line(88), Text: []string{"Trailing comment at end of file."}},
}}},
// No trailing comma:
{`ALTER TABLE T ADD COLUMN C2 INT64`, &DDL{Filename: "filename", List: []DDLStmt{
Expand Down
12 changes: 12 additions & 0 deletions spanner/spansql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,18 @@ func (sa StatisticsOptions) SQL() string {
return str
}

func (ai AlterIndex) SQL() string {
return "ALTER INDEX " + ai.Name.SQL() + " " + ai.Alteration.SQL()
}

func (asc AddStoredColumn) SQL() string {
return "ADD STORED COLUMN " + asc.Name.SQL()
}

func (dsc DropStoredColumn) SQL() string {
return "DROP STORED COLUMN " + dsc.Name.SQL()
}

func (d *Delete) SQL() string {
return "DELETE FROM " + d.Table.SQL() + " WHERE " + d.Where.SQL()
}
Expand Down
22 changes: 22 additions & 0 deletions spanner/spansql/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,28 @@ func TestSQL(t *testing.T) {
"ALTER STATISTICS auto_20191128_14_47_22UTC SET OPTIONS (allow_gc=false)",
reparseDDL,
},
{
&AlterIndex{
Name: "iname",
Alteration: AddStoredColumn{
Name: "cname",
},
Position: line(1),
},
"ALTER INDEX iname ADD STORED COLUMN cname",
reparseDDL,
},
{
&AlterIndex{
Name: "iname",
Alteration: DropStoredColumn{
Name: "cname",
},
Position: line(1),
},
"ALTER INDEX iname DROP STORED COLUMN cname",
reparseDDL,
},
{
&Insert{
Table: "Singers",
Expand Down
25 changes: 25 additions & 0 deletions spanner/spansql/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1146,3 +1146,28 @@ func (SetStatisticsOptions) isStatisticsAlteration() {}
type StatisticsOptions struct {
AllowGC *bool
}

type AlterIndex struct {
Name ID
Alteration IndexAlteration

Position Position // position of the "ALTER" token
}

func (as *AlterIndex) String() string { return fmt.Sprintf("%#v", as) }
func (*AlterIndex) isDDLStmt() {}
func (as *AlterIndex) Pos() Position { return as.Position }
func (as *AlterIndex) clearOffset() { as.Position.Offset = 0 }

type IndexAlteration interface {
isIndexAlteration()
SQL() string
}

func (AddStoredColumn) isIndexAlteration() {}
func (DropStoredColumn) isIndexAlteration() {}

type (
AddStoredColumn struct{ Name ID }
DropStoredColumn struct{ Name ID }
)

0 comments on commit fbe1bd4

Please sign in to comment.