]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Update the parser so that sub-queries and CTEs may have WITH clauses.
authordan <dan@noemail.net>
Sat, 11 Jan 2014 19:19:36 +0000 (19:19 +0000)
committerdan <dan@noemail.net>
Sat, 11 Jan 2014 19:19:36 +0000 (19:19 +0000)
FossilOrigin-Name: 704d3931b855562a619769955969d439c42ca406

manifest
manifest.uuid
src/build.c
src/parse.y
src/sqliteInt.h
test/with1.test [new file with mode: 0644]

index 16d294c829ec438aa1880d44fb95b4b3918c259d..c9d03126cd69d45a52f23bf2dd7c84d486a99b15 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Parse\scommon\stable\sexpressions.\s\sBut\sdo\snot\sdo\sanything\swith\sthem\s(yet).
-D 2014-01-11T13:22:17.016
+C Update\sthe\sparser\sso\sthat\ssub-queries\sand\sCTEs\smay\shave\sWITH\sclauses.
+D 2014-01-11T19:19:36.147
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -169,7 +169,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df
 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9
 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c 198670a78fe748b6e60d6345a8aa1db57794511a
+F src/build.c 1da29e4e93d9774599f1f791d011ba46d841000c
 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
@@ -209,7 +209,7 @@ F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968
 F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07
 F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
-F src/parse.y 0ccd364dd3670ad5763a5e94dd11196ddc10927a
+F src/parse.y 1e3fd22fc82930d0cce01f2ab90616100c59ee0c
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
@@ -224,7 +224,7 @@ F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344
 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h bb093076ba1eb956330cca0ca2a206c91facab4b
+F src/sqliteInt.h 2710b3a6c66edda9f193453268f6fe878ff5a0ca
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -1091,6 +1091,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
 F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
 F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
+F test/with1.test e8146198319c3627bb21ef085c58a827f35686a7
 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
@@ -1148,10 +1149,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 29ba458d849ad8864711cbe59fb10447a947e06a
-R b8f42a0591e43b680c1e09056e8afd6e
-T *branch * common-table-expr
-T *sym-common-table-expr *
-T -sym-trunk *
-U drh
-Z 9a38087dfe69ad33926bbf7c01c0b22a
+P da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5
+R bbb9d541af414d7b8bb3f418deb50875
+U dan
+Z a973a84816d55810384771a899b1092b
index 17610fd9e7ec6234279b1c2e55e43b629f54202e..f6a009da18958b2ae798451999b88aa9ea65e53f 100644 (file)
@@ -1 +1 @@
-da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5
\ No newline at end of file
+704d3931b855562a619769955969d439c42ca406
\ No newline at end of file
index 4fb4b4efa9cb777a016d250851a9966aab947a98..23628f73be093d6460a427489ef25f65a9d02a7f 100644 (file)
@@ -4200,22 +4200,26 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
 }
 
 #ifndef SQLITE_OMIT_CTE
-/* This routine is invoked when a single with_query of a
-** common-table-expression has been parsed.  Record the query.
+/* 
+** This routine is invoked once per CTE by the parser while parsing a 
+** WITH clause. 
 */
