diff --git a/crates/squawk_linter/src/rules/prefer_timestamptz.rs b/crates/squawk_linter/src/rules/prefer_timestamptz.rs index 6f35a0f4..3756b1cd 100644 --- a/crates/squawk_linter/src/rules/prefer_timestamptz.rs +++ b/crates/squawk_linter/src/rules/prefer_timestamptz.rs @@ -32,7 +32,9 @@ pub fn is_not_allowed_timestamp(ty: &ast::Type) -> bool { ast::Type::BitType(_) => false, ast::Type::DoubleType(_) => false, ast::Type::TimeType(time_type) => { - if time_type.timestamp_token().is_some() && time_type.with_timezone().is_none() { + if time_type.timestamp_token().is_some() + && !matches!(time_type.timezone(), Some(ast::Timezone::WithTimezone(_))) + { return true; } false diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index c6b6855f..797ed233 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -763,6 +763,7 @@ pub enum SyntaxKind { FILTER_CLAUSE, FORCE_RLS, FOREIGN_KEY_CONSTRAINT, + FRAME_CLAUSE, FROM_CLAUSE, FROM_ITEM, FUNC_OPTION, @@ -838,6 +839,7 @@ pub enum SyntaxKind { MATCH_PARTIAL, MATCH_SIMPLE, MATCH_TYPE, + MATERIALIZED, MERGE, MOVE, NAME, @@ -852,6 +854,7 @@ pub enum SyntaxKind { NOT_ILIKE, NOT_IN, NOT_LIKE, + NOT_MATERIALIZED, NOT_NULL_CONSTRAINT, NOT_OF, NOT_SIMILAR_TO, @@ -890,8 +893,13 @@ pub enum SyntaxKind { PAREN_EXPR, PAREN_SELECT, PARTITION_BY, + PARTITION_DEFAULT, + PARTITION_FOR_VALUES_FROM, + PARTITION_FOR_VALUES_IN, + PARTITION_FOR_VALUES_WITH, PARTITION_ITEM, PARTITION_OF, + PARTITION_TYPE, PATH, PATH_SEGMENT, PATH_TYPE, @@ -988,9 +996,9 @@ pub enum SyntaxKind { TABLE_LIST, TARGET, TARGET_LIST, + TIMEZONE, TIME_TYPE, TRANSACTION_MODE, - TRANSACTION_MODE_ISOLATION_LEVEL, TRANSACTION_MODE_LIST, TRANSFORM_FUNC_OPTION, TRUNCATE, @@ -1012,6 +1020,7 @@ pub enum SyntaxKind { WINDOW_CLAUSE, WINDOW_DEF, WINDOW_FUNC_OPTION, + WINDOW_SPEC, WITHIN_CLAUSE, WITHOUT_OIDS, WITHOUT_TIMEZONE, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index a567656b..0a8bed6f 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -1959,17 +1959,12 @@ fn call_expr_args(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { } fn opt_agg_clauses(p: &mut Parser<'_>) { - // postgres has: - // func_expr: func_application within_group_clause filter_clause over_clause - if p.at(WITHIN_KW) { - let m = p.start(); - p.expect(WITHIN_KW); - p.expect(GROUP_KW); - p.expect(L_PAREN); - opt_order_by_clause(p); - p.expect(R_PAREN); - m.complete(p, WITHIN_CLAUSE); - } + opt_within_clause(p); + opt_filter_clause(p); + opt_over_clause(p); +} + +fn opt_filter_clause(p: &mut Parser<'_>) { if p.at(FILTER_KW) { let m = p.start(); p.expect(FILTER_KW); @@ -1981,13 +1976,16 @@ fn opt_agg_clauses(p: &mut Parser<'_>) { p.expect(R_PAREN); m.complete(p, FILTER_CLAUSE); } +} + +fn opt_over_clause(p: &mut Parser<'_>) { if p.at(OVER_KW) { // OVER window_name // OVER ( window_definition ) let m = p.start(); p.expect(OVER_KW); if p.eat(L_PAREN) { - window_definition(p); + window_spec(p); p.expect(R_PAREN); } else { name_ref(p); @@ -1996,6 +1994,18 @@ fn opt_agg_clauses(p: &mut Parser<'_>) { } } +fn opt_within_clause(p: &mut Parser<'_>) { + if p.at(WITHIN_KW) { + let m = p.start(); + p.expect(WITHIN_KW); + p.expect(GROUP_KW); + p.expect(L_PAREN); + opt_order_by_clause(p); + p.expect(R_PAREN); + m.complete(p, WITHIN_CLAUSE); + } +} + // foo[] // foo[:b] // foo[a:] @@ -2360,12 +2370,7 @@ fn with_query(p: &mut Parser<'_>) -> CompletedMarker { name(p); opt_column_list_with(p, ColumnDefKind::Name); p.expect(AS_KW); - // [ [ NOT ] MATERIALIZED ] - if p.eat(NOT_KW) { - p.expect(MATERIALIZED_KW); - } else { - p.eat(MATERIALIZED_KW); - } + opt_materialized(p); p.expect(L_PAREN); preparable_stmt(p); p.expect(R_PAREN); @@ -2387,31 +2392,50 @@ fn with_query(p: &mut Parser<'_>) -> CompletedMarker { p.expect(SET_KW); name_ref(p); } - // [ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ] - if p.eat(CYCLE_KW) { - separated( - p, - COMMA, - || "unexpected comma, expected a column name".to_string(), - NAME_REF_FIRST, - TokenSet::new(&[SET_KW]), - |p| opt_name_ref(p).is_some(), - ); - p.expect(SET_KW); - name_ref(p); - if p.eat(TO_KW) { - if expr(p).is_none() { - p.error("expected an expression"); - } - p.expect(DEFAULT_KW); - if expr(p).is_none() { - p.error("expected an expression"); - } + opt_cycle_clause(p); + m.complete(p, WITH_TABLE) +} + +// [ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ] +fn opt_cycle_clause(p: &mut Parser<'_>) { + if !p.at(CYCLE_KW) { + return; + } + p.expect(CYCLE_KW); + separated( + p, + COMMA, + || "unexpected comma, expected a column name".to_string(), + NAME_REF_FIRST, + TokenSet::new(&[SET_KW]), + |p| opt_name_ref(p).is_some(), + ); + p.expect(SET_KW); + name_ref(p); + if p.eat(TO_KW) { + if expr(p).is_none() { + p.error("expected an expression"); + } + p.expect(DEFAULT_KW); + if expr(p).is_none() { + p.error("expected an expression"); } - p.expect(USING_KW); - name_ref(p); } - m.complete(p, WITH_TABLE) + p.expect(USING_KW); + name_ref(p); +} + +// [ [ NOT ] MATERIALIZED ] +fn opt_materialized(p: &mut Parser<'_>) { + let m = p.start(); + if p.eat(NOT_KW) { + p.expect(MATERIALIZED_KW); + m.complete(p, NOT_MATERIALIZED); + } else if p.eat(MATERIALIZED_KW) { + m.complete(p, MATERIALIZED); + } else { + m.abandon(p); + } } const WITH_FOLLOW: TokenSet = TokenSet::new(&[ @@ -4350,7 +4374,7 @@ const WINDOW_DEF_START: TokenSet = // The frame_clause can be one of // { RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ] // { RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ] -fn window_definition(p: &mut Parser<'_>) -> Option { +fn window_spec(p: &mut Parser<'_>) -> Option { if !p.at_ts(WINDOW_DEF_START) { return None; } @@ -4363,7 +4387,13 @@ fn window_definition(p: &mut Parser<'_>) -> Option { } } opt_order_by_clause(p); + opt_frame_clause(p); + Some(m.complete(p, WINDOW_SPEC)) +} + +fn opt_frame_clause(p: &mut Parser<'_>) { if p.at(RANGE_KW) || p.at(ROWS_KW) || p.at(GROUPS_KW) { + let m = p.start(); p.bump_any(); if p.eat(BETWEEN_KW) { frame_start_end(p); @@ -4374,8 +4404,8 @@ fn window_definition(p: &mut Parser<'_>) -> Option { frame_start_end(p); opt_frame_exclusion(p); } + m.complete(p, FRAME_CLAUSE); } - Some(m.complete(p, WINDOW_DEF)) } /// @@ -4393,11 +4423,13 @@ fn opt_window_clause(p: &mut Parser<'_>) -> Option { } fn window_def(p: &mut Parser<'_>) { + let m = p.start(); name(p); p.expect(AS_KW); p.expect(L_PAREN); - window_definition(p); + window_spec(p); p.expect(R_PAREN); + m.complete(p, WINDOW_DEF); } // [ LIMIT { count | ALL } ] @@ -4787,7 +4819,8 @@ fn table_arg_list(p: &mut Parser<'_>, t: ColDefType) -> Option // { FOR VALUES partition_bound_spec | DEFAULT } fn partition_option(p: &mut Parser<'_>) { - if p.eat(FOR_KW) { + let m = p.start(); + let kind = if p.eat(FOR_KW) { p.expect(VALUES_KW); // FOR VALUES WITH (modulus 5, remainder 0) if p.eat(WITH_KW) { @@ -4798,6 +4831,7 @@ fn partition_option(p: &mut Parser<'_>) { ident(p); p.expect(INT_NUMBER); p.expect(R_PAREN); + PARTITION_FOR_VALUES_WITH // FOR VALUES IN '(' expr_list ')' } else if p.eat(IN_KW) { p.expect(L_PAREN); @@ -4805,6 +4839,7 @@ fn partition_option(p: &mut Parser<'_>) { p.error("expected expr list"); } p.expect(R_PAREN); + PARTITION_FOR_VALUES_IN // FOR VALUES FROM '(' expr_list ')' TO '(' expr_list ')' } else if p.eat(FROM_KW) { p.expect(L_PAREN); @@ -4818,11 +4853,17 @@ fn partition_option(p: &mut Parser<'_>) { p.error("expected expr list"); } p.expect(R_PAREN); + PARTITION_FOR_VALUES_FROM + } else { + p.error("expected partition option"); + PARTITION_DEFAULT } // DEFAULT } else { p.expect(DEFAULT_KW); - } + PARTITION_DEFAULT + }; + m.complete(p, kind); } fn opt_inherits_tables(p: &mut Parser<'_>) { @@ -4909,14 +4950,7 @@ fn create_table(p: &mut Parser<'_>) -> CompletedMarker { // AS query // [ WITH [ NO ] DATA ] if p.eat(AS_KW) { - match stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ) - .map(|x| x.kind()) - { + match stmt(p, &StmtRestrictions::default()).map(|x| x.kind()) { Some( SELECT | COMPOUND_SELECT | SELECT_INTO | PAREN_SELECT | TABLE | VALUES | EXECUTE, ) => (), @@ -5104,38 +5138,46 @@ fn opt_transaction_mode(p: &mut Parser<'_>) -> bool { if !p.at_ts(TRANSACTION_MODE_FIRST) { return false; } + let m = p.start(); // ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED } - if p.eat(ISOLATION_KW) { + let kind = if p.eat(ISOLATION_KW) { p.expect(LEVEL_KW); if p.eat(SERIALIZABLE_KW) { - true + SERIALIZABLE } else if p.eat(REPEATABLE_KW) { - p.expect(READ_KW) + p.expect(READ_KW); + REPEATABLE_READ } else if p.eat(READ_KW) { - p.eat(UNCOMMITTED_KW) || p.expect(COMMITTED_KW) + if p.eat(UNCOMMITTED_KW) { + READ_UNCOMMITTED + } else { + p.expect(COMMITTED_KW); + READ_COMMITTED + } } else { - false + p.error("expected isolation level"); + READ_COMMITTED } // READ WRITE | READ ONLY } else if p.eat(READ_KW) { - p.eat(WRITE_KW) || p.expect(ONLY_KW) + if p.eat(WRITE_KW) { + READ_WRITE + } else { + p.expect(ONLY_KW); + READ_ONLY + } // [ NOT ] DEFERRABLE } else { - p.eat(NOT_KW); - p.expect(DEFERRABLE_KW) - } -} - -// [ transaction_mode [, ...] ] -fn opt_transaction_mode_list(p: &mut Parser<'_>) { - while !p.at(EOF) { - if !opt_transaction_mode(p) { - break; - } - if !p.eat(COMMA) && !p.at_ts(TRANSACTION_MODE_FIRST) { - break; - } - } + let kind = if p.eat(NOT_KW) { + NOT_DEFERRABLE + } else { + DEFERRABLE + }; + p.expect(DEFERRABLE_KW); + kind + }; + m.complete(p, kind); + true } // BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ] @@ -5156,12 +5198,12 @@ fn begin(p: &mut Parser<'_>) -> CompletedMarker { if p.eat(BEGIN_KW) { // [ WORK | TRANSACTION ] let _ = p.eat(WORK_KW) || p.eat(TRANSACTION_KW); - opt_transaction_mode_list(p); + transaction_mode_list(p); } else { // START TRANSACTION [ transaction_mode [, ...] ] p.bump(START_KW); p.expect(TRANSACTION_KW); - opt_transaction_mode_list(p); + transaction_mode_list(p); } m.complete(p, BEGIN) } @@ -5258,6 +5300,7 @@ fn rollback(p: &mut Parser<'_>) -> CompletedMarker { m.complete(p, ROLLBACK) } +#[derive(Default)] struct StmtRestrictions { begin_end_allowed: bool, } @@ -8601,12 +8644,7 @@ fn create_materialized_view(p: &mut Parser<'_>) -> CompletedMarker { opt_tablespace(p); p.expect(AS_KW); // A SELECT, TABLE, or VALUES command. - let statement = stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + let statement = stmt(p, &StmtRestrictions::default()); match statement.map(|x| x.kind()) { Some(SELECT | SELECT_INTO | COMPOUND_SELECT | TABLE | VALUES) => (), Some(kind) => { @@ -8922,12 +8960,7 @@ fn create_role(p: &mut Parser<'_>) -> CompletedMarker { fn select_insert_delete_update_or_notify(p: &mut Parser<'_>) { // statement // Any SELECT, INSERT, UPDATE, DELETE, MERGE, or VALUES statement. - let statement = stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + let statement = stmt(p, &StmtRestrictions::default()); if let Some(statement) = statement { match statement.kind() { SELECT | VALUES | INSERT | UPDATE | DELETE | NOTIFY => (), @@ -9907,12 +9940,7 @@ fn explain(p: &mut Parser<'_>) -> CompletedMarker { p.expect(R_PAREN); } // statement is SELECT, INSERT, UPDATE, DELETE, MERGE, VALUES, EXECUTE, DECLARE, CREATE TABLE AS, or CREATE MATERIALIZED VIEW AS - let statement = stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + let statement = stmt(p, &StmtRestrictions::default()); if let Some(statement) = statement { match statement.kind() { SELECT @@ -10954,12 +10982,7 @@ fn create_view(p: &mut Parser<'_>) -> CompletedMarker { // TODO: this can be more specific opt_with_params(p); p.expect(AS_KW); - match stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ) { + match stmt(p, &StmtRestrictions::default()) { Some(statement) => match statement.kind() { SELECT | COMPOUND_SELECT | SELECT_INTO | VALUES | TABLE => (), kind => p.error(format!("expected SELECT, got {:?}", kind)), @@ -11156,12 +11179,7 @@ fn declare(p: &mut Parser<'_>) -> CompletedMarker { } p.expect(FOR_KW); // select stmt - let statement = stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + let statement = stmt(p, &StmtRestrictions::default()); match statement.map(|x| x.kind()) { Some(SELECT | SELECT_INTO | COMPOUND_SELECT | TABLE | VALUES) => (), Some(kind) => { @@ -11588,12 +11606,7 @@ fn copy(p: &mut Parser<'_>) -> CompletedMarker { } fn preparable_stmt(p: &mut Parser<'_>) { - let statement = stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + let statement = stmt(p, &StmtRestrictions::default()); match statement.map(|x| x.kind()) { // select | insert | update | delete | merge Some( @@ -12624,12 +12637,7 @@ fn opt_function_option(p: &mut Parser<'_>) -> bool { p.error("expected expr") } } else { - stmt( - p, - &StmtRestrictions { - begin_end_allowed: false, - }, - ); + stmt(p, &StmtRestrictions::default()); } if p.at(END_KW) { p.expect(SEMICOLON); diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_table_ok.snap b/crates/squawk_parser/tests/snapshots/tests__alter_table_ok.snap index c878f572..72782947 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_table_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_table_ok.snap @@ -3583,7 +3583,8 @@ SOURCE_FILE NAME_REF IDENT "f" WHITESPACE " " - DEFAULT_KW "default" + PARTITION_DEFAULT + DEFAULT_KW "default" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- partition spec" @@ -3609,20 +3610,21 @@ SOURCE_FILE NAME_REF IDENT "f" WHITESPACE " " - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - IN_KW "in" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'bar'" - COMMA "," - WHITESPACE " " - LITERAL - STRING "'buzz'" - R_PAREN ")" + PARTITION_FOR_VALUES_IN + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- multiple_actions" diff --git a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap index 3122da0f..32dd90e8 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_foreign_table_ok.snap @@ -248,7 +248,8 @@ SOURCE_FILE NAME_REF IDENT "u" WHITESPACE "\n " - DEFAULT_KW "default" + PARTITION_DEFAULT + DEFAULT_KW "default" WHITESPACE "\n " SERVER_KW "server" WHITESPACE " " @@ -349,7 +350,8 @@ SOURCE_FILE WHITESPACE "\n " R_PAREN ")" WHITESPACE "\n " - DEFAULT_KW "default" + PARTITION_DEFAULT + DEFAULT_KW "default" WHITESPACE "\n " SERVER_KW "server" WHITESPACE " " @@ -410,22 +412,23 @@ SOURCE_FILE WHITESPACE "\n " R_PAREN ")" WHITESPACE "\n " - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - IN_KW "in" - WHITESPACE " " - L_PAREN "(" - BIN_EXPR - NAME_REF - IDENT "a" + PARTITION_FOR_VALUES_IN + FOR_KW "for" WHITESPACE " " - R_ANGLE ">" + VALUES_KW "values" WHITESPACE " " - NAME_REF - IDENT "b" - R_PAREN ")" + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + R_PAREN ")" WHITESPACE "\n " SERVER_KW "server" WHITESPACE " " @@ -469,41 +472,42 @@ SOURCE_FILE WHITESPACE "\n " R_PAREN ")" WHITESPACE "\n " - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - FROM_KW "from" - WHITESPACE " " - L_PAREN "(" - BIN_EXPR + PARTITION_FOR_VALUES_FROM + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + BIN_EXPR + NAME_REF + IDENT "a" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " NAME_REF - IDENT "a" + MINVALUE_KW "minvalue" + COMMA "," WHITESPACE " " - R_ANGLE ">" + NAME_REF + MAXVALUE_KW "maxvalue" + R_PAREN ")" + WHITESPACE " \n " + TO_KW "to" WHITESPACE " " + L_PAREN "(" NAME_REF - IDENT "b" - COMMA "," - WHITESPACE " " - NAME_REF - MINVALUE_KW "minvalue" - COMMA "," - WHITESPACE " " - NAME_REF - MAXVALUE_KW "maxvalue" - R_PAREN ")" - WHITESPACE " \n " - TO_KW "to" - WHITESPACE " " - L_PAREN "(" - NAME_REF - MAXVALUE_KW "maxvalue" - COMMA "," - WHITESPACE " " - NAME_REF - MINVALUE_KW "minvalue" - R_PAREN ")" + MAXVALUE_KW "maxvalue" + COMMA "," + WHITESPACE " " + NAME_REF + MINVALUE_KW "minvalue" + R_PAREN ")" WHITESPACE "\n " SERVER_KW "server" WHITESPACE " " @@ -547,22 +551,23 @@ SOURCE_FILE WHITESPACE "\n " R_PAREN ")" WHITESPACE "\n " - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - WITH_KW "with" - WHITESPACE " " - L_PAREN "(" - IDENT "modulus" - WHITESPACE " " - INT_NUMBER "10" - COMMA "," - WHITESPACE " " - IDENT "remainder" - WHITESPACE " " - INT_NUMBER "2" - R_PAREN ")" + PARTITION_FOR_VALUES_WITH + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + IDENT "modulus" + WHITESPACE " " + INT_NUMBER "10" + COMMA "," + WHITESPACE " " + IDENT "remainder" + WHITESPACE " " + INT_NUMBER "2" + R_PAREN ")" WHITESPACE "\n " SERVER_KW "server" WHITESPACE " " diff --git a/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap index 6daeaa13..0493adfd 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap @@ -2892,7 +2892,8 @@ SOURCE_FILE NAME_REF IDENT "bar" WHITESPACE " " - DEFAULT_KW "default" + PARTITION_DEFAULT + DEFAULT_KW "default" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE @@ -2951,7 +2952,8 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE " " - DEFAULT_KW "default" + PARTITION_DEFAULT + DEFAULT_KW "default" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE @@ -2981,22 +2983,23 @@ SOURCE_FILE NAME_REF IDENT "bar" WHITESPACE " \n" - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - WITH_KW "with" - WHITESPACE " " - L_PAREN "(" - IDENT "modulus" - WHITESPACE " " - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - IDENT "remainder" - WHITESPACE " " - INT_NUMBER "1" - R_PAREN ")" + PARTITION_FOR_VALUES_WITH + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + WITH_KW "with" + WHITESPACE " " + L_PAREN "(" + IDENT "modulus" + WHITESPACE " " + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + IDENT "remainder" + WHITESPACE " " + INT_NUMBER "1" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE @@ -3026,20 +3029,21 @@ SOURCE_FILE NAME_REF IDENT "bar" WHITESPACE " \n" - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - IN_KW "in" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'bar'" - COMMA "," - WHITESPACE " " - LITERAL - STRING "'buzz'" - R_PAREN ")" + PARTITION_FOR_VALUES_IN + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + IN_KW "in" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + COMMA "," + WHITESPACE " " + LITERAL + STRING "'buzz'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE @@ -3069,23 +3073,24 @@ SOURCE_FILE NAME_REF IDENT "bar" WHITESPACE "\n" - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - FROM_KW "from" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'bar'" - R_PAREN ")" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'buzz'" - R_PAREN ")" + PARTITION_FOR_VALUES_FROM + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'bar'" + R_PAREN ")" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'buzz'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE @@ -3137,23 +3142,24 @@ SOURCE_FILE WHITESPACE "\n" R_PAREN ")" WHITESPACE " " - FOR_KW "for" - WHITESPACE " " - VALUES_KW "values" - WHITESPACE " " - FROM_KW "from" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2016-09-01'" - R_PAREN ")" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2016-10-01'" - R_PAREN ")" + PARTITION_FOR_VALUES_FROM + FOR_KW "for" + WHITESPACE " " + VALUES_KW "values" + WHITESPACE " " + FROM_KW "from" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2016-09-01'" + R_PAREN ")" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2016-10-01'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" CREATE_TABLE diff --git a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap index e1fbf4de..8c58d1b5 100644 --- a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap @@ -1273,7 +1273,8 @@ SOURCE_FILE NAME_REF IDENT "time_taptest_table" WHITESPACE " " - DEFAULT_KW "DEFAULT" + PARTITION_DEFAULT + DEFAULT_KW "DEFAULT" SEMICOLON ";" WHITESPACE "\n\n" INSERT @@ -1383,23 +1384,24 @@ SOURCE_FILE NAME_REF IDENT "time_taptest_table" WHITESPACE " " - FOR_KW "FOR" - WHITESPACE " " - VALUES_KW "VALUES" - WHITESPACE " " - FROM_KW "FROM" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2024-12-25'" - R_PAREN ")" - WHITESPACE " " - TO_KW "TO" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2024-12-26'" - R_PAREN ")" + PARTITION_FOR_VALUES_FROM + FOR_KW "FOR" + WHITESPACE " " + VALUES_KW "VALUES" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-25'" + R_PAREN ")" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-26'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" BEGIN @@ -1555,23 +1557,24 @@ SOURCE_FILE NAME_REF IDENT "time_taptest_table" WHITESPACE " " - FOR_KW "FOR" - WHITESPACE " " - VALUES_KW "VALUES" - WHITESPACE " " - FROM_KW "FROM" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2024-12-25'" - R_PAREN ")" - WHITESPACE " " - TO_KW "TO" - WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'2024-12-26'" - R_PAREN ")" + PARTITION_FOR_VALUES_FROM + FOR_KW "FOR" + WHITESPACE " " + VALUES_KW "VALUES" + WHITESPACE " " + FROM_KW "FROM" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-25'" + R_PAREN ")" + WHITESPACE " " + TO_KW "TO" + WHITESPACE " " + L_PAREN "(" + LITERAL + STRING "'2024-12-26'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" INSERT @@ -4674,7 +4677,7 @@ SOURCE_FILE WHITESPACE " " L_PAREN "(" WHITESPACE "\n " - WINDOW_DEF + WINDOW_SPEC ORDER_BY_CLAUSE ORDER_KW "ORDER" WHITESPACE " " @@ -4684,20 +4687,21 @@ SOURCE_FILE NAME_REF MONTH_KW "month" WHITESPACE " \n " - ROWS_KW "ROWS" - WHITESPACE " " - BETWEEN_KW "BETWEEN" - WHITESPACE " " - LITERAL - INT_NUMBER "2" - WHITESPACE " " - PRECEDING_KW "PRECEDING" - WHITESPACE " " - AND_KW "AND" - WHITESPACE " " - CURRENT_KW "CURRENT" - WHITESPACE " " - ROW_KW "ROW" + FRAME_CLAUSE + ROWS_KW "ROWS" + WHITESPACE " " + BETWEEN_KW "BETWEEN" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + WHITESPACE " " + PRECEDING_KW "PRECEDING" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + CURRENT_KW "CURRENT" + WHITESPACE " " + ROW_KW "ROW" WHITESPACE "\n " R_PAREN ")" WHITESPACE " " @@ -4781,7 +4785,7 @@ SOURCE_FILE WHITESPACE " " L_PAREN "(" WHITESPACE "\n " - WINDOW_DEF + WINDOW_SPEC PARTITION_KW "PARTITION" WHITESPACE " " BY_KW "BY" 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 69600a9b..4bc08d9e 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap @@ -216,7 +216,8 @@ SOURCE_FILE WHITESPACE " " AS_KW "as" WHITESPACE " " - MATERIALIZED_KW "materialized" + MATERIALIZED + MATERIALIZED_KW "materialized" WHITESPACE " " L_PAREN "(" WHITESPACE "\n " @@ -258,9 +259,10 @@ SOURCE_FILE WHITESPACE " " AS_KW "as" WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATERIALIZED_KW "materialized" + NOT_MATERIALIZED + NOT_KW "not" + WHITESPACE " " + MATERIALIZED_KW "materialized" WHITESPACE " " L_PAREN "(" WHITESPACE "\n " @@ -1344,7 +1346,7 @@ SOURCE_FILE WHITESPACE " " L_PAREN "(" WHITESPACE "\n " - WINDOW_DEF + WINDOW_SPEC PARTITION_KW "PARTITION" WHITESPACE " " BY_KW "BY" 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 711962ee..0dc4d173 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap @@ -3765,7 +3765,7 @@ SOURCE_FILE OVER_KW "over" WHITESPACE " " L_PAREN "(" - WINDOW_DEF + WINDOW_SPEC PARTITION_KW "partition" WHITESPACE " " BY_KW "by" @@ -3838,40 +3838,42 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - OWNER_KW "owner" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ORDER_BY_CLAUSE - ORDER_KW "order" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SORT_BY - NAME_REF - IDENT "a" - R_PAREN ")" + NAME + OWNER_KW "owner" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_SPEC + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SORT_BY + NAME_REF + IDENT "a" + R_PAREN ")" COMMA "," WHITESPACE " " - NAME - IDENT "w2" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ORDER_BY_CLAUSE - ORDER_KW "order" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SORT_BY - NAME_REF - IDENT "b" - R_PAREN ")" + NAME + IDENT "w2" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_SPEC + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SORT_BY + NAME_REF + IDENT "b" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" COMMENT "-- ^^^^^ make sure we allow using keywords" diff --git a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap index c29f96ee..ff45cfe7 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_ok.snap @@ -3494,13 +3494,14 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" - R_PAREN ")" + WINDOW_DEF + NAME + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- with window def order by" @@ -3517,22 +3518,23 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ORDER_BY_CLAUSE - ORDER_KW "order" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SORT_BY - LITERAL - INT_NUMBER "1" - R_PAREN ")" + NAME + IDENT "w" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WINDOW_SPEC + ORDER_BY_CLAUSE + ORDER_KW "order" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SORT_BY + LITERAL + INT_NUMBER "1" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- with window def frame_start, frame_end" @@ -3549,20 +3551,22 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - RANGE_KW "range" + NAME + IDENT "w" WHITESPACE " " - LITERAL - INT_NUMBER "1" + AS_KW "as" WHITESPACE " " - PRECEDING_KW "preceding" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + RANGE_KW "range" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3577,20 +3581,22 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ROWS_KW "rows" + NAME + IDENT "w" WHITESPACE " " - LITERAL - INT_NUMBER "1" + AS_KW "as" WHITESPACE " " - PRECEDING_KW "preceding" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3605,20 +3611,22 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - GROUPS_KW "groups" + NAME + IDENT "w" WHITESPACE " " - LITERAL - INT_NUMBER "1" + AS_KW "as" WHITESPACE " " - PRECEDING_KW "preceding" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + GROUPS_KW "groups" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- with window def frame_exclusion" @@ -3635,26 +3643,28 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ROWS_KW "rows" - WHITESPACE " " - LITERAL - INT_NUMBER "1" - WHITESPACE " " - PRECEDING_KW "preceding" + NAME + IDENT "w" WHITESPACE " " - EXCLUDE_KW "exclude" + AS_KW "as" WHITESPACE " " - CURRENT_KW "current" - WHITESPACE " " - ROW_KW "row" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + CURRENT_KW "current" + WHITESPACE " " + ROW_KW "row" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3669,24 +3679,26 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ROWS_KW "rows" - WHITESPACE " " - LITERAL - INT_NUMBER "1" - WHITESPACE " " - PRECEDING_KW "preceding" + NAME + IDENT "w" WHITESPACE " " - EXCLUDE_KW "exclude" + AS_KW "as" WHITESPACE " " - GROUP_KW "group" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + GROUP_KW "group" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3701,24 +3713,26 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ROWS_KW "rows" - WHITESPACE " " - LITERAL - INT_NUMBER "1" - WHITESPACE " " - PRECEDING_KW "preceding" + NAME + IDENT "w" WHITESPACE " " - EXCLUDE_KW "exclude" + AS_KW "as" WHITESPACE " " - TIES_KW "ties" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + TIES_KW "ties" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -3733,26 +3747,28 @@ SOURCE_FILE WINDOW_CLAUSE WINDOW_KW "window" WHITESPACE " " - NAME - IDENT "w" - WHITESPACE " " - AS_KW "as" - WHITESPACE " " - L_PAREN "(" WINDOW_DEF - ROWS_KW "rows" - WHITESPACE " " - LITERAL - INT_NUMBER "1" + NAME + IDENT "w" WHITESPACE " " - PRECEDING_KW "preceding" + AS_KW "as" WHITESPACE " " - EXCLUDE_KW "exclude" - WHITESPACE " " - NO_KW "no" - WHITESPACE " " - OTHERS_KW "others" - R_PAREN ")" + L_PAREN "(" + WINDOW_SPEC + FRAME_CLAUSE + ROWS_KW "rows" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE " " + PRECEDING_KW "preceding" + WHITESPACE " " + EXCLUDE_KW "exclude" + WHITESPACE " " + NO_KW "no" + WHITESPACE " " + OTHERS_KW "others" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- select_having_clause" diff --git a/crates/squawk_parser/tests/snapshots/tests__set_transaction_ok.snap b/crates/squawk_parser/tests/snapshots/tests__set_transaction_ok.snap index c09d765c..7b8cb192 100644 --- a/crates/squawk_parser/tests/snapshots/tests__set_transaction_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__set_transaction_ok.snap @@ -27,18 +27,20 @@ SOURCE_FILE WHITESPACE " " TRANSACTION_KW "TRANSACTION" WHITESPACE " " - ISOLATION_KW "ISOLATION" - WHITESPACE " " - LEVEL_KW "LEVEL" - WHITESPACE " " - READ_KW "READ" - WHITESPACE " " - COMMITTED_KW "COMMITTED" + READ_COMMITTED + ISOLATION_KW "ISOLATION" + WHITESPACE " " + LEVEL_KW "LEVEL" + WHITESPACE " " + READ_KW "READ" + WHITESPACE " " + COMMITTED_KW "COMMITTED" COMMA "," WHITESPACE " " - READ_KW "read" - WHITESPACE " " - WRITE_KW "write" + READ_WRITE + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" SEMICOLON ";" WHITESPACE "\n\n" SET_TRANSACTION @@ -46,21 +48,24 @@ SOURCE_FILE WHITESPACE " " TRANSACTION_KW "TRANSACTION" WHITESPACE " " - ISOLATION_KW "ISOLATION" - WHITESPACE " " - LEVEL_KW "LEVEL" - WHITESPACE " " - SERIALIZABLE_KW "SERIALIZABLE" + SERIALIZABLE + ISOLATION_KW "ISOLATION" + WHITESPACE " " + LEVEL_KW "LEVEL" + WHITESPACE " " + SERIALIZABLE_KW "SERIALIZABLE" COMMA "," WHITESPACE " " - READ_KW "READ" - WHITESPACE " " - WRITE_KW "WRITE" + READ_WRITE + READ_KW "READ" + WHITESPACE " " + WRITE_KW "WRITE" COMMA "," WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - DEFERRABLE_KW "DEFERRABLE" + NOT_DEFERRABLE + NOT_KW "NOT" + WHITESPACE " " + DEFERRABLE_KW "DEFERRABLE" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- no commas is postgres historical according to gram.y" @@ -70,18 +75,21 @@ SOURCE_FILE WHITESPACE " " TRANSACTION_KW "TRANSACTION" WHITESPACE " " - ISOLATION_KW "ISOLATION" - WHITESPACE " " - LEVEL_KW "LEVEL" - WHITESPACE " " - SERIALIZABLE_KW "SERIALIZABLE" - WHITESPACE " " - READ_KW "READ" - WHITESPACE " " - WRITE_KW "WRITE" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - DEFERRABLE_KW "DEFERRABLE" + SERIALIZABLE + ISOLATION_KW "ISOLATION" + WHITESPACE " " + LEVEL_KW "LEVEL" + WHITESPACE " " + SERIALIZABLE_KW "SERIALIZABLE" + WHITESPACE " " + READ_WRITE + READ_KW "READ" + WHITESPACE " " + WRITE_KW "WRITE" + WHITESPACE " " + NOT_DEFERRABLE + NOT_KW "NOT" + WHITESPACE " " + DEFERRABLE_KW "DEFERRABLE" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__transaction_ok.snap b/crates/squawk_parser/tests/snapshots/tests__transaction_ok.snap index 39f7627a..38f91af6 100644 --- a/crates/squawk_parser/tests/snapshots/tests__transaction_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__transaction_ok.snap @@ -71,82 +71,95 @@ SOURCE_FILE BEGIN BEGIN_KW "begin" WHITESPACE " \n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - COMMITTED_KW "committed" + READ_COMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - ONLY_KW "only" + READ_ONLY + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - WRITE_KW "write" + READ_WRITE + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" WHITESPACE "\n " - DEFERRABLE_KW "deferrable" + DEFERRABLE + DEFERRABLE_KW "deferrable" WHITESPACE "\n " - NOT_KW "not" - WHITESPACE " " - DEFERRABLE_KW "deferrable" + NOT_DEFERRABLE + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" SEMICOLON ";" WHITESPACE "\n\n" BEGIN BEGIN_KW "begin" WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - COMMITTED_KW "committed" + READ_COMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - UNCOMMITTED_KW "uncommitted" + READ_UNCOMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + UNCOMMITTED_KW "uncommitted" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - REPEATABLE_KW "repeatable" - WHITESPACE " " - READ_KW "read" + REPEATABLE_READ + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + REPEATABLE_KW "repeatable" + WHITESPACE " " + READ_KW "read" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - SERIALIZABLE_KW "serializable" + SERIALIZABLE + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SERIALIZABLE_KW "serializable" COMMA "," WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - ONLY_KW "only" + READ_ONLY + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" COMMA "," WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - WRITE_KW "write" + READ_WRITE + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" COMMA "," WHITESPACE "\n " - DEFERRABLE_KW "deferrable" + DEFERRABLE + DEFERRABLE_KW "deferrable" COMMA "," WHITESPACE "\n " - NOT_KW "not" - WHITESPACE " " - DEFERRABLE_KW "deferrable" + NOT_DEFERRABLE + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" SEMICOLON ";" WHITESPACE "\n\n" BEGIN @@ -154,27 +167,32 @@ SOURCE_FILE WHITESPACE " " TRANSACTION_KW "transaction" WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - COMMITTED_KW "committed" + READ_COMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - ONLY_KW "only" + READ_ONLY + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - WRITE_KW "write" + READ_WRITE + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" WHITESPACE "\n " - DEFERRABLE_KW "deferrable" + DEFERRABLE + DEFERRABLE_KW "deferrable" WHITESPACE "\n " - NOT_KW "not" - WHITESPACE " " - DEFERRABLE_KW "deferrable" + NOT_DEFERRABLE + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" SEMICOLON ";" WHITESPACE "\n\n" BEGIN @@ -182,56 +200,64 @@ SOURCE_FILE WHITESPACE " " TRANSACTION_KW "transaction" WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - COMMITTED_KW "committed" + READ_COMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + COMMITTED_KW "committed" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - READ_KW "read" - WHITESPACE " " - UNCOMMITTED_KW "uncommitted" + READ_UNCOMMITTED + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + READ_KW "read" + WHITESPACE " " + UNCOMMITTED_KW "uncommitted" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - REPEATABLE_KW "repeatable" - WHITESPACE " " - READ_KW "read" + REPEATABLE_READ + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + REPEATABLE_KW "repeatable" + WHITESPACE " " + READ_KW "read" COMMA "," WHITESPACE "\n " - ISOLATION_KW "isolation" - WHITESPACE " " - LEVEL_KW "level" - WHITESPACE " " - SERIALIZABLE_KW "serializable" + SERIALIZABLE + ISOLATION_KW "isolation" + WHITESPACE " " + LEVEL_KW "level" + WHITESPACE " " + SERIALIZABLE_KW "serializable" COMMA "," WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - ONLY_KW "only" + READ_ONLY + READ_KW "read" + WHITESPACE " " + ONLY_KW "only" COMMA "," WHITESPACE "\n " - READ_KW "read" - WHITESPACE " " - WRITE_KW "write" + READ_WRITE + READ_KW "read" + WHITESPACE " " + WRITE_KW "write" COMMA "," WHITESPACE "\n " - DEFERRABLE_KW "deferrable" + DEFERRABLE + DEFERRABLE_KW "deferrable" COMMA "," WHITESPACE "\n " - NOT_KW "not" - WHITESPACE " " - DEFERRABLE_KW "deferrable" + NOT_DEFERRABLE + NOT_KW "not" + WHITESPACE " " + DEFERRABLE_KW "deferrable" SEMICOLON ";" WHITESPACE "\n\n" PREPARE_TRANSACTION diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index 0bfb0e52..d23f0af2 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -1221,6 +1221,14 @@ pub struct AttachPartition { pub(crate) syntax: SyntaxNode, } impl AttachPartition { + #[inline] + pub fn partition_type(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn path(&self) -> Option { + support::child(&self.syntax) + } #[inline] pub fn attach_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::ATTACH_KW) @@ -4719,6 +4727,25 @@ impl ForeignKeyConstraint { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct FrameClause { + pub(crate) syntax: SyntaxNode, +} +impl FrameClause { + #[inline] + pub fn groups_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::GROUPS_KW) + } + #[inline] + pub fn range_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::RANGE_KW) + } + #[inline] + pub fn rows_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ROWS_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FromClause { pub(crate) syntax: SyntaxNode, @@ -6122,6 +6149,17 @@ impl MatchSimple { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Materialized { + pub(crate) syntax: SyntaxNode, +} +impl Materialized { + #[inline] + pub fn materialized_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MATERIALIZED_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Merge { pub(crate) syntax: SyntaxNode, @@ -6362,6 +6400,21 @@ impl NotLike { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct NotMaterialized { + pub(crate) syntax: SyntaxNode, +} +impl NotMaterialized { + #[inline] + pub fn materialized_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MATERIALIZED_KW) + } + #[inline] + pub fn not_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NOT_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NotNullConstraint { pub(crate) syntax: SyntaxNode, @@ -7108,6 +7161,122 @@ impl PartitionBy { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PartitionDefault { + pub(crate) syntax: SyntaxNode, +} +impl PartitionDefault { + #[inline] + pub fn default_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DEFAULT_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PartitionForValuesFrom { + pub(crate) syntax: SyntaxNode, +} +impl PartitionForValuesFrom { + #[inline] + pub fn exprs(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } + #[inline] + pub fn for_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::FOR_KW) + } + #[inline] + pub fn from_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::FROM_KW) + } + #[inline] + pub fn to_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::TO_KW) + } + #[inline] + pub fn values_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::VALUES_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PartitionForValuesIn { + pub(crate) syntax: SyntaxNode, +} +impl PartitionForValuesIn { + #[inline] + pub fn exprs(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } + #[inline] + pub fn for_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::FOR_KW) + } + #[inline] + pub fn in_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::IN_KW) + } + #[inline] + pub fn values_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::VALUES_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PartitionForValuesWith { + pub(crate) syntax: SyntaxNode, +} +impl PartitionForValuesWith { + #[inline] + pub fn literal(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } + #[inline] + pub fn comma_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::COMMA) + } + #[inline] + pub fn for_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::FOR_KW) + } + #[inline] + pub fn ident_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::IDENT) + } + #[inline] + pub fn values_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::VALUES_KW) + } + #[inline] + pub fn with_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::WITH_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct PartitionItem { pub(crate) syntax: SyntaxNode, @@ -7337,6 +7506,14 @@ impl ReadCommitted { support::token(&self.syntax, SyntaxKind::COMMITTED_KW) } #[inline] + pub fn isolation_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ISOLATION_KW) + } + #[inline] + pub fn level_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::LEVEL_KW) + } + #[inline] pub fn read_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::READ_KW) } @@ -7362,6 +7539,14 @@ pub struct ReadUncommitted { pub(crate) syntax: SyntaxNode, } impl ReadUncommitted { + #[inline] + pub fn isolation_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ISOLATION_KW) + } + #[inline] + pub fn level_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::LEVEL_KW) + } #[inline] pub fn read_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::READ_KW) @@ -7618,6 +7803,14 @@ pub struct RepeatableRead { pub(crate) syntax: SyntaxNode, } impl RepeatableRead { + #[inline] + pub fn isolation_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ISOLATION_KW) + } + #[inline] + pub fn level_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::LEVEL_KW) + } #[inline] pub fn read_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::READ_KW) @@ -8048,6 +8241,14 @@ pub struct Serializable { pub(crate) syntax: SyntaxNode, } impl Serializable { + #[inline] + pub fn isolation_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ISOLATION_KW) + } + #[inline] + pub fn level_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::LEVEL_KW) + } #[inline] pub fn serializable_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::SERIALIZABLE_KW) @@ -8788,11 +8989,7 @@ impl TimeType { support::child(&self.syntax) } #[inline] - pub fn with_timezone(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn without_timezone(&self) -> Option { + pub fn timezone(&self) -> Option { support::child(&self.syntax) } #[inline] @@ -8813,37 +9010,6 @@ impl TimeType { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TransactionModeIsolationLevel { - pub(crate) syntax: SyntaxNode, -} -impl TransactionModeIsolationLevel { - #[inline] - pub fn read_committed(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn read_uncommitted(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn repeatable_read(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn serializable(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn isolation_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::ISOLATION_KW) - } - #[inline] - pub fn level_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::LEVEL_KW) - } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TransactionModeList { pub(crate) syntax: SyntaxNode, @@ -9145,8 +9311,8 @@ pub struct WindowClause { } impl WindowClause { #[inline] - pub fn ident_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::IDENT) + pub fn window_defs(&self) -> AstChildren { + support::children(&self.syntax) } #[inline] pub fn window_token(&self) -> Option { @@ -9160,20 +9326,24 @@ pub struct WindowDef { } impl WindowDef { #[inline] - pub fn expr(&self) -> Option { + pub fn name(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn by_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::BY_KW) + pub fn window_spec(&self) -> Option { + support::child(&self.syntax) } #[inline] - pub fn ident_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::IDENT) + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) } #[inline] - pub fn partition_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::PARTITION_KW) + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } + #[inline] + pub fn as_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AS_KW) } } @@ -9188,6 +9358,37 @@ impl WindowFuncOption { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct WindowSpec { + pub(crate) syntax: SyntaxNode, +} +impl WindowSpec { + #[inline] + pub fn exprs(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn frame_clause(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn order_by_clause(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn by_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::BY_KW) + } + #[inline] + pub fn ident_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::IDENT) + } + #[inline] + pub fn partition_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::PARTITION_KW) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct WithClause { pub(crate) syntax: SyntaxNode, @@ -9280,6 +9481,14 @@ pub struct WithTable { pub(crate) syntax: SyntaxNode, } impl WithTable { + #[inline] + pub fn materialized(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn not_materialized(&self) -> Option { + support::child(&self.syntax) + } #[inline] pub fn with_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::WITH_KW) @@ -9610,6 +9819,14 @@ pub enum ParamMode { ParamVariadic(ParamVariadic), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum PartitionType { + PartitionDefault(PartitionDefault), + PartitionForValuesFrom(PartitionForValuesFrom), + PartitionForValuesIn(PartitionForValuesIn), + PartitionForValuesWith(PartitionForValuesWith), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum RefAction { Cascade(Cascade), @@ -9817,13 +10034,22 @@ pub enum TableConstraint { UniqueConstraint(UniqueConstraint), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Timezone { + WithTimezone(WithTimezone), + WithoutTimezone(WithoutTimezone), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TransactionMode { Deferrable(Deferrable), NotDeferrable(NotDeferrable), + ReadCommitted(ReadCommitted), ReadOnly(ReadOnly), + ReadUncommitted(ReadUncommitted), ReadWrite(ReadWrite), - TransactionModeIsolationLevel(TransactionModeIsolationLevel), + RepeatableRead(RepeatableRead), + Serializable(Serializable), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -13743,6 +13969,24 @@ impl AstNode for ForeignKeyConstraint { &self.syntax } } +impl AstNode for FrameClause { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::FRAME_CLAUSE + } + #[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 FromClause { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -15039,6 +15283,24 @@ impl AstNode for MatchSimple { &self.syntax } } +impl AstNode for Materialized { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MATERIALIZED + } + #[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 Merge { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -15327,6 +15589,24 @@ impl AstNode for NotLike { &self.syntax } } +impl AstNode for NotMaterialized { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::NOT_MATERIALIZED + } + #[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 NotNullConstraint { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -15939,6 +16219,78 @@ impl AstNode for PartitionBy { &self.syntax } } +impl AstNode for PartitionDefault { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::PARTITION_DEFAULT + } + #[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 PartitionForValuesFrom { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::PARTITION_FOR_VALUES_FROM + } + #[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 PartitionForValuesIn { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::PARTITION_FOR_VALUES_IN + } + #[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 PartitionForValuesWith { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::PARTITION_FOR_VALUES_WITH + } + #[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 PartitionItem { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -17649,24 +18001,6 @@ impl AstNode for TimeType { &self.syntax } } -impl AstNode for TransactionModeIsolationLevel { - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { - kind == SyntaxKind::TRANSACTION_MODE_ISOLATION_LEVEL - } - #[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 TransactionModeList { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -18027,6 +18361,24 @@ impl AstNode for WindowFuncOption { &self.syntax } } +impl AstNode for WindowSpec { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::WINDOW_SPEC + } + #[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 WithClause { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -19667,6 +20019,72 @@ impl From for ParamMode { ParamMode::ParamVariadic(node) } } +impl AstNode for PartitionType { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::PARTITION_DEFAULT + | SyntaxKind::PARTITION_FOR_VALUES_FROM + | SyntaxKind::PARTITION_FOR_VALUES_IN + | SyntaxKind::PARTITION_FOR_VALUES_WITH + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::PARTITION_DEFAULT => { + PartitionType::PartitionDefault(PartitionDefault { syntax }) + } + SyntaxKind::PARTITION_FOR_VALUES_FROM => { + PartitionType::PartitionForValuesFrom(PartitionForValuesFrom { syntax }) + } + SyntaxKind::PARTITION_FOR_VALUES_IN => { + PartitionType::PartitionForValuesIn(PartitionForValuesIn { syntax }) + } + SyntaxKind::PARTITION_FOR_VALUES_WITH => { + PartitionType::PartitionForValuesWith(PartitionForValuesWith { syntax }) + } + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + PartitionType::PartitionDefault(it) => &it.syntax, + PartitionType::PartitionForValuesFrom(it) => &it.syntax, + PartitionType::PartitionForValuesIn(it) => &it.syntax, + PartitionType::PartitionForValuesWith(it) => &it.syntax, + } + } +} +impl From for PartitionType { + #[inline] + fn from(node: PartitionDefault) -> PartitionType { + PartitionType::PartitionDefault(node) + } +} +impl From for PartitionType { + #[inline] + fn from(node: PartitionForValuesFrom) -> PartitionType { + PartitionType::PartitionForValuesFrom(node) + } +} +impl From for PartitionType { + #[inline] + fn from(node: PartitionForValuesIn) -> PartitionType { + PartitionType::PartitionForValuesIn(node) + } +} +impl From for PartitionType { + #[inline] + fn from(node: PartitionForValuesWith) -> PartitionType { + PartitionType::PartitionForValuesWith(node) + } +} impl AstNode for RefAction { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -21545,6 +21963,45 @@ impl From for TableConstraint { TableConstraint::UniqueConstraint(node) } } +impl AstNode for Timezone { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::WITH_TIMEZONE | SyntaxKind::WITHOUT_TIMEZONE + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::WITH_TIMEZONE => Timezone::WithTimezone(WithTimezone { syntax }), + SyntaxKind::WITHOUT_TIMEZONE => Timezone::WithoutTimezone(WithoutTimezone { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + Timezone::WithTimezone(it) => &it.syntax, + Timezone::WithoutTimezone(it) => &it.syntax, + } + } +} +impl From for Timezone { + #[inline] + fn from(node: WithTimezone) -> Timezone { + Timezone::WithTimezone(node) + } +} +impl From for Timezone { + #[inline] + fn from(node: WithoutTimezone) -> Timezone { + Timezone::WithoutTimezone(node) + } +} impl AstNode for TransactionMode { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -21552,9 +22009,12 @@ impl AstNode for TransactionMode { kind, SyntaxKind::DEFERRABLE | SyntaxKind::NOT_DEFERRABLE + | SyntaxKind::READ_COMMITTED | SyntaxKind::READ_ONLY + | SyntaxKind::READ_UNCOMMITTED | SyntaxKind::READ_WRITE - | SyntaxKind::TRANSACTION_MODE_ISOLATION_LEVEL + | SyntaxKind::REPEATABLE_READ + | SyntaxKind::SERIALIZABLE ) } #[inline] @@ -21562,13 +22022,16 @@ impl AstNode for TransactionMode { let res = match syntax.kind() { SyntaxKind::DEFERRABLE => TransactionMode::Deferrable(Deferrable { syntax }), SyntaxKind::NOT_DEFERRABLE => TransactionMode::NotDeferrable(NotDeferrable { syntax }), + SyntaxKind::READ_COMMITTED => TransactionMode::ReadCommitted(ReadCommitted { syntax }), SyntaxKind::READ_ONLY => TransactionMode::ReadOnly(ReadOnly { syntax }), + SyntaxKind::READ_UNCOMMITTED => { + TransactionMode::ReadUncommitted(ReadUncommitted { syntax }) + } SyntaxKind::READ_WRITE => TransactionMode::ReadWrite(ReadWrite { syntax }), - SyntaxKind::TRANSACTION_MODE_ISOLATION_LEVEL => { - TransactionMode::TransactionModeIsolationLevel(TransactionModeIsolationLevel { - syntax, - }) + SyntaxKind::REPEATABLE_READ => { + TransactionMode::RepeatableRead(RepeatableRead { syntax }) } + SyntaxKind::SERIALIZABLE => TransactionMode::Serializable(Serializable { syntax }), _ => { return None; } @@ -21580,9 +22043,12 @@ impl AstNode for TransactionMode { match self { TransactionMode::Deferrable(it) => &it.syntax, TransactionMode::NotDeferrable(it) => &it.syntax, + TransactionMode::ReadCommitted(it) => &it.syntax, TransactionMode::ReadOnly(it) => &it.syntax, + TransactionMode::ReadUncommitted(it) => &it.syntax, TransactionMode::ReadWrite(it) => &it.syntax, - TransactionMode::TransactionModeIsolationLevel(it) => &it.syntax, + TransactionMode::RepeatableRead(it) => &it.syntax, + TransactionMode::Serializable(it) => &it.syntax, } } } @@ -21598,22 +22064,40 @@ impl From for TransactionMode { TransactionMode::NotDeferrable(node) } } +impl From for TransactionMode { + #[inline] + fn from(node: ReadCommitted) -> TransactionMode { + TransactionMode::ReadCommitted(node) + } +} impl From for TransactionMode { #[inline] fn from(node: ReadOnly) -> TransactionMode { TransactionMode::ReadOnly(node) } } +impl From for TransactionMode { + #[inline] + fn from(node: ReadUncommitted) -> TransactionMode { + TransactionMode::ReadUncommitted(node) + } +} impl From for TransactionMode { #[inline] fn from(node: ReadWrite) -> TransactionMode { TransactionMode::ReadWrite(node) } } -impl From for TransactionMode { +impl From for TransactionMode { + #[inline] + fn from(node: RepeatableRead) -> TransactionMode { + TransactionMode::RepeatableRead(node) + } +} +impl From for TransactionMode { #[inline] - fn from(node: TransactionModeIsolationLevel) -> TransactionMode { - TransactionMode::TransactionModeIsolationLevel(node) + fn from(node: Serializable) -> TransactionMode { + TransactionMode::Serializable(node) } } impl AstNode for Type { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index 45e4d0d9..6036c437 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -243,10 +243,14 @@ BitType = DoubleType = 'double' 'precision' +Timezone = + WithTimezone +| WithoutTimezone + TimeType = ('time' | 'timestamp') ('(' Literal ')')? - (WithTimezone | WithoutTimezone)? + Timezone? IntervalType = 'interval' @@ -515,8 +519,11 @@ GroupingExpr = HavingClause = 'having' +WindowDef = + Name 'as' '(' WindowSpec ')' + WindowClause = - 'window' '#ident' + 'window' (WindowDef (',' WindowDef)*) LimitClause = 'limit' @@ -632,19 +639,17 @@ Select = FilterClause? Serializable = - 'serializable' + 'isolation' 'level' 'serializable' RepeatableRead = - 'repeatable' 'read' + 'isolation' 'level' 'repeatable' 'read' ReadCommitted = - 'read' 'committed' + 'isolation' 'level' 'read' 'committed' ReadUncommitted = - 'read' 'uncommitted' + 'isolation' 'level' 'read' 'uncommitted' -TransactionModeIsolationLevel = - 'isolation' 'level' ( Serializable | RepeatableRead | ReadCommitted | ReadUncommitted ) ReadWrite = 'read' 'write' @@ -659,7 +664,10 @@ NotDeferrable = 'not' 'deferrable' TransactionMode = - TransactionModeIsolationLevel + Serializable +| RepeatableRead +| ReadCommitted +| ReadUncommitted | ReadWrite | ReadOnly | Deferrable @@ -979,8 +987,14 @@ OverClause = WithinClause = 'within' 'group' '(' OrderByClause ')' +Materialized = + 'materialized' + +NotMaterialized = + 'not' 'materialized' + WithTable = - 'with' + 'with' (Materialized | NotMaterialized)? WithClause = 'with' 'recursive'? (WithTable (',' WithTable)*) @@ -1071,8 +1085,11 @@ ConstraintWhereClause = ExcludeConstraint = 'exclude' ConstraintIndexMethod? ConstraintExclusions -WindowDef = - '#ident'? ('partition' 'by' Expr)? +FrameClause = + ('range' | 'rows' | 'groups') + +WindowSpec = + '#ident'? ('partition' 'by' (Expr (',' Expr)*))? OrderByClause? FrameClause? AlterStatistics = 'alter' 'statistics' NameRef @@ -1630,8 +1647,26 @@ DropColumn = AddColumn = 'add' 'column'? IfNotExists? NameRef Type Collate? (Constraint (',' Constraint)*)? +PartitionForValuesWith = + 'for' 'values' 'with' '(' '#ident' Literal ',' '#ident' Literal ')' + +PartitionForValuesIn = + 'for' 'values' 'in' '(' (Expr (',' Expr)*) ')' + +PartitionForValuesFrom = + 'for' 'values' 'from' '(' (Expr (',' Expr)*) ')' 'to' '(' (Expr (',' Expr)*) ')' + +PartitionDefault = + 'default' + +PartitionType = + PartitionForValuesWith +| PartitionForValuesIn +| PartitionForValuesFrom +| PartitionDefault + AttachPartition = - 'attach' 'partition' + 'attach' 'partition' Path PartitionType SetTablespace = 'set' 'tablespace' NameRef