diff --git a/crates/squawk_ide/src/goto_definition.rs b/crates/squawk_ide/src/goto_definition.rs index 294424f0..40d7cf52 100644 --- a/crates/squawk_ide/src/goto_definition.rs +++ b/crates/squawk_ide/src/goto_definition.rs @@ -5829,13 +5829,13 @@ select 1::smallint$0; fn goto_cast_double_precision_falls_back_to_float8() { assert_snapshot!(goto(" create type pg_catalog.float8; -select '1'::double precision[]$0; +select '1'::double precision[$0]; "), @r" ╭▸ 2 │ create type pg_catalog.float8; │ ────── 2. destination 3 │ select '1'::double precision[]; - ╰╴ ─ 1. source + ╰╴ ─ 1. source "); } diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 8a781d91..208ad5e2 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -660,6 +660,7 @@ pub enum SyntaxKind { ANY_FN, ARG, ARG_LIST, + ARRAY_BOUND, ARRAY_EXPR, ARRAY_TYPE, ASENSITIVE, @@ -1115,7 +1116,13 @@ pub enum SyntaxKind { INSENSITIVE, INSERT, INTERSECT, + INTERVAL_DAY, + INTERVAL_HOUR, + INTERVAL_MINUTE, + INTERVAL_MONTH, + INTERVAL_SECOND, INTERVAL_TYPE, + INTERVAL_YEAR, INTO_CLAUSE, INTO_SCHEMA, IN_DATABASE, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index dbf09bfd..00cc720e 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -2149,16 +2149,25 @@ fn opt_percent_type(p: &mut Parser<'_>) -> Option { } } -fn opt_array_index(p: &mut Parser<'_>) -> bool { - if p.eat(L_BRACK) { - if !p.at(R_BRACK) { - let _ = expr(p); - } - p.expect(R_BRACK); - true - } else { - false +fn opt_array_bound(p: &mut Parser<'_>) -> bool { + if !p.at(L_BRACK) { + return false; + } + let m = p.start(); + p.bump(L_BRACK); + if !p.at(R_BRACK) { + let _ = expr(p); } + p.expect(R_BRACK); + m.complete(p, ARRAY_BOUND); + true +} + +fn allows_type_mods(kind: SyntaxKind) -> bool { + matches!( + kind, + PATH_TYPE | BIT_TYPE | BIT_VARYING_TYPE | CHARACTER_TYPE | VARCHAR_TYPE + ) } fn type_mods( @@ -2170,7 +2179,7 @@ fn type_mods( if opt_percent_type(p).is_some() { return Some(m.complete(p, PERCENT_TYPE)); } - if p.at(L_PAREN) && type_args_enabled { + if p.at(L_PAREN) && type_args_enabled && allows_type_mods(kind) { let m = p.start(); delimited( p, @@ -2188,13 +2197,12 @@ fn type_mods( return Some(cm); } let m = cm.precede(p); - // TODO: we should probably mimic the INDEX_EXPR but be stricter if p.eat(ARRAY_KW) { - opt_array_index(p); + opt_array_bound(p); } else { let mut found_one_array_bracks = false; while !p.at(EOF) && p.at(L_BRACK) { - if opt_array_index(p) { + if opt_array_bound(p) { found_one_array_bracks = true; } } @@ -2422,49 +2430,75 @@ fn interval_second(p: &mut Parser<'_>) { } fn opt_interval_trailing(p: &mut Parser<'_>) { - match (p.current(), p.nth(1)) { + let m = p.start(); + let kind = match (p.current(), p.nth(1)) { (DAY_KW, TO_KW) => { p.bump(DAY_KW); p.bump(TO_KW); match p.current() { HOUR_KW => { p.bump(HOUR_KW); + INTERVAL_HOUR } MINUTE_KW => { p.bump(MINUTE_KW); + INTERVAL_MINUTE } SECOND_KW => { interval_second(p); + INTERVAL_SECOND + } + _ => { + p.error("expected HOUR, MINUTE, or SECOND"); + INTERVAL_DAY } - _ => p.error("expected HOUR, MINUTE, or SECOND"), } } - (DAY_KW, _) => p.bump(DAY_KW), + (DAY_KW, _) => { + p.bump(DAY_KW); + INTERVAL_DAY + } (HOUR_KW, TO_KW) => { p.bump(HOUR_KW); p.bump(TO_KW); - if !p.eat(MINUTE_KW) { + if p.eat(MINUTE_KW) { + INTERVAL_MINUTE + } else { interval_second(p); + INTERVAL_SECOND } } - (HOUR_KW, _) => p.bump(HOUR_KW), + (HOUR_KW, _) => { + p.bump(HOUR_KW); + INTERVAL_HOUR + } (MINUTE_KW, TO_KW) => { p.bump(MINUTE_KW); p.bump(TO_KW); interval_second(p); + INTERVAL_SECOND + } + (MINUTE_KW, _) => { + p.bump(MINUTE_KW); + INTERVAL_MINUTE + } + (MONTH_KW, _) => { + p.bump(MONTH_KW); + INTERVAL_MONTH } - (MINUTE_KW, _) => p.bump(MINUTE_KW), - (MONTH_KW, _) => p.bump(MONTH_KW), (YEAR_KW, TO_KW) => { p.bump(YEAR_KW); p.bump(TO_KW); p.expect(MONTH_KW); + INTERVAL_MONTH } (YEAR_KW, _) => { p.bump(YEAR_KW); + INTERVAL_YEAR } (SECOND_KW, _) => { interval_second(p); + INTERVAL_SECOND } (L_PAREN, _) => { p.bump(L_PAREN); @@ -2472,9 +2506,14 @@ fn opt_interval_trailing(p: &mut Parser<'_>) { p.error("expected number") } p.expect(R_PAREN); + INTERVAL_SECOND } - _ => (), - } + _ => { + m.abandon(p); + return; + } + }; + m.complete(p, kind); } fn name_ref_(p: &mut Parser<'_>) -> Option { diff --git a/crates/squawk_parser/tests/snapshots/tests__create_function_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_function_ok.snap index c1b5ea9d..3590b723 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_function_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_function_ok.snap @@ -448,8 +448,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF NUMERIC_KW "numeric" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE "\n" FUNC_OPTION_LIST AS_FUNC_OPTION @@ -3176,8 +3177,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF TEXT_KW "text" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " " PARAM @@ -3253,8 +3255,9 @@ SOURCE_FILE DOT "." PATH_SEGMENT_REF IDENT "u" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " " PARAM 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 35331639..5e290a4c 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_table_ok.snap @@ -2750,8 +2750,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INTEGER_KW "integer" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE "\n " COLUMN @@ -2763,10 +2764,12 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF TEXT_KW "text" - L_BRACK "[" - R_BRACK "]" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE "\n" R_PAREN ")" SEMICOLON ";" @@ -2795,14 +2798,16 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INTEGER_KW "integer" - L_BRACK "[" - LITERAL - INT_NUMBER "3" - R_BRACK "]" - L_BRACK "[" - LITERAL - INT_NUMBER "3" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" WHITESPACE "\n" R_PAREN ")" SEMICOLON ";" @@ -2833,10 +2838,11 @@ SOURCE_FILE INTEGER_KW "integer" WHITESPACE " " ARRAY_KW "ARRAY" - L_BRACK "[" - LITERAL - INT_NUMBER "4" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" COMMA "," WHITESPACE "\n " COLUMN diff --git a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap index 5bad0738..25485b95 100644 --- a/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__misc_ok.snap @@ -107,8 +107,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "timestamptz" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " \n " ARG @@ -123,8 +124,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF TEXT_KW "text" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " \n " ARG @@ -139,8 +141,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "float8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE "\n" R_PAREN ")" SEMICOLON ";" @@ -838,8 +841,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " " PARAM @@ -877,8 +881,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE " " FUNC_OPTION_LIST LANGUAGE_FUNC_OPTION @@ -979,8 +984,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE "\n " ATTRIBUTE_OPTION @@ -1231,8 +1237,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COMMA "," WHITESPACE " " PARAM @@ -1247,8 +1254,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE " " R_PAREN ")" WHITESPACE " " @@ -1260,8 +1268,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE " " FUNC_OPTION_LIST AS_FUNC_OPTION diff --git a/crates/squawk_parser/tests/snapshots/tests__select_casts_ok.snap b/crates/squawk_parser/tests/snapshots/tests__select_casts_ok.snap index d8292524..ef196cdd 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_casts_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_casts_ok.snap @@ -183,8 +183,9 @@ SOURCE_FILE LITERAL INT_NUMBER "1" R_PAREN ")" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -204,8 +205,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INT_KW "int" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -243,8 +245,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF NUMERIC_KW "numeric" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -268,8 +271,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INT_KW "int" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE " " COLON_COLON COLON ":" @@ -280,8 +284,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" WHITESPACE " " COLON_COLON COLON ":" @@ -292,10 +297,11 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF NUMERIC_KW "numeric" - L_BRACK "[" - LITERAL - INT_NUMBER "1" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -317,8 +323,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INT_KW "int" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COLON_COLON COLON ":" COLON ":" @@ -327,8 +334,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" COLON_COLON COLON ":" COLON ":" @@ -337,10 +345,11 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF NUMERIC_KW "numeric" - L_BRACK "[" - LITERAL - INT_NUMBER "1" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- setof" @@ -647,8 +656,9 @@ SOURCE_FILE NCHAR_KW "nchar" WHITESPACE " " VARYING_KW "varying" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- ConstDatetime" @@ -1152,7 +1162,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - YEAR_KW "year" + INTERVAL_YEAR + YEAR_KW "year" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1170,7 +1181,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - MONTH_KW "month" + INTERVAL_MONTH + MONTH_KW "month" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1187,10 +1199,11 @@ SOURCE_FILE COLON ":" INTERVAL_TYPE INTERVAL_KW "interval" - L_PAREN "(" - LITERAL - INT_NUMBER "0" - R_PAREN ")" + INTERVAL_SECOND + L_PAREN "(" + LITERAL + INT_NUMBER "0" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1208,7 +1221,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - DAY_KW "day" + INTERVAL_DAY + DAY_KW "day" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1226,7 +1240,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - HOUR_KW "hour" + INTERVAL_HOUR + HOUR_KW "hour" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1244,7 +1259,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1262,7 +1278,8 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1280,11 +1297,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "100" - R_PAREN ")" + INTERVAL_SECOND + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "100" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1302,11 +1320,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - YEAR_KW "year" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MONTH_KW "month" + INTERVAL_MONTH + YEAR_KW "year" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MONTH_KW "month" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1324,11 +1343,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - HOUR_KW "hour" + INTERVAL_HOUR + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + HOUR_KW "hour" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1346,11 +1366,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1368,11 +1389,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1390,15 +1412,16 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1416,11 +1439,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1438,11 +1462,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1460,15 +1485,16 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1486,11 +1512,12 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - MINUTE_KW "minute" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1508,15 +1535,16 @@ SOURCE_FILE INTERVAL_TYPE INTERVAL_KW "interval" WHITESPACE " " - MINUTE_KW "minute" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1533,10 +1561,11 @@ SOURCE_FILE COLON ":" INTERVAL_TYPE INTERVAL_KW "interval" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- JsonType" @@ -1711,8 +1740,9 @@ SOURCE_FILE LITERAL INT_NUMBER "255" R_PAREN ")" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1730,10 +1760,11 @@ SOURCE_FILE ARRAY_TYPE VARCHAR_TYPE VARCHAR_KW "varchar" - L_BRACK "[" - LITERAL - INT_NUMBER "5" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "5" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -1759,8 +1790,9 @@ SOURCE_FILE LITERAL INT_NUMBER "255" R_PAREN ")" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1816,10 +1848,11 @@ SOURCE_FILE DOT "." PATH_SEGMENT_REF IDENT "buzz" - L_BRACK "[" - LITERAL - INT_NUMBER "5" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "5" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -1853,8 +1886,9 @@ SOURCE_FILE LITERAL INT_NUMBER "255" R_PAREN ")" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- Numeric" @@ -2187,10 +2221,11 @@ SOURCE_FILE LITERAL INT_NUMBER "2" R_PAREN ")" - L_BRACK "[" - LITERAL - INT_NUMBER "10" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "10" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- interval_cast_trailing" @@ -2208,7 +2243,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - YEAR_KW "year" + INTERVAL_YEAR + YEAR_KW "year" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2224,7 +2260,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - MONTH_KW "month" + INTERVAL_MONTH + MONTH_KW "month" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2240,7 +2277,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - DAY_KW "day" + INTERVAL_DAY + DAY_KW "day" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2256,7 +2294,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - HOUR_KW "hour" + INTERVAL_HOUR + HOUR_KW "hour" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2272,7 +2311,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2288,7 +2328,8 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2304,11 +2345,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - YEAR_KW "year" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MONTH_KW "month" + INTERVAL_MONTH + YEAR_KW "year" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MONTH_KW "month" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2324,11 +2366,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - HOUR_KW "hour" + INTERVAL_HOUR + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + HOUR_KW "hour" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2344,11 +2387,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2364,11 +2408,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2384,15 +2429,16 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - DAY_KW "day" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + DAY_KW "day" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2408,11 +2454,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - MINUTE_KW "minute" + INTERVAL_MINUTE + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + MINUTE_KW "minute" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2428,11 +2475,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2448,15 +2496,16 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - HOUR_KW "hour" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + HOUR_KW "hour" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2472,11 +2521,12 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - MINUTE_KW "minute" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" + INTERVAL_SECOND + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" SEMICOLON ";" WHITESPACE "\n" SELECT @@ -2492,15 +2542,16 @@ SOURCE_FILE LITERAL STRING "'1'" WHITESPACE " " - MINUTE_KW "minute" - WHITESPACE " " - TO_KW "to" - WHITESPACE " " - SECOND_KW "second" - L_PAREN "(" - LITERAL - INT_NUMBER "10" - R_PAREN ")" + INTERVAL_SECOND + MINUTE_KW "minute" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + SECOND_KW "second" + L_PAREN "(" + LITERAL + INT_NUMBER "10" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- pgdoc_char" @@ -2641,10 +2692,11 @@ SOURCE_FILE INTEGER_KW "integer" WHITESPACE " " ARRAY_KW "ARRAY" - L_BRACK "[" - LITERAL - INT_NUMBER "4" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -2691,10 +2743,11 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INT_KW "int" - L_BRACK "[" - LITERAL - INT_NUMBER "4" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "4" + R_BRACK "]" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -2717,14 +2770,16 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INTEGER_KW "integer" - L_BRACK "[" - LITERAL - INT_NUMBER "3" - R_BRACK "]" - L_BRACK "[" - LITERAL - INT_NUMBER "3" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" @@ -2745,26 +2800,32 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INTEGER_KW "integer" - L_BRACK "[" - LITERAL - INT_NUMBER "1" - R_BRACK "]" - L_BRACK "[" - LITERAL - INT_NUMBER "2" - R_BRACK "]" - L_BRACK "[" - LITERAL - INT_NUMBER "3" - R_BRACK "]" - L_BRACK "[" - R_BRACK "]" - L_BRACK "[" - R_BRACK "]" - L_BRACK "[" - LITERAL - INT_NUMBER "1000" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "1" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "2" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "3" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "1000" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -2786,10 +2847,11 @@ SOURCE_FILE INT_KW "int" WHITESPACE " " ARRAY_KW "array" - L_BRACK "[" - LITERAL - INT_NUMBER "10" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + LITERAL + INT_NUMBER "10" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" SELECT @@ -2811,8 +2873,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF INTEGER_KW "integer" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- casts" @@ -2969,8 +3032,9 @@ SOURCE_FILE DOT "." PATH_SEGMENT_REF IDENT "int8" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n\n\n" COMMENT "-- cast" @@ -3029,8 +3093,9 @@ SOURCE_FILE LITERAL INT_NUMBER "1" R_PAREN ")" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n\n" 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 6731a43c..9c88ec2c 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_funcs_ok.snap @@ -4455,8 +4455,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF NUMERIC_KW "numeric" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" 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 1dca5d00..efd0cda6 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_operators_ok.snap @@ -4010,8 +4010,9 @@ SOURCE_FILE PATH_REF PATH_SEGMENT_REF TEXT_KW "text" - L_BRACK "[" - R_BRACK "]" + ARRAY_BOUND + L_BRACK "[" + R_BRACK "]" SEMICOLON ";" WHITESPACE "\n" SELECT diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index 8e27040e..1140ff74 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -2500,6 +2500,25 @@ impl ArgList { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ArrayBound { + pub(crate) syntax: SyntaxNode, +} +impl ArrayBound { + #[inline] + pub fn expr(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn l_brack_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_BRACK) + } + #[inline] + pub fn r_brack_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_BRACK) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ArrayExpr { pub(crate) syntax: SyntaxNode, @@ -2541,20 +2560,16 @@ pub struct ArrayType { } impl ArrayType { #[inline] - pub fn expr(&self) -> Option { + pub fn array_bound(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn ty(&self) -> Option { - support::child(&self.syntax) - } - #[inline] - pub fn l_brack_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::L_BRACK) + pub fn array_bounds(&self) -> AstChildren { + support::children(&self.syntax) } #[inline] - pub fn r_brack_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::R_BRACK) + pub fn ty(&self) -> Option { + support::child(&self.syntax) } #[inline] pub fn array_token(&self) -> Option { @@ -3338,6 +3353,10 @@ impl CastExpr { support::child(&self.syntax) } #[inline] + pub fn interval_qualifier(&self) -> Option { + support::child(&self.syntax) + } + #[inline] pub fn literal(&self) -> Option { support::child(&self.syntax) } @@ -12955,10 +12974,82 @@ impl Intersect { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct IntervalType { +pub struct IntervalDay { pub(crate) syntax: SyntaxNode, } -impl IntervalType { +impl IntervalDay { + #[inline] + pub fn day_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DAY_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalHour { + pub(crate) syntax: SyntaxNode, +} +impl IntervalHour { + #[inline] + pub fn day_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DAY_KW) + } + #[inline] + pub fn hour_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::HOUR_KW) + } + #[inline] + pub fn to_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::TO_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalMinute { + pub(crate) syntax: SyntaxNode, +} +impl IntervalMinute { + #[inline] + pub fn day_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DAY_KW) + } + #[inline] + pub fn hour_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::HOUR_KW) + } + #[inline] + pub fn minute_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MINUTE_KW) + } + #[inline] + pub fn to_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::TO_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalMonth { + pub(crate) syntax: SyntaxNode, +} +impl IntervalMonth { + #[inline] + pub fn month_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MONTH_KW) + } + #[inline] + pub fn to_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::TO_KW) + } + #[inline] + pub fn year_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::YEAR_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalSecond { + pub(crate) syntax: SyntaxNode, +} +impl IntervalSecond { #[inline] pub fn literal(&self) -> Option { support::child(&self.syntax) @@ -12980,29 +13071,43 @@ impl IntervalType { support::token(&self.syntax, SyntaxKind::HOUR_KW) } #[inline] - pub fn interval_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::INTERVAL_KW) - } - #[inline] pub fn minute_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::MINUTE_KW) } #[inline] - pub fn month_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::MONTH_KW) - } - #[inline] pub fn second_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::SECOND_KW) } #[inline] - pub fn setof_token(&self) -> Option { - support::token(&self.syntax, SyntaxKind::SETOF_KW) - } - #[inline] pub fn to_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::TO_KW) } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalType { + pub(crate) syntax: SyntaxNode, +} +impl IntervalType { + #[inline] + pub fn interval_qualifier(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn interval_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::INTERVAL_KW) + } + #[inline] + pub fn setof_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SETOF_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct IntervalYear { + pub(crate) syntax: SyntaxNode, +} +impl IntervalYear { #[inline] pub fn year_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::YEAR_KW) @@ -28875,6 +28980,16 @@ pub enum InsertSource { SelectVariant(SelectVariant), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum IntervalQualifier { + IntervalDay(IntervalDay), + IntervalHour(IntervalHour), + IntervalMinute(IntervalMinute), + IntervalMonth(IntervalMonth), + IntervalSecond(IntervalSecond), + IntervalYear(IntervalYear), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum JoinCondition { JoinUsingClause(JoinUsingClause), @@ -31556,6 +31671,24 @@ impl AstNode for ArgList { &self.syntax } } +impl AstNode for ArrayBound { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::ARRAY_BOUND + } + #[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 ArrayExpr { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -39782,6 +39915,96 @@ impl AstNode for Intersect { &self.syntax } } +impl AstNode for IntervalDay { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_DAY + } + #[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 IntervalHour { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_HOUR + } + #[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 IntervalMinute { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_MINUTE + } + #[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 IntervalMonth { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_MONTH + } + #[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 IntervalSecond { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_SECOND + } + #[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 IntervalType { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -39800,6 +40023,24 @@ impl AstNode for IntervalType { &self.syntax } } +impl AstNode for IntervalYear { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::INTERVAL_YEAR + } + #[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 IntoClause { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -63122,6 +63363,88 @@ impl From for InsertSource { InsertSource::DefaultValues(node) } } +impl AstNode for IntervalQualifier { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::INTERVAL_DAY + | SyntaxKind::INTERVAL_HOUR + | SyntaxKind::INTERVAL_MINUTE + | SyntaxKind::INTERVAL_MONTH + | SyntaxKind::INTERVAL_SECOND + | SyntaxKind::INTERVAL_YEAR + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::INTERVAL_DAY => IntervalQualifier::IntervalDay(IntervalDay { syntax }), + SyntaxKind::INTERVAL_HOUR => IntervalQualifier::IntervalHour(IntervalHour { syntax }), + SyntaxKind::INTERVAL_MINUTE => { + IntervalQualifier::IntervalMinute(IntervalMinute { syntax }) + } + SyntaxKind::INTERVAL_MONTH => { + IntervalQualifier::IntervalMonth(IntervalMonth { syntax }) + } + SyntaxKind::INTERVAL_SECOND => { + IntervalQualifier::IntervalSecond(IntervalSecond { syntax }) + } + SyntaxKind::INTERVAL_YEAR => IntervalQualifier::IntervalYear(IntervalYear { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + IntervalQualifier::IntervalDay(it) => &it.syntax, + IntervalQualifier::IntervalHour(it) => &it.syntax, + IntervalQualifier::IntervalMinute(it) => &it.syntax, + IntervalQualifier::IntervalMonth(it) => &it.syntax, + IntervalQualifier::IntervalSecond(it) => &it.syntax, + IntervalQualifier::IntervalYear(it) => &it.syntax, + } + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalDay) -> IntervalQualifier { + IntervalQualifier::IntervalDay(node) + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalHour) -> IntervalQualifier { + IntervalQualifier::IntervalHour(node) + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalMinute) -> IntervalQualifier { + IntervalQualifier::IntervalMinute(node) + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalMonth) -> IntervalQualifier { + IntervalQualifier::IntervalMonth(node) + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalSecond) -> IntervalQualifier { + IntervalQualifier::IntervalSecond(node) + } +} +impl From for IntervalQualifier { + #[inline] + fn from(node: IntervalYear) -> IntervalQualifier { + IntervalQualifier::IntervalYear(node) + } +} impl AstNode for JoinCondition { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index fda8ea5a..8b9e414f 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -536,7 +536,7 @@ ExistsFn = CastExpr = ('cast' | 'treat') '(' Expr 'as' Type ')' | Expr ColonColon Type -| Type Literal +| Type Literal IntervalQualifier? ArrayExpr = 'array' '[' (Expr (',' Expr)*) ']' @@ -760,10 +760,14 @@ Expr = | PostfixExpr ArrayType = + // int array // int array[] // text[] // t[10][10] - Type 'array'? '[' Expr? ']' + Type 'array'? ArrayBound* + +ArrayBound = + '[' Expr? ']' PercentType = 'setof'? PathRef PercentTypeClause @@ -813,23 +817,37 @@ TimestampType = IntervalType = 'setof'? 'interval' - ( - 'year' - | 'month' - | 'day' - | 'hour' - | 'minute' - | 'second' - | 'year' 'to' 'month' - | 'day' 'to' 'hour' - | 'day' 'to' 'minute' - | 'day' 'to' 'second' - | 'hour' 'to' 'minute' - | 'hour' 'to' 'second' - | 'minute' 'to' 'second' - )? - ('(' Literal ')')? + IntervalQualifier? + +IntervalQualifier = + IntervalYear +| IntervalMonth +| IntervalDay +| IntervalHour +| IntervalMinute +| IntervalSecond + +IntervalYear = + 'year' + +IntervalMonth = + 'month' +| 'year' 'to' 'month' + +IntervalDay = + 'day' + +IntervalHour = + 'hour' +| 'day' 'to' 'hour' + +IntervalMinute = + 'minute' +| ('day' | 'hour') 'to' 'minute' +IntervalSecond = + '(' Literal ')' +| (('day' | 'hour' | 'minute') 'to')? 'second' ('(' Literal ')')? Type = ArrayType