Skip to content

Commit fa252e3

Browse files
authored
parser: fix parsing group by all in CTE (#780)
1 parent ec0d59e commit fa252e3

File tree

4 files changed

+77
-7
lines changed

4 files changed

+77
-7
lines changed

crates/squawk_parser/src/grammar.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4504,12 +4504,12 @@ fn opt_group_by_clause(p: &mut Parser<'_>) -> Option<CompletedMarker> {
45044504
if p.at(ALL_KW) || p.at(DISTINCT_KW) {
45054505
p.bump_any();
45064506
}
4507-
group_by_list(p);
4507+
opt_group_by_list(p);
45084508

45094509
Some(m.complete(p, GROUP_BY_CLAUSE))
45104510
}
45114511

4512-
fn group_by_list(p: &mut Parser<'_>) {
4512+
fn opt_group_by_list(p: &mut Parser<'_>) {
45134513
// From pg docs:
45144514
// An expression used inside a grouping_element can be an input column name,
45154515
// or the name or ordinal number of an output column (SELECT list item), or
@@ -4518,15 +4518,21 @@ fn group_by_list(p: &mut Parser<'_>) {
45184518
// rather than an output column name.
45194519

45204520
let m = p.start();
4521-
while !p.at(EOF) && !p.at(SEMICOLON) {
4521+
let mut found_item = false;
4522+
while !p.at(EOF) {
45224523
if opt_group_by_item(p).is_none() {
4523-
p.error("expected group by item");
4524+
break;
45244525
}
4526+
found_item = true;
45254527
if !p.eat(COMMA) {
45264528
break;
45274529
}
45284530
}
4529-
m.complete(p, GROUP_BY_LIST);
4531+
if found_item {
4532+
m.complete(p, GROUP_BY_LIST);
4533+
} else {
4534+
m.abandon(p);
4535+
}
45304536
}
45314537

45324538
const GROUP_BY_ITEM_FIRST: TokenSet =
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- group by all
2+
with x as (
3+
select * from t group by all
4+
)
5+
select * from x;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
source: crates/squawk_parser/tests/tests.rs
3+
input_file: crates/squawk_parser/tests/data/ok/select_cte_pg19.sql
4+
---
5+
SOURCE_FILE
6+
COMMENT "-- group by all"
7+
WHITESPACE "\n"
8+
SELECT
9+
WITH_CLAUSE
10+
WITH_KW "with"
11+
WHITESPACE " "
12+
WITH_TABLE
13+
NAME
14+
IDENT "x"
15+
WHITESPACE " "
16+
AS_KW "as"
17+
WHITESPACE " "
18+
L_PAREN "("
19+
WHITESPACE "\n "
20+
SELECT
21+
SELECT_CLAUSE
22+
SELECT_KW "select"
23+
WHITESPACE " "
24+
TARGET_LIST
25+
TARGET
26+
STAR "*"
27+
WHITESPACE " "
28+
FROM_CLAUSE
29+
FROM_KW "from"
30+
WHITESPACE " "
31+
FROM_ITEM
32+
NAME_REF
33+
IDENT "t"
34+
WHITESPACE " "
35+
GROUP_BY_CLAUSE
36+
GROUP_KW "group"
37+
WHITESPACE " "
38+
BY_KW "by"
39+
WHITESPACE " "
40+
ALL_KW "all"
41+
WHITESPACE "\n"
42+
R_PAREN ")"
43+
WHITESPACE "\n"
44+
SELECT_CLAUSE
45+
SELECT_KW "select"
46+
WHITESPACE " "
47+
TARGET_LIST
48+
TARGET
49+
STAR "*"
50+
WHITESPACE " "
51+
FROM_CLAUSE
52+
FROM_KW "from"
53+
WHITESPACE " "
54+
FROM_ITEM
55+
NAME_REF
56+
IDENT "x"
57+
SEMICOLON ";"
58+
WHITESPACE "\n"

crates/squawk_parser/tests/tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ fn parser_ok(fixture: Fixture<&str>) {
3434
errors.is_none(),
3535
"tests defined in the `ok` can't have parser errors."
3636
);
37-
// skipping pg17/pg18 specific stuff since our parser isn't using the latest parser
38-
if !test_name.ends_with("pg17") && !test_name.ends_with("pg18") {
37+
// skipping pg17/pg18/pg19 specific stuff since our parser isn't using the latest parser
38+
if !test_name.ends_with("pg17") && !test_name.ends_with("pg18") && !test_name.ends_with("pg19")
39+
{
3940
let pg_result = pg_query::parse(content);
4041
if let Err(e) = &pg_result {
4142
assert!(

0 commit comments

Comments
 (0)