From 2bd7987cde1794eb34aa6352f158609d257a53df Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Wed, 13 Nov 2024 23:28:50 +0900 Subject: [PATCH] Implement CREATE PLACEMENT statement (#194) * Implement CREATE PLACEMENT statement * Update testdata * Update generated ast/pos.go --- ast/ast.go | 15 +++++++++ ast/pos.go | 8 +++++ ast/sql.go | 4 +++ parser.go | 15 +++++++++ testdata/input/ddl/create_placement.sql | 1 + testdata/result/ddl/create_placement.sql.txt | 32 +++++++++++++++++++ .../result/statement/create_placement.sql.txt | 32 +++++++++++++++++++ 7 files changed, 107 insertions(+) create mode 100644 testdata/input/ddl/create_placement.sql create mode 100644 testdata/result/ddl/create_placement.sql.txt create mode 100644 testdata/result/statement/create_placement.sql.txt diff --git a/ast/ast.go b/ast/ast.go index 6956f65c..3c6fd069 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -64,6 +64,7 @@ func (CreateSchema) isStatement() {} func (DropSchema) isStatement() {} func (CreateDatabase) isStatement() {} func (AlterDatabase) isStatement() {} +func (CreatePlacement) isStatement() {} func (CreateProtoBundle) isStatement() {} func (AlterProtoBundle) isStatement() {} func (DropProtoBundle) isStatement() {} @@ -307,6 +308,7 @@ func (CreateSchema) isDDL() {} func (DropSchema) isDDL() {} func (CreateDatabase) isDDL() {} func (AlterDatabase) isDDL() {} +func (CreatePlacement) isDDL() {} func (CreateProtoBundle) isDDL() {} func (AlterProtoBundle) isDDL() {} func (DropProtoBundle) isDDL() {} @@ -1827,6 +1829,19 @@ type AlterDatabase struct { Options *Options } +// CreatePlacement is CREATE PLACEMENT statement node. +// +// CREATE PLACEMENT {{.Name | sql}} {{.Options | sqlOpt}} +type CreatePlacement struct { + // pos = Create + // end = (Options ?? Name).end + + Create token.Pos // position of "CREATE" keyword + + Name *Ident + Options *Options // optional +} + // ================================================================================ // // PROTO BUNDLE statements diff --git a/ast/pos.go b/ast/pos.go index af1b319f..7b6dcf10 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -822,6 +822,14 @@ func (a *AlterDatabase) End() token.Pos { return nodeEnd(wrapNode(a.Name)) } +func (c *CreatePlacement) Pos() token.Pos { + return c.Create +} + +func (c *CreatePlacement) End() token.Pos { + return nodeEnd(nodeChoice(wrapNode(c.Options), wrapNode(c.Name))) +} + func (p *ProtoBundleTypes) Pos() token.Pos { return p.Lparen } diff --git a/ast/sql.go b/ast/sql.go index 242b653c..01c2098d 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -794,6 +794,10 @@ func (d *AlterDatabase) SQL() string { return "ALTER DATABASE " + d.Name.SQL() + " SET " + d.Options.SQL() } +func (c *CreatePlacement) SQL() string { + return "CREATE PLACEMENT " + c.Name.SQL() + sqlOpt(" ", c.Options, " ") +} + func (p *ProtoBundleTypes) SQL() string { return "(" + sqlJoin(p.Types, ", ") + ")" } func (b *CreateProtoBundle) SQL() string { return "CREATE PROTO BUNDLE " + b.Types.SQL() } diff --git a/parser.go b/parser.go index 708db3b6..98947349 100644 --- a/parser.go +++ b/parser.go @@ -2304,6 +2304,8 @@ func (p *Parser) parseDDL() ast.DDL { return p.parseCreateSchema(pos) case p.Token.IsKeywordLike("DATABASE"): return p.parseCreateDatabase(pos) + case p.Token.IsKeywordLike("PLACEMENT"): + return p.parseCreatePlacement(pos) case p.Token.Kind == "PROTO": return p.parseCreateProtoBundle(pos) case p.Token.IsKeywordLike("TABLE"): @@ -2411,6 +2413,7 @@ func (p *Parser) parseDropSchema(pos token.Pos) *ast.DropSchema { func (p *Parser) parseCreateDatabase(pos token.Pos) *ast.CreateDatabase { p.expectKeywordLike("DATABASE") name := p.parseIdent() + return &ast.CreateDatabase{ Create: pos, Name: name, @@ -2430,6 +2433,18 @@ func (p *Parser) parseAlterDatabase(pos token.Pos) *ast.AlterDatabase { } } +func (p *Parser) parseCreatePlacement(pos token.Pos) *ast.CreatePlacement { + p.expectKeywordLike("PLACEMENT") + name := p.parseIdent() + options := p.parseOptions() + + return &ast.CreatePlacement{ + Create: pos, + Name: name, + Options: options, + } +} + func (p *Parser) parseProtoBundleTypes() *ast.ProtoBundleTypes { lparen := p.expect("(").Pos types := parseCommaSeparatedList(p, p.parseNamedType) diff --git a/testdata/input/ddl/create_placement.sql b/testdata/input/ddl/create_placement.sql new file mode 100644 index 00000000..5b19cd32 --- /dev/null +++ b/testdata/input/ddl/create_placement.sql @@ -0,0 +1 @@ +CREATE PLACEMENT `europeplacement` OPTIONS (instance_partition="europe-partition") \ No newline at end of file diff --git a/testdata/result/ddl/create_placement.sql.txt b/testdata/result/ddl/create_placement.sql.txt new file mode 100644 index 00000000..efbb1bc0 --- /dev/null +++ b/testdata/result/ddl/create_placement.sql.txt @@ -0,0 +1,32 @@ +--- create_placement.sql +CREATE PLACEMENT `europeplacement` OPTIONS (instance_partition="europe-partition") +--- AST +&ast.CreatePlacement{ + Create: 0, + Name: &ast.Ident{ + NamePos: 17, + NameEnd: 34, + Name: "europeplacement", + }, + Options: &ast.Options{ + Options: 35, + Rparen: 81, + Records: []*ast.OptionsDef{ + &ast.OptionsDef{ + Name: &ast.Ident{ + NamePos: 44, + NameEnd: 62, + Name: "instance_partition", + }, + Value: &ast.StringLiteral{ + ValuePos: 63, + ValueEnd: 81, + Value: "europe-partition", + }, + }, + }, + }, +} + +--- SQL +CREATE PLACEMENT europeplacement OPTIONS (instance_partition = "europe-partition") diff --git a/testdata/result/statement/create_placement.sql.txt b/testdata/result/statement/create_placement.sql.txt new file mode 100644 index 00000000..efbb1bc0 --- /dev/null +++ b/testdata/result/statement/create_placement.sql.txt @@ -0,0 +1,32 @@ +--- create_placement.sql +CREATE PLACEMENT `europeplacement` OPTIONS (instance_partition="europe-partition") +--- AST +&ast.CreatePlacement{ + Create: 0, + Name: &ast.Ident{ + NamePos: 17, + NameEnd: 34, + Name: "europeplacement", + }, + Options: &ast.Options{ + Options: 35, + Rparen: 81, + Records: []*ast.OptionsDef{ + &ast.OptionsDef{ + Name: &ast.Ident{ + NamePos: 44, + NameEnd: 62, + Name: "instance_partition", + }, + Value: &ast.StringLiteral{ + ValuePos: 63, + ValueEnd: 81, + Value: "europe-partition", + }, + }, + }, + }, +} + +--- SQL +CREATE PLACEMENT europeplacement OPTIONS (instance_partition = "europe-partition")