Reactivate query flattening when the result set of the outer query has
no function calls or subqueries. This is a partial reversal of check-in [c9104b59]. Co-routines are still preferred if the outer query has a complex result set, but for simple results sets, query flattening is used. Check-in [4464f40ccd7] is completely backed out due to this change. FossilOrigin-Name: d17ef7d153058f7332b3fec421ade42c67e26b06f36fc1629e6799537a5afc5f
This commit is contained in:
parent
6d6e76f75f
commit
fca23557fe
17
manifest
17
manifest
@ -1,5 +1,5 @@
|
||||
C Add\stest\scases\sfrom\sOSSFuzz\sto\sprevent\sa\sregression\sin\sco-routine\nprocessing.
|
||||
D 2017-10-28T12:20:09.635
|
||||
C Reactivate\squery\sflattening\swhen\sthe\sresult\sset\sof\sthe\souter\squery\shas\nno\sfunction\scalls\sor\ssubqueries.\s\sThis\sis\sa\spartial\sreversal\sof\s\ncheck-in\s[c9104b59].\s\sCo-routines\sare\sstill\spreferred\sif\sthe\souter\nquery\shas\sa\scomplex\sresult\sset,\sbut\sfor\ssimple\sresults\ssets,\squery\sflattening\nis\sused.\s\sCheck-in\s[4464f40ccd7]\sis\scompletely\sbacked\nout\sdue\sto\sthis\schange.
|
||||
D 2017-10-28T20:51:54.404
|
||||
F Makefile.in e016061b23e60ac9ec27c65cb577292b6bde0307ca55abd874ab3487b3b1beb2
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 37740aba9c4bb359c627eadccf1cfd7be4f5f847078723777ea7763969e533b1
|
||||
@ -416,7 +416,7 @@ F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
|
||||
F src/dbpage.c 003755140e21b917c0a39e70907c1e4612b25d1e24b9a3c64b0d638c8ecb5dc2
|
||||
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
||||
F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023
|
||||
F src/expr.c 755caeafc43e3cd31e1d810795712641f6e19f7e7e9575faece4c77381fd8304
|
||||
F src/expr.c 0016b95aed1df47ebc0eb7415bd621841d72dbffd3bfb62210e50e71d83b4691
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
|
||||
F src/func.c b4d259af627e3cd9510cf08db37f0bcc88b1887c735169c74490c3739d5cf5c6
|
||||
@ -463,12 +463,12 @@ F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 5a461643f294ec510ca615b67256fc3861e4c8eff5f29e5940491e70553b1955
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 0b4c1ac59221c91c9f01c326105c1749874704a77310735c0417f3c3026a4f11
|
||||
F src/select.c 36345c63153e3e3e8ba533c6d3be6201c317358e8c2b34c51400abdf192515ab
|
||||
F src/shell.c.in 08cbffc31900359fea85896342a46147e9772c370d8a5079b7be26e3a1f50e8a
|
||||
F src/sqlite.h.in ab4f8a29d1580dfaeb6891fa1b83cff8229ba0daa56994707ceaca71495d9ab7
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
|
||||
F src/sqliteInt.h 6f93fd6fde862410ac26b930f70752c38ad99ea78c3fc28356bac78049c53bd9
|
||||
F src/sqliteInt.h f5377febf86654c975e1d4e4353a5ad2fbaa5bc86b584ba3761ed33e24ce2c0e
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@ -1666,7 +1666,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 c063bb04da77d6847e4e254b6bb939c860e781382e34ddff8e0454d9db7552e2
|
||||
R 49302fb645a8bd5bf1702bc6c1b70644
|
||||
P 689743d8e3fa81e65dcb067bbf61bab09210b3b39586c865c00d9f1d6692daf2
|
||||
Q -4464f40ccd7c5553f4d44120ca6dac4e9445f08f083f7dcb3bd66b4413d818e0
|
||||
R 645c7260930835d4324fc70970813d97
|
||||
U drh
|
||||
Z 9899cde33cecabbc451b9857a10233e0
|
||||
Z 4445aa956123d14dc2e74ce6385c6a77
|
||||
|
@ -1 +1 @@
|
||||
689743d8e3fa81e65dcb067bbf61bab09210b3b39586c865c00d9f1d6692daf2
|
||||
d17ef7d153058f7332b3fec421ade42c67e26b06f36fc1629e6799537a5afc5f
|
@ -952,6 +952,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||
return 0;
|
||||
}
|
||||
pNew->x.pList = pList;
|
||||
ExprSetProperty(pNew, EP_HasFunc);
|
||||
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pNew);
|
||||
return pNew;
|
||||
|
48
src/select.c
48
src/select.c
@ -3383,12 +3383,11 @@ static void substSelect(
|
||||
** (19) If the subquery uses LIMIT then the outer query may not
|
||||
** have a WHERE clause.
|
||||
**
|
||||
** (**) Subsumed into (17d3). Was: If the sub-query is a compound select,
|
||||
** then it must not use an ORDER BY clause - Ticket #3773. Because
|
||||
** of (17d3), then only way to have a compound subquery is if it is
|
||||
** the only term in the FROM clause of the outer query. But if the
|
||||
** only term in the FROM clause has an ORDER BY, then it will be
|
||||
** implemented as a co-routine and the flattener will never be called.
|
||||
** (20) If the sub-query is a compound select, then it must not use
|
||||
** an ORDER BY clause. Ticket #3773. We could relax this constraint
|
||||
** somewhat by saying that the terms of the ORDER BY clause must
|
||||
** appear as unmodified result columns in the outer query. But we
|
||||
** have other optimizations in mind to deal with that case.
|
||||
**
|
||||
** (21) If the subquery uses LIMIT then the outer query may not be
|
||||
** DISTINCT. (See ticket [752e1646fc]).
|
||||
@ -3522,6 +3521,9 @@ static int flattenSubquery(
|
||||
** queries.
|
||||
*/
|
||||
if( pSub->pPrior ){
|
||||
if( pSub->pOrderBy ){
|
||||
return 0; /* Restriction (20) */
|
||||
}
|
||||
if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
|
||||
return 0; /* (17d1), (17d2), or (17d3) */
|
||||
}
|
||||
@ -3556,15 +3558,6 @@ static int flattenSubquery(
|
||||
*/
|
||||
assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );
|
||||
|
||||
/* Ex-restriction (20):
|
||||
** A compound subquery must be the only term in the FROM clause of the
|
||||
** outer query by restriction (17d3). But if that term also has an
|
||||
** ORDER BY clause, then the subquery will be implemented by co-routine
|
||||
** and so the flattener will never be invoked. Hence, it is not possible
|
||||
** for the subquery to be a compound and have an ORDER BY clause.
|
||||
*/
|
||||
assert( pSub->pPrior==0 || pSub->pOrderBy==0 );
|
||||
|
||||
/***** If we reach this point, flattening is permitted. *****/
|
||||
SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
|
||||
pSub->zSelName, pSub, iFrom));
|
||||
@ -4343,6 +4336,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
sqlite3 *db = pParse->db;
|
||||
Expr *pE, *pRight, *pExpr;
|
||||
u16 selFlags = p->selFlags;
|
||||
u32 elistFlags = 0;
|
||||
|
||||
p->selFlags |= SF_Expanded;
|
||||
if( db->mallocFailed ){
|
||||
@ -4455,6 +4449,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
assert( pE->op!=TK_DOT || pE->pRight!=0 );
|
||||
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
|
||||
if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
|
||||
elistFlags |= pE->flags;
|
||||
}
|
||||
if( k<pEList->nExpr ){
|
||||
/*
|
||||
@ -4470,6 +4465,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
|
||||
for(k=0; k<pEList->nExpr; k++){
|
||||
pE = a[k].pExpr;
|
||||
elistFlags |= pE->flags;
|
||||
pRight = pE->pRight;
|
||||
assert( pE->op!=TK_DOT || pRight!=0 );
|
||||
if( pE->op!=TK_ASTERISK
|
||||
@ -4599,9 +4595,14 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
sqlite3ExprListDelete(db, pEList);
|
||||
p->pEList = pNew;
|
||||
}
|
||||
if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||
sqlite3ErrorMsg(pParse, "too many columns in result set");
|
||||
return WRC_Abort;
|
||||
if( p->pEList ){
|
||||
if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
||||
sqlite3ErrorMsg(pParse, "too many columns in result set");
|
||||
return WRC_Abort;
|
||||
}
|
||||
if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
|
||||
p->selFlags |= SF_ComplexResult;
|
||||
}
|
||||
}
|
||||
return WRC_Continue;
|
||||
}
|
||||
@ -5225,7 +5226,9 @@ int sqlite3Select(
|
||||
if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
|
||||
assert( pSub->pGroupBy==0 );
|
||||
|
||||
/* If the subquery contains an ORDER BY clause and if
|
||||
/* If the outer query contains a "complex" result set (that is,
|
||||
** if the result set of the outer query uses functions or subqueries)
|
||||
** and if the subquery contains an ORDER BY clause and if
|
||||
** it will be implemented as a co-routine, then do not flatten. This
|
||||
** restriction allows SQL constructs like this:
|
||||
**
|
||||
@ -5234,9 +5237,16 @@ int sqlite3Select(
|
||||
**
|
||||
** The expensive_function() is only computed on the 10 rows that
|
||||
** are output, rather than every row of the table.
|
||||
**
|
||||
** The requirement that the outer query have a complex result set
|
||||
** means that flattening does occur on simpler SQL constraints without
|
||||
** the expensive_function() like:
|
||||
**
|
||||
** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
|
||||
*/
|
||||
if( pSub->pOrderBy!=0
|
||||
&& i==0
|
||||
&& (p->selFlags & SF_ComplexResult)!=0
|
||||
&& (pTabList->nSrc==1
|
||||
|| (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
|
||||
){
|
||||
|
@ -2402,7 +2402,7 @@ struct Expr {
|
||||
*/
|
||||
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
|
||||
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
|
||||
/* 0x000004 // available for use */
|
||||
#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
|
||||
/* 0x000008 // available for use */
|
||||
#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
|
||||
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
|
||||
@ -2426,9 +2426,10 @@ struct Expr {
|
||||
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
|
||||
|
||||
/*
|
||||
** Combinations of two or more EP_* flags
|
||||
** The EP_Propagate mask is a set of properties that automatically propagate
|
||||
** upwards into parent nodes.
|
||||
*/
|
||||
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
|
||||
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
|
||||
|
||||
/*
|
||||
** These macros can be used to test, set, or clear bits in the
|
||||
@ -2708,6 +2709,7 @@ struct NameContext {
|
||||
#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
|
||||
#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */
|
||||
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
|
||||
#define NC_Complex 0x2000 /* True if a function or subquery seen */
|
||||
|
||||
/*
|
||||
** An instance of the following structure contains all information
|
||||
@ -2778,6 +2780,7 @@ struct Select {
|
||||
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
|
||||
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
|
||||
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
|
||||
#define SF_ComplexResult 0x40000 /* Result set contains subquery or function */
|
||||
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user