]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Disable the flattening optimization if the sub-query is a recursive CTE.
authordan <dan@noemail.net>
Wed, 15 Jan 2014 14:17:31 +0000 (14:17 +0000)
committerdan <dan@noemail.net>
Wed, 15 Jan 2014 14:17:31 +0000 (14:17 +0000)
FossilOrigin-Name: 9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73

manifest
manifest.uuid
src/expr.c
src/parse.y
src/select.c
test/with1.test

index 3d4a6ad8973c5a943174b268f436b7b563a822e8..1f819eb3887e58031957bcc9113dd4ce2e0285c5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Use\sthe\suser-supplied\stable\sname\sin\sWITH\sRECURSIVE\stables\sas\sthe\sinternal\nname\sof\sthe\stable\sand\sthe\sname\sof\sthe\stable\sin\sVDBE\scomments.
-D 2014-01-15T02:40:11.688
+C Disable\sthe\sflattening\soptimization\sif\sthe\ssub-query\sis\sa\srecursive\sCTE.
+D 2014-01-15T14:17:31.048
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
 F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff
-F src/expr.c fee4b54fdcf5a979e6f5012da3dfb084ac5d3aac
+F src/expr.c 2277282d8938b8eab782e4f5111ca0cd492529b3
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
 F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19
@@ -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 e5c4a23f445cde4b30d50948df8f21bc586dd7a4
+F src/parse.y 824eeb752c026b551bda2b66163889d7664b42e4
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
 F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
@@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
-F src/select.c 3d93e3b4736a95507540b708106c1db6d01c41a8
+F src/select.c 51c74176eb949d1ff5797735acedd6c08d19450a
 F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344
 F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
@@ -1091,7 +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 12a6661eabcc9ae299020f7b4197a75a9c084748
+F test/with1.test 77739a9e5e88873e7655634297d9dc4360334f9a
 F test/withM.test ac3ec7ee0b33a02d0fa15da91214d97ddea64e34
 F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
@@ -1150,7 +1150,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 a5c2a54a07d35166911abc792008c05dea897742
-R cc1fc541222b981017b72fc3aee14bde
-U drh
-Z dcce44e449a071e984cc874f0c8e1e54
+P a29330238be6366444269a0b1b328475b2d01ae2
+R baaf1d38169072daf03c7e43cc689f3b
+U dan
+Z e4d26324d0deafbbb1cfbafb0f22db9f
index 1be3de1308d5adcc873d9bf1cd4c4c9e272019e2..493b55e69239398ae99e63021d10079dc38870b9 100644 (file)
@@ -1 +1 @@
-a29330238be6366444269a0b1b328475b2d01ae2
\ No newline at end of file
+9472f6d820a7fb233936d9b8f7a39c9d4c4d6d73
\ No newline at end of file
index e271e467963fcf965423fea8a1893bf67652c1b6..4da9d6263c8a792033b0d6cd6f7caeec1892246b 100644 (file)
@@ -895,7 +895,12 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
   return pNew;
 }
 
-With *withDup(sqlite3 *db, With *p){
+/*
+** Create and return a deep copy of the object passed as the second 
+** argument. If an OOM condition is encountered, NULL is returned
+** and the db->mallocFailed flag set.
+*/
+static With *withDup(sqlite3 *db, With *p){
   With *pRet = 0;
   if( p ){
     int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
@@ -1055,7 +1060,8 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
   pNew->addrOpenEphm[1] = -1;
   pNew->addrOpenEphm[2] = -1;
   pNew->pWith = withDup(db, p->pWith);
-  pNew->pRecurse = p->pRecurse;
+  assert( p->pRecurse==0 );
+  pNew->pRecurse = 0;
   return pNew;
 }
 #else
index b1992f2415b2ad52a8851faee88bf7eb072c3d3e..937669eb5c4dfd7973c8643340421a9d046d600e 100644 (file)
@@ -684,8 +684,9 @@ where_opt(A) ::= WHERE expr(X).       {A = X.pExpr;}
 ////////////////////////// The UPDATE command ////////////////////////////////
 //
 %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
-cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
+cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
         where_opt(W) orderby_opt(O) limit_opt(L).  {
+  sqlite3WithPush(pParse, C);
   sqlite3SrcListIndexedBy(pParse, X, &I);
   sqlite3ExprListCheckLength(pParse,Y,"set list"); 
   W = sqlite3LimitWhere(pParse, X, W, O, L.pLimit, L.pOffset, "UPDATE");
index 22eaf1b1cbfda7ec165f3c36efc596d613ab5096..35edcbb03c968b3ebbee4784602a84c4a3bcbaea 100644 (file)
@@ -2844,6 +2844,8 @@ static void substSelect(
 **
 ** Flattening is only attempted if all of the following are true:
 **
+**   (0)  The subquery is not a recursive CTE.
+**
 **   (1)  The subquery and the outer query do not both use aggregates.
 **
 **   (2)  The subquery is not an aggregate or the outer query is not a join.
@@ -2968,6 +2970,7 @@ static int flattenSubquery(
   iParent = pSubitem->iCursor;
   pSub = pSubitem->pSelect;
   assert( pSub!=0 );
+  if( pSub->pRecurse ) return 0;                         /* Restriction (0)  */
   if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
   if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
   pSubSrc = pSub->pSrc;
index 3dd8c47ea2847dfd6645be526786a0294487bebf..480afa8074d5d771f46bcd3c227b2c4f5202ef9f 100644 (file)
@@ -164,6 +164,50 @@ do_execsql_test 5.5 {
   SELECT x FROM i LIMIT 20;
 } {1 2 3 4 5 6 7 8 9 0}
 
+#-------------------------------------------------------------------------
+#
+do_execsql_test 6.1 {
+  CREATE TABLE f(
+      id INTEGER PRIMARY KEY, parentid REFERENCES f, name TEXT
+  );
+
+  INSERT INTO f VALUES(0, NULL, '');
+  INSERT INTO f VALUES(1, 0, 'bin');
+    INSERT INTO f VALUES(2, 1, 'true');
+    INSERT INTO f VALUES(3, 1, 'false');
+    INSERT INTO f VALUES(4, 1, 'ls');
+    INSERT INTO f VALUES(5, 1, 'grep');
+  INSERT INTO f VALUES(6, 0, 'etc');
+    INSERT INTO f VALUES(7, 6, 'rc.d');
+      INSERT INTO f VALUES(8, 7, 'rc.apache');
+      INSERT INTO f VALUES(9, 7, 'rc.samba');
+  INSERT INTO f VALUES(10, 0, 'home');
+    INSERT INTO f VALUES(11, 10, 'dan');
+      INSERT INTO f VALUES(12, 11, 'public_html');
+        INSERT INTO f VALUES(13, 12, 'index.html');
+          INSERT INTO f VALUES(14, 13, 'logo.gif');
+}
+
+do_execsql_test 6.2 {
+  WITH flat(fid, fpath) AS (
+    SELECT id, '' FROM f WHERE parentid IS NULL
+    UNION ALL
+    SELECT id, fpath || '/' || name FROM f, flat WHERE +parentid=+fid
+  )
+  SELECT fpath FROM flat WHERE fpath!='' ORDER BY 1;
+} {
+  /bin 
+  /bin/false /bin/grep /bin/ls /bin/true 
+  /etc 
+  /etc/rc.d 
+  /etc/rc.d/rc.apache /etc/rc.d/rc.samba 
+  /home 
+  /home/dan 
+  /home/dan/public_html 
+  /home/dan/public_html/index.html 
+  /home/dan/public_html/index.html/logo.gif
+}
+
 finish_test