diff --git a/parser.go b/parser.go index 59284a71..49f35167 100644 --- a/parser.go +++ b/parser.go @@ -717,7 +717,7 @@ func (p *Parser) parseSelectResults() []ast.SelectItem { break } p.nextToken() - if p.Token.Kind == token.TokenEOF || p.Token.Kind == "FROM" { + if p.Token.Kind == token.TokenEOF || p.Token.Kind == "FROM" || p.Token.Kind == ")" || p.Token.Kind == "|>" { break } results = append(results, p.parseSelectItem()) diff --git a/testdata/input/query/pipe_select_trailing_comma.sql b/testdata/input/query/pipe_select_trailing_comma.sql new file mode 100644 index 00000000..66dc883f --- /dev/null +++ b/testdata/input/query/pipe_select_trailing_comma.sql @@ -0,0 +1,3 @@ +(FROM UNNEST([1]) AS x |> SELECT x,) +|> SELECT x, +|> WHERE TRUE diff --git a/testdata/input/query/select_trailing_comma_subqueries.sql b/testdata/input/query/select_trailing_comma_subqueries.sql new file mode 100644 index 00000000..8be97d91 --- /dev/null +++ b/testdata/input/query/select_trailing_comma_subqueries.sql @@ -0,0 +1 @@ +(SELECT EXISTS(SELECT 1,), ARRAY(SELECT 2,),) diff --git a/testdata/result/query/pipe_select_trailing_comma.sql.txt b/testdata/result/query/pipe_select_trailing_comma.sql.txt new file mode 100644 index 00000000..0df5a286 --- /dev/null +++ b/testdata/result/query/pipe_select_trailing_comma.sql.txt @@ -0,0 +1,83 @@ +--- pipe_select_trailing_comma.sql +(FROM UNNEST([1]) AS x |> SELECT x,) +|> SELECT x, +|> WHERE TRUE + +--- AST +&ast.QueryStatement{ + Query: &ast.Query{ + Query: &ast.SubQuery{ + Rparen: 35, + Query: &ast.Query{ + Query: &ast.FromQuery{ + From: &ast.From{ + From: 1, + Source: &ast.Unnest{ + Unnest: 6, + Rparen: 16, + Expr: &ast.ArrayLiteral{ + Array: -1, + Lbrack: 13, + Rbrack: 15, + Values: []ast.Expr{ + &ast.IntLiteral{ + ValuePos: 14, + ValueEnd: 15, + Base: 10, + Value: "1", + }, + }, + }, + As: &ast.AsAlias{ + As: 18, + Alias: &ast.Ident{ + NamePos: 21, + NameEnd: 22, + Name: "x", + }, + }, + }, + }, + }, + PipeOperators: []ast.PipeOperator{ + &ast.PipeSelect{ + Pipe: 23, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.Ident{ + NamePos: 33, + NameEnd: 34, + Name: "x", + }, + }, + }, + }, + }, + }, + }, + PipeOperators: []ast.PipeOperator{ + &ast.PipeSelect{ + Pipe: 37, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.Ident{ + NamePos: 47, + NameEnd: 48, + Name: "x", + }, + }, + }, + }, + &ast.PipeWhere{ + Pipe: 50, + Expr: &ast.BoolLiteral{ + ValuePos: 59, + Value: true, + }, + }, + }, + }, +} + +--- SQL +(FROM UNNEST([1]) AS x |> SELECT x) |> SELECT x |> WHERE TRUE diff --git a/testdata/result/query/select_trailing_comma_subqueries.sql.txt b/testdata/result/query/select_trailing_comma_subqueries.sql.txt new file mode 100644 index 00000000..41efbb56 --- /dev/null +++ b/testdata/result/query/select_trailing_comma_subqueries.sql.txt @@ -0,0 +1,55 @@ +--- select_trailing_comma_subqueries.sql +(SELECT EXISTS(SELECT 1,), ARRAY(SELECT 2,),) + +--- AST +&ast.QueryStatement{ + Query: &ast.SubQuery{ + Rparen: 44, + Query: &ast.Select{ + Select: 1, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.ExistsSubQuery{ + Exists: 8, + Rparen: 24, + Query: &ast.Select{ + Select: 15, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.IntLiteral{ + ValuePos: 22, + ValueEnd: 23, + Base: 10, + Value: "1", + }, + }, + }, + }, + }, + }, + &ast.ExprSelectItem{ + Expr: &ast.ArraySubQuery{ + Array: 27, + Rparen: 42, + Query: &ast.Select{ + Select: 33, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.IntLiteral{ + ValuePos: 40, + ValueEnd: 41, + Base: 10, + Value: "2", + }, + }, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +(SELECT EXISTS(SELECT 1), ARRAY(SELECT 2)) diff --git a/testdata/result/statement/pipe_select_trailing_comma.sql.txt b/testdata/result/statement/pipe_select_trailing_comma.sql.txt new file mode 100644 index 00000000..0df5a286 --- /dev/null +++ b/testdata/result/statement/pipe_select_trailing_comma.sql.txt @@ -0,0 +1,83 @@ +--- pipe_select_trailing_comma.sql +(FROM UNNEST([1]) AS x |> SELECT x,) +|> SELECT x, +|> WHERE TRUE + +--- AST +&ast.QueryStatement{ + Query: &ast.Query{ + Query: &ast.SubQuery{ + Rparen: 35, + Query: &ast.Query{ + Query: &ast.FromQuery{ + From: &ast.From{ + From: 1, + Source: &ast.Unnest{ + Unnest: 6, + Rparen: 16, + Expr: &ast.ArrayLiteral{ + Array: -1, + Lbrack: 13, + Rbrack: 15, + Values: []ast.Expr{ + &ast.IntLiteral{ + ValuePos: 14, + ValueEnd: 15, + Base: 10, + Value: "1", + }, + }, + }, + As: &ast.AsAlias{ + As: 18, + Alias: &ast.Ident{ + NamePos: 21, + NameEnd: 22, + Name: "x", + }, + }, + }, + }, + }, + PipeOperators: []ast.PipeOperator{ + &ast.PipeSelect{ + Pipe: 23, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.Ident{ + NamePos: 33, + NameEnd: 34, + Name: "x", + }, + }, + }, + }, + }, + }, + }, + PipeOperators: []ast.PipeOperator{ + &ast.PipeSelect{ + Pipe: 37, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.Ident{ + NamePos: 47, + NameEnd: 48, + Name: "x", + }, + }, + }, + }, + &ast.PipeWhere{ + Pipe: 50, + Expr: &ast.BoolLiteral{ + ValuePos: 59, + Value: true, + }, + }, + }, + }, +} + +--- SQL +(FROM UNNEST([1]) AS x |> SELECT x) |> SELECT x |> WHERE TRUE diff --git a/testdata/result/statement/select_trailing_comma_subqueries.sql.txt b/testdata/result/statement/select_trailing_comma_subqueries.sql.txt new file mode 100644 index 00000000..41efbb56 --- /dev/null +++ b/testdata/result/statement/select_trailing_comma_subqueries.sql.txt @@ -0,0 +1,55 @@ +--- select_trailing_comma_subqueries.sql +(SELECT EXISTS(SELECT 1,), ARRAY(SELECT 2,),) + +--- AST +&ast.QueryStatement{ + Query: &ast.SubQuery{ + Rparen: 44, + Query: &ast.Select{ + Select: 1, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.ExistsSubQuery{ + Exists: 8, + Rparen: 24, + Query: &ast.Select{ + Select: 15, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.IntLiteral{ + ValuePos: 22, + ValueEnd: 23, + Base: 10, + Value: "1", + }, + }, + }, + }, + }, + }, + &ast.ExprSelectItem{ + Expr: &ast.ArraySubQuery{ + Array: 27, + Rparen: 42, + Query: &ast.Select{ + Select: 33, + Results: []ast.SelectItem{ + &ast.ExprSelectItem{ + Expr: &ast.IntLiteral{ + ValuePos: 40, + ValueEnd: 41, + Base: 10, + Value: "2", + }, + }, + }, + }, + }, + }, + }, + }, + }, +} + +--- SQL +(SELECT EXISTS(SELECT 1), ARRAY(SELECT 2))