From 868091c299243fdfdc979a880eaaa823b58e91e6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 8 Apr 2022 10:35:32 +0000 Subject: [PATCH] Tokenizer and grammar rules sufficient for the MERGE command. FossilOrigin-Name: 2deee326e850e829a73535930aecc5d512eb87790862c16c0993e92766d5c779 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/parse.y | 28 ++++++++++++++++++++++++++++ tool/mkkeywordhash.c | 13 +++++++++++-- 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9e29deaa06..c4421dbef7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sunreachable\sbranches\sintroduced\sby\sthe\srecent\nsqlite3TriggersExist()\soptimization. -D 2022-04-07T20:45:38.697 +C Tokenizer\sand\sgrammar\srules\ssufficient\sfor\sthe\sMERGE\scommand. +D 2022-04-08T10:35:32.552 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y 9130a936927658e7c574e97e5d4f0a747a3f6b9a42bc5c63e455c8e40cc74216 +F src/parse.y ff8f0f6f1086c6c480503f21386422f1dcd3d37dfe1011c9089abc7a14772c50 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -1873,7 +1873,7 @@ F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a19 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl ac96a74f5e6d9dac672d5229f79c583d3357a50e7d098e473e6b2ce2f8ae1704 x -F tool/mkkeywordhash.c 35bfc41adacc4aa6ef6fca7fd0c63e0ec0534b78daf4d0cfdebe398216bbffc3 +F tool/mkkeywordhash.c eb57113139c6a37d80a3247026c5acc1efa0711678d6f76d54d2c46d39db5a8f F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef F tool/mkopcodeh.tcl 5dab48c49a25452257494e9601702ab63adaba6bd54a9b382615fa52661c8f8c @@ -1945,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c -R 07d0b0c26e9cd2798bbb00ddbafc6a3b +P 1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 +R 6aa4900a9c6f26de4fb4a6a1056c6eed +T *branch * merge-statement +T *sym-merge-statement * +T -sym-trunk * U drh -Z 93237070ff101cf9292ceb1ee884c28a +Z b59368f7e6309c70d89f64cbb029dfb3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 55edbcf9bb..d462c4d1de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 \ No newline at end of file +2deee326e850e829a73535930aecc5d512eb87790862c16c0993e92766d5c779 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 4deae14b4c..1f094cbc64 100644 --- a/src/parse.y +++ b/src/parse.y @@ -263,6 +263,9 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);} %endif MATERIALIZED REINDEX RENAME CTIME_KW IF +%ifndef SQLITE_OMIT_MERGE + MERGE MATCHED SOURCE TARGET +%endif . %wildcard ANY. @@ -1011,6 +1014,30 @@ idlist(A) ::= idlist(A) COMMA nm(Y). idlist(A) ::= nm(Y). {A = sqlite3IdListAppend(pParse,0,&Y); /*A-overwrites-Y*/} + +////////////////////////// The MERGE command ////////////////////////////////// +// +%ifndef SQLITE_OMIT_MERGE +cmd ::= mergecmd. +mergecmd ::= with MERGE INTO nm dbnm as USING nm dbnm as ON expr whenclause. +mergecmd ::= with MERGE INTO nm dbnm as USING LP select RP as ON expr whenclause. +whenclause ::= when. +whenclause ::= whenclause when. +when ::= WHEN MATCHED whencond THEN whenaction1. +when ::= WHEN NOT MATCHED whencond THEN whenaction2. +when ::= WHEN NOT MATCHED BY TARGET whencond THEN whenaction2. +when ::= WHEN NOT MATCHED BY SOURCE whencond THEN whenaction1. +whencond ::= . +whencond ::= AND expr. +whenaction1 ::= UPDATE SET setlist. +whenaction1 ::= DELETE. +whenaction1 ::= DO NOTHING. +whenaction2 ::= INSERT DEFAULT VALUES. +whenaction2 ::= INSERT idlist_opt values. +whenaction2 ::= DO NOTHING. +%endif /* SQLITE_OMIT_MERGE */ + + /////////////////////////// Expression Processing ///////////////////////////// // @@ -1852,6 +1879,7 @@ over_clause(A) ::= OVER nm(Z). { filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } %endif /* SQLITE_OMIT_WINDOWFUNC */ + /* ** The code generator needs some extra TK_ token values for tokens that ** are synthesized and do not actually appear in the grammar: diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index fe25b5abc0..81ccc06dd6 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -164,6 +164,11 @@ struct Keyword { #else # define RETURNING 0x00400000 #endif +#ifdef SQLITE_OMIT_MERGE +# define MERGE 0 +#else +# define MERGE 0x00800000 +#endif /* @@ -210,7 +215,7 @@ static Keyword aKeywordTable[] = { { "DESC", "TK_DESC", ALWAYS, 3 }, { "DETACH", "TK_DETACH", ATTACH, 0 }, { "DISTINCT", "TK_DISTINCT", ALWAYS, 5 }, - { "DO", "TK_DO", UPSERT, 2 }, + { "DO", "TK_DO", UPSERT|MERGE, 2 }, { "DROP", "TK_DROP", ALWAYS, 1 }, { "END", "TK_END", ALWAYS, 1 }, { "EACH", "TK_EACH", TRIGGER, 1 }, @@ -255,11 +260,13 @@ static Keyword aKeywordTable[] = { { "LIKE", "TK_LIKE_KW", ALWAYS, 5 }, { "LIMIT", "TK_LIMIT", ALWAYS, 3 }, { "MATCH", "TK_MATCH", ALWAYS, 2 }, + { "MATCHED", "TK_MATCHED", MERGE, 10 }, { "MATERIALIZED", "TK_MATERIALIZED", CTE, 12 }, + { "MERGE", "TK_MERGE", MERGE, 10 }, { "NATURAL", "TK_JOIN_KW", ALWAYS, 3 }, { "NO", "TK_NO", FKEY|WINDOWFUNC, 2 }, { "NOT", "TK_NOT", ALWAYS, 10 }, - { "NOTHING", "TK_NOTHING", UPSERT, 1 }, + { "NOTHING", "TK_NOTHING", UPSERT|MERGE, 1 }, { "NOTNULL", "TK_NOTNULL", ALWAYS, 3 }, { "NULL", "TK_NULL", ALWAYS, 10 }, { "NULLS", "TK_NULLS", ALWAYS, 3 }, @@ -295,6 +302,8 @@ static Keyword aKeywordTable[] = { { "SAVEPOINT", "TK_SAVEPOINT", ALWAYS, 1 }, { "SELECT", "TK_SELECT", ALWAYS, 10 }, { "SET", "TK_SET", ALWAYS, 10 }, + { "SOURCE", "TK_SOURCE", MERGE, 10 }, + { "TARGET", "TK_TARGET", MERGE, 10 }, { "TABLE", "TK_TABLE", ALWAYS, 1 }, { "TEMP", "TK_TEMP", ALWAYS, 1 }, { "TEMPORARY", "TK_TEMP", ALWAYS, 1 }, -- 2.39.5