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:
16
manifest
16
manifest
@ -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.
|
||||
|
@ -1 +1 @@
|
||||
a2b6883ac2ef878f525ee847b170beb9f9ab9d1fa67557101be2cdae1e7f7a57
|
||||
1ad41840c5e0fa702ba2c0df77a3ea126bd695b910b5d1271fa3129c38c58f5f
|
53
src/select.c
53
src/select.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user