-void sqlite3CteAdd(
+With *sqlite3WithAdd(
   Parse *pParse,          /* Parsing context */
+  With *pWith,            /* Existing WITH clause, or NULL */
   Token *pName,           /* Name of the common-table */
-  ExprList *pArgList,     /* Optional column name list for the table */
+  IdList *pArglist,       /* Optional column name list for the table */
   Select *pQuery          /* Query used to initialize the table */
 ){
-  sqlite3ExprListDelete(pParse->db, pArgList);
+  sqlite3IdListDelete(pParse->db, pArglist);
   sqlite3SelectDelete(pParse->db, pQuery);
+  return 0;
 }
 
-/* This routine is invoked at the end of the entire WITH clause.
+/*
+** Free the contents of the With object passed as the second argument.
 */
-void sqlite3CteFinish(Parse *pParse, int isRecursive){
+void sqlite3WithDelete(sqlite3 *db, With *pWith){
   /* TBD */
 }
 #endif /* !defined(SQLITE_OMIT_CTE) */
index f4fa4b276d7c3cf4aefaba46ba786113ae09e629..c3cb2d62aa762fd8eea85d62e1421d0aac0eaf71 100644 (file)
@@ -396,7 +396,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). {
 
 //////////////////////// The SELECT statement /////////////////////////////////
 //
-cmd ::= with select(X).  {
+cmd ::= select(X).  {
   SelectDest dest = {SRT_Output, 0, 0, 0, 0};
   sqlite3Select(pParse, X, &dest);
   sqlite3ExplainBegin(pParse->pVdbe);
@@ -407,12 +407,16 @@ cmd ::= with select(X).  {
 
 %type select {Select*}
 %destructor select {sqlite3SelectDelete(pParse->db, $$);}
+%type selectnowith {Select*}
+%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
 %type oneselect {Select*}
 %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
 
-select(A) ::= oneselect(X).                      {A = X;}
+select(A) ::= with selectnowith(X). {A = X;}
+
+selectnowith(A) ::= oneselect(X).                      {A = X;}
 %ifndef SQLITE_OMIT_COMPOUND_SELECT
-select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
+selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z).  {
   if( Z ){
     Z->op = (u8)Y;
     Z->pPrior = X;
@@ -1365,13 +1369,19 @@ anylist ::= anylist ANY.
 
 
 //////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
-with ::= .
+%type with {With*}
+%type wqlist {With*}
+%destructor with {sqlite3WithDelete(pParse->db, $$);}
+
+with(A) ::= . {A = 0;}
 %ifndef SQLITE_OMIT_CTE
-with ::= WITH wqlist.              {sqlite3CteFinish(pParse, 0);}
-with ::= WITH RECURSIVE wqlist.    {sqlite3CteFinish(pParse, 1);}
-wqlist ::= with_query.
-wqlist ::= wqlist COMMA with_query.
-with_query ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. {
-  sqlite3CteAdd(pParse, &X, Y, Z);
+with(A) ::= WITH wqlist(W).              { A = W; }
+with(A) ::= WITH RECURSIVE wqlist(W).    { A = W; }
+
+wqlist(A) ::= nm(X) inscollist_opt(Y) AS LP select(Z) RP. {
+  A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
+}
+wqlist(A) ::= wqlist(W) COMMA nm(X) inscollist_opt(Y) AS LP select(Z) RP. {
+  A = sqlite3WithAdd(pParse, W, &X, Y, Z);
 }
 %endif  SQLITE_OMIT_CTE
index d517789da052e041d25cd85a9c321bc0f4742d44..8846ffb04c1918f46edb824c88c3e69bef65054f 100644 (file)
@@ -760,6 +760,7 @@ typedef struct VTable VTable;
 typedef struct VtabCtx VtabCtx;
 typedef struct Walker Walker;
 typedef struct WhereInfo WhereInfo;
+typedef struct With With;
 
 /*
 ** Defer sourcing vdbe.h and btree.h until after the "u8" and 
@@ -2631,6 +2632,19 @@ int sqlite3WalkSelectFrom(Walker*, Select*);
 #define WRC_Prune       1   /* Omit children but continue walking siblings */
 #define WRC_Abort       2   /* Abandon the tree walk */
 
+/*
+** An instance of this structure represents a set of CTEs (common table 
+** expressions) created by a single WITH clause.
+*/
+struct With {
+  int nCte;                       /* Number of CTEs */
+  struct Cte {
+    const char *zName;            /* Name of this CTE */
+    IdList *pCol;                 /* List of explicit column names, or NULL */
+    Select *pSelect;              /* The contents of the CTE */
+  } a[1];
+};
+
 /*
 ** Assuming zIn points to the first byte of a UTF-8 character,
 ** advance zIn to point to the first byte of the next UTF-8 character.
@@ -3330,8 +3344,8 @@ const char *sqlite3JournalModename(int);
   int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
 #endif
 #ifndef SQLITE_OMIT_CTE
-  void sqlite3CteAdd(Parse*,Token*,ExprList*,Select*);
-  void sqlite3CteFinish(Parse*,int);
+  With *sqlite3WithAdd(Parse*,With*,Token*,IdList*,Select*);
+  void sqlite3WithDelete(sqlite3*,With*);
 #endif
 
 /* Declarations for functions in fkey.c. All of these are replaced by
diff --git a/test/with1.test b/test/with1.test
new file mode 100644 (file)
index 0000000..80e879a
--- /dev/null
@@ -0,0 +1,40 @@
+# 2014 January 11
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this file is testing the WITH clause.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix with1
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(x INTEGER, y INTEGER);
+  WITH x(a) AS ( SELECT * FROM t1) SELECT 10
+} {10}
+
+do_execsql_test 1.1 {
+  SELECT * FROM ( WITH x AS ( SELECT * FROM t1) SELECT 10 );
+} {10}
+
+do_execsql_test 1.2 {
+  WITH x(a) AS ( SELECT * FROM t1) INSERT INTO t1 VALUES(1,2);
+} {}
+
+do_execsql_test 1.3 {
+  WITH x(a) AS ( SELECT * FROM t1) DELETE FROM t1;
+} {}
+
+do_execsql_test 1.4 {
+  WITH x(a) AS ( SELECT * FROM t1) UPDATE t1 SET x = y;
+} {}
+finish_test