1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Add restriction (9) to the push-down optimization: If the subquery is

a compound then all arms of the compound must have the same affinity.
dbsqlfuzz 3a548de406a50e896c1bf7142692d35d339d697f.

FossilOrigin-Name: 1ad41840c5e0fa702ba2c0df77a3ea126bd695b910b5d1271fa3129c38c58f5f
This commit is contained in:
drh
2022-11-25 15:52:00 +00:00
parent eb84c81c53
commit 23f61a4ba8
4 changed files with 74 additions and 24 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\stest\scase\sin\sfts3expr4.test\sto\saccount\sfor\sdifferent\slocales.
D 2022-11-24T17:58:55.503
C Add\srestriction\s(9)\sto\sthe\spush-down\soptimization:\s\sIf\sthe\ssubquery\sis\na\scompound\sthen\sall\sarms\sof\sthe\scompound\smust\shave\sthe\ssame\saffinity.\ndbsqlfuzz\s3a548de406a50e896c1bf7142692d35d339d697f.
D 2022-11-25T15:52:00.241
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -641,7 +641,7 @@ F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 4c48373abb4e67129c36bc15d1f5a99a0dfd9534afeb539a2169a09ae91ccec9
F src/select.c bafe6424e942aad558b2d4be8dbcf5e35ce427ce3cf66d7f0c0ac37c366b00c6
F src/shell.c.in 09cb15d7421c475f2d308f6a4312d8d690916ea5cb62ea1618f2f4ce5703af35
F src/sqlite.h.in 100fc660c2f19961b8ed8437b9d53d687de2f8eb2b96437ec6da216adcb643ca
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@ -1403,7 +1403,7 @@ F test/printf.test 390d0d7fcffc3c4ea3c1bb4cbb267444e32b33b048ae21895f23a291844fe
F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60
F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/pushdown.test 5e72c51c5e33253ed639ccee1e01ce62d62b6eee5ca893cd82334e4ee7b1d7fc
F test/pushdown.test c69f0970ea17e0afc674b89741f60c172cb6f761d81665fc71015f674f0f66ba
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
@ -2059,8 +2059,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 18e89a436daa18a8c972caf06b298da43c97a6ea3e2e5229dccb6920c27bfdb9
R e3089d3062e617db155d3fe3a44f9c32
U dan
Z c38105809dd01fc34e6f6bf40716c164
P a2b6883ac2ef878f525ee847b170beb9f9ab9d1fa67557101be2cdae1e7f7a57
R 9c0acbc69bb427be679e111e4ec839ec
U drh
Z ae1fb8eb841aaf444344209ddd2c7ea7
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
a2b6883ac2ef878f525ee847b170beb9f9ab9d1fa67557101be2cdae1e7f7a57
1ad41840c5e0fa702ba2c0df77a3ea126bd695b910b5d1271fa3129c38c58f5f

View File

@ -4050,6 +4050,34 @@ static ExprList *findLeftmostExprlist(Select *pSel){
return pSel->pEList;
}
/*
** Return true if any of the result-set columns in the compound query
** have incompatible affinities on one or more arms of the compound.
*/
static int compoundHasDifferentAffinities(Select *p){
int ii;
ExprList *pList;
assert( p!=0 );
assert( p->pEList!=0 );
assert( p->pPrior!=0 );
pList = p->pEList;
for(ii=0; ii<pList->nExpr; ii++){
char aff;
Select *pSub1;
assert( pList->a[ii].pExpr!=0 );
aff = sqlite3ExprAffinity(pList->a[ii].pExpr);
for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){
assert( pSub1->pEList!=0 );
assert( pSub1->pEList->nExpr>ii );
assert( pSub1->pEList->a[ii].pExpr!=0 );
if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){
return 1;
}
}
}
return 0;
}
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
@ -4153,7 +4181,8 @@ static ExprList *findLeftmostExprlist(Select *pSel){
** query or there are no RIGHT or FULL JOINs in any arm
** of the subquery. (This is a duplicate of condition (27b).)
** (17h) The corresponding result set expressions in all arms of the
** compound must have the same affinity.
** compound must have the same affinity. (See restriction (9)
** on the push-down optimization.)
**
** The parent and sub-query may contain WHERE clauses. Subject to
** rules (11), (13) and (14), they may also contain ORDER BY,
@ -4372,19 +4401,7 @@ static int flattenSubquery(
if( (p->selFlags & SF_Recursive) ) return 0;
/* Restriction (17h) */
for(ii=0; ii<pSub->pEList->nExpr; ii++){
char aff;
assert( pSub->pEList->a[ii].pExpr!=0 );
aff = sqlite3ExprAffinity(pSub->pEList->a[ii].pExpr);
for(pSub1=pSub->pPrior; pSub1; pSub1=pSub1->pPrior){
assert( pSub1->pEList!=0 );
assert( pSub1->pEList->nExpr>ii );
assert( pSub1->pEList->a[ii].pExpr!=0 );
if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){
return 0;
}
}
}
if( compoundHasDifferentAffinities(pSub) ) return 0;
if( pSrc->nSrc>1 ){
if( pParse->nSelect>500 ) return 0;
@ -5036,6 +5053,11 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
** But it is a lot of work to check that case for an obscure and
** minor optimization, so we omit it for now.)
**
** (9) If the subquery is a compound, then all arms of the compound must
** have the same affinity. (This is the same as restriction (17h)
** for query flattening.)
**
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
*/
@ -5061,6 +5083,9 @@ static int pushDownWhereTerms(
if( op!=TK_ALL && op!=TK_SELECT ) return 0; /* restriction (8) */
if( pSel->pWin ) return 0; /* restriction (6b) */
}
if( compoundHasDifferentAffinities(pSubq) ){
return 0; /* restriction (9) */
}
}else{
if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0;
}

View File

@ -86,6 +86,31 @@ do_test 2.2 {
set L
} {three}
# 2022-11-25 dbsqlfuzz crash-3a548de406a50e896c1bf7142692d35d339d697f
# Disable the push-down optimization for compound subqueries if any
# arm of the compound has an incompatible affinity.
#
reset_db
do_execsql_test 3.1 {
CREATE TABLE t0(c0 INT);
INSERT INTO t0 VALUES(0);
CREATE TABLE t1_a(a INTEGER PRIMARY KEY, b TEXT);
INSERT INTO t1_a VALUES(1,'one'); --,(4,'four');
CREATE TABLE t1_b(c INTEGER PRIMARY KEY, d TEXT);
INSERT INTO t1_b VALUES(2,'two'); --,(5,'five');
CREATE VIEW v0 AS SELECT CAST(t0.c0 AS INTEGER) AS c0 FROM t0;
CREATE VIEW t1 AS SELECT a, b FROM t1_a UNION ALL SELECT c, 0 FROM t1_b;
SELECT t1.a, quote(t1.b), t0.c0 AS cd FROM t0 LEFT JOIN v0 ON v0.c0!=0,t1;
} {
1 'one' 0
2 '0' 0
}
do_execsql_test 3.2 {
SELECT a, quote(b), cd FROM (
SELECT t1.a, t1.b, t0.c0 AS cd FROM t0 LEFT JOIN v0 ON v0.c0!=0,t1
) WHERE a=2 AND b='0' AND cd=0;
} {
2 '0' 0
}
finish_test