From a2ea88e8fe92f6a07259ae8d45fe72822aae7054 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:04:48 +0900 Subject: [PATCH 1/2] Implement CREATE SCHEMA and DROP SCHEMA statements --- ast/ast.go | 30 +++++++++++++++++++++++++++++- ast/pos.go | 6 ++++++ ast/sql.go | 4 ++++ parser.go | 22 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/ast/ast.go b/ast/ast.go index 6cf6a0af..a0aebab0 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -56,6 +56,8 @@ type Statement interface { // - https://cloud.google.com/spanner/docs/reference/standard-sql/dml-syntax func (QueryStatement) isStatement() {} +func (CreateSchema) isStatement() {} +func (DropSchema) isStatement() {} func (CreateDatabase) isStatement() {} func (AlterDatabase) isStatement() {} func (CreateTable) isStatement() {} @@ -270,6 +272,8 @@ type DDL interface { // // - https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language +func (CreateSchema) isDDL() {} +func (DropSchema) isDDL() {} func (CreateDatabase) isDDL() {} func (AlterDatabase) isDDL() {} func (CreateTable) isDDL() {} @@ -1637,6 +1641,30 @@ type OptionsDef struct { Value Expr } +// CreateSchema is CREATE SCHEMA statement node. +// +// CREATE SCHEMA {{.Name | sql}} +type CreateSchema struct { + // pos = Create + // end = Name.end + + Create token.Pos // position of "CREATE" keyword + + Name *Ident +} + +// DropSchema is DROP SCHEMA statement node. +// +// DROP SCHEMA {{.Name | sql}} +type DropSchema struct { + // pos = Drop + // end = Name.end + + Drop token.Pos // position of "DROP" keyword + + Name *Ident +} + // CreateDatabase is CREATE DATABASE statement node. // // CREATE DATABASE {{.Name | sql}} @@ -1703,7 +1731,7 @@ type Synonym struct { Synonym token.Pos // position of "SYNONYM" pseudo keyword Rparen token.Pos // position of ")" - Name *Ident + Name *Ident } // CreateSequence is CREATE SEQUENCE statement node. diff --git a/ast/pos.go b/ast/pos.go index f11df8d8..450b489f 100644 --- a/ast/pos.go +++ b/ast/pos.go @@ -557,6 +557,12 @@ func (g *Options) End() token.Pos { return g.Rparen + 1 } func (g *OptionsDef) Pos() token.Pos { return g.Name.Pos() } func (g *OptionsDef) End() token.Pos { return g.Value.End() } +func (s *CreateSchema) Pos() token.Pos { return s.Create } +func (s *CreateSchema) End() token.Pos { return s.Name.End() } + +func (s *DropSchema) Pos() token.Pos { return s.Drop } +func (s *DropSchema) End() token.Pos { return s.Name.End() } + func (c *CreateDatabase) Pos() token.Pos { return c.Create } func (c *CreateDatabase) End() token.Pos { return c.Name.End() } diff --git a/ast/sql.go b/ast/sql.go index dd38f0bc..a6a5c4c0 100644 --- a/ast/sql.go +++ b/ast/sql.go @@ -767,6 +767,10 @@ func (c *CreateDatabase) SQL() string { return "CREATE DATABASE " + c.Name.SQL() } +func (s *CreateSchema) SQL() string { return "CREATE SCHEMA " + s.Name.SQL() } + +func (s *DropSchema) SQL() string { return "DROP SCHEMA " + s.Name.SQL() } + func (d *AlterDatabase) SQL() string { return "ALTER DATABASE " + d.Name.SQL() + " SET " + d.Options.SQL() } diff --git a/parser.go b/parser.go index 0d004854..442f8fa5 100644 --- a/parser.go +++ b/parser.go @@ -2150,6 +2150,8 @@ func (p *Parser) parseDDL() ast.DDL { case p.Token.Kind == "CREATE": p.nextToken() switch { + case p.Token.IsKeywordLike("SCHEMA"): + return p.parseCreateSchema(pos) case p.Token.IsKeywordLike("DATABASE"): return p.parseCreateDatabase(pos) case p.Token.IsKeywordLike("TABLE"): @@ -2192,6 +2194,8 @@ func (p *Parser) parseDDL() ast.DDL { case p.Token.IsKeywordLike("DROP"): p.nextToken() switch { + case p.Token.IsKeywordLike("SCHEMA"): + return p.parseDropSchema(pos) case p.Token.IsKeywordLike("TABLE"): return p.parseDropTable(pos) case p.Token.IsKeywordLike("INDEX"): @@ -2228,6 +2232,24 @@ func (p *Parser) parseDDL() ast.DDL { panic(p.errorfAtToken(&p.Token, "expected pseudo keyword: ALTER, DROP, but: %s", p.Token.AsString)) } +func (p *Parser) parseCreateSchema(pos token.Pos) *ast.CreateSchema { + p.expectKeywordLike("SCHEMA") + name := p.parseIdent() + return &ast.CreateSchema{ + Create: pos, + Name: name, + } +} + +func (p *Parser) parseDropSchema(pos token.Pos) *ast.DropSchema { + p.expectKeywordLike("SCHEMA") + name := p.parseIdent() + return &ast.DropSchema{ + Drop: pos, + Name: name, + } +} + func (p *Parser) parseCreateDatabase(pos token.Pos) *ast.CreateDatabase { p.expectKeywordLike("DATABASE") name := p.parseIdent() From f0ddd36a82dbb23d6124d92d1086ae257cf86e7f Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:05:08 +0900 Subject: [PATCH 2/2] Update testdata --- testdata/input/ddl/create_schema.sql | 1 + testdata/input/ddl/drop_schema.sql | 1 + testdata/result/ddl/create_schema.sql.txt | 14 ++++++++++++++ testdata/result/ddl/drop_schema.sql.txt | 14 ++++++++++++++ testdata/result/statement/create_schema.sql.txt | 14 ++++++++++++++ testdata/result/statement/drop_schema.sql.txt | 14 ++++++++++++++ 6 files changed, 58 insertions(+) create mode 100644 testdata/input/ddl/create_schema.sql create mode 100644 testdata/input/ddl/drop_schema.sql create mode 100644 testdata/result/ddl/create_schema.sql.txt create mode 100644 testdata/result/ddl/drop_schema.sql.txt create mode 100644 testdata/result/statement/create_schema.sql.txt create mode 100644 testdata/result/statement/drop_schema.sql.txt diff --git a/testdata/input/ddl/create_schema.sql b/testdata/input/ddl/create_schema.sql new file mode 100644 index 00000000..f2c2fc04 --- /dev/null +++ b/testdata/input/ddl/create_schema.sql @@ -0,0 +1 @@ +CREATE SCHEMA sch1 \ No newline at end of file diff --git a/testdata/input/ddl/drop_schema.sql b/testdata/input/ddl/drop_schema.sql new file mode 100644 index 00000000..1c2cdbac --- /dev/null +++ b/testdata/input/ddl/drop_schema.sql @@ -0,0 +1 @@ +DROP SCHEMA sch1 \ No newline at end of file diff --git a/testdata/result/ddl/create_schema.sql.txt b/testdata/result/ddl/create_schema.sql.txt new file mode 100644 index 00000000..2b04f8f5 --- /dev/null +++ b/testdata/result/ddl/create_schema.sql.txt @@ -0,0 +1,14 @@ +--- create_schema.sql +CREATE SCHEMA sch1 +--- AST +&ast.CreateSchema{ + Create: 0, + Name: &ast.Ident{ + NamePos: 14, + NameEnd: 18, + Name: "sch1", + }, +} + +--- SQL +CREATE SCHEMA sch1 diff --git a/testdata/result/ddl/drop_schema.sql.txt b/testdata/result/ddl/drop_schema.sql.txt new file mode 100644 index 00000000..b9356805 --- /dev/null +++ b/testdata/result/ddl/drop_schema.sql.txt @@ -0,0 +1,14 @@ +--- drop_schema.sql +DROP SCHEMA sch1 +--- AST +&ast.DropSchema{ + Drop: 0, + Name: &ast.Ident{ + NamePos: 12, + NameEnd: 16, + Name: "sch1", + }, +} + +--- SQL +DROP SCHEMA sch1 diff --git a/testdata/result/statement/create_schema.sql.txt b/testdata/result/statement/create_schema.sql.txt new file mode 100644 index 00000000..2b04f8f5 --- /dev/null +++ b/testdata/result/statement/create_schema.sql.txt @@ -0,0 +1,14 @@ +--- create_schema.sql +CREATE SCHEMA sch1 +--- AST +&ast.CreateSchema{ + Create: 0, + Name: &ast.Ident{ + NamePos: 14, + NameEnd: 18, + Name: "sch1", + }, +} + +--- SQL +CREATE SCHEMA sch1 diff --git a/testdata/result/statement/drop_schema.sql.txt b/testdata/result/statement/drop_schema.sql.txt new file mode 100644 index 00000000..b9356805 --- /dev/null +++ b/testdata/result/statement/drop_schema.sql.txt @@ -0,0 +1,14 @@ +--- drop_schema.sql +DROP SCHEMA sch1 +--- AST +&ast.DropSchema{ + Drop: 0, + Name: &ast.Ident{ + NamePos: 12, + NameEnd: 16, + Name: "sch1", + }, +} + +--- SQL +DROP SCHEMA sch1