diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 193589c5..6ba0ac98 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -38,12 +38,14 @@ const DELIMITED_LIST_KINDS: &[SyntaxKind] = &[ SyntaxKind::ATTRIBUTE_LIST, SyntaxKind::COLUMN_LIST, SyntaxKind::CONSTRAINT_EXCLUSION_LIST, + SyntaxKind::GROUP_BY_LIST, SyntaxKind::JSON_TABLE_COLUMN_LIST, SyntaxKind::OPTIONS_LIST, SyntaxKind::PARAM_LIST, SyntaxKind::PARTITION_ITEM_LIST, SyntaxKind::ROW_LIST, SyntaxKind::SET_OPTIONS_LIST, + SyntaxKind::SORT_BY_LIST, SyntaxKind::TABLE_ARG_LIST, SyntaxKind::TABLE_LIST, SyntaxKind::TARGET_LIST, diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 176a60f6..9f7ad1fa 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -772,6 +772,7 @@ pub enum SyntaxKind { GROUPING_ROLLUP, GROUPING_SETS, GROUP_BY_CLAUSE, + GROUP_BY_LIST, GTEQ, HAVING_CLAUSE, IF_EXISTS, @@ -993,6 +994,7 @@ pub enum SyntaxKind { SIMILAR_TO, SORT_ASC, SORT_BY, + SORT_BY_LIST, SORT_DESC, SORT_USING, SOURCE_FILE, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 7536cda7..68fa7d03 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -2727,14 +2727,20 @@ fn opt_order_by_clause(p: &mut Parser<'_>) -> bool { return false; } p.expect(BY_KW); + sort_by_list(p); + m.complete(p, ORDER_BY_CLAUSE); + true +} + +fn sort_by_list(p: &mut Parser<'_>) { + let m = p.start(); while !p.at(EOF) { sort_by(p); if !p.eat(COMMA) { break; } } - m.complete(p, ORDER_BY_CLAUSE); - true + m.complete(p, SORT_BY_LIST); } fn sort_by(p: &mut Parser<'_>) { @@ -4334,6 +4340,7 @@ fn group_by_list(p: &mut Parser<'_>) { // ambiguity, a GROUP BY name will be interpreted as an input-column name // rather than an output column name. + let m = p.start(); while !p.at(EOF) && !p.at(SEMICOLON) { if opt_group_by_item(p).is_none() { p.error("expected group by item"); @@ -4342,6 +4349,7 @@ fn group_by_list(p: &mut Parser<'_>) { break; } } + m.complete(p, GROUP_BY_LIST); } const GROUP_BY_ITEM_FIRST: TokenSet = diff --git a/crates/squawk_parser/tests/snapshots/tests__create_view_extra_parens_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_view_extra_parens_ok.snap index c19938ed..7d69ddea 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_view_extra_parens_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_view_extra_parens_ok.snap @@ -68,11 +68,12 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "y" - WHITESPACE " " - SORT_DESC - DESC_KW "desc" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "y" + WHITESPACE " " + SORT_DESC + DESC_KW "desc" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__delete_ok.snap b/crates/squawk_parser/tests/snapshots/tests__delete_ok.snap index 53327ed1..b6e9efff 100644 --- a/crates/squawk_parser/tests/snapshots/tests__delete_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__delete_ok.snap @@ -326,9 +326,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "user_id" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "user_id" R_PAREN ")" WHITESPACE " " ALIAS @@ -999,13 +1000,14 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - FIELD_EXPR - NAME_REF - IDENT "l" - DOT "." - NAME_REF - IDENT "creation_date" + SORT_BY_LIST + SORT_BY + FIELD_EXPR + NAME_REF + IDENT "l" + DOT "." + NAME_REF + IDENT "creation_date" WHITESPACE "\n " LOCKING_CLAUSE FOR_KW "FOR" diff --git a/crates/squawk_parser/tests/snapshots/tests__explain_ok.snap b/crates/squawk_parser/tests/snapshots/tests__explain_ok.snap index b72ca9cc..38033f0f 100644 --- a/crates/squawk_parser/tests/snapshots/tests__explain_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__explain_ok.snap @@ -398,9 +398,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "foo" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "foo" SEMICOLON ";" WHITESPACE "\n\n" EXPLAIN @@ -484,9 +485,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "foo" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "foo" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- doc_example_8" @@ -561,9 +563,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "foo" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "foo" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- parens_select" diff --git a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap index 80dc7fcb..abd6270d 100644 --- a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap @@ -408,58 +408,59 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - CALL_EXPR - NAME_REF - IDENT "ts_rank_cd" - ARG_LIST - L_PAREN "(" - CALL_EXPR - NAME_REF - IDENT "to_tsvector" - ARG_LIST - L_PAREN "(" - LITERAL - STRING "'english'" - COMMA "," - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "title" - WHITESPACE " " - CUSTOM_OP - PIPE "|" - PIPE "|" + SORT_BY_LIST + SORT_BY + CALL_EXPR + NAME_REF + IDENT "ts_rank_cd" + ARG_LIST + L_PAREN "(" + CALL_EXPR + NAME_REF + IDENT "to_tsvector" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'english'" + COMMA "," WHITESPACE " " BIN_EXPR - LITERAL - STRING "' '" + NAME_REF + IDENT "title" WHITESPACE " " CUSTOM_OP PIPE "|" PIPE "|" WHITESPACE " " - CALL_EXPR - NAME_REF - COALESCE_KW "COALESCE" - ARG_LIST - L_PAREN "(" + BIN_EXPR + LITERAL + STRING "' '" + WHITESPACE " " + CUSTOM_OP + PIPE "|" + PIPE "|" + WHITESPACE " " + CALL_EXPR NAME_REF - IDENT "overview" - COMMA "," - WHITESPACE " " - LITERAL - STRING "''" - R_PAREN ")" - R_PAREN ")" - COMMA "," - WHITESPACE " " - NAME_REF - IDENT "query" - R_PAREN ")" - WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + COALESCE_KW "COALESCE" + ARG_LIST + L_PAREN "(" + NAME_REF + IDENT "overview" + COMMA "," + WHITESPACE " " + LITERAL + STRING "''" + R_PAREN ")" + R_PAREN ")" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "query" + R_PAREN ")" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" WHITESPACE "\n" LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -560,26 +561,27 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - BIN_EXPR - FIELD_EXPR - NAME_REF - IDENT "movies" - DOT "." - NAME_REF - IDENT "embedding" - WHITESPACE " " - CUSTOM_OP - L_ANGLE "<" - EQ "=" - R_ANGLE ">" - WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "query_embedding" - DOT "." - NAME_REF - IDENT "embedding" + SORT_BY_LIST + SORT_BY + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "movies" + DOT "." + NAME_REF + IDENT "embedding" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + EQ "=" + R_ANGLE ">" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "query_embedding" + DOT "." + NAME_REF + IDENT "embedding" WHITESPACE "\n" LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -748,12 +750,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "relevance_score" - WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "relevance_score" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" WHITESPACE "\n" LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -1107,38 +1110,40 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "2" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "3" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + LITERAL + INT_NUMBER "3" WHITESPACE "\n" ORDER_BY_CLAUSE ORDER_KW "ORDER" WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "2" - COMMA "," - WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "3" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + SORT_BY + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + SORT_BY + LITERAL + INT_NUMBER "3" SEMICOLON ";" WHITESPACE "\n\n" CREATE_FUNCTION @@ -2114,43 +2119,44 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - BIN_EXPR - NAME_REF - IDENT "vec" - WHITESPACE " " - CUSTOM_OP - L_ANGLE "<" - MINUS "-" - R_ANGLE ">" - WHITESPACE " " - PAREN_EXPR - L_PAREN "(" - SELECT - SELECT_CLAUSE - SELECT_KW "SELECT" - WHITESPACE " " - TARGET_LIST - TARGET - CAST_EXPR - CALL_EXPR - FIELD_EXPR - NAME_REF - IDENT "openai" - DOT "." - NAME_REF - IDENT "vector" - ARG_LIST - L_PAREN "(" - LITERAL - STRING "'What is the Star Trek episode where Deanna and her mother are kidnapped?'" - R_PAREN ")" - COLON_COLON - COLON ":" - COLON ":" - NAME_REF - IDENT "vector" - R_PAREN ")" + SORT_BY_LIST + SORT_BY + BIN_EXPR + NAME_REF + IDENT "vec" + WHITESPACE " " + CUSTOM_OP + L_ANGLE "<" + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "SELECT" + WHITESPACE " " + TARGET_LIST + TARGET + CAST_EXPR + CALL_EXPR + FIELD_EXPR + NAME_REF + IDENT "openai" + DOT "." + NAME_REF + IDENT "vector" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'What is the Star Trek episode where Deanna and her mother are kidnapped?'" + R_PAREN ")" + COLON_COLON + COLON ":" + COLON ":" + NAME_REF + IDENT "vector" + R_PAREN ")" WHITESPACE "\n" LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -2551,21 +2557,23 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" WHITESPACE " " ORDER_BY_CLAUSE ORDER_KW "order" WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "2" - WHITESPACE " " - SORT_DESC - DESC_KW "desc" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "2" + WHITESPACE " " + SORT_DESC + DESC_KW "desc" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "limit" @@ -2820,9 +2828,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "/* define a function that wraps a COPY TO command to export data */" @@ -3113,12 +3122,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - WHITESPACE " " - SORT_DESC - DESC_KW "desc" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" + WHITESPACE " " + SORT_DESC + DESC_KW "desc" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "limit" @@ -3753,9 +3763,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n" CREATE_INDEX @@ -4710,9 +4721,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - MONTH_KW "month" + SORT_BY_LIST + SORT_BY + NAME_REF + MONTH_KW "month" WHITESPACE " \n " FRAME_CLAUSE ROWS_KW "ROWS" @@ -4828,19 +4840,20 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - CALL_EXPR - NAME_REF - IDENT "date_trunc" - ARG_LIST - L_PAREN "(" - LITERAL - STRING "'month'" - COMMA "," - WHITESPACE " " + SORT_BY_LIST + SORT_BY + CALL_EXPR NAME_REF - TIMESTAMP_KW "timestamp" - R_PAREN ")" + IDENT "date_trunc" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'month'" + COMMA "," + WHITESPACE " " + NAME_REF + TIMESTAMP_KW "timestamp" + R_PAREN ")" WHITESPACE "\n " R_PAREN ")" WHITESPACE " " @@ -4862,14 +4875,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "2" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + LITERAL + INT_NUMBER "2" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Use CTEs to break down complex analytics" @@ -4985,9 +4999,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" WHITESPACE "\n" R_PAREN ")" COMMA "," @@ -5174,14 +5189,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "2" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + LITERAL + INT_NUMBER "2" SEMICOLON ";" WHITESPACE "\n\n" EXPLAIN @@ -5261,9 +5277,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Key settings for parallel queries" @@ -5413,9 +5430,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - TIMESTAMP_KW "timestamp" + SORT_BY_LIST + SORT_BY + NAME_REF + TIMESTAMP_KW "timestamp" WHITESPACE "\n" R_PAREN ")" WHITESPACE " " @@ -5428,9 +5446,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Remove unnecessary ORDER BY" @@ -5491,9 +5510,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Gets all rows then filters" @@ -5570,9 +5590,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "user_id" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "user_id" WHITESPACE "\n" R_PAREN ")" SEMICOLON ";" @@ -5615,17 +5636,18 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "user_id" - COMMA "," - WHITESPACE " " - SORT_BY - NAME_REF - TIMESTAMP_KW "timestamp" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "user_id" + COMMA "," WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + SORT_BY + NAME_REF + TIMESTAMP_KW "timestamp" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" SEMICOLON ";" WHITESPACE "\n\n" CREATE_INDEX @@ -5906,25 +5928,27 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE "\n " - GROUPING_EXPR - FIELD_EXPR - NAME_REF - IDENT "p" - DOT "." - NAME_REF - IDENT "sku" + GROUP_BY_LIST + GROUPING_EXPR + FIELD_EXPR + NAME_REF + IDENT "p" + DOT "." + NAME_REF + IDENT "sku" WHITESPACE "\n" ORDER_BY_CLAUSE ORDER_KW "ORDER" WHITESPACE " " BY_KW "BY" WHITESPACE "\n " - SORT_BY - LITERAL - INT_NUMBER "2" - WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "2" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" SEMICOLON ";" WHITESPACE "\n\n" CREATE_INDEX @@ -6283,19 +6307,20 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - DAY_KW "day" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "panel_id" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "expected_power" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + DAY_KW "day" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + NAME_REF + IDENT "panel_id" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + NAME_REF + IDENT "expected_power" WHITESPACE "\n" HAVING_CLAUSE HAVING_KW "HAVING" @@ -6405,9 +6430,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "turbine_id" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "turbine_id" WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n" @@ -6669,26 +6695,28 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - INTERVAL_KW "interval" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "resource_type" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + INTERVAL_KW "interval" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + NAME_REF + IDENT "resource_type" WHITESPACE "\n" ORDER_BY_CLAUSE ORDER_KW "ORDER" WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - INTERVAL_KW "interval" - WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + SORT_BY_LIST + SORT_BY + NAME_REF + INTERVAL_KW "interval" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Identify optimal trading windows" @@ -6769,9 +6797,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "price" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "price" R_PAREN ")" WHITESPACE " " AS_NAME @@ -6818,9 +6847,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - HOUR_KW "hour" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + HOUR_KW "hour" WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n" @@ -6908,8 +6938,9 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - HOUR_KW "hour" + SORT_BY_LIST + SORT_BY + NAME_REF + HOUR_KW "hour" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__precedence_ok.snap b/crates/squawk_parser/tests/snapshots/tests__precedence_ok.snap index 0219f484..29f0cac1 100644 --- a/crates/squawk_parser/tests/snapshots/tests__precedence_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__precedence_ok.snap @@ -99,9 +99,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "baz" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "baz" SEMICOLON ";" WHITESPACE "\n" COMMENT "-- equal to:" @@ -135,8 +136,9 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "baz" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "baz" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_compound_union_select_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_compound_union_select_ok.snap index 45b5c712..1584e544 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_compound_union_select_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_compound_union_select_ok.snap @@ -63,12 +63,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "\"id\"" - WHITESPACE " " - SORT_ASC - ASC_KW "ASC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "\"id\"" + WHITESPACE " " + SORT_ASC + ASC_KW "ASC" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -114,12 +115,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "\"id\"" - WHITESPACE " " - SORT_ASC - ASC_KW "ASC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "\"id\"" + WHITESPACE " " + SORT_ASC + ASC_KW "ASC" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -199,12 +201,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "\"id\"" - WHITESPACE " " - SORT_ASC - ASC_KW "ASC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "\"id\"" + WHITESPACE " " + SORT_ASC + ASC_KW "ASC" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "LIMIT" @@ -248,12 +251,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "\"id\"" - WHITESPACE " " - SORT_ASC - ASC_KW "ASC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "\"id\"" + WHITESPACE " " + SORT_ASC + ASC_KW "ASC" WHITESPACE " " LIMIT_CLAUSE LIMIT_KW "LIMIT" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap index f5a30953..fbe3111f 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap @@ -110,9 +110,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "ordercol" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "ordercol" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- search depth missing comma" @@ -180,9 +181,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "ordercol" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "ordercol" SEMICOLON ";" WHITESPACE "\n\n" SELECT diff --git a/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap index a96fc3b7..bbc00f5e 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap @@ -555,9 +555,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "ordercol" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "ordercol" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- search breadth first (from pg docs)" @@ -747,9 +748,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "ordercol" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "ordercol" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- search cycle (from pg docs)" @@ -1367,12 +1369,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "created_at" - WHITESPACE " " - SORT_DESC - DESC_KW "DESC" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "created_at" + WHITESPACE " " + SORT_DESC + DESC_KW "DESC" WHITESPACE "\n " R_PAREN ")" WHITESPACE "\n " diff --git a/crates/squawk_parser/tests/snapshots/tests__select_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_err.snap index a6b24a5c..5fcde5ea 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_err.snap @@ -179,17 +179,18 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" - COMMA "," - WHITESPACE " " - SORT_BY - NAME_REF - IDENT "b" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "a" + COMMA "," WHITESPACE " " - SORT_DESC - DESC_KW "desc" + SORT_BY + NAME_REF + IDENT "b" + WHITESPACE " " + SORT_DESC + DESC_KW "desc" SEMICOLON ";" WHITESPACE " \n\n" COMMENT "-- group bys with missing commas" @@ -214,19 +215,20 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_ROLLUP - ROLLUP_KW "rollup" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "1" - WHITESPACE " " - LITERAL - INT_NUMBER "2" - WHITESPACE " " - LITERAL - INT_NUMBER "3" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_ROLLUP + ROLLUP_KW "rollup" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -249,19 +251,20 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_CUBE - CUBE_KW "cube" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "1" - WHITESPACE " " - LITERAL - INT_NUMBER "2" - WHITESPACE " " - LITERAL - INT_NUMBER "3" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_CUBE + CUBE_KW "cube" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -284,21 +287,7 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_SETS - GROUPING_KW "grouping" - WHITESPACE " " - SETS_KW "sets" - L_PAREN "(" - GROUPING_EXPR - TUPLE_EXPR - L_PAREN "(" - LITERAL - INT_NUMBER "1" - WHITESPACE " " - LITERAL - INT_NUMBER "2" - R_PAREN ")" - WHITESPACE " " + GROUP_BY_LIST GROUPING_SETS GROUPING_KW "grouping" WHITESPACE " " @@ -307,8 +296,12 @@ SOURCE_FILE GROUPING_EXPR TUPLE_EXPR L_PAREN "(" + LITERAL + INT_NUMBER "1" + WHITESPACE " " + LITERAL + INT_NUMBER "2" R_PAREN ")" - COMMA "," WHITESPACE " " GROUPING_SETS GROUPING_KW "grouping" @@ -319,9 +312,20 @@ SOURCE_FILE TUPLE_EXPR L_PAREN "(" R_PAREN ")" + COMMA "," + WHITESPACE " " + GROUPING_SETS + GROUPING_KW "grouping" + WHITESPACE " " + SETS_KW "sets" + L_PAREN "(" + GROUPING_EXPR + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" R_PAREN ")" R_PAREN ")" - R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- trailing comma in args" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap index 4aa8bc64..8b30cc7c 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap @@ -3249,12 +3249,13 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "v" - WHITESPACE " " - SORT_DESC - DESC_KW "desc" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "v" + WHITESPACE " " + SORT_DESC + DESC_KW "desc" R_PAREN ")" WHITESPACE " " FROM_CLAUSE @@ -3290,9 +3291,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "v" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "v" R_PAREN ")" WHITESPACE " " FROM_CLAUSE @@ -3328,9 +3330,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "a" R_PAREN ")" WHITESPACE " " FROM_CLAUSE @@ -3362,14 +3365,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" - COMMA "," - WHITESPACE " " - SORT_BY - LITERAL - STRING "','" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + SORT_BY + LITERAL + STRING "','" R_PAREN ")" WHITESPACE " " FROM_CLAUSE @@ -3408,9 +3412,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "c" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "c" R_PAREN ")" WHITESPACE " " FROM_CLAUSE @@ -3856,9 +3861,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "a" R_PAREN ")" COMMA "," WHITESPACE " " @@ -3875,9 +3881,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "b" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "b" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap index f6a48c24..2aa1fdfa 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap @@ -3411,9 +3411,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- nulls" @@ -3432,14 +3433,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - WHITESPACE " " - NULLS_FIRST - NULLS_KW "nulls" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" WHITESPACE " " - FIRST_KW "first" + NULLS_FIRST + NULLS_KW "nulls" + WHITESPACE " " + FIRST_KW "first" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3456,14 +3458,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - WHITESPACE " " - NULLS_LAST - NULLS_KW "nulls" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" WHITESPACE " " - LAST_KW "last" + NULLS_LAST + NULLS_KW "nulls" + WHITESPACE " " + LAST_KW "last" SEMICOLON ";" WHITESPACE "\n\n\n" SELECT @@ -3480,19 +3483,20 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - WHITESPACE " " - SORT_USING - USING_KW "using" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" WHITESPACE " " - R_ANGLE ">" - WHITESPACE " " - NULLS_LAST - NULLS_KW "nulls" + SORT_USING + USING_KW "using" + WHITESPACE " " + R_ANGLE ">" WHITESPACE " " - LAST_KW "last" + NULLS_LAST + NULLS_KW "nulls" + WHITESPACE " " + LAST_KW "last" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- select_window_clause" @@ -3548,9 +3552,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -3826,10 +3831,11 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - TUPLE_EXPR - L_PAREN "(" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_EXPR + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- simple expr" @@ -3848,9 +3854,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- multi expr" @@ -3874,14 +3881,15 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "2" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + LITERAL + INT_NUMBER "2" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- all" @@ -3902,9 +3910,10 @@ SOURCE_FILE WHITESPACE " " ALL_KW "all" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- distinct" @@ -3925,9 +3934,10 @@ SOURCE_FILE WHITESPACE " " DISTINCT_KW "distinct" WHITESPACE " " - GROUPING_EXPR - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_EXPR + LITERAL + INT_NUMBER "1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- rollup" @@ -3946,17 +3956,18 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_ROLLUP - ROLLUP_KW "rollup" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "2" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_ROLLUP + ROLLUP_KW "rollup" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- rollup multi" @@ -3975,26 +3986,27 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_ROLLUP - ROLLUP_KW "rollup" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "1" + GROUP_BY_LIST + GROUPING_ROLLUP + ROLLUP_KW "rollup" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" COMMA "," WHITESPACE " " - LITERAL - INT_NUMBER "2" - R_PAREN ")" - COMMA "," - WHITESPACE " " - GROUPING_ROLLUP - ROLLUP_KW "rollup" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "3" - R_PAREN ")" + GROUPING_ROLLUP + ROLLUP_KW "rollup" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "3" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- cube" @@ -4015,21 +4027,22 @@ SOURCE_FILE WHITESPACE " " DISTINCT_KW "distinct" WHITESPACE " " - GROUPING_CUBE - CUBE_KW "cube" - WHITESPACE " " - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "2" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "3" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_CUBE + CUBE_KW "cube" + WHITESPACE " " + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- grouping sets" @@ -4048,55 +4061,56 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_SETS - GROUPING_KW "grouping" - WHITESPACE " " - SETS_KW "sets" - WHITESPACE " " - L_PAREN "(" - WHITESPACE "\n " - GROUPING_EXPR - TUPLE_EXPR - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "2" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "3" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - GROUPING_EXPR - TUPLE_EXPR - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "2" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - GROUPING_EXPR - PAREN_EXPR - L_PAREN "(" - LITERAL - INT_NUMBER "1" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - GROUPING_EXPR - TUPLE_EXPR - L_PAREN "(" - R_PAREN ")" - WHITESPACE "\n" - R_PAREN ")" + GROUP_BY_LIST + GROUPING_SETS + GROUPING_KW "grouping" + WHITESPACE " " + SETS_KW "sets" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + GROUPING_EXPR + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + GROUPING_EXPR + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + GROUPING_EXPR + PAREN_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + GROUPING_EXPR + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + WHITESPACE "\n" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- select_with_offset_clause" @@ -4199,9 +4213,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" + SORT_BY_LIST + SORT_BY + LITERAL + INT_NUMBER "1" WHITESPACE " " FETCH_CLAUSE FETCH_KW "fetch" @@ -4806,9 +4821,10 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "f1" + GROUP_BY_LIST + GROUPING_EXPR + NAME_REF + IDENT "f1" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- using w/ join alias" @@ -5923,17 +5939,18 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" - WHITESPACE " " - SORT_USING - USING_KW "using" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "a" WHITESPACE " " - CUSTOM_OP - R_ANGLE ">" - R_ANGLE ">" - R_ANGLE ">" + SORT_USING + USING_KW "using" + WHITESPACE " " + CUSTOM_OP + R_ANGLE ">" + R_ANGLE ">" + R_ANGLE ">" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- order_by_regression" @@ -6046,38 +6063,40 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - GROUPING_EXPR - NAME_REF - IDENT "sensor_id" - COMMA "," - WHITESPACE " " - GROUPING_EXPR - CALL_EXPR + GROUP_BY_LIST + GROUPING_EXPR NAME_REF - IDENT "DATE_TRUNC" - ARG_LIST - L_PAREN "(" - LITERAL - STRING "'day'" - COMMA "," - WHITESPACE " " + IDENT "sensor_id" + COMMA "," + WHITESPACE " " + GROUPING_EXPR + CALL_EXPR NAME_REF - IDENT "ts" - R_PAREN ")" + IDENT "DATE_TRUNC" + ARG_LIST + L_PAREN "(" + LITERAL + STRING "'day'" + COMMA "," + WHITESPACE " " + NAME_REF + IDENT "ts" + R_PAREN ")" WHITESPACE "\n" ORDER_BY_CLAUSE ORDER_KW "ORDER" WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - NAME_REF - IDENT "sensor_id" - COMMA "," - WHITESPACE " " - SORT_BY - NAME_REF - DAY_KW "day" + SORT_BY_LIST + SORT_BY + NAME_REF + IDENT "sensor_id" + COMMA "," + WHITESPACE " " + SORT_BY + NAME_REF + DAY_KW "day" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- select with uescape;" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap index da396b95..3bb5b225 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap @@ -4139,23 +4139,24 @@ SOURCE_FILE WHITESPACE " " BY_KW "by" WHITESPACE " " - SORT_BY - BIN_EXPR - NAME_REF - IDENT "a" - WHITESPACE " " - CUSTOM_OP - PIPE "|" - PIPE "|" - WHITESPACE " " + SORT_BY_LIST + SORT_BY BIN_EXPR NAME_REF - IDENT "b" + IDENT "a" WHITESPACE " " - COLLATE_KW "collate" + CUSTOM_OP + PIPE "|" + PIPE "|" WHITESPACE " " - NAME_REF - IDENT "\"fr_FR\"" + BIN_EXPR + NAME_REF + IDENT "b" + WHITESPACE " " + COLLATE_KW "collate" + WHITESPACE " " + NAME_REF + IDENT "\"fr_FR\"" SEMICOLON ";" WHITESPACE "\n\n" SELECT diff --git a/crates/squawk_parser/tests/snapshots/tests__update_ok.snap b/crates/squawk_parser/tests/snapshots/tests__update_ok.snap index 3878f412..603ed2a1 100644 --- a/crates/squawk_parser/tests/snapshots/tests__update_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__update_ok.snap @@ -1200,13 +1200,14 @@ SOURCE_FILE WHITESPACE " " BY_KW "BY" WHITESPACE " " - SORT_BY - FIELD_EXPR - NAME_REF - IDENT "w" - DOT "." - NAME_REF - IDENT "retry_timestamp" + SORT_BY_LIST + SORT_BY + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "retry_timestamp" WHITESPACE "\n " LOCKING_CLAUSE FOR_KW "FOR" diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index cb71fd18..6fd3506a 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -5104,19 +5104,7 @@ pub struct GroupByClause { } impl GroupByClause { #[inline] - pub fn grouping_cube(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn grouping_expr(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn grouping_rollup(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn grouping_sets(&self) -> Option { + pub fn group_by_list(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -5137,6 +5125,17 @@ impl GroupByClause { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct GroupByList { + pub(crate) syntax: SyntaxNode, +} +impl GroupByList { + #[inline] + pub fn group_bys(&self) -> AstChildren { + support::children(&self.syntax) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GroupingCube { pub(crate) syntax: SyntaxNode, @@ -7624,8 +7623,8 @@ pub struct OrderByClause { } impl OrderByClause { #[inline] - pub fn sort_bys(&self) -> AstChildren { - support::children(&self.syntax) + pub fn sort_by_list(&self) -> Option { + support::child(&self.syntax) } #[inline] pub fn by_token(&self) -> Option { @@ -9563,6 +9562,17 @@ impl SortBy { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SortByList { + pub(crate) syntax: SyntaxNode, +} +impl SortByList { + #[inline] + pub fn sort_bys(&self) -> AstChildren { + support::children(&self.syntax) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SortDesc { pub(crate) syntax: SyntaxNode, @@ -10693,6 +10703,14 @@ pub enum FuncOption { WindowFuncOption(WindowFuncOption), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum GroupBy { + GroupingCube(GroupingCube), + GroupingExpr(GroupingExpr), + GroupingRollup(GroupingRollup), + GroupingSets(GroupingSets), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum JoinType { JoinCross(JoinCross), @@ -15092,6 +15110,24 @@ impl AstNode for GroupByClause { &self.syntax } } +impl AstNode for GroupByList { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::GROUP_BY_LIST + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} impl AstNode for GroupingCube { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -19142,6 +19178,24 @@ impl AstNode for SortBy { &self.syntax } } +impl AstNode for SortByList { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::SORT_BY_LIST + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} impl AstNode for SortDesc { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -21389,6 +21443,64 @@ impl From for FuncOption { FuncOption::WindowFuncOption(node) } } +impl AstNode for GroupBy { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::GROUPING_CUBE + | SyntaxKind::GROUPING_EXPR + | SyntaxKind::GROUPING_ROLLUP + | SyntaxKind::GROUPING_SETS + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::GROUPING_CUBE => GroupBy::GroupingCube(GroupingCube { syntax }), + SyntaxKind::GROUPING_EXPR => GroupBy::GroupingExpr(GroupingExpr { syntax }), + SyntaxKind::GROUPING_ROLLUP => GroupBy::GroupingRollup(GroupingRollup { syntax }), + SyntaxKind::GROUPING_SETS => GroupBy::GroupingSets(GroupingSets { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + GroupBy::GroupingCube(it) => &it.syntax, + GroupBy::GroupingExpr(it) => &it.syntax, + GroupBy::GroupingRollup(it) => &it.syntax, + GroupBy::GroupingSets(it) => &it.syntax, + } + } +} +impl From for GroupBy { + #[inline] + fn from(node: GroupingCube) -> GroupBy { + GroupBy::GroupingCube(node) + } +} +impl From for GroupBy { + #[inline] + fn from(node: GroupingExpr) -> GroupBy { + GroupBy::GroupingExpr(node) + } +} +impl From for GroupBy { + #[inline] + fn from(node: GroupingRollup) -> GroupBy { + GroupBy::GroupingRollup(node) + } +} +impl From for GroupBy { + #[inline] + fn from(node: GroupingSets) -> GroupBy { + GroupBy::GroupingSets(node) + } +} impl AstNode for JoinType { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index 52bb31bb..e625ace4 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -538,7 +538,16 @@ WhereClause = 'where' Expr GroupByClause = - 'group' 'by' ('all' | 'distinct') (GroupingRollup | GroupingCube | GroupingSets | GroupingExpr) + 'group' 'by' ('all' | 'distinct') GroupByList + +GroupByList = + GroupBy (',' GroupBy)* + +GroupBy = + GroupingExpr +| GroupingRollup +| GroupingCube +| GroupingSets GroupingRollup = 'rollup' Expr @@ -1195,7 +1204,10 @@ SortBy = Expr (SortAsc | SortDesc | SortUsing)? (NullsFirst | NullsLast)? OrderByClause = - 'order' 'by' (SortBy (',' SortBy)*) + 'order' 'by' SortByList + +SortByList = + SortBy (',' SortBy)* FromItem = 'only'? NameRef Alias?