diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 0ed6dae3..193589c5 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -547,19 +547,18 @@ $0 SyntaxKind::WHEN_CLAUSE_LIST, ]; - let generated_list_kinds: Vec = (0..SyntaxKind::__LAST as u16) + let unhandled_list_kinds = (0..SyntaxKind::__LAST as u16) .map(SyntaxKind::from) .filter(|kind| { format!("{:?}", kind).ends_with("_LIST") && !delimited_ws_list_kinds.contains(kind) }) - .collect(); - - let diff: Vec = generated_list_kinds - .iter() .filter(|kind| !DELIMITED_LIST_KINDS.contains(kind)) - .copied() - .collect(); + .collect::>(); - assert_eq!(diff, vec![], "We shouldn't have any unhandled list kinds") + assert_eq!( + unhandled_list_kinds, + vec![], + "We shouldn't have any unhandled list kinds" + ) } } diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 0fc416a7..006e0d6e 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -845,6 +845,13 @@ pub enum SyntaxKind { MATCH_SIMPLE, MATERIALIZED, MERGE, + MERGE_DELETE, + MERGE_DO_NOTHING, + MERGE_INSERT, + MERGE_UPDATE, + MERGE_WHEN_MATCHED, + MERGE_WHEN_NOT_MATCHED_SOURCE, + MERGE_WHEN_NOT_MATCHED_TARGET, MOVE, NAME, NAMED_ARG, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 3f0ef022..1c3fd1bb 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -10261,22 +10261,35 @@ fn merge(p: &mut Parser<'_>, m: Option) -> CompletedMarker { // and merge_delete is: // DELETE fn merge_when_clause(p: &mut Parser<'_>) { + let m = p.start(); p.expect(WHEN_KW); - match p.current() { + let kind = match p.current() { MATCHED_KW => { p.bump(MATCHED_KW); + MERGE_WHEN_MATCHED } NOT_KW => { p.bump(NOT_KW); p.expect(MATCHED_KW); - // TODO: need a validation to check these // BY SOURCE | BY TARGET if p.eat(BY_KW) { - let _ = p.eat(SOURCE_KW) || p.eat(TARGET_KW); + if p.eat(SOURCE_KW) { + MERGE_WHEN_NOT_MATCHED_SOURCE + } else if p.eat(TARGET_KW) { + MERGE_WHEN_NOT_MATCHED_TARGET + } else { + p.error("expected SOURCE or TARGET"); + MERGE_WHEN_NOT_MATCHED_TARGET + } + } else { + MERGE_WHEN_NOT_MATCHED_TARGET } } - _ => p.error("expected MATCHED, or NOT MATCHED"), - } + _ => { + p.error("expected MATCHED, or NOT MATCHED"); + MERGE_WHEN_NOT_MATCHED_TARGET + } + }; // [ AND condition ] if p.eat(AND_KW) { if expr(p).is_none() { @@ -10284,16 +10297,24 @@ fn merge_when_clause(p: &mut Parser<'_>) { } } p.expect(THEN_KW); - // merge_update | merge_delete | merge_insert | DO NOTHING - match p.current() { + merge_action(p); + m.complete(p, kind); +} + +// merge_update | merge_delete | merge_insert | DO NOTHING +fn merge_action(p: &mut Parser<'_>) { + let m = p.start(); + let kind = match p.current() { // merge_delete DELETE_KW => { p.bump(DELETE_KW); + MERGE_DELETE } // merge_update UPDATE_KW => { p.bump(UPDATE_KW); set_clause(p); + MERGE_UPDATE } // merge_insert INSERT_KW => { @@ -10315,14 +10336,20 @@ fn merge_when_clause(p: &mut Parser<'_>) { } else { p.error("expected VALUES or DEFAULT VALUES"); } + MERGE_INSERT } // DO NOTHING DO_KW => { p.bump(DO_KW); p.expect(NOTHING_KW); + MERGE_DO_NOTHING } - _ => p.error("expected INSERT, UPDATE, DELETE, or DO NOTHING"), - } + _ => { + p.error("expected INSERT, UPDATE, DELETE, or DO NOTHING"); + MERGE_DO_NOTHING + } + }; + m.complete(p, kind); } // REASSIGN OWNED BY { old_role | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] diff --git a/crates/squawk_parser/tests/snapshots/tests__merge_ok.snap b/crates/squawk_parser/tests/snapshots/tests__merge_ok.snap index 8d66a93a..ec227ccc 100644 --- a/crates/squawk_parser/tests/snapshots/tests__merge_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__merge_ok.snap @@ -42,15 +42,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- aliases_with_as" @@ -104,15 +106,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- using_rows_from" @@ -156,15 +160,17 @@ SOURCE_FILE LITERAL TRUE_KW "true" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- aliases_no_as" @@ -214,15 +220,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- table_with_star" @@ -266,15 +274,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- table_with_only" @@ -318,15 +328,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- paren_query" @@ -386,15 +398,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" MERGE @@ -493,15 +507,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" MERGE @@ -563,15 +579,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- when_clauses_dupe" @@ -613,24 +631,28 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__merge_pg17_ok.snap b/crates/squawk_parser/tests/snapshots/tests__merge_pg17_ok.snap index 81cd8d2e..c176dade 100644 --- a/crates/squawk_parser/tests/snapshots/tests__merge_pg17_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__merge_pg17_ok.snap @@ -43,43 +43,49 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- when_clauses_all_with_conditions" @@ -107,76 +113,82 @@ SOURCE_FILE LITERAL TRUE_KW "true" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - AND_KW "and" - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "foo" + MERGE_WHEN_MATCHED + WHEN_KW "when" WHITESPACE " " - EQ "=" + MATCHED_KW "matched" WHITESPACE " " - NAME_REF - IDENT "bar" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - AND_KW "and" - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "bar" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" WHITESPACE " " - EQ "=" + NOT_KW "not" WHITESPACE " " - NAME_REF - IDENT "foo" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "bar" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - AND_KW "and" - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "buzz" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" WHITESPACE " " - EQ "=" + NOT_KW "not" WHITESPACE " " - NAME_REF - IDENT "bar" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MATCHED_KW "matched" + WHITESPACE " " + AND_KW "and" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "buzz" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- returning_all" @@ -218,43 +230,49 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " RETURNING_CLAUSE RETURNING_KW "returning" @@ -303,43 +321,49 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " RETURNING_CLAUSE RETURNING_KW "returning" @@ -423,19 +447,21 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - INSERT_KW "insert" - WHITESPACE "\n " - DEFAULT_KW "default" - WHITESPACE " " - VALUES_KW "values" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "insert" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE " " + VALUES_KW "values" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- merge_insert_default" @@ -477,42 +503,44 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - INSERT_KW "insert" - WHITESPACE " " - COLUMN_LIST - L_PAREN "(" - COLUMN - NAME_REF - IDENT "a" - COMMA "," + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" WHITESPACE " " - COLUMN - NAME_REF - IDENT "b" - COMMA "," + NOT_KW "not" WHITESPACE " " - COLUMN - NAME_REF - IDENT "c" - R_PAREN ")" - WHITESPACE "\n " - OVERRIDING_KW "overriding" - WHITESPACE " " - USER_KW "user" - WHITESPACE " " - VALUE_KW "value" - WHITESPACE "\n " - DEFAULT_KW "default" - WHITESPACE " " - VALUES_KW "values" + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "insert" + WHITESPACE " " + COLUMN_LIST + L_PAREN "(" + COLUMN + NAME_REF + IDENT "a" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "b" + COMMA "," + WHITESPACE " " + COLUMN + NAME_REF + IDENT "c" + R_PAREN ")" + WHITESPACE "\n " + OVERRIDING_KW "overriding" + WHITESPACE " " + USER_KW "user" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE "\n " + DEFAULT_KW "default" + WHITESPACE " " + VALUES_KW "values" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- merge_insert_values" @@ -554,59 +582,61 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - INSERT_KW "insert" - WHITESPACE "\n " - OVERRIDING_KW "overriding" - WHITESPACE " " - SYSTEM_KW "system" - WHITESPACE " " - VALUE_KW "value" - WHITESPACE "\n " - VALUES - VALUES_KW "values" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" WHITESPACE " " - ROW_LIST - ROW - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "2" - COMMA "," - WHITESPACE " " - LITERAL - DEFAULT_KW "default" - COMMA "," - WHITESPACE " " - LITERAL - INT_NUMBER "3" - COMMA "," + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "insert" + WHITESPACE "\n " + OVERRIDING_KW "overriding" + WHITESPACE " " + SYSTEM_KW "system" + WHITESPACE " " + VALUE_KW "value" + WHITESPACE "\n " + VALUES + VALUES_KW "values" WHITESPACE " " - BIN_EXPR - BIN_EXPR + ROW_LIST + ROW + L_PAREN "(" LITERAL - INT_NUMBER "10" + INT_NUMBER "1" + COMMA "," WHITESPACE " " - STAR "*" + LITERAL + INT_NUMBER "2" + COMMA "," WHITESPACE " " LITERAL - INT_NUMBER "10" - WHITESPACE " " - PLUS "+" - WHITESPACE " " - LITERAL - INT_NUMBER "2" - R_PAREN ")" + DEFAULT_KW "default" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "3" + COMMA "," + WHITESPACE " " + BIN_EXPR + BIN_EXPR + LITERAL + INT_NUMBER "10" + WHITESPACE " " + STAR "*" + WHITESPACE " " + LITERAL + INT_NUMBER "10" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LITERAL + INT_NUMBER "2" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- merge_update" @@ -648,137 +678,141 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - UPDATE_KW "update" - WHITESPACE " " - SET_KW "set" - WHITESPACE "\n " - NAME_REF - IDENT "a" - WHITESPACE " " - EQ "=" - WHITESPACE " " - DEFAULT_KW "default" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "b" - WHITESPACE " " - EQ "=" - WHITESPACE " " - LITERAL - INT_NUMBER "1" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "c" - WHITESPACE " " - EQ "=" - WHITESPACE " " - NAME_REF - IDENT "d" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "e" - WHITESPACE " " - EQ "=" - WHITESPACE " " - PAREN_EXPR - L_PAREN "(" - SELECT - SELECT_CLAUSE - SELECT_KW "select" - WHITESPACE " " - TARGET_LIST - TARGET - LITERAL - INT_NUMBER "1" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "f" - WHITESPACE " " - EQ "=" - WHITESPACE " " - CALL_EXPR - NAME_REF - ROW_KW "row" - ARG_LIST - L_PAREN "(" - LITERAL - INT_NUMBER "1" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE "\n " + NAME_REF + IDENT "a" + WHITESPACE " " + EQ "=" + WHITESPACE " " + DEFAULT_KW "default" COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "b" + WHITESPACE " " + EQ "=" WHITESPACE " " LITERAL - INT_NUMBER "2" + INT_NUMBER "1" COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "c" WHITESPACE " " - LITERAL - DEFAULT_KW "default" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "g" - WHITESPACE " " - EQ "=" - WHITESPACE " " - TUPLE_EXPR - L_PAREN "(" - LITERAL - INT_NUMBER "1" - COMMA "," + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "d" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "e" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "f" + WHITESPACE " " + EQ "=" + WHITESPACE " " + CALL_EXPR + NAME_REF + ROW_KW "row" + ARG_LIST + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "g" + WHITESPACE " " + EQ "=" + WHITESPACE " " + TUPLE_EXPR + L_PAREN "(" + LITERAL + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + LITERAL + INT_NUMBER "2" + COMMA "," + WHITESPACE " " + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + NAME_REF + IDENT "h" + WHITESPACE " " + EQ "=" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + LITERAL + DEFAULT_KW "default" + R_PAREN ")" + WHITESPACE "\n " + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" WHITESPACE " " - LITERAL - INT_NUMBER "2" - COMMA "," + NOT_KW "not" WHITESPACE " " - LITERAL - DEFAULT_KW "default" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - NAME_REF - IDENT "h" - WHITESPACE " " - EQ "=" - WHITESPACE " " - PAREN_EXPR - L_PAREN "(" - LITERAL - DEFAULT_KW "default" - R_PAREN ")" - WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - UPDATE_KW "update" - WHITESPACE " " - SET_KW "set" - WHITESPACE " " - NAME_REF - IDENT "foo" - WHITESPACE " " - EQ "=" - WHITESPACE " " - NAME_REF - IDENT "bar" + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "update" + WHITESPACE " " + SET_KW "set" + WHITESPACE " " + NAME_REF + IDENT "foo" + WHITESPACE " " + EQ "=" + WHITESPACE " " + NAME_REF + IDENT "bar" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- merge_delete" @@ -820,27 +854,31 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DELETE_KW "delete" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DELETE + DELETE_KW "delete" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DELETE_KW "delete" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DELETE + DELETE_KW "delete" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- with_select" @@ -912,15 +950,17 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE "\n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE "\n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- doc_example_1" @@ -970,73 +1010,77 @@ SOURCE_FILE NAME_REF IDENT "customer_id" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - UPDATE_KW "UPDATE" - WHITESPACE " " - SET_KW "SET" - WHITESPACE " " - NAME_REF - IDENT "balance" - WHITESPACE " " - EQ "=" - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "balance" + MERGE_WHEN_MATCHED + WHEN_KW "WHEN" WHITESPACE " " - PLUS "+" + MATCHED_KW "MATCHED" WHITESPACE " " - NAME_REF - IDENT "transaction_value" - WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - INSERT_KW "INSERT" - WHITESPACE " " - COLUMN_LIST - L_PAREN "(" - COLUMN - NAME_REF - IDENT "customer_id" - COMMA "," - WHITESPACE " " - COLUMN + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " NAME_REF IDENT "balance" - R_PAREN ")" - WHITESPACE "\n " - VALUES - VALUES_KW "VALUES" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "balance" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "transaction_value" + WHITESPACE "\n" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" WHITESPACE " " - ROW_LIST - ROW + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "INSERT" + WHITESPACE " " + COLUMN_LIST L_PAREN "(" - FIELD_EXPR - NAME_REF - IDENT "t" - DOT "." + COLUMN NAME_REF IDENT "customer_id" COMMA "," WHITESPACE " " - FIELD_EXPR + COLUMN NAME_REF - IDENT "t" - DOT "." - NAME_REF - IDENT "transaction_value" + IDENT "balance" R_PAREN ")" + WHITESPACE "\n " + VALUES + VALUES_KW "VALUES" + WHITESPACE " " + ROW_LIST + ROW + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "transaction_value" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- doc_example_2" @@ -1109,73 +1153,77 @@ SOURCE_FILE NAME_REF IDENT "customer_id" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - UPDATE_KW "UPDATE" - WHITESPACE " " - SET_KW "SET" - WHITESPACE " " - NAME_REF - IDENT "balance" - WHITESPACE " " - EQ "=" - WHITESPACE " " - BIN_EXPR - NAME_REF - IDENT "balance" - WHITESPACE " " - PLUS "+" + MERGE_WHEN_MATCHED + WHEN_KW "WHEN" WHITESPACE " " - NAME_REF - IDENT "transaction_value" - WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - INSERT_KW "INSERT" - WHITESPACE " " - COLUMN_LIST - L_PAREN "(" - COLUMN - NAME_REF - IDENT "customer_id" - COMMA "," + MATCHED_KW "MATCHED" WHITESPACE " " - COLUMN + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " NAME_REF IDENT "balance" - R_PAREN ")" - WHITESPACE "\n " - VALUES - VALUES_KW "VALUES" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "balance" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + NAME_REF + IDENT "transaction_value" + WHITESPACE "\n" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "WHEN" WHITESPACE " " - ROW_LIST - ROW + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "INSERT" + WHITESPACE " " + COLUMN_LIST L_PAREN "(" - FIELD_EXPR - NAME_REF - IDENT "t" - DOT "." + COLUMN NAME_REF IDENT "customer_id" COMMA "," WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "t" - DOT "." + COLUMN NAME_REF - IDENT "transaction_value" + IDENT "balance" R_PAREN ")" + WHITESPACE "\n " + VALUES + VALUES_KW "VALUES" + WHITESPACE " " + ROW_LIST + ROW + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "customer_id" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "t" + DOT "." + NAME_REF + IDENT "transaction_value" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- doc_example_3" @@ -1225,43 +1273,71 @@ SOURCE_FILE NAME_REF IDENT "winename" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - AND_KW "AND" - WHITESPACE " " - BIN_EXPR - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "stock_delta" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "WHEN" WHITESPACE " " - R_ANGLE ">" + NOT_KW "NOT" WHITESPACE " " - LITERAL - INT_NUMBER "0" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - INSERT_KW "INSERT" - WHITESPACE " " - VALUES - VALUES_KW "VALUES" - ROW_LIST - ROW - L_PAREN "(" + MATCHED_KW "MATCHED" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "INSERT" + WHITESPACE " " + VALUES + VALUES_KW "VALUES" + ROW_LIST + ROW + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + R_PAREN ")" + WHITESPACE "\n" + MERGE_WHEN_MATCHED + WHEN_KW "WHEN" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + BIN_EXPR FIELD_EXPR NAME_REF - IDENT "s" + IDENT "w" DOT "." NAME_REF - IDENT "winename" - COMMA "," + IDENT "stock" + WHITESPACE " " + PLUS "+" WHITESPACE " " FIELD_EXPR NAME_REF @@ -1269,72 +1345,50 @@ SOURCE_FILE DOT "." NAME_REF IDENT "stock_delta" - R_PAREN ")" - WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - AND_KW "AND" - WHITESPACE " " - BIN_EXPR - BIN_EXPR - FIELD_EXPR - NAME_REF - IDENT "w" - DOT "." - NAME_REF - IDENT "stock" WHITESPACE " " - PLUS "+" + R_ANGLE ">" WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "stock_delta" - WHITESPACE " " - R_ANGLE ">" + LITERAL + INT_NUMBER "0" WHITESPACE " " - LITERAL - INT_NUMBER "0" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - UPDATE_KW "UPDATE" - WHITESPACE " " - SET_KW "SET" - WHITESPACE " " - NAME_REF - IDENT "stock" - WHITESPACE " " - EQ "=" - WHITESPACE " " - BIN_EXPR - FIELD_EXPR - NAME_REF - IDENT "w" - DOT "." + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " NAME_REF IDENT "stock" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock_delta" + WHITESPACE "\n" + MERGE_WHEN_MATCHED + WHEN_KW "WHEN" WHITESPACE " " - PLUS "+" + MATCHED_KW "MATCHED" WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "stock_delta" - WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - DELETE_KW "DELETE" + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_DELETE + DELETE_KW "DELETE" WHITESPACE "\n" RETURNING_CLAUSE RETURNING_KW "RETURNING" @@ -1404,94 +1458,100 @@ SOURCE_FILE NAME_REF IDENT "winename" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - BY_KW "BY" - WHITESPACE " " - TARGET_KW "TARGET" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - INSERT_KW "INSERT" - WHITESPACE " " - VALUES - VALUES_KW "VALUES" - ROW_LIST - ROW - L_PAREN "(" - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "winename" - COMMA "," - WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "stock" - R_PAREN ")" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + TARGET_KW "TARGET" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_INSERT + INSERT_KW "INSERT" + WHITESPACE " " + VALUES + VALUES_KW "VALUES" + ROW_LIST + ROW + L_PAREN "(" + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "winename" + COMMA "," + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" + R_PAREN ")" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - AND_KW "AND" - WHITESPACE " " - BIN_EXPR - FIELD_EXPR - NAME_REF - IDENT "w" - DOT "." - NAME_REF - IDENT "stock" + MERGE_WHEN_MATCHED + WHEN_KW "WHEN" WHITESPACE " " - NEQ "!=" + MATCHED_KW "MATCHED" WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." + AND_KW "AND" + WHITESPACE " " + BIN_EXPR + FIELD_EXPR + NAME_REF + IDENT "w" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + NEQ "!=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_UPDATE + UPDATE_KW "UPDATE" + WHITESPACE " " + SET_KW "SET" + WHITESPACE " " NAME_REF IDENT "stock" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - UPDATE_KW "UPDATE" - WHITESPACE " " - SET_KW "SET" - WHITESPACE " " - NAME_REF - IDENT "stock" - WHITESPACE " " - EQ "=" - WHITESPACE " " - FIELD_EXPR - NAME_REF - IDENT "s" - DOT "." - NAME_REF - IDENT "stock" + WHITESPACE " " + EQ "=" + WHITESPACE " " + FIELD_EXPR + NAME_REF + IDENT "s" + DOT "." + NAME_REF + IDENT "stock" WHITESPACE "\n" - WHEN_KW "WHEN" - WHITESPACE " " - NOT_KW "NOT" - WHITESPACE " " - MATCHED_KW "MATCHED" - WHITESPACE " " - BY_KW "BY" - WHITESPACE " " - SOURCE_KW "SOURCE" - WHITESPACE " " - THEN_KW "THEN" - WHITESPACE "\n " - DELETE_KW "DELETE" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "WHEN" + WHITESPACE " " + NOT_KW "NOT" + WHITESPACE " " + MATCHED_KW "MATCHED" + WHITESPACE " " + BY_KW "BY" + WHITESPACE " " + SOURCE_KW "SOURCE" + WHITESPACE " " + THEN_KW "THEN" + WHITESPACE "\n " + MERGE_DELETE + DELETE_KW "DELETE" SEMICOLON ";" WHITESPACE "\n" diff --git a/crates/squawk_parser/tests/snapshots/tests__prepare_ok.snap b/crates/squawk_parser/tests/snapshots/tests__prepare_ok.snap index 99076920..45651131 100644 --- a/crates/squawk_parser/tests/snapshots/tests__prepare_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__prepare_ok.snap @@ -336,43 +336,49 @@ SOURCE_FILE NAME_REF IDENT "id" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - BY_KW "by" - WHITESPACE " " - SOURCE_KW "source" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_SOURCE + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + BY_KW "by" + WHITESPACE " " + SOURCE_KW "source" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - NOT_KW "not" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_NOT_MATCHED_TARGET + WHEN_KW "when" + WHITESPACE " " + NOT_KW "not" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- values" 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 1e5e0fd6..a96fc3b7 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_ok.snap @@ -40,15 +40,17 @@ SOURCE_FILE LITERAL TRUE_KW "true" WHITESPACE "\n " - WHEN_KW "when" - WHITESPACE " " - MATCHED_KW "matched" - WHITESPACE " " - THEN_KW "then" - WHITESPACE " \n " - DO_KW "do" - WHITESPACE " " - NOTHING_KW "nothing" + MERGE_WHEN_MATCHED + WHEN_KW "when" + WHITESPACE " " + MATCHED_KW "matched" + WHITESPACE " " + THEN_KW "then" + WHITESPACE " \n " + MERGE_DO_NOTHING + DO_KW "do" + WHITESPACE " " + NOTHING_KW "nothing" WHITESPACE "\n" R_PAREN ")" WHITESPACE "\n" diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index 5e987ed0..a175d530 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -6461,10 +6461,207 @@ pub struct Merge { pub(crate) syntax: SyntaxNode, } impl Merge { + #[inline] + pub fn alias(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn merge_when_clauses(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn name_ref(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn using_clause(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn star_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::STAR) + } + #[inline] + pub fn into_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::INTO_KW) + } #[inline] pub fn merge_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::MERGE_KW) } + #[inline] + pub fn only_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ONLY_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeDelete { + pub(crate) syntax: SyntaxNode, +} +impl MergeDelete { + #[inline] + pub fn delete_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DELETE_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeDoNothing { + pub(crate) syntax: SyntaxNode, +} +impl MergeDoNothing { + #[inline] + pub fn do_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::DO_KW) + } + #[inline] + pub fn nothing_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NOTHING_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeInsert { + pub(crate) syntax: SyntaxNode, +} +impl MergeInsert { + #[inline] + pub fn insert_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::INSERT_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeUpdate { + pub(crate) syntax: SyntaxNode, +} +impl MergeUpdate { + #[inline] + pub fn set_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SET_KW) + } + #[inline] + pub fn update_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::UPDATE_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeWhenMatched { + pub(crate) syntax: SyntaxNode, +} +impl MergeWhenMatched { + #[inline] + pub fn condition(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn merge_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn and_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AND_KW) + } + #[inline] + pub fn matched_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MATCHED_KW) + } + #[inline] + pub fn then_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::THEN_KW) + } + #[inline] + pub fn when_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::WHEN_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeWhenNotMatchedSource { + pub(crate) syntax: SyntaxNode, +} +impl MergeWhenNotMatchedSource { + #[inline] + pub fn condition(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn merge_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn and_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AND_KW) + } + #[inline] + pub fn by_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::BY_KW) + } + #[inline] + pub fn matched_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MATCHED_KW) + } + #[inline] + pub fn not_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NOT_KW) + } + #[inline] + pub fn source_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::SOURCE_KW) + } + #[inline] + pub fn then_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::THEN_KW) + } + #[inline] + pub fn when_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::WHEN_KW) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MergeWhenNotMatchedTarget { + pub(crate) syntax: SyntaxNode, +} +impl MergeWhenNotMatchedTarget { + #[inline] + pub fn condition(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn merge_action(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn and_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AND_KW) + } + #[inline] + pub fn by_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::BY_KW) + } + #[inline] + pub fn matched_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::MATCHED_KW) + } + #[inline] + pub fn not_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::NOT_KW) + } + #[inline] + pub fn target_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::TARGET_KW) + } + #[inline] + pub fn then_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::THEN_KW) + } + #[inline] + pub fn when_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::WHEN_KW) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -10341,6 +10538,21 @@ pub enum MatchType { MatchSimple(MatchSimple), } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum MergeAction { + MergeDelete(MergeDelete), + MergeDoNothing(MergeDoNothing), + MergeInsert(MergeInsert), + MergeUpdate(MergeUpdate), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum MergeWhenClause { + MergeWhenMatched(MergeWhenMatched), + MergeWhenNotMatchedSource(MergeWhenNotMatchedSource), + MergeWhenNotMatchedTarget(MergeWhenNotMatchedTarget), +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum OnCommitAction { DeleteRows(DeleteRows), @@ -16082,6 +16294,132 @@ impl AstNode for Merge { &self.syntax } } +impl AstNode for MergeDelete { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_DELETE + } + #[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 MergeDoNothing { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_DO_NOTHING + } + #[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 MergeInsert { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_INSERT + } + #[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 MergeUpdate { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_UPDATE + } + #[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 MergeWhenMatched { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_WHEN_MATCHED + } + #[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 MergeWhenNotMatchedSource { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_WHEN_NOT_MATCHED_SOURCE + } + #[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 MergeWhenNotMatchedTarget { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::MERGE_WHEN_NOT_MATCHED_TARGET + } + #[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 Move { #[inline] fn can_cast(kind: SyntaxKind) -> bool { @@ -21037,6 +21375,119 @@ impl From for MatchType { MatchType::MatchSimple(node) } } +impl AstNode for MergeAction { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::MERGE_DELETE + | SyntaxKind::MERGE_DO_NOTHING + | SyntaxKind::MERGE_INSERT + | SyntaxKind::MERGE_UPDATE + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::MERGE_DELETE => MergeAction::MergeDelete(MergeDelete { syntax }), + SyntaxKind::MERGE_DO_NOTHING => MergeAction::MergeDoNothing(MergeDoNothing { syntax }), + SyntaxKind::MERGE_INSERT => MergeAction::MergeInsert(MergeInsert { syntax }), + SyntaxKind::MERGE_UPDATE => MergeAction::MergeUpdate(MergeUpdate { syntax }), + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + MergeAction::MergeDelete(it) => &it.syntax, + MergeAction::MergeDoNothing(it) => &it.syntax, + MergeAction::MergeInsert(it) => &it.syntax, + MergeAction::MergeUpdate(it) => &it.syntax, + } + } +} +impl From for MergeAction { + #[inline] + fn from(node: MergeDelete) -> MergeAction { + MergeAction::MergeDelete(node) + } +} +impl From for MergeAction { + #[inline] + fn from(node: MergeDoNothing) -> MergeAction { + MergeAction::MergeDoNothing(node) + } +} +impl From for MergeAction { + #[inline] + fn from(node: MergeInsert) -> MergeAction { + MergeAction::MergeInsert(node) + } +} +impl From for MergeAction { + #[inline] + fn from(node: MergeUpdate) -> MergeAction { + MergeAction::MergeUpdate(node) + } +} +impl AstNode for MergeWhenClause { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + matches!( + kind, + SyntaxKind::MERGE_WHEN_MATCHED + | SyntaxKind::MERGE_WHEN_NOT_MATCHED_SOURCE + | SyntaxKind::MERGE_WHEN_NOT_MATCHED_TARGET + ) + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + SyntaxKind::MERGE_WHEN_MATCHED => { + MergeWhenClause::MergeWhenMatched(MergeWhenMatched { syntax }) + } + SyntaxKind::MERGE_WHEN_NOT_MATCHED_SOURCE => { + MergeWhenClause::MergeWhenNotMatchedSource(MergeWhenNotMatchedSource { syntax }) + } + SyntaxKind::MERGE_WHEN_NOT_MATCHED_TARGET => { + MergeWhenClause::MergeWhenNotMatchedTarget(MergeWhenNotMatchedTarget { syntax }) + } + _ => { + return None; + } + }; + Some(res) + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + match self { + MergeWhenClause::MergeWhenMatched(it) => &it.syntax, + MergeWhenClause::MergeWhenNotMatchedSource(it) => &it.syntax, + MergeWhenClause::MergeWhenNotMatchedTarget(it) => &it.syntax, + } + } +} +impl From for MergeWhenClause { + #[inline] + fn from(node: MergeWhenMatched) -> MergeWhenClause { + MergeWhenClause::MergeWhenMatched(node) + } +} +impl From for MergeWhenClause { + #[inline] + fn from(node: MergeWhenNotMatchedSource) -> MergeWhenClause { + MergeWhenClause::MergeWhenNotMatchedSource(node) + } +} +impl From for MergeWhenClause { + #[inline] + fn from(node: MergeWhenNotMatchedTarget) -> MergeWhenClause { + MergeWhenClause::MergeWhenNotMatchedTarget(node) + } +} impl AstNode for OnCommitAction { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index 6acd881c..92fe2683 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -928,8 +928,45 @@ Delete = Notify = 'notify' +MergeWhenMatched = + 'when' 'matched' + ('and' condition:Expr) 'then' MergeAction + +MergeWhenNotMatchedSource = + 'when' 'not' 'matched' 'by' 'source' + ('and' condition:Expr) 'then' MergeAction + +MergeWhenNotMatchedTarget = + 'when' 'not' 'matched' ('by' 'target')? + ('and' condition:Expr) 'then' MergeAction + +MergeWhenClause = + MergeWhenMatched +| MergeWhenNotMatchedSource +| MergeWhenNotMatchedTarget + +MergeDelete = + 'delete' + +MergeUpdate = + 'update' 'set' + +MergeInsert = + 'insert' + +MergeDoNothing = + 'do' 'nothing' + +MergeAction = + MergeDelete +| MergeUpdate +| MergeInsert +| MergeDoNothing + Merge = - 'merge' + 'merge' 'into' 'only'? NameRef '*'? Alias? + UsingClause + MergeWhenClause* Declare = 'declare'