Disable the query flattener for aggregate subqueries if the parent query
uses other subqueries in its result set or WHERE clause or ORDER BY clause. Preliminary fix for ticket [2f7170d73bf9abf8]. However it still contains a defect similar to the COLLATE problem of [ca0d20b6cddd]. FossilOrigin-Name: 0b7d65e3fda676d193347cb782854c28a48252af
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Rename\sthe\sinternal\s"EP_Constant"\sbitmask\sto\sa\sless\smisleading\s"EP_ConstFunc".
|
||||
D 2015-02-09T14:07:07.358
|
||||
C Disable\sthe\squery\sflattener\sfor\saggregate\ssubqueries\sif\sthe\sparent\squery\nuses\sother\ssubqueries\sin\sits\sresult\sset\sor\sWHERE\sclause\sor\sORDER\sBY\sclause.\nPreliminary\sfix\sfor\sticket\s[2f7170d73bf9abf8].\s\sHowever\sit\sstill\scontains\na\sdefect\ssimilar\sto\sthe\sCOLLATE\sproblem\sof\s[ca0d20b6cddd].
|
||||
D 2015-02-09T15:21:36.228
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@@ -182,7 +182,7 @@ F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463
|
||||
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
|
||||
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
|
||||
F src/delete.c bd1a91ddd247ce13004075251e0b7fe2bf9925ef
|
||||
F src/expr.c d66424535d3155eca7f2d8820d26b96870dfcb2d
|
||||
F src/expr.c 3fbe5a2a0be67b337b4947adde81694b4d48a84d
|
||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||
F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12
|
||||
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
|
||||
@@ -219,7 +219,7 @@ F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
|
||||
F src/parse.y c5d0d964f9ac023e8154cad512e54b0b6058e086
|
||||
F src/parse.y d6507371513e94c03e61f7ec097d7b7e90a66665
|
||||
F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
|
||||
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
|
||||
F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
|
||||
@@ -230,12 +230,12 @@ F src/printf.c 05edc41450d0eb2c05ef7db113bf32742ae65325
|
||||
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
|
||||
F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c edcf8ba8163526f2340f10f19b0a71547c6f97ba
|
||||
F src/select.c 15490b9da27a688a9fa09f943ebf4e6c749dc33b
|
||||
F src/shell.c 82c25508dac802b32198af6f5256ca1597c6a1af
|
||||
F src/sqlite.h.in 54678c21401909f72b221344dd560d285a1ba5eb
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h 436c02d0877b9b9a1c3351717c2c93bd248000e9
|
||||
F src/sqliteInt.h b7b14a15f2c60e15f99145e9f5a90f5280e98582
|
||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
|
||||
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
|
||||
@@ -1239,7 +1239,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P aa093fef2d2a7e26d987b46654963e4d7e66d444
|
||||
R f51c0a3a4046c27eeedc2e4a71b172ba
|
||||
P 4ef7ceced2b0000d21f7f8014384c04a0e4661d3
|
||||
R b512281a09e1b31cff93e7ca5bacbcdc
|
||||
T *branch * tkt-2f7170d7
|
||||
T *sym-tkt-2f7170d7 *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 4b79838e5fc774abeed8438ce319eb67
|
||||
Z f683ca0757ba5ade9ef6c768a943d35e
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
4ef7ceced2b0000d21f7f8014384c04a0e4661d3
|
||||
0b7d65e3fda676d193347cb782854c28a48252af
|
||||
+15
-2
@@ -490,11 +490,11 @@ void sqlite3ExprAttachSubtrees(
|
||||
}else{
|
||||
if( pRight ){
|
||||
pRoot->pRight = pRight;
|
||||
pRoot->flags |= EP_Collate & pRight->flags;
|
||||
pRoot->flags |= EP_Propagate & pRight->flags;
|
||||
}
|
||||
if( pLeft ){
|
||||
pRoot->pLeft = pLeft;
|
||||
pRoot->flags |= EP_Collate & pLeft->flags;
|
||||
pRoot->flags |= EP_Propagate & pLeft->flags;
|
||||
}
|
||||
exprSetHeight(pRoot);
|
||||
}
|
||||
@@ -1209,6 +1209,19 @@ void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
|
||||
sqlite3DbFree(db, pList);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if any expression in ExprList has any of the EP_*
|
||||
** properties given by "m"
|
||||
*/
|
||||
int sqlite3AnyExprListHasProperty(const ExprList *pList, u32 m){
|
||||
int i;
|
||||
if( pList==0 ) return 0;
|
||||
for(i=0; i<pList->nExpr; i++){
|
||||
if( ExprHasProperty(pList->a[i].pExpr, m) ) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** These routines are Walker callbacks used to check expressions to
|
||||
** see if they are "constant" for some definition of constant. The
|
||||
|
||||
+4
-4
@@ -1091,7 +1091,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = X;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, X);
|
||||
@@ -1103,7 +1103,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = Y;
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
@@ -1117,7 +1117,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
||||
if( A.pExpr ){
|
||||
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect);
|
||||
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3SrcListDelete(pParse->db, pSrc);
|
||||
@@ -1130,7 +1130,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
|
||||
if( p ){
|
||||
p->x.pSelect = Y;
|
||||
ExprSetProperty(p, EP_xIsSelect);
|
||||
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeight(pParse, p);
|
||||
}else{
|
||||
sqlite3SelectDelete(pParse->db, Y);
|
||||
|
||||
+15
-3
@@ -3194,7 +3194,10 @@ static void substSelect(
|
||||
**
|
||||
** (1) The subquery and the outer query do not both use aggregates.
|
||||
**
|
||||
** (2) The subquery is not an aggregate or the outer query is not a join.
|
||||
** (2) The subquery is not an aggregate or (2a) the outer query is not a join
|
||||
** and (2b) the outer query does not use subqueries other than the one
|
||||
** FROM-clause subquery that is a candidate for flattening. (2b is
|
||||
** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
|
||||
**
|
||||
** (3) The subquery is not the right operand of a left outer join
|
||||
** (Originally ticket #306. Strengthened by ticket #3300)
|
||||
@@ -3331,8 +3334,17 @@ static int flattenSubquery(
|
||||
iParent = pSubitem->iCursor;
|
||||
pSub = pSubitem->pSelect;
|
||||
assert( pSub!=0 );
|
||||
if( isAgg && subqueryIsAgg ) return 0; /* Restriction (1) */
|
||||
if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; /* Restriction (2) */
|
||||
if( subqueryIsAgg ){
|
||||
if( isAgg ) return 0; /* Restriction (1) */
|
||||
if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
|
||||
if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
|
||||
|| sqlite3AnyExprListHasProperty(p->pEList,EP_Subquery)
|
||||
|| sqlite3AnyExprListHasProperty(p->pOrderBy,EP_Subquery)
|
||||
){
|
||||
return 0; /* Restriction (2b) */
|
||||
}
|
||||
}
|
||||
|
||||
pSubSrc = pSub->pSrc;
|
||||
assert( pSubSrc );
|
||||
/* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
|
||||
|
||||
@@ -2046,6 +2046,12 @@ struct Expr {
|
||||
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
|
||||
#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
|
||||
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
|
||||
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
|
||||
|
||||
/*
|
||||
** Combinations of two or more EP_* flags
|
||||
*/
|
||||
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
|
||||
|
||||
/*
|
||||
** These macros can be used to test, set, or clear bits in the
|
||||
@@ -3153,6 +3159,7 @@ ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
|
||||
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
|
||||
void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
|
||||
void sqlite3ExprListDelete(sqlite3*, ExprList*);
|
||||
int sqlite3AnyExprListHasProperty(const ExprList*,u32);
|
||||
int sqlite3Init(sqlite3*, char**);
|
||||
int sqlite3InitCallback(void*, int, char**, char**);
|
||||
void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
|
||||
|
||||
Reference in New Issue
Block a user