]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the handling of sub-queries with LIMIT clauses by the optimization
authordan <dan@noemail.net>
Fri, 3 Aug 2018 20:19:52 +0000 (20:19 +0000)
committerdan <dan@noemail.net>
Fri, 3 Aug 2018 20:19:52 +0000 (20:19 +0000)
activated by compile-time symbol SQLITE_COUNTOFVIEW_OPTIMIZATION.

FossilOrigin-Name: 21235d9a41567897418aa12f7bd6dd8d6ee363147527e1d8fbca14fc83e0f2c9

manifest
manifest.uuid
src/select.c
test/countofview.test [new file with mode: 0644]

index f5de273e6ba6f10f449bcde19052861dbef38ea1..ad4766b85feccacfd77e838e03ba51b36a779e57 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\sOP_SeekRowid\sopcode\sso\sthat\sit\shas\sno\stype-change\sside-effects\son\sthe\nkey\sregister\sin\sP3.\s\sThis\sfixes\san\sobcure\sproblem\sthat\sarises\swhen\sdoing\nequi-joins\sbetween\sa\stable\swith\sa\sTEXT\scolumn\sagainst\sanother\stable\swith\nan\sINTEGER\sPRIMARY\sKEY.\s\sThe\soriginal\sproblem\swas\sdiscovered\swhen\sOSSFuzz\ncreated\ssuch\sa\squery\sand\shit\san\sassert()\sin\sOP_VerifyTabCol\sthat\swas\nspecifically\sdesigned\sto\scatch\sthese\skinds\sof\serrors\sat\srun-time.
-D 2018-08-03T15:58:07.068
+C Fix\sthe\shandling\sof\ssub-queries\swith\sLIMIT\sclauses\sby\sthe\soptimization\nactivated\sby\scompile-time\ssymbol\sSQLITE_COUNTOFVIEW_OPTIMIZATION.
+D 2018-08-03T20:19:52.614
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -498,7 +498,7 @@ F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 797088662ed61102485e3070ba3b3f7828bd5ef6a588223ba6865d77d52f6cea
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
-F src/select.c 22ed163cf65258a1101685228bb67d85b60b2965fec344f5c56d185f46fc62f2
+F src/select.c 18636c49eeb9016bb429ac6892220aea51bc618d021cf16770146e1858cf6f1e
 F src/shell.c.in 5e4c139799f059a5231f0259111f51f6dffcb28154c535f6b4c2192619a40844
 F src/sqlite.h.in c6451bb876adced3aba5b1682c6317d215c5eceaba21a6ce979e71a0b8d0bf95
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -733,6 +733,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
 F test/corruptK.test 91550557849244a9904f4e090052e3f2c1c3f1106840d58b00ffaa3a8c2d3fc0
 F test/cost.test b37db8a10d467a69e71a9f3d40bbb266c2f587742b37c6912f6e3f7185a0e216
 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
+F test/countofview.test 2d0ce23daca1bada0522c3d62e0e0c0d69ec4e0fc41df2bcd662a5e11169b9c9
 F test/coveridxscan.test 5ec98719a2e2914e8908dc75f7247d9b54a26df04625f846ac7900d5483f7296
 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
 F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
@@ -1753,7 +1754,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 0f881955ed173c7c35dfca2d4aeca855858e40bb951e6fb6fedd9a2fff6a5a86
-R fd20495db4931704facdb29762bad04e
-U drh
-Z 309f6ab0d792269409cda7bb806561c5
+P fa94b49e02eb6b8fc4acc220ecc2fabef546c65845696758b25965c26b251ea9
+R 776956319daae57e1b0c061e1c2d74c6
+U dan
+Z 9283c73cf2ac7987df796a062f7aa1c4
index 2061fc217315319422a7a7f0b247d2e0478a3897..dce9e6973e7cbb15214b3555d825b12a63b3032f 100644 (file)
@@ -1 +1 @@
-fa94b49e02eb6b8fc4acc220ecc2fabef546c65845696758b25965c26b251ea9
\ No newline at end of file
+21235d9a41567897418aa12f7bd6dd8d6ee363147527e1d8fbca14fc83e0f2c9
\ No newline at end of file
index 521e3b4a96396063cac2e5ef1b24e8fb095be097..ef3052383b1de5ab2a724358c9def87d4a107162 100644 (file)
@@ -5495,6 +5495,7 @@ static struct SrcList_item *isSelfJoinView(
 ** The transformation only works if all of the following are true:
 **
 **   *  The subquery is a UNION ALL of two or more terms
+**   *  The subquery does not have a LIMIT clause
 **   *  There is no WHERE or GROUP BY or HAVING clauses on the subqueries
 **   *  The outer query is a simple count(*)
 **
@@ -5518,6 +5519,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
   do{
     if( pSub->op!=TK_ALL && pSub->pPrior ) return 0;  /* Must be UNION ALL */
     if( pSub->pWhere ) return 0;                      /* No WHERE clause */
+    if( pSub->pLimit ) return 0;                      /* No LIMIT clause */
     if( pSub->selFlags & SF_Aggregate ) return 0;     /* Not an aggregate */
     pSub = pSub->pPrior;                              /* Repeat over compound */
   }while( pSub );
@@ -5779,6 +5781,16 @@ int sqlite3Select(
     SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
   }
 
+#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
+  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
+   && countOfViewOptimization(pParse, p)
+  ){
+    if( db->mallocFailed ) goto select_end;
+    pEList = p->pEList;
+    pTabList = p->pSrc;
+  }
+#endif
+
   /* For each term in the FROM clause, do two things:
   ** (1) Authorized unreferenced tables
   ** (2) Generate code for all sub-queries
@@ -5957,16 +5969,6 @@ int sqlite3Select(
   }
 #endif
 
-#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
-  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
-   && countOfViewOptimization(pParse, p)
-  ){
-    if( db->mallocFailed ) goto select_end;
-    pEList = p->pEList;
-    pTabList = p->pSrc;
-  }
-#endif
-
   /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
   ** if the select-list is the same as the ORDER BY list, then this query
   ** can be rewritten as a GROUP BY. In other words, this:
diff --git a/test/countofview.test b/test/countofview.test
new file mode 100644 (file)
index 0000000..aebd6ed
--- /dev/null
@@ -0,0 +1,44 @@
+# 2018-08-04
+#
+# 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.
+#
+#***********************************************************************
+# 
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/malloc_common.tcl
+set testprefix countofview
+
+do_execsql_test 1.0 {
+  CREATE TABLE t2(c);
+  CREATE TABLE t3(f);
+
+  INSERT INTO t2 VALUES(1), (2);
+  INSERT INTO t3 VALUES(3);
+}
+
+do_execsql_test 1.1 {
+  select c from t2 union all select f from t3 limit 1 offset 1
+} {2}
+
+do_execsql_test 1.2 {
+  select count(*) from (
+    select c from t2 union all select f from t3 limit 1 offset 1
+  )
+} {1}
+
+do_execsql_test 1.3 {
+  select count(*) from (
+    select c from t2 union all select f from t3
+  )
+} {3}
+
+finish_test
+