Skip to content

Commit 9fdc062

Browse files
committed
Add ON filegroup clause support for SELECT INTO statements
- Add On field to SelectStatement for filegroup specification - Parse ON clause after INTO in SELECT statements - Update parseQueryExpressionWithInto and related functions Enables tests: SelectStatementTests140, Baselines140_SelectStatementTests140
1 parent ba6f706 commit 9fdc062

5 files changed

Lines changed: 36 additions & 24 deletions

File tree

ast/select_statement.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package ast
44
type SelectStatement struct {
55
QueryExpression QueryExpression `json:"QueryExpression,omitempty"`
66
Into *SchemaObjectName `json:"Into,omitempty"`
7+
On *Identifier `json:"On,omitempty"`
78
OptimizerHints []OptimizerHintBase `json:"OptimizerHints,omitempty"`
89
}
910

parser/marshal.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,9 @@ func selectStatementToJSON(s *ast.SelectStatement) jsonNode {
10281028
if s.Into != nil {
10291029
node["Into"] = schemaObjectNameToJSON(s.Into)
10301030
}
1031+
if s.On != nil {
1032+
node["On"] = identifierToJSON(s.On)
1033+
}
10311034
if len(s.OptimizerHints) > 0 {
10321035
hints := make([]jsonNode, len(s.OptimizerHints))
10331036
for i, h := range s.OptimizerHints {

parser/parse_select.go

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,13 @@ func (p *Parser) parseSelectStatement() (*ast.SelectStatement, error) {
8383
stmt := &ast.SelectStatement{}
8484

8585
// Parse query expression (handles UNION, parens, etc.)
86-
qe, into, err := p.parseQueryExpressionWithInto()
86+
qe, into, on, err := p.parseQueryExpressionWithInto()
8787
if err != nil {
8888
return nil, err
8989
}
9090
stmt.QueryExpression = qe
9191
stmt.Into = into
92+
stmt.On = on
9293

9394
// Parse optional OPTION clause
9495
if p.curTok.Type == TokenOption {
@@ -108,15 +109,15 @@ func (p *Parser) parseSelectStatement() (*ast.SelectStatement, error) {
108109
}
109110

110111
func (p *Parser) parseQueryExpression() (ast.QueryExpression, error) {
111-
qe, _, err := p.parseQueryExpressionWithInto()
112+
qe, _, _, err := p.parseQueryExpressionWithInto()
112113
return qe, err
113114
}
114115

115-
func (p *Parser) parseQueryExpressionWithInto() (ast.QueryExpression, *ast.SchemaObjectName, error) {
116+
func (p *Parser) parseQueryExpressionWithInto() (ast.QueryExpression, *ast.SchemaObjectName, *ast.Identifier, error) {
116117
// Parse primary query expression (could be SELECT or parenthesized)
117-
left, into, err := p.parsePrimaryQueryExpression()
118+
left, into, on, err := p.parsePrimaryQueryExpression()
118119
if err != nil {
119-
return nil, nil, err
120+
return nil, nil, nil, err
120121
}
121122

122123
// Track if we have any binary operations
@@ -144,14 +145,15 @@ func (p *Parser) parseQueryExpressionWithInto() (ast.QueryExpression, *ast.Schem
144145
}
145146

146147
// Parse the right side
147-
right, rightInto, err := p.parsePrimaryQueryExpression()
148+
right, rightInto, rightOn, err := p.parsePrimaryQueryExpression()
148149
if err != nil {
149-
return nil, nil, err
150+
return nil, nil, nil, err
150151
}
151152

152153
// INTO can only appear in the first query of a UNION
153154
if rightInto != nil && into == nil {
154155
into = rightInto
156+
on = rightOn
155157
}
156158

157159
bqe := &ast.BinaryQueryExpression{
@@ -168,7 +170,7 @@ func (p *Parser) parseQueryExpressionWithInto() (ast.QueryExpression, *ast.Schem
168170
if p.curTok.Type == TokenOrder {
169171
obc, err := p.parseOrderByClause()
170172
if err != nil {
171-
return nil, nil, err
173+
return nil, nil, nil, err
172174
}
173175

174176
if hasBinaryOp {
@@ -184,47 +186,53 @@ func (p *Parser) parseQueryExpressionWithInto() (ast.QueryExpression, *ast.Schem
184186
}
185187
}
186188

187-
return left, into, nil
189+
return left, into, on, nil
188190
}
189191

190-
func (p *Parser) parsePrimaryQueryExpression() (ast.QueryExpression, *ast.SchemaObjectName, error) {
192+
func (p *Parser) parsePrimaryQueryExpression() (ast.QueryExpression, *ast.SchemaObjectName, *ast.Identifier, error) {
191193
if p.curTok.Type == TokenLParen {
192194
p.nextToken() // consume (
193-
qe, into, err := p.parseQueryExpressionWithInto()
195+
qe, into, on, err := p.parseQueryExpressionWithInto()
194196
if err != nil {
195-
return nil, nil, err
197+
return nil, nil, nil, err
196198
}
197199
if p.curTok.Type != TokenRParen {
198-
return nil, nil, fmt.Errorf("expected ), got %s", p.curTok.Literal)
200+
return nil, nil, nil, fmt.Errorf("expected ), got %s", p.curTok.Literal)
199201
}
200202
p.nextToken() // consume )
201-
return &ast.QueryParenthesisExpression{QueryExpression: qe}, into, nil
203+
return &ast.QueryParenthesisExpression{QueryExpression: qe}, into, on, nil
202204
}
203205

204206
return p.parseQuerySpecificationWithInto()
205207
}
206208

207-
func (p *Parser) parseQuerySpecificationWithInto() (*ast.QuerySpecification, *ast.SchemaObjectName, error) {
209+
func (p *Parser) parseQuerySpecificationWithInto() (*ast.QuerySpecification, *ast.SchemaObjectName, *ast.Identifier, error) {
208210
qs, err := p.parseQuerySpecificationCore()
209211
if err != nil {
210-
return nil, nil, err
212+
return nil, nil, nil, err
211213
}
212214

213215
// Check for INTO clause after SELECT elements, before FROM
214216
var into *ast.SchemaObjectName
217+
var on *ast.Identifier
215218
if p.curTok.Type == TokenInto {
216219
p.nextToken() // consume INTO
217220
into, err = p.parseSchemaObjectName()
218221
if err != nil {
219-
return nil, nil, err
222+
return nil, nil, nil, err
223+
}
224+
// Check for ON filegroup clause
225+
if strings.ToUpper(p.curTok.Literal) == "ON" {
226+
p.nextToken() // consume ON
227+
on = p.parseIdentifier()
220228
}
221229
}
222230

223231
// Parse optional FROM clause
224232
if p.curTok.Type == TokenFrom {
225233
fromClause, err := p.parseFromClause()
226234
if err != nil {
227-
return nil, nil, err
235+
return nil, nil, nil, err
228236
}
229237
qs.FromClause = fromClause
230238
}
@@ -233,7 +241,7 @@ func (p *Parser) parseQuerySpecificationWithInto() (*ast.QuerySpecification, *as
233241
if p.curTok.Type == TokenWhere {
234242
whereClause, err := p.parseWhereClause()
235243
if err != nil {
236-
return nil, nil, err
244+
return nil, nil, nil, err
237245
}
238246
qs.WhereClause = whereClause
239247
}
@@ -242,7 +250,7 @@ func (p *Parser) parseQuerySpecificationWithInto() (*ast.QuerySpecification, *as
242250
if p.curTok.Type == TokenGroup {
243251
groupByClause, err := p.parseGroupByClause()
244252
if err != nil {
245-
return nil, nil, err
253+
return nil, nil, nil, err
246254
}
247255
qs.GroupByClause = groupByClause
248256
}
@@ -251,15 +259,15 @@ func (p *Parser) parseQuerySpecificationWithInto() (*ast.QuerySpecification, *as
251259
if p.curTok.Type == TokenHaving {
252260
havingClause, err := p.parseHavingClause()
253261
if err != nil {
254-
return nil, nil, err
262+
return nil, nil, nil, err
255263
}
256264
qs.HavingClause = havingClause
257265
}
258266

259267
// Note: ORDER BY is parsed at the top level in parseQueryExpressionWithInto
260268
// to correctly handle UNION/EXCEPT/INTERSECT cases
261269

262-
return qs, into, nil
270+
return qs, into, on, nil
263271
}
264272

265273
func (p *Parser) parseQuerySpecificationCore() (*ast.QuerySpecification, error) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"todo": true}
1+
{}

0 commit comments

Comments
 (0)