mirror of
https://github.com/sqlite/sqlite.git
synced 2024-11-30 16:50:51 +01:00
Generalize the pushdown of IN right-hand sides to cover more SELECTs.
FossilOrigin-Name: 4120bc740a3ef06873723e74dbf4a6fb64a7ec87ecb0d8405129329062cd5b25
This commit is contained in:
parent
743ae4c68b
commit
610dbfb451
23
manifest
23
manifest
@ -1,5 +1,5 @@
|
||||
C Experimental\senhancement\sin\swhich\sexpressions\sof\sthe\sform\s"expr\sIN\stable"\ncan\sbe\spushed\sdown\sinto\ssubexpressions.
|
||||
D 2024-04-05T20:01:28.787
|
||||
C Generalize\sthe\spushdown\sof\sIN\sright-hand\ssides\sto\scover\smore\sSELECTs.
|
||||
D 2024-04-06T11:59:42.724
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -699,8 +699,8 @@ F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
|
||||
F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||
F src/expr.c 48e6732170b5f3c07f9ebbdbe12c478e2867ea4be4361946ed26e2c8d607f7e8
|
||||
F src/delete.c 3ed56178c5c16075d87041ac927fdaf7529a9c30c4800720f2e92c4ac9dbec67
|
||||
F src/expr.c 099b6d3621e3ef98b0c8a7fc7c81e3c4828859f2dd6f0385330980ce33376547
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00
|
||||
F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f
|
||||
@ -739,7 +739,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c ff60e98138d2499082ac6230f01ac508aba545315debccfca2fd6042f5f10fcd
|
||||
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
|
||||
F src/parse.y 67b9965a501599d5a1a4333125fab0dd230e03e28045700c9b331f7c3269bda5
|
||||
F src/parse.y 2627499660eb056a229ee0cae0eea13c038055bbe2bf6e2630ba3f1b584b1543
|
||||
F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
|
||||
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
|
||||
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
|
||||
@ -750,12 +750,12 @@ F src/printf.c 87b67bba3662a0523f39ae6b084a3907109702f717c654d6cecb838af5cd57f1
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c eb1860b134fb044fd819c4347105c148d5aac7c6498032be2829e5cc95619b28
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 15a221347789e393b39e7d2d2bd102167979c95a1ce0675bb870b86a24ca6cf4
|
||||
F src/select.c ccc33d6ac4f7d0b2cae44b71390b0eef46b9aa09fd40df3c1bc2524aeea11da5
|
||||
F src/shell.c.in 0354ca51eee5fbf6af394a7ef9f5ef6823ef45b743db65431f6777e4d5be2199
|
||||
F src/sqlite.h.in 32389e0d584551b300d0157881336162c14315a424cbf385c0d65eb7c2e31f7b
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h a0d0f014baafcb61f5d0a6d206d4b190644d57bb762dff2073903595653d6319
|
||||
F src/sqliteInt.h 0a6c3d01e0e6e134c6ffb2d6bbe6430f1a70df0b1ccb23f3e8004576a3948ec0
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@ -2184,11 +2184,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 4484ec6d26b31305e31de89bdbae26344d8083a7e7de20861430d31737d9979c
|
||||
R 445c665a7eec3209ded422866778f161
|
||||
T *branch * pushdown-IN-table
|
||||
T *sym-pushdown-IN-table *
|
||||
T -sym-trunk *
|
||||
P 2cbd7838fd6ffdf210f34671cd2e3e749a076a3a6f155bbe5f910a67db31c5b1
|
||||
R d2558bc866649b9c87f6dd6d97016be9
|
||||
U drh
|
||||
Z 5ecd3bbce21aa8f702309c384d09dab0
|
||||
Z ca2e9ca9786d13faae254dd96f18d689
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
2cbd7838fd6ffdf210f34671cd2e3e749a076a3a6f155bbe5f910a67db31c5b1
|
||||
4120bc740a3ef06873723e74dbf4a6fb64a7ec87ecb0d8405129329062cd5b25
|
@ -270,7 +270,7 @@ Expr *sqlite3LimitWhere(
|
||||
|
||||
/* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */
|
||||
pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
|
||||
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
|
||||
sqlite3PExprAddSelect(pParse, pInClause, pSelect, SF_RhsIsIN);
|
||||
return pInClause;
|
||||
}
|
||||
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
|
||||
|
46
src/expr.c
46
src/expr.c
@ -1050,18 +1050,27 @@ Expr *sqlite3PExpr(
|
||||
}
|
||||
|
||||
/*
|
||||
** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due
|
||||
** do a memory allocation failure) then delete the pSelect object.
|
||||
** Add pSelect to the Expr.x.pSelect field. Or, if there has been
|
||||
** any kind of prior error (especially an OOM) then delete the pSelect object.
|
||||
**
|
||||
** mFlags are added to the Select.selFlags field of the SELECT statement.
|
||||
*/
|
||||
void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){
|
||||
if( pExpr ){
|
||||
pExpr->x.pSelect = pSelect;
|
||||
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
|
||||
}else{
|
||||
assert( pParse->db->mallocFailed );
|
||||
void sqlite3PExprAddSelect(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pExpr, /* Expr node to which pSelect should be added */
|
||||
Select *pSelect, /* The SELECT statement to add */
|
||||
u32 mFlags /* Add these SF_ flags to pSelect */
|
||||
){
|
||||
if( pParse->nErr ){
|
||||
sqlite3SelectDelete(pParse->db, pSelect);
|
||||
return;
|
||||
}
|
||||
assert( pExpr!=0 );
|
||||
assert( pSelect!=0 );
|
||||
pExpr->x.pSelect = pSelect;
|
||||
ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery);
|
||||
pSelect->selFlags |= mFlags;
|
||||
sqlite3ExprSetHeightAndFlags(pParse, pExpr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2563,26 +2572,19 @@ static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
|
||||
static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){
|
||||
int savedCursor;
|
||||
assert( pSelect!=0 );
|
||||
assert( pSelect->pSrc!=0 );
|
||||
assert( pWalker->eCode==3 || pWalker->eCode==0 );
|
||||
if( (pSelect->selFlags & SF_RhsOfIN)==0 ){
|
||||
if( (pSelect->selFlags & SF_RhsOfIN)==0
|
||||
|| pSelect->pSrc->nSrc!=1
|
||||
){
|
||||
pWalker->eCode = 0;
|
||||
return WRC_Abort;
|
||||
}
|
||||
assert( pSelect->pSrc!=0 );
|
||||
assert( pSelect->pSrc->nSrc==1 );
|
||||
assert( pSelect->pWhere==0 );
|
||||
assert( pSelect->pGroupBy==0 );
|
||||
assert( pSelect->pHaving==0 );
|
||||
assert( pSelect->pOrderBy==0 );
|
||||
assert( pSelect->pPrior==0 );
|
||||
assert( pSelect->pNext==0 );
|
||||
assert( pSelect->pLimit==0 );
|
||||
assert( pSelect->pWith==0 );
|
||||
savedCursor = pWalker->u.iCur;
|
||||
pWalker->u.iCur = pSelect->pSrc->a[0].iCursor;
|
||||
sqlite3WalkExprList(pWalker, pSelect->pEList);
|
||||
sqlite3WalkSelectExpr(pWalker, pSelect);
|
||||
pWalker->u.iCur = savedCursor;
|
||||
return WRC_Prune;
|
||||
return pWalker->eCode==0 ? WRC_Abort : WRC_Prune;
|
||||
}
|
||||
|
||||
/*
|
||||
|
16
src/parse.y
16
src/parse.y
@ -1332,7 +1332,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
|
||||
}else if( Y->nExpr==1 && pRHS->op==TK_SELECT ){
|
||||
A = sqlite3PExpr(pParse, TK_IN, A, 0);
|
||||
sqlite3PExprAddSelect(pParse, A, pRHS->x.pSelect);
|
||||
sqlite3PExprAddSelect(pParse, A, pRHS->x.pSelect, SF_RhsOfIN);
|
||||
pRHS->x.pSelect = 0;
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
}else{
|
||||
@ -1344,7 +1344,7 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, Y);
|
||||
if( pSelectRHS ){
|
||||
parserDoubleLinkSelect(pParse, pSelectRHS);
|
||||
sqlite3PExprAddSelect(pParse, A, pSelectRHS);
|
||||
sqlite3PExprAddSelect(pParse, A, pSelectRHS, 0);
|
||||
}
|
||||
}else{
|
||||
A->x.pList = Y;
|
||||
@ -1356,11 +1356,11 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
}
|
||||
expr(A) ::= LP select(X) RP. {
|
||||
A = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
|
||||
sqlite3PExprAddSelect(pParse, A, X);
|
||||
sqlite3PExprAddSelect(pParse, A, X, 0);
|
||||
}
|
||||
expr(A) ::= expr(A) in_op(N) LP select(Y) RP. [IN] {
|
||||
A = sqlite3PExpr(pParse, TK_IN, A, 0);
|
||||
sqlite3PExprAddSelect(pParse, A, Y);
|
||||
sqlite3PExprAddSelect(pParse, A, Y, SF_RhsOfIN);
|
||||
if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
|
||||
}
|
||||
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
|
||||
@ -1368,17 +1368,13 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
|
||||
if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E);
|
||||
A = sqlite3PExpr(pParse, TK_IN, A, 0);
|
||||
sqlite3PExprAddSelect(pParse, A, pSelect);
|
||||
if( pParse->nErr==0 ){
|
||||
assert( pSelect!=0 );
|
||||
pSelect->selFlags |= SF_RhsOfIN;
|
||||
}
|
||||
sqlite3PExprAddSelect(pParse, A, pSelect, SF_RhsOfIN);
|
||||
if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
|
||||
}
|
||||
expr(A) ::= EXISTS LP select(Y) RP. {
|
||||
Expr *p;
|
||||
p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
|
||||
sqlite3PExprAddSelect(pParse, p, Y);
|
||||
sqlite3PExprAddSelect(pParse, p, Y, 0);
|
||||
}
|
||||
%endif SQLITE_OMIT_SUBQUERY
|
||||
|
||||
|
@ -7163,7 +7163,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
|
||||
pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount;
|
||||
pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm);
|
||||
pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
|
||||
sqlite3PExprAddSelect(pParse, pTerm, pSub);
|
||||
sqlite3PExprAddSelect(pParse, pTerm, pSub, 0);
|
||||
if( pExpr==0 ){
|
||||
pExpr = pTerm;
|
||||
}else{
|
||||
|
@ -4846,7 +4846,7 @@ Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
|
||||
Expr *sqlite3Expr(sqlite3*,int,const char*);
|
||||
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
|
||||
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
|
||||
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
|
||||
void sqlite3PExprAddSelect(Parse*, Expr*, Select*, u32);
|
||||
Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
|
||||
Expr *sqlite3ExprSimplifiedAndOr(Expr*);
|
||||
Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int);
|
||||
|
Loading…
Reference in New Issue
Block a user