Skip to content

Commit f53711e

Browse files
committed
Add CREATE DATABASE WITH options and enable 2 tests
- Add IdentifierDatabaseOption and CreateDatabaseOption types - Parse WITH LEDGER and CATALOG_COLLATION options for CREATE DATABASE - Add JSON marshaling for new database options - Only output AttachMode when options are present - Enable CreateDatabaseTests160 and Baselines160_CreateDatabaseTests160
1 parent 9a336e1 commit f53711e

6 files changed

Lines changed: 117 additions & 3 deletions

File tree

ast/alter_database_set_statement.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,26 @@ type DelayedDurabilityDatabaseOption struct {
4444
func (d *DelayedDurabilityDatabaseOption) node() {}
4545
func (d *DelayedDurabilityDatabaseOption) databaseOption() {}
4646

47+
// IdentifierDatabaseOption represents a database option with an identifier value
48+
type IdentifierDatabaseOption struct {
49+
OptionKind string `json:"OptionKind,omitempty"` // "CatalogCollation"
50+
Value *Identifier `json:"Value,omitempty"`
51+
}
52+
53+
func (i *IdentifierDatabaseOption) node() {}
54+
func (i *IdentifierDatabaseOption) databaseOption() {}
55+
56+
// CreateDatabaseOption is an interface for CREATE DATABASE options (can be DatabaseOption)
57+
type CreateDatabaseOption interface {
58+
node()
59+
createDatabaseOption()
60+
}
61+
62+
// Make existing database options implement CreateDatabaseOption
63+
func (o *OnOffDatabaseOption) createDatabaseOption() {}
64+
func (i *IdentifierDatabaseOption) createDatabaseOption() {}
65+
func (d *DelayedDurabilityDatabaseOption) createDatabaseOption() {}
66+
4767
// AlterDatabaseAddFileStatement represents ALTER DATABASE ... ADD FILE statement
4868
type AlterDatabaseAddFileStatement struct {
4969
DatabaseName *Identifier

ast/create_simple_statements.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package ast
22

33
// CreateDatabaseStatement represents a CREATE DATABASE statement.
44
type CreateDatabaseStatement struct {
5-
DatabaseName *Identifier `json:"DatabaseName,omitempty"`
5+
DatabaseName *Identifier `json:"DatabaseName,omitempty"`
6+
Options []CreateDatabaseOption `json:"Options,omitempty"`
7+
AttachMode string `json:"AttachMode,omitempty"` // "None", "Attach", "AttachRebuildLog"
68
}
79

810
func (s *CreateDatabaseStatement) node() {}

parser/marshal.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6070,9 +6070,42 @@ func createDatabaseStatementToJSON(s *ast.CreateDatabaseStatement) jsonNode {
60706070
if s.DatabaseName != nil {
60716071
node["DatabaseName"] = identifierToJSON(s.DatabaseName)
60726072
}
6073+
if len(s.Options) > 0 {
6074+
opts := make([]jsonNode, len(s.Options))
6075+
for i, opt := range s.Options {
6076+
opts[i] = createDatabaseOptionToJSON(opt)
6077+
}
6078+
node["Options"] = opts
6079+
// Only output AttachMode when there are options
6080+
if s.AttachMode != "" {
6081+
node["AttachMode"] = s.AttachMode
6082+
}
6083+
}
60736084
return node
60746085
}
60756086

6087+
func createDatabaseOptionToJSON(opt ast.CreateDatabaseOption) jsonNode {
6088+
switch o := opt.(type) {
6089+
case *ast.OnOffDatabaseOption:
6090+
return jsonNode{
6091+
"$type": "OnOffDatabaseOption",
6092+
"OptionState": o.OptionState,
6093+
"OptionKind": o.OptionKind,
6094+
}
6095+
case *ast.IdentifierDatabaseOption:
6096+
node := jsonNode{
6097+
"$type": "IdentifierDatabaseOption",
6098+
"OptionKind": o.OptionKind,
6099+
}
6100+
if o.Value != nil {
6101+
node["Value"] = identifierToJSON(o.Value)
6102+
}
6103+
return node
6104+
default:
6105+
return jsonNode{"$type": "CreateDatabaseOption"}
6106+
}
6107+
}
6108+
60766109
func createLoginStatementToJSON(s *ast.CreateLoginStatement) jsonNode {
60776110
node := jsonNode{
60786111
"$type": "CreateLoginStatement",

parser/parse_statements.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4531,13 +4531,72 @@ func (p *Parser) parseCreateDatabaseStatement() (ast.Statement, error) {
45314531

45324532
stmt := &ast.CreateDatabaseStatement{
45334533
DatabaseName: p.parseIdentifier(),
4534+
AttachMode: "None",
4535+
}
4536+
4537+
// Check for WITH clause
4538+
if p.curTok.Type == TokenWith {
4539+
p.nextToken() // consume WITH
4540+
opts, err := p.parseCreateDatabaseOptions()
4541+
if err != nil {
4542+
return nil, err
4543+
}
4544+
stmt.Options = opts
45344545
}
45354546

45364547
// Skip rest of statement
45374548
p.skipToEndOfStatement()
45384549
return stmt, nil
45394550
}
45404551

4552+
func (p *Parser) parseCreateDatabaseOptions() ([]ast.CreateDatabaseOption, error) {
4553+
var options []ast.CreateDatabaseOption
4554+
4555+
for {
4556+
optName := strings.ToUpper(p.curTok.Literal)
4557+
switch optName {
4558+
case "LEDGER":
4559+
p.nextToken() // consume LEDGER
4560+
if p.curTok.Type != TokenEquals {
4561+
return nil, fmt.Errorf("expected = after LEDGER, got %s", p.curTok.Literal)
4562+
}
4563+
p.nextToken() // consume =
4564+
state := strings.ToUpper(p.curTok.Literal)
4565+
p.nextToken() // consume ON/OFF
4566+
opt := &ast.OnOffDatabaseOption{
4567+
OptionKind: "Ledger",
4568+
OptionState: capitalizeFirst(state),
4569+
}
4570+
options = append(options, opt)
4571+
4572+
case "CATALOG_COLLATION":
4573+
p.nextToken() // consume CATALOG_COLLATION
4574+
if p.curTok.Type != TokenEquals {
4575+
return nil, fmt.Errorf("expected = after CATALOG_COLLATION, got %s", p.curTok.Literal)
4576+
}
4577+
p.nextToken() // consume =
4578+
opt := &ast.IdentifierDatabaseOption{
4579+
OptionKind: "CatalogCollation",
4580+
Value: p.parseIdentifier(),
4581+
}
4582+
options = append(options, opt)
4583+
4584+
default:
4585+
// Unknown option, return what we have
4586+
return options, nil
4587+
}
4588+
4589+
// Check for comma separator
4590+
if p.curTok.Type == TokenComma {
4591+
p.nextToken()
4592+
} else {
4593+
break
4594+
}
4595+
}
4596+
4597+
return options, nil
4598+
}
4599+
45414600
func (p *Parser) parseCreateLoginStatement() (*ast.CreateLoginStatement, error) {
45424601
p.nextToken() // consume LOGIN
45434602

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"skip": true}
1+
{"skip": false}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"skip": true}
1+
{"skip": false}

0 commit comments

Comments
 (0)