Skip to content

Commit f2edbc4

Browse files
authored
Add parser features and enable 14 more tests (#15)
1 parent 0fa0ccc commit f2edbc4

File tree

24 files changed

+697
-45
lines changed

24 files changed

+697
-45
lines changed

ast/alter_procedure_statement.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package ast
2+
3+
// AlterProcedureStatement represents an ALTER PROCEDURE statement.
4+
type AlterProcedureStatement struct {
5+
ProcedureReference *ProcedureReference
6+
Parameters []*ProcedureParameter
7+
StatementList *StatementList
8+
IsForReplication bool
9+
}
10+
11+
func (s *AlterProcedureStatement) node() {}
12+
func (s *AlterProcedureStatement) statement() {}

ast/alter_simple_statements.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,19 @@ func (s *AlterQueueStatement) statement() {}
6666

6767
// AlterPartitionSchemeStatement represents an ALTER PARTITION SCHEME statement.
6868
type AlterPartitionSchemeStatement struct {
69-
Name *Identifier `json:"Name,omitempty"`
69+
Name *Identifier `json:"Name,omitempty"`
70+
FileGroup *IdentifierOrValueExpression `json:"FileGroup,omitempty"`
7071
}
7172

7273
func (s *AlterPartitionSchemeStatement) node() {}
7374
func (s *AlterPartitionSchemeStatement) statement() {}
7475

7576
// AlterPartitionFunctionStatement represents an ALTER PARTITION FUNCTION statement.
7677
type AlterPartitionFunctionStatement struct {
77-
Name *Identifier `json:"Name,omitempty"`
78+
Name *Identifier `json:"Name,omitempty"`
79+
HasAction bool `json:"-"` // Internal: true if SPLIT or MERGE was specified
80+
IsSplit bool `json:"IsSplit,omitempty"`
81+
Boundary ScalarExpression `json:"Boundary,omitempty"`
7882
}
7983

8084
func (s *AlterPartitionFunctionStatement) node() {}
@@ -106,6 +110,9 @@ func (s *AlterSymmetricKeyStatement) statement() {}
106110

107111
// AlterServiceMasterKeyStatement represents an ALTER SERVICE MASTER KEY statement.
108112
type AlterServiceMasterKeyStatement struct {
113+
Kind string `json:"Kind,omitempty"`
114+
Account *StringLiteral `json:"Account,omitempty"`
115+
Password *StringLiteral `json:"Password,omitempty"`
109116
}
110117

111118
func (s *AlterServiceMasterKeyStatement) node() {}

ast/external_statements.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,30 @@ type ExternalLibraryOption struct {
7979
OptionKind string
8080
Value ScalarExpression
8181
}
82+
83+
// AlterExternalDataSourceStatement represents ALTER EXTERNAL DATA SOURCE statement
84+
type AlterExternalDataSourceStatement struct {
85+
Name *Identifier
86+
Options []*ExternalDataSourceOption
87+
}
88+
89+
func (s *AlterExternalDataSourceStatement) node() {}
90+
func (s *AlterExternalDataSourceStatement) statement() {}
91+
92+
// AlterExternalLanguageStatement represents ALTER EXTERNAL LANGUAGE statement
93+
type AlterExternalLanguageStatement struct {
94+
Name *Identifier
95+
Options []*ExternalLanguageOption
96+
}
97+
98+
func (s *AlterExternalLanguageStatement) node() {}
99+
func (s *AlterExternalLanguageStatement) statement() {}
100+
101+
// AlterExternalLibraryStatement represents ALTER EXTERNAL LIBRARY statement
102+
type AlterExternalLibraryStatement struct {
103+
Name *Identifier
104+
Options []*ExternalLibraryOption
105+
}
106+
107+
func (s *AlterExternalLibraryStatement) node() {}
108+
func (s *AlterExternalLibraryStatement) statement() {}

ast/function_call.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,34 @@
11
package ast
22

3+
// CallTarget represents a call target for a function call.
4+
type CallTarget interface {
5+
callTarget()
6+
}
7+
8+
// MultiPartIdentifierCallTarget represents a multi-part identifier call target.
9+
type MultiPartIdentifierCallTarget struct {
10+
MultiPartIdentifier *MultiPartIdentifier
11+
}
12+
13+
func (*MultiPartIdentifierCallTarget) callTarget() {}
14+
15+
// ExpressionCallTarget represents an expression call target.
16+
type ExpressionCallTarget struct {
17+
Expression ScalarExpression
18+
}
19+
20+
func (*ExpressionCallTarget) callTarget() {}
21+
22+
// UserDefinedTypeCallTarget represents a user-defined type call target.
23+
type UserDefinedTypeCallTarget struct {
24+
SchemaObjectName *SchemaObjectName
25+
}
26+
27+
func (*UserDefinedTypeCallTarget) callTarget() {}
28+
329
// FunctionCall represents a function call.
430
type FunctionCall struct {
31+
CallTarget CallTarget `json:"CallTarget,omitempty"`
532
FunctionName *Identifier `json:"FunctionName,omitempty"`
633
Parameters []ScalarExpression `json:"Parameters,omitempty"`
734
UniqueRowFilter string `json:"UniqueRowFilter,omitempty"`

ast/max_literal.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package ast
2+
3+
// MaxLiteral represents the MAX keyword used in data type declarations like VARCHAR(MAX).
4+
type MaxLiteral struct {
5+
LiteralType string `json:"LiteralType,omitempty"`
6+
Value string `json:"Value,omitempty"`
7+
}
8+
9+
func (*MaxLiteral) node() {}
10+
func (*MaxLiteral) scalarExpression() {}

parser/marshal.go

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ func statementToJSON(stmt ast.Statement) jsonNode {
7272
return createSchemaStatementToJSON(s)
7373
case *ast.CreateProcedureStatement:
7474
return createProcedureStatementToJSON(s)
75+
case *ast.AlterProcedureStatement:
76+
return alterProcedureStatementToJSON(s)
7577
case *ast.CreateRoleStatement:
7678
return createRoleStatementToJSON(s)
7779
case *ast.ExecuteStatement:
@@ -146,6 +148,12 @@ func statementToJSON(stmt ast.Statement) jsonNode {
146148
return dropSecurityPolicyStatementToJSON(s)
147149
case *ast.DropExternalDataSourceStatement:
148150
return dropExternalDataSourceStatementToJSON(s)
151+
case *ast.AlterExternalDataSourceStatement:
152+
return alterExternalDataSourceStatementToJSON(s)
153+
case *ast.AlterExternalLanguageStatement:
154+
return alterExternalLanguageStatementToJSON(s)
155+
case *ast.AlterExternalLibraryStatement:
156+
return alterExternalLibraryStatementToJSON(s)
149157
case *ast.DropExternalFileFormatStatement:
150158
return dropExternalFileFormatStatementToJSON(s)
151159
case *ast.DropExternalTableStatement:
@@ -1045,6 +1053,9 @@ func scalarExpressionToJSON(expr ast.ScalarExpression) jsonNode {
10451053
node := jsonNode{
10461054
"$type": "FunctionCall",
10471055
}
1056+
if e.CallTarget != nil {
1057+
node["CallTarget"] = callTargetToJSON(e.CallTarget)
1058+
}
10481059
if e.FunctionName != nil {
10491060
node["FunctionName"] = identifierToJSON(e.FunctionName)
10501061
}
@@ -1058,9 +1069,7 @@ func scalarExpressionToJSON(expr ast.ScalarExpression) jsonNode {
10581069
if e.UniqueRowFilter != "" {
10591070
node["UniqueRowFilter"] = e.UniqueRowFilter
10601071
}
1061-
if e.WithArrayWrapper {
1062-
node["WithArrayWrapper"] = e.WithArrayWrapper
1063-
}
1072+
node["WithArrayWrapper"] = e.WithArrayWrapper
10641073
return node
10651074
case *ast.BinaryExpression:
10661075
node := jsonNode{
@@ -1103,6 +1112,17 @@ func scalarExpressionToJSON(expr ast.ScalarExpression) jsonNode {
11031112
node["Value"] = e.Value
11041113
}
11051114
return node
1115+
case *ast.MaxLiteral:
1116+
node := jsonNode{
1117+
"$type": "MaxLiteral",
1118+
}
1119+
if e.LiteralType != "" {
1120+
node["LiteralType"] = e.LiteralType
1121+
}
1122+
if e.Value != "" {
1123+
node["Value"] = e.Value
1124+
}
1125+
return node
11061126
case *ast.OdbcLiteral:
11071127
node := jsonNode{
11081128
"$type": "OdbcLiteral",
@@ -5577,6 +5597,9 @@ func alterPartitionSchemeStatementToJSON(s *ast.AlterPartitionSchemeStatement) j
55775597
if s.Name != nil {
55785598
node["Name"] = identifierToJSON(s.Name)
55795599
}
5600+
if s.FileGroup != nil {
5601+
node["FileGroup"] = identifierOrValueExpressionToJSON(s.FileGroup)
5602+
}
55805603
return node
55815604
}
55825605

@@ -5587,6 +5610,13 @@ func alterPartitionFunctionStatementToJSON(s *ast.AlterPartitionFunctionStatemen
55875610
if s.Name != nil {
55885611
node["Name"] = identifierToJSON(s.Name)
55895612
}
5613+
// Only include IsSplit when there was a SPLIT or MERGE action
5614+
if s.HasAction {
5615+
node["IsSplit"] = s.IsSplit
5616+
}
5617+
if s.Boundary != nil {
5618+
node["Boundary"] = scalarExpressionToJSON(s.Boundary)
5619+
}
55905620
return node
55915621
}
55925622

@@ -5621,9 +5651,19 @@ func alterSymmetricKeyStatementToJSON(s *ast.AlterSymmetricKeyStatement) jsonNod
56215651
}
56225652

56235653
func alterServiceMasterKeyStatementToJSON(s *ast.AlterServiceMasterKeyStatement) jsonNode {
5624-
return jsonNode{
5654+
node := jsonNode{
56255655
"$type": "AlterServiceMasterKeyStatement",
56265656
}
5657+
if s.Kind != "" {
5658+
node["Kind"] = s.Kind
5659+
}
5660+
if s.Account != nil {
5661+
node["Account"] = scalarExpressionToJSON(s.Account)
5662+
}
5663+
if s.Password != nil {
5664+
node["Password"] = scalarExpressionToJSON(s.Password)
5665+
}
5666+
return node
56275667
}
56285668

56295669
func createDatabaseStatementToJSON(s *ast.CreateDatabaseStatement) jsonNode {
@@ -5956,3 +5996,105 @@ func alterDatabaseRemoveFileGroupStatementToJSON(s *ast.AlterDatabaseRemoveFileG
59565996
return node
59575997
}
59585998

5999+
func callTargetToJSON(ct ast.CallTarget) jsonNode {
6000+
switch t := ct.(type) {
6001+
case *ast.MultiPartIdentifierCallTarget:
6002+
node := jsonNode{
6003+
"$type": "MultiPartIdentifierCallTarget",
6004+
}
6005+
if t.MultiPartIdentifier != nil {
6006+
node["MultiPartIdentifier"] = multiPartIdentifierToJSON(t.MultiPartIdentifier)
6007+
}
6008+
return node
6009+
case *ast.ExpressionCallTarget:
6010+
node := jsonNode{
6011+
"$type": "ExpressionCallTarget",
6012+
}
6013+
if t.Expression != nil {
6014+
node["Expression"] = scalarExpressionToJSON(t.Expression)
6015+
}
6016+
return node
6017+
case *ast.UserDefinedTypeCallTarget:
6018+
node := jsonNode{
6019+
"$type": "UserDefinedTypeCallTarget",
6020+
}
6021+
if t.SchemaObjectName != nil {
6022+
node["SchemaObjectName"] = schemaObjectNameToJSON(t.SchemaObjectName)
6023+
}
6024+
return node
6025+
default:
6026+
return jsonNode{}
6027+
}
6028+
}
6029+
6030+
func alterProcedureStatementToJSON(s *ast.AlterProcedureStatement) jsonNode {
6031+
node := jsonNode{
6032+
"$type": "AlterProcedureStatement",
6033+
}
6034+
if s.ProcedureReference != nil {
6035+
node["ProcedureReference"] = procedureReferenceToJSON(s.ProcedureReference)
6036+
}
6037+
node["IsForReplication"] = s.IsForReplication
6038+
if len(s.Parameters) > 0 {
6039+
params := make([]jsonNode, len(s.Parameters))
6040+
for i, p := range s.Parameters {
6041+
params[i] = procedureParameterToJSON(p)
6042+
}
6043+
node["Parameters"] = params
6044+
}
6045+
if s.StatementList != nil {
6046+
node["StatementList"] = statementListToJSON(s.StatementList)
6047+
}
6048+
return node
6049+
}
6050+
6051+
func alterExternalDataSourceStatementToJSON(s *ast.AlterExternalDataSourceStatement) jsonNode {
6052+
node := jsonNode{
6053+
"$type": "AlterExternalDataSourceStatement",
6054+
}
6055+
if s.Name != nil {
6056+
node["Name"] = identifierToJSON(s.Name)
6057+
}
6058+
if len(s.Options) > 0 {
6059+
opts := make([]jsonNode, len(s.Options))
6060+
for i, o := range s.Options {
6061+
opts[i] = externalDataSourceOptionToJSON(o)
6062+
}
6063+
node["ExternalDataSourceOptions"] = opts
6064+
}
6065+
return node
6066+
}
6067+
6068+
func externalDataSourceOptionToJSON(o *ast.ExternalDataSourceOption) jsonNode {
6069+
node := jsonNode{
6070+
"$type": "ExternalDataSourceLiteralOrIdentifierOption",
6071+
}
6072+
if o.OptionKind != "" {
6073+
node["OptionKind"] = o.OptionKind
6074+
}
6075+
if o.Value != nil {
6076+
node["Value"] = scalarExpressionToJSON(o.Value)
6077+
}
6078+
return node
6079+
}
6080+
6081+
func alterExternalLanguageStatementToJSON(s *ast.AlterExternalLanguageStatement) jsonNode {
6082+
node := jsonNode{
6083+
"$type": "AlterExternalLanguageStatement",
6084+
}
6085+
if s.Name != nil {
6086+
node["Name"] = identifierToJSON(s.Name)
6087+
}
6088+
return node
6089+
}
6090+
6091+
func alterExternalLibraryStatementToJSON(s *ast.AlterExternalLibraryStatement) jsonNode {
6092+
node := jsonNode{
6093+
"$type": "AlterExternalLibraryStatement",
6094+
}
6095+
if s.Name != nil {
6096+
node["Name"] = identifierToJSON(s.Name)
6097+
}
6098+
return node
6099+
}
6100+

0 commit comments

Comments
 (0)