Skip to content

Commit 5deac6f

Browse files
kyleconroyclaude
andcommitted
Fix Settings['key'] map access being confused with SETTINGS clause (#122)
The Settings column in system tables was being lexed as token.SETTINGS and incorrectly terminating function argument parsing. Now check for array access syntax (followed by [) before treating SETTINGS as a clause keyword. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent aa1b527 commit 5deac6f

File tree

2 files changed

+10
-12
lines changed

2 files changed

+10
-12
lines changed

parser/expression.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,9 @@ func (p *Parser) parseGroupingSets() []ast.Expression {
270270
func (p *Parser) parseFunctionArgumentList() []ast.Expression {
271271
var exprs []ast.Expression
272272

273-
if p.currentIs(token.RPAREN) || p.currentIs(token.EOF) || p.currentIs(token.SETTINGS) {
273+
// Stop at RPAREN/EOF, but only stop at SETTINGS if it's a clause keyword (not followed by [ for array access)
274+
// Settings['key'] is the Settings map column, not a SETTINGS clause
275+
if p.currentIs(token.RPAREN) || p.currentIs(token.EOF) || (p.currentIs(token.SETTINGS) && !p.peekIs(token.LBRACKET)) {
274276
return exprs
275277
}
276278

@@ -283,8 +285,8 @@ func (p *Parser) parseFunctionArgumentList() []ast.Expression {
283285

284286
for p.currentIs(token.COMMA) {
285287
p.nextToken()
286-
// Stop if we hit SETTINGS
287-
if p.currentIs(token.SETTINGS) {
288+
// Stop if we hit SETTINGS clause (but not Settings['key'] map access)
289+
if p.currentIs(token.SETTINGS) && !p.peekIs(token.LBRACKET) {
288290
break
289291
}
290292
expr := p.parseExpression(LOWEST)
@@ -791,13 +793,13 @@ func (p *Parser) parseFunctionCall(name string, pos token.Position) *ast.Functio
791793
if strings.ToLower(name) == "view" && (p.currentIs(token.SELECT) || p.currentIs(token.WITH)) {
792794
subquery := p.parseSelectWithUnion()
793795
fn.Arguments = []ast.Expression{&ast.Subquery{Position: pos, Query: subquery}}
794-
} else if !p.currentIs(token.RPAREN) && !p.currentIs(token.SETTINGS) {
795-
// Parse arguments
796+
} else if !p.currentIs(token.RPAREN) && !(p.currentIs(token.SETTINGS) && !p.peekIs(token.LBRACKET)) {
797+
// Parse arguments, but allow Settings['key'] map access (SETTINGS followed by [)
796798
fn.Arguments = p.parseFunctionArgumentList()
797799
}
798800

799-
// Handle SETTINGS inside function call (table functions)
800-
if p.currentIs(token.SETTINGS) {
801+
// Handle SETTINGS inside function call (table functions), but not Settings['key'] map access
802+
if p.currentIs(token.SETTINGS) && !p.peekIs(token.LBRACKET) {
801803
p.nextToken()
802804
fn.Settings = p.parseSettingsList()
803805
}
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
{
2-
"explain_todo": {
3-
"stmt15": true
4-
}
5-
}
1+
{}

0 commit comments

Comments
 (0)