Fix the handling of sub-queries with LIMIT clauses by the optimization

activated by compile-time symbol SQLITE_COUNTOFVIEW_OPTIMIZATION.

FossilOrigin-Name: 21235d9a41567897418aa12f7bd6dd8d6ee363147527e1d8fbca14fc83e0f2c9
This commit is contained in:
dan 2018-08-03 20:19:52 +00:00
parent e4fe6d4e62
commit a4b5fb55f3
4 changed files with 65 additions and 18 deletions

View File

@ -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

View File

@ -1 +1 @@
fa94b49e02eb6b8fc4acc220ecc2fabef546c65845696758b25965c26b251ea9
21235d9a41567897418aa12f7bd6dd8d6ee363147527e1d8fbca14fc83e0f2c9

View 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:

44
test/countofview.test Normal file
View File

@ -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