Skip to content

Commit

Permalink
Add support for ALTER INDEX statement (#76)
Browse files Browse the repository at this point in the history
Co-authored-by: Hiroya Fujinami <[email protected]>
  • Loading branch information
toga4 and makenowjust authored Oct 22, 2023
1 parent 8de04c5 commit 9bdd6e4
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 0 deletions.
48 changes: 48 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (CreateView) isStatement() {}
func (CreateIndex) isStatement() {}
func (CreateRole) isStatement() {}
func (AlterTable) isStatement() {}
func (AlterIndex) isStatement() {}
func (DropTable) isStatement() {}
func (DropIndex) isStatement() {}
func (DropRole) isStatement() {}
Expand Down Expand Up @@ -225,6 +226,7 @@ func (CreateSequence) isDDL() {}
func (AlterTable) isDDL() {}
func (DropTable) isDDL() {}
func (CreateIndex) isDDL() {}
func (AlterIndex) isDDL() {}
func (DropIndex) isDDL() {}
func (CreateRole) isDDL() {}
func (DropRole) isDDL() {}
Expand Down Expand Up @@ -292,6 +294,15 @@ func (ScalarSchemaType) isSchemaType() {}
func (SizedSchemaType) isSchemaType() {}
func (ArraySchemaType) isSchemaType() {}

// IndexAlternation represents ALTER INDEX action.
type IndexAlternation interface {
Node
isIndexAlternation()
}

func (AddStoredColumn) isIndexAlternation() {}
func (DropStoredColumn) isIndexAlternation() {}

// DML represents data manipulation language in SQL.
//
// https://cloud.google.com/spanner/docs/data-definition-language
Expand Down Expand Up @@ -1626,6 +1637,19 @@ type AlterTable struct {
TableAlternation TableAlternation
}

// AlterIndex is ALTER INDEX statement node.
//
// ALTER INDEX {{.Name | sql}} {{.IndexAlternation | sql}}
type AlterIndex struct {
// pos = Alter
// end = IndexAlternation.end

Alter token.Pos // position of "ALTER" keyword

Name *Ident
IndexAlternation IndexAlternation
}

// AlterChangeStream is ALTER CHANGE STREAM statement node.
//
// ALTER CHANGE STREAM {{.Name | sql}} {{.ChangeStreamAlternation | sql}}
Expand Down Expand Up @@ -1939,6 +1963,30 @@ type InterleaveIn struct {
TableName *Ident
}

// AddStoredColumn is ADD STORED COLUMN clause in ALTER INDEX.
//
// ADD STORED COLUMN {{.Name | sql}}
type AddStoredColumn struct {
// pos = Add
// end = Name.end

Add token.Pos // position of "ADD" keyword

Name *Ident
}

// DropStoredColumn is DROP STORED COLUMN clause in ALTER INDEX.
//
// DROP STORED COLUMN {{.Name | sql}}
type DropStoredColumn struct {
// pos = Drop
// end = Name.end

Drop token.Pos // position of "DROP" keyword

Name *Ident
}

// DropIndex is DROP INDEX statement node.
//
// DROP INDEX {{if .IfExists}}IF EXISTS{{end}} {{.Name | sql}}
Expand Down
7 changes: 7 additions & 0 deletions ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func TestStatement(t *testing.T) {
Statement(&CreateSequence{}).isStatement()
Statement(&CreateRole{}).isStatement()
Statement(&AlterTable{}).isStatement()
Statement(&AlterIndex{}).isStatement()
Statement(&DropTable{}).isStatement()
Statement(&DropIndex{}).isStatement()
Statement(&DropRole{}).isStatement()
Expand Down Expand Up @@ -128,6 +129,7 @@ func TestDDL(t *testing.T) {
DDL(&AlterTable{}).isDDL()
DDL(&DropTable{}).isDDL()
DDL(&CreateIndex{}).isDDL()
DDL(&AlterIndex{}).isDDL()
DDL(&DropIndex{}).isDDL()
DDL(&CreateRole{}).isDDL()
DDL(&DropRole{}).isDDL()
Expand Down Expand Up @@ -170,6 +172,11 @@ func TestSchemaType(t *testing.T) {
SchemaType(&ArraySchemaType{}).isSchemaType()
}

func TestIndexAlternation(t *testing.T) {
IndexAlternation(&AddStoredColumn{}).isIndexAlternation()
IndexAlternation(&DropStoredColumn{}).isIndexAlternation()
}

func TestDML(t *testing.T) {
DML(&Insert{}).isDML()
DML(&Delete{}).isDML()
Expand Down
9 changes: 9 additions & 0 deletions ast/pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,15 @@ func (s *Storing) End() token.Pos { return s.Rparen + 1 }
func (i *InterleaveIn) Pos() token.Pos { return i.Comma }
func (i *InterleaveIn) End() token.Pos { return i.TableName.End() }

func (a *AlterIndex) Pos() token.Pos { return a.Alter }
func (a *AlterIndex) End() token.Pos { return a.IndexAlternation.End() }

func (a *AddStoredColumn) Pos() token.Pos { return a.Add }
func (a *AddStoredColumn) End() token.Pos { return a.Name.End() }

func (a *DropStoredColumn) Pos() token.Pos { return a.Drop }
func (a *DropStoredColumn) End() token.Pos { return a.Name.End() }

func (d *DropIndex) Pos() token.Pos { return d.Drop }
func (d *DropIndex) End() token.Pos { return d.Name.End() }

Expand Down
12 changes: 12 additions & 0 deletions ast/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,18 @@ func (i *InterleaveIn) SQL() string {
return ", INTERLEAVE IN " + i.TableName.SQL()
}

func (a *AlterIndex) SQL() string {
return "ALTER INDEX " + a.Name.SQL() + " " + a.IndexAlternation.SQL()
}

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

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

func (d *DropIndex) SQL() string {
sql := "DROP INDEX "
if d.IfExists {
Expand Down
49 changes: 49 additions & 0 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1997,6 +1997,8 @@ func (p *Parser) parseDDL() ast.DDL {
switch {
case p.Token.IsKeywordLike("TABLE"):
return p.parseAlterTable(pos)
case p.Token.IsKeywordLike("INDEX"):
return p.parseAlterIndex(pos)
case p.Token.IsKeywordLike("CHANGE"):
return p.parseAlterChangeStream(pos)
}
Expand Down Expand Up @@ -2851,6 +2853,53 @@ func (p *Parser) parseAlterColumn() ast.TableAlternation {
}
}

func (p *Parser) parseAlterIndex(pos token.Pos) *ast.AlterIndex {
p.expectKeywordLike("INDEX")

name := p.parseIdent()

var alternation ast.IndexAlternation
switch {
case p.Token.IsKeywordLike("ADD"):
alternation = p.parseAddStoredColumn()
case p.Token.IsKeywordLike("DROP"):
alternation = p.parseDropStoredColumn()
default:
p.panicfAtToken(&p.Token, "expected pseudo keyword: ADD, DROP, but: %s", p.Token.AsString)
}

return &ast.AlterIndex{
Alter: pos,
Name: name,
IndexAlternation: alternation,
}
}

func (p *Parser) parseAddStoredColumn() ast.IndexAlternation {
pos := p.expectKeywordLike("ADD").Pos
p.expectKeywordLike("STORED")
p.expectKeywordLike("COLUMN")

name := p.parseIdent()

return &ast.AddStoredColumn{
Add: pos,
Name: name,
}
}

func (p *Parser) parseDropStoredColumn() ast.IndexAlternation {
pos := p.expectKeywordLike("DROP").Pos
p.expectKeywordLike("STORED")
p.expectKeywordLike("COLUMN")

name := p.parseIdent()

return &ast.DropStoredColumn{
Drop: pos,
Name: name,
}
}
func (p *Parser) parseDropTable(pos token.Pos) *ast.DropTable {
p.expectKeywordLike("TABLE")
ifExists := p.parseIfExists()
Expand Down
1 change: 1 addition & 0 deletions testdata/input/ddl/alter_index_add_stored_column.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alter index foo add stored column bar
1 change: 1 addition & 0 deletions testdata/input/ddl/alter_index_drop_stored_column.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
alter index foo drop stored column bar
23 changes: 23 additions & 0 deletions testdata/result/ddl/alter_index_add_stored_column.sql.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--- alter_index_add_stored_column.sql
alter index foo add stored column bar

--- AST
&ast.AlterIndex{
Alter: 0,
Name: &ast.Ident{
NamePos: 12,
NameEnd: 15,
Name: "foo",
},
IndexAlternation: &ast.AddStoredColumn{
Add: 16,
Name: &ast.Ident{
NamePos: 34,
NameEnd: 37,
Name: "bar",
},
},
}

--- SQL
ALTER INDEX foo ADD STORED COLUMN bar
23 changes: 23 additions & 0 deletions testdata/result/ddl/alter_index_drop_stored_column.sql.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--- alter_index_drop_stored_column.sql
alter index foo drop stored column bar

--- AST
&ast.AlterIndex{
Alter: 0,
Name: &ast.Ident{
NamePos: 12,
NameEnd: 15,
Name: "foo",
},
IndexAlternation: &ast.DropStoredColumn{
Drop: 16,
Name: &ast.Ident{
NamePos: 35,
NameEnd: 38,
Name: "bar",
},
},
}

--- SQL
ALTER INDEX foo DROP STORED COLUMN bar
23 changes: 23 additions & 0 deletions testdata/result/statement/alter_index_add_stored_column.sql.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--- alter_index_add_stored_column.sql
alter index foo add stored column bar

--- AST
&ast.AlterIndex{
Alter: 0,
Name: &ast.Ident{
NamePos: 12,
NameEnd: 15,
Name: "foo",
},
IndexAlternation: &ast.AddStoredColumn{
Add: 16,
Name: &ast.Ident{
NamePos: 34,
NameEnd: 37,
Name: "bar",
},
},
}

--- SQL
ALTER INDEX foo ADD STORED COLUMN bar
23 changes: 23 additions & 0 deletions testdata/result/statement/alter_index_drop_stored_column.sql.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--- alter_index_drop_stored_column.sql
alter index foo drop stored column bar

--- AST
&ast.AlterIndex{
Alter: 0,
Name: &ast.Ident{
NamePos: 12,
NameEnd: 15,
Name: "foo",
},
IndexAlternation: &ast.DropStoredColumn{
Drop: 16,
Name: &ast.Ident{
NamePos: 35,
NameEnd: 38,
Name: "bar",
},
},
}

--- SQL
ALTER INDEX foo DROP STORED COLUMN bar

0 comments on commit 9bdd6e4

Please sign in to comment.