Protect all accesses to the Expr.x union using nearby assert()s and branches.

FossilOrigin-Name: 8eaa1d4a98b24adf245bbd2fe9212aa6a924a0f09c445906d7f87574f36a7423
This commit is contained in:
drh 2021-10-07 17:43:30 +00:00
parent 9d43db5b5c
commit a4eeccdfdf
14 changed files with 197 additions and 107 deletions

View File

@ -1,5 +1,5 @@
C Fix\san\sincorrect\sassert()\son\sPRAGMA\stable_xinfo\sadded\sby\sthe\sprevious\scheck-in.
D 2021-10-07T14:19:32.259
C Protect\sall\saccesses\sto\sthe\sExpr.x\sunion\susing\snearby\sassert()s\sand\sbranches.
D 2021-10-07T17:43:30.167
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -501,10 +501,10 @@ F src/date.c fa928630fecf1d436cdc7a7a5c950c781709023ca782c21b7a43cc7361a9451e
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 3ce6af6b64c8b476de51ccc32da0cb3142d42e65754e1d8118addf65b8bcba15
F src/expr.c a2ceac9ee826c43d0943d1412bd8ef668db24fca57d2829453d13c6eb1dccb1c
F src/expr.c 19c0b5c7afaf6a305274b7de312f319bd86e802383f08ef6633f0752f51d96a8
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 0c57a9cd2a0ecd04dde0c06e41df46959526f52a68c4409591e0f8c41a577042
F src/func.c 315c63812b5ad965158fccdb3c15b155f62d123d064efeda87d35b23fd5d529d
F src/func.c 9577175a1459f65c9e3c4bbe7ed0bdf97ee928f693c81ee9f61e2642414c917c
F src/global.c 612ea60c9acbcb45754c2ed659b4a56936a06814718e969636fedc7e3b889808
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
@ -547,14 +547,14 @@ F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad
F src/prepare.c 8f07616db04337057b8498b72d051ee90f73c54615c2e908c05404cef1e060b7
F src/printf.c 5901672228f305f7d493cbc4e7d76a61a5caecdbc1cd06b1f9ec42ea4265cf8d
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c efbb58ab3bf5ce041a8529f08866811148fca2ee079d5b919c7681319b5e5ebc
F src/resolve.c 7f8954f49ddf18d16a13866593eb4f51a6deba8b30b2d877e27ef1b385cd94db
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 6b33d8197dad64015aca2031ee7ae67968c1532e812662fbce2406b39f46c278
F src/select.c 6164779bdafadf23f506e87224095b73f27be519b242579bd9d24a6d6a53d9fb
F src/shell.c.in ac685e63c506fb2e39375c83347c88bff84dc48fa5d6a59f508d7d67951693a0
F src/sqlite.h.in 4e977a5e2ed1a9e8987ff65a2cab5f99a4298ebf040ea5ff636e1753339ff45a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
F src/sqliteInt.h 398111a3db45b92158b81d1fb9d7add8907704e83d4190a3560ebcf2bae6a151
F src/sqliteInt.h e62e6eab356e01a8cf1c88d0a2ec7e403e5d3b141b4816ec0b5ea23acd1fcd14
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -614,7 +614,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
F src/treeview.c f8eaf6e9a237e7666ae18b47d7ff5a9091afdc5c2d2a08a493d41be24ce70c46
F src/treeview.c e80a6126f82c0cd0a939aa617c428329c6e2c3351b7d4dabb8b8a83c9b4e7696
F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de
F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
@ -627,7 +627,7 @@ F src/vdbeInt.h 38206c8dd6b60ff03d9fd4f626b1b4fd0eef7cdc44f2fc2c1973b0f932a3f26b
F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5
F src/vdbeaux.c 897912feb91ec3cd8dedc3fce21d192fd6d37d299538a13d9d93100b22e4d4a0
F src/vdbeblob.c 292e96c01c4219fca71d74e1002906d43eb232af4bd83f7552a3faec741f3eb8
F src/vdbemem.c 51cb5d507a0f62cbf2ab6dd1f2042873807146d05920c6943955ecf4cec6529f
F src/vdbemem.c 8be0af1060012520381d3296fcb1718e80cd5b99ce04f51f7e1c4dba4072caac
F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
@ -635,12 +635,12 @@ F src/vtab.c 3a6640d86d5dfae8f69715a1ee7405bb96d8982b39655b91c1f3648baae476a8
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c 7342becedf3f8a26f9817f08436bdf8b56ad69af83705f6b9320a0ad3092c2ac
F src/where.c f71086505c5db78209574eaffdb01c4e7beb745873ccba2cfcd4822232ef4e39
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c 56e1902e9b91fb1fe159181a21c34abd59a01e2cb8f5ef4c3e478d32c5d838df
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
F src/wherecode.c af9bc0608f07f6582affb0e4f30f95815cca080feb5359c2acc4558b48500604
F src/whereexpr.c 108a89887ea4943c2573f43c0b37342e4a23afa215d88f5d137d205c7fd2f66a
F src/window.c 7bb95e7e6e1c7279ccaf1784c06ccf55c33303c1c2dc37aa4b13fab312b7bd50
F src/wherecode.c 6721f5de1d74d952b473c3f2473ea36b4a3aafed2c0ae0edb02c7e8a6b908d43
F src/whereexpr.c 01d87dc0d5fb0a18100a65ba5466e399f2b8d96b3ec8a6056cf2aac10436afa5
F src/window.c 0dff6fedf61493490d21ced5d7a7b4321d4c0db6c8123f0179c46080a860850a
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7
@ -1929,7 +1929,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 9af863f065e0bef491c2ab7525194505f9516f4e6dfc789d2e3a9d2c2438533a
R eeba287e3c7adfad939bd3178ae64a7a
P f85cb287c52baa729aeb223038e979a3b74a1eb3d97bf59c01f5417998204f84
R d1a38de85ec9395d66459f512bc9b39f
U drh
Z ead3dbf79919d143e014b4c2002fbeb0
Z a07d4736a8e9c697e3914dd4948a3735

View File

@ -1 +1 @@
f85cb287c52baa729aeb223038e979a3b74a1eb3d97bf59c01f5417998204f84
8eaa1d4a98b24adf245bbd2fe9212aa6a924a0f09c445906d7f87574f36a7423

View File

@ -57,7 +57,7 @@ char sqlite3ExprAffinity(const Expr *pExpr){
return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
assert( ExprUseXSelect(pExpr) );
assert( pExpr->x.pSelect!=0 );
assert( pExpr->x.pSelect->pEList!=0 );
assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
@ -70,7 +70,7 @@ char sqlite3ExprAffinity(const Expr *pExpr){
}
#endif
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft->flags&EP_xIsSelect );
assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
assert( pExpr->iColumn < pExpr->iTable );
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
return sqlite3ExprAffinity(
@ -78,6 +78,7 @@ char sqlite3ExprAffinity(const Expr *pExpr){
);
}
if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
}
return pExpr->affExpr;
@ -137,7 +138,7 @@ Expr *sqlite3ExprSkipCollate(Expr *pExpr){
Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( ExprUseXList(pExpr) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
@ -187,6 +188,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
continue;
}
if( op==TK_VECTOR ){
assert( ExprUseXList(p) );
p = p->x.pList->a[0].pExpr;
continue;
}
@ -201,11 +203,9 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
}else{
Expr *pNext = p->pRight;
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( ExprUseXList(p) );
assert( p->x.pList==0 || p->pRight==0 );
if( p->x.pList!=0
&& !db->mallocFailed
&& ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
){
if( p->x.pList!=0 && !db->mallocFailed ){
int i;
for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
@ -288,7 +288,7 @@ static char comparisonAffinity(const Expr *pExpr){
aff = sqlite3ExprAffinity(pExpr->pLeft);
if( pExpr->pRight ){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
}else if( ExprUseXSelect(pExpr) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( aff==0 ){
aff = SQLITE_AFF_BLOB;
@ -428,8 +428,10 @@ int sqlite3ExprVectorSize(const Expr *pExpr){
u8 op = pExpr->op;
if( op==TK_REGISTER ) op = pExpr->op2;
if( op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
return pExpr->x.pList->nExpr;
}else if( op==TK_SELECT ){
assert( ExprUseXSelect(pExpr) );
return pExpr->x.pSelect->pEList->nExpr;
}else{
return 1;
@ -456,8 +458,10 @@ Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
if( sqlite3ExprIsVector(pVector) ){
assert( pVector->op2==0 || pVector->op==TK_REGISTER );
if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
return pVector->x.pSelect->pEList->a[i].pExpr;
}else{
assert( ExprUseXList(pVector) );
return pVector->x.pList->a[i].pExpr;
}
}
@ -493,7 +497,7 @@ Expr *sqlite3ExprForVectorField(
){
Expr *pRet;
if( pVector->op==TK_SELECT ){
assert( pVector->flags & EP_xIsSelect );
assert( ExprUseXSelect(pVector) );
/* The TK_SELECT_COLUMN Expr node:
**
** pLeft: pVector containing TK_SELECT. Not deleted.
@ -518,7 +522,9 @@ Expr *sqlite3ExprForVectorField(
}
}else{
if( pVector->op==TK_VECTOR ){
Expr **ppVector = &pVector->x.pList->a[iField].pExpr;
Expr **ppVector;
assert( ExprUseXList(pVector) );
ppVector = &pVector->x.pList->a[iField].pExpr;
pVector = *ppVector;
if( IN_RENAME_OBJECT ){
/* This must be a vector UPDATE inside a trigger */
@ -582,10 +588,12 @@ static int exprVectorRegister(
return pVector->iTable+iField;
}
if( op==TK_SELECT ){
assert( ExprUseXSelect(pVector) );
*ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
return regSelect+iField;
}
if( op==TK_VECTOR ){
assert( ExprUseXList(pVector) );
*ppExpr = pVector->x.pList->a[iField].pExpr;
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
}
@ -760,7 +768,7 @@ static void exprSetHeight(Expr *p){
int nHeight = 0;
heightOfExpr(p->pLeft, &nHeight);
heightOfExpr(p->pRight, &nHeight);
if( ExprHasProperty(p, EP_xIsSelect) ){
if( ExprUseXSelect(p) ){
heightOfSelect(p->x.pSelect, &nHeight);
}else if( p->x.pList ){
heightOfExprList(p->x.pList, &nHeight);
@ -799,7 +807,7 @@ int sqlite3SelectExprHeight(const Select *p){
*/
void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
if( pParse->nErr ) return;
if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
if( p && ExprUseXList(p) && p->x.pList ){
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
}
}
@ -983,13 +991,20 @@ Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){
for(ii=0; ii<pEList->nExpr; ii++){
Select *pSel;
Expr *pExpr = pEList->a[ii].pExpr;
int nExprElem = (pExpr->op==TK_VECTOR ? pExpr->x.pList->nExpr : 1);
int nExprElem;
if( pExpr->op==TK_VECTOR ){
assert( ExprUseXList(pExpr) );
nExprElem = pExpr->x.pList->nExpr;
}else{
nExprElem = 1;
}
if( nExprElem!=nElem ){
sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d",
nExprElem, nExprElem>1?"s":"", nElem
);
break;
}
assert( ExprUseXList(pExpr) );
pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0);
pExpr->x.pList = 0;
if( pSel ){
@ -1059,7 +1074,7 @@ Expr *sqlite3ExprFunction(
}
pNew->x.pList = pList;
ExprSetProperty(pNew, EP_HasFunc);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
assert( ExprUseXList(pNew) );
sqlite3ExprSetHeightAndFlags(pParse, pNew);
if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
return pNew;
@ -1195,17 +1210,18 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
assert( p->pRight==0 );
assert( p->x.pSelect==0 );
assert( !ExprUseXSelect(p) || p->x.pSelect==0 );
assert( !ExprUseXList(p) || p->x.pList==0 );
}
#endif
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
if( p->pRight ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3ExprDeleteNN(db, p->pRight);
}else if( ExprHasProperty(p, EP_xIsSelect) ){
}else if( ExprUseXSelect(p) ){
assert( !ExprHasProperty(p, EP_WinFunc) );
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@ -1436,7 +1452,7 @@ static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
if( ExprUseXSelect(p) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
}else{
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
@ -2285,7 +2301,7 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
}
/* Check if pExpr is a sub-select. If so, consider it variable. */
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
pWalker->eCode = 0;
return WRC_Abort;
}
@ -2512,7 +2528,7 @@ static Select *isCandidateForInOpt(const Expr *pX){
ExprList *pEList;
Table *pTab;
int i;
if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */
if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
p = pX->x.pSelect;
if( p->pPrior ) return 0; /* Not a compound SELECT */
@ -2683,7 +2699,7 @@ int sqlite3FindInIndex(
** or not NULL is actually possible (it may not be, for example, due
** to NOT NULL constraints in the schema). If no NULL values are possible,
** set prRhsHasNull to 0 before continuing. */
if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
if( prRhsHasNull && ExprUseXSelect(pX) ){
int i;
ExprList *pEList = pX->x.pSelect->pEList;
for(i=0; i<pEList->nExpr; i++){
@ -2839,7 +2855,7 @@ int sqlite3FindInIndex(
*/
if( eType==0
&& (inFlags & IN_INDEX_NOOP_OK)
&& !ExprHasProperty(pX, EP_xIsSelect)
&& ExprUseXList(pX)
&& (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
){
eType = IN_INDEX_NOOP;
@ -2887,7 +2903,7 @@ int sqlite3FindInIndex(
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
Expr *pLeft = pExpr->pLeft;
int nVal = sqlite3ExprVectorSize(pLeft);
Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
char *zRet;
assert( pExpr->op==TK_IN );
@ -2937,7 +2953,7 @@ void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
*/
void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
#ifndef SQLITE_OMIT_SUBQUERY
if( pExpr->flags & EP_xIsSelect ){
if( ExprUseXSelect(pExpr) ){
sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
}else
#endif
@ -3001,7 +3017,7 @@ void sqlite3CodeRhsOfIN(
*/
if( ExprHasProperty(pExpr, EP_Subrtn) ){
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
pExpr->x.pSelect->selId));
}
@ -3033,7 +3049,7 @@ void sqlite3CodeRhsOfIN(
pExpr->iTable = iTab;
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
}else{
VdbeComment((v, "RHS of IN operator"));
@ -3041,7 +3057,7 @@ void sqlite3CodeRhsOfIN(
#endif
pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
/* Case 1: expr IN (SELECT ...)
**
** Generate code to write the results of the select into the temporary
@ -3175,7 +3191,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
assert( ExprUseXSelect(pExpr) );
pSel = pExpr->x.pSelect;
/* If this routine has already been coded, then invoke it as a
@ -3283,7 +3299,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
*/
int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
int nVector = sqlite3ExprVectorSize(pIn->pLeft);
if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){
if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){
if( nVector!=pIn->x.pSelect->pEList->nExpr ){
sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
return 1;
@ -3417,13 +3433,15 @@ static void sqlite3ExprCodeIN(
** This is step (1) in the in-operator.md optimized algorithm.
*/
if( eType==IN_INDEX_NOOP ){
ExprList *pList = pExpr->x.pList;
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
ExprList *pList;
CollSeq *pColl;
int labelOk = sqlite3VdbeMakeLabel(pParse);
int r2, regToFree;
int regCkNull = 0;
int ii;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( ExprUseXList(pExpr) );
pList = pExpr->x.pList;
pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
@ -3809,6 +3827,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
int i;
iResult = pParse->nMem+1;
pParse->nMem += nResult;
assert( ExprUseXList(p) );
for(i=0; i<nResult; i++){
sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
}
@ -4315,8 +4334,8 @@ expr_code_doover:
** multiple times if we know they always give the same result */
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
assert( ExprUseXList(pExpr) );
pFarg = pExpr->x.pList;
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
@ -4435,7 +4454,10 @@ expr_code_doover:
testcase( op==TK_SELECT );
if( pParse->db->mallocFailed ){
return 0;
}else if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
}else if( op==TK_SELECT
&& ALWAYS( ExprUseXSelect(pExpr) )
&& (nCol = pExpr->x.pSelect->pEList->nExpr)!=1
){
sqlite3SubselectError(pParse, nCol, 1);
}else{
return sqlite3CodeSubselect(pParse, pExpr);
@ -4607,7 +4629,7 @@ expr_code_doover:
Expr *pDel = 0;
sqlite3 *db = pParse->db;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 );
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
@ -4952,7 +4974,7 @@ static void exprCodeBetween(
memset(&compRight, 0, sizeof(Expr));
memset(&exprAnd, 0, sizeof(Expr));
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( ExprUseXList(pExpr) );
pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
if( db->mallocFailed==0 ){
exprAnd.op = TK_AND;
@ -5539,12 +5561,13 @@ static int exprImpliesNotNull(
switch( p->op ){
case TK_IN: {
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
assert( ExprHasProperty(p,EP_xIsSelect)
|| (p->x.pList!=0 && p->x.pList->nExpr>0) );
assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) );
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
}
case TK_BETWEEN: {
ExprList *pList = p->x.pList;
ExprList *pList;
assert( ExprUseXList(p) );
pList = p->x.pList;
assert( pList!=0 );
assert( pList->nExpr==2 );
if( seenNot ) return 0;
@ -5908,6 +5931,7 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
cnt.nThis = 0;
cnt.nOther = 0;
assert( ExprUseXList(pExpr) );
sqlite3WalkExprList(&w, pExpr->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( ExprHasProperty(pExpr, EP_WinFunc) ){
@ -6112,7 +6136,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
pItem = &pAggInfo->aFunc[i];
pItem->pFExpr = pExpr;
pItem->iMem = ++pParse->nMem;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( ExprUseUToken(pExpr) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
pExpr->u.zToken,
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);

View File

@ -1935,10 +1935,10 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
int nExpr;
assert( pExpr!=0 );
assert( pExpr->op==TK_FUNCTION );
assert( ExprUseXList(pExpr) );
if( !pExpr->x.pList ){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
nExpr = pExpr->x.pList->nExpr;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);

View File

@ -518,8 +518,8 @@ static int lookupName(
){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 );
assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
@ -1120,7 +1120,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
int nRef = pNC->nRef;
testcase( pNC->ncFlags & NC_IsCheck );
testcase( pNC->ncFlags & NC_PartIdx );
@ -1177,6 +1177,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( pExpr->pLeft!=0 );
nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
if( pExpr->op==TK_BETWEEN ){
assert( ExprUseXList(pExpr) );
nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
if( nRight==nLeft ){
nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);

View File

@ -391,10 +391,13 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = iTable;
if( p->op==TK_FUNCTION && p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
if( p->op==TK_FUNCTION ){
assert( ExprUseXList(p) );
if( p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
}
}
}
sqlite3SetJoinExpr(p->pLeft, iTable);
@ -417,10 +420,13 @@ static void unsetJoinExpr(Expr *p, int iTable){
if( p->op==TK_COLUMN && p->iTable==iTable ){
ExprClearProperty(p, EP_CanBeNull);
}
if( p->op==TK_FUNCTION && p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
if( p->op==TK_FUNCTION ){
assert( ExprUseXList(p) );
if( p->x.pList ){
int i;
for(i=0; i<p->x.pList->nExpr; i++){
unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
}
}
}
unsetJoinExpr(p->pLeft, iTable);
@ -1866,9 +1872,11 @@ static const char *columnTypeImpl(
** statement.
*/
NameContext sNC;
Select *pS = pExpr->x.pSelect;
Expr *p = pS->pEList->a[0].pExpr;
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
Select *pS;
Expr *p;
assert( ExprUseXSelect(pExpr) );
pS = pExpr->x.pSelect;
p = pS->pEList->a[0].pExpr;
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
@ -3675,7 +3683,7 @@ static Expr *substExpr(
}
pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
pExpr->pRight = substExpr(pSubst, pExpr->pRight);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
substExprList(pSubst, pExpr->x.pList);
@ -4886,7 +4894,7 @@ static int pushDownWhereTerms(
*/
static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
ExprList *pEList; /* Arguments to agg function */
const char *zFunc; /* Name of aggregate function pFunc */
ExprList *pOrderBy;
u8 sortFlags = 0;
@ -4894,6 +4902,8 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
assert( *ppMinMax==0 );
assert( pFunc->op==TK_AGG_FUNCTION );
assert( !IsWindowFunc(pFunc) );
assert( ExprUseXList(pFunc) );
pEList = pFunc->x.pList;
if( pEList==0
|| pEList->nExpr!=1
|| ExprHasProperty(pFunc, EP_WinFunc)
@ -5870,7 +5880,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pFExpr;
assert( !ExprHasProperty(pE, EP_xIsSelect) );
assert( ExprUseXList(pE) );
if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
"argument");
@ -5895,8 +5905,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
int i;
struct AggInfo_func *pF;
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
ExprList *pList = pF->pFExpr->x.pList;
assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
ExprList *pList;
assert( ExprUseXList(pF->pFExpr) );
pList = pF->pFExpr->x.pList;
sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
}
@ -5930,9 +5941,10 @@ static void updateAccumulator(
int nArg;
int addrNext = 0;
int regAgg;
ExprList *pList = pF->pFExpr->x.pList;
assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
ExprList *pList;
assert( ExprUseXList(pF->pFExpr) );
assert( !IsWindowFunc(pF->pFExpr) );
pList = pF->pFExpr->x.pList;
if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
if( pAggInfo->nAccumulator
@ -6178,8 +6190,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
if( p->pGroupBy ) return 0;
pExpr = p->pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
assert( !ExprHasProperty(pExpr, EP_IntValue) );
assert( ExprUseUToken(pExpr) );
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
assert( ExprUseXList(pExpr) );
if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
pSub = p->pSrc->a[0].pSelect;
@ -6994,7 +7007,7 @@ int sqlite3Select(
}
for(i=0; i<pAggInfo->nFunc; i++){
Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
assert( ExprUseXList(pExpr) );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
#ifndef SQLITE_OMIT_WINDOWFUNC
@ -7049,7 +7062,9 @@ int sqlite3Select(
if( pAggInfo->nFunc==1
&& pAggInfo->aFunc[0].iDistinct>=0
&& pAggInfo->aFunc[0].pFExpr->x.pList
&& ALWAYS(pAggInfo->aFunc[0].pFExpr!=0)
&& ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr))
&& pAggInfo->aFunc[0].pFExpr->x.pList!=0
){
Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr;
pExpr = sqlite3ExprDup(db, pExpr, 0);
@ -7370,6 +7385,7 @@ int sqlite3Select(
sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
}
}else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){
assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) );
pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList;
distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0;
}

View File

@ -2886,6 +2886,16 @@ struct Expr {
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
/*
** Macros used to ensure that the correct members of unions are accessed.
*/
#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
#define ExprUseYTab(E) ((E)->op==TK_COLUMN)
#define ExprUseYWin(E) ((E)->flags&EP_WinFunc)!=0)
#define ExprUseYSub(E) ((E)->op==TK_IN||(E)->op==TK_SELECT||(E)->op==TK_EXISTS)
/* Flags for use with Expr.vvaFlags
*/

View File

@ -583,6 +583,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
pFarg = 0;
pWin = 0;
}else{
assert( ExprUseXList(pExpr) );
pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
@ -622,11 +623,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS: {
assert( ExprUseXSelect(pExpr) );
sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
break;
}
case TK_SELECT: {
assert( ExprUseXSelect(pExpr) );
sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags);
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
break;
@ -634,7 +637,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
case TK_IN: {
sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
}else{
sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
@ -655,9 +658,12 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
Expr *pX = pExpr->pLeft;
Expr *pY = pExpr->x.pList->a[0].pExpr;
Expr *pZ = pExpr->x.pList->a[1].pExpr;
const Expr *pX, *pY, *pZ;
pX = pExpr->pLeft;
assert( ExprUseXList(pExpr) );
assert( pExpr->x.pList->nExpr==2 );
pY = pExpr->x.pList->a[0].pExpr;
pZ = pExpr->x.pList->a[1].pExpr;
sqlite3TreeViewLine(pView, "BETWEEN");
sqlite3TreeViewExpr(pView, pX, 1);
sqlite3TreeViewExpr(pView, pY, 1);
@ -679,6 +685,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
case TK_CASE: {
sqlite3TreeViewLine(pView, "CASE");
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
assert( ExprUseXList(pExpr) );
sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
break;
}
@ -704,6 +711,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
}
case TK_VECTOR: {
char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
assert( ExprUseXList(pExpr) );
sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
sqlite3_free(z);
break;
@ -712,6 +720,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s",
pExpr->iColumn, pExpr->iTable-1,
pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : "");
assert( ExprUseXSelect(pExpr->pLeft) );
sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
break;
}

View File

@ -1418,6 +1418,7 @@ static int valueFromFunction(
assert( pCtx!=0 );
assert( (p->flags & EP_TokenOnly)==0 );
assert( ExprUseXList(p) );
pList = p->x.pList;
if( pList ) nVal = pList->nExpr;
assert( !ExprHasProperty(p, EP_IntValue) );

View File

@ -75,7 +75,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
pExpr = pExpr->pRight;
continue;
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
}else if( ExprUseXSelect(pExpr) ){
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else{

View File

@ -2419,9 +2419,12 @@ static int whereRangeVectorLen(
char aff; /* Comparison affinity */
char idxaff = 0; /* Indexed columns affinity */
CollSeq *pColl; /* Comparison collation sequence */
Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
Expr *pRhs = pTerm->pExpr->pRight;
if( pRhs->flags & EP_xIsSelect ){
Expr *pLhs, *pRhs;
assert( ExprUseXList(pTerm->pExpr->pLeft) );
pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
pRhs = pTerm->pExpr->pRight;
if( ExprUseXSelect(pRhs) ){
pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
}else{
pRhs = pRhs->x.pList->a[i].pExpr;
@ -2582,7 +2585,7 @@ static int whereLoopAddBtreeIndex(
if( eOp & WO_IN ){
Expr *pExpr = pTerm->pExpr;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
int i;
nIn = 46; assert( 46==sqlite3LogEst(25) );
@ -2723,7 +2726,7 @@ static int whereLoopAddBtreeIndex(
if( nInMul==0
&& pProbe->nSample
&& ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol)
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
&& ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr))
&& OptimizationEnabled(db, SQLITE_Stat4)
){
Expr *pExpr = pTerm->pExpr;

View File

@ -416,13 +416,18 @@ static Expr *removeUnindexableInClauseTerms(
Expr *pNew;
pNew = sqlite3ExprDup(db, pX, 0);
if( db->mallocFailed==0 ){
ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */
ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */
ExprList *pOrigRhs; /* Original unmodified RHS */
ExprList *pOrigLhs; /* Original unmodified LHS */
ExprList *pRhs = 0; /* New RHS after modifications */
ExprList *pLhs = 0; /* New LHS after mods */
int i; /* Loop counter */
Select *pSelect; /* Pointer to the SELECT on the RHS */
assert( ExprUseXSelect(pNew) );
pOrigRhs = pNew->x.pSelect->pEList;
assert( pNew->pLeft!=0 );
assert( ExprUseXList(pNew->pLeft) );
pOrigLhs = pNew->pLeft->x.pList;
for(i=iEq; i<pLoop->nLTerm; i++){
if( pLoop->aLTerm[i]->pExpr==pX ){
int iField = pLoop->aLTerm[i]->u.x.iField - 1;
@ -540,7 +545,7 @@ static int codeEqualityTerm(
}
iTab = 0;
if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
}else{
sqlite3 *db = pParse->db;
@ -1105,7 +1110,7 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
assert( nReg>0 );
if( p && sqlite3ExprIsVector(p) ){
#ifndef SQLITE_OMIT_SUBQUERY
if( (p->flags & EP_xIsSelect) ){
if( ExprUseXSelect(p) ){
Vdbe *v = pParse->pVdbe;
int iSelect;
assert( p->op==TK_SELECT );
@ -1115,7 +1120,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
#endif
{
int i;
ExprList *pList = p->x.pList;
const ExprList *pList;
assert( ExprUseXList(p) );
pList = p->x.pList;
assert( nReg<=pList->nExpr );
for(i=0; i<nReg; i++){
sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
@ -2461,7 +2468,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
if( (pAlt->eOperator & WO_IN)
&& (pAlt->pExpr->flags & EP_xIsSelect)
&& ExprUseXSelect(pAlt->pExpr)
&& (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
){
continue;

View File

@ -195,6 +195,7 @@ static int isLikeOrGlob(
#ifdef SQLITE_EBCDIC
if( *pnoCase ) return 0;
#endif
assert( ExprUseXList(pExpr) );
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
@ -368,6 +369,7 @@ static int isAuxiliaryVtabOperator(
Expr *pCol; /* Column reference */
int i;
assert( ExprUseXList(pExpr) );
pList = pExpr->x.pList;
if( pList==0 || pList->nExpr!=2 ){
return 0;
@ -873,7 +875,7 @@ static void exprAnalyzeOrTerm(
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
assert( ExprUseXList(pNew) );
pNew->x.pList = pList;
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
@ -1001,6 +1003,7 @@ static int exprMightBeIndexed(
assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
assert( op<=TK_GE );
if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
assert( ExprUseXList(pExpr) );
pExpr = pExpr->x.pList->a[0].pExpr;
}
@ -1067,7 +1070,7 @@ static void exprAnalyze(
if( op==TK_IN ){
assert( pExpr->pRight==0 );
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( ExprUseXSelect(pExpr) ){
pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
}else{
pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
@ -1103,6 +1106,7 @@ static void exprAnalyze(
if( pTerm->u.x.iField>0 ){
assert( op==TK_IN );
assert( pLeft->op==TK_VECTOR );
assert( ExprUseXList(pLeft) );
pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
}
@ -1181,9 +1185,11 @@ static void exprAnalyze(
** BETWEEN term is skipped.
*/
else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
ExprList *pList = pExpr->x.pList;
ExprList *pList;
int i;
static const u8 ops[] = {TK_GE, TK_LE};
assert( ExprUseXList(pExpr) );
pList = pExpr->x.pList;
assert( pList!=0 );
assert( pList->nExpr==2 );
for(i=0; i<2; i++){
@ -1276,6 +1282,7 @@ static void exprAnalyze(
const char *zCollSeqName; /* Name of collating sequence */
const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
assert( ExprUseXList(pExpr) );
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) );
@ -1380,6 +1387,7 @@ static void exprAnalyze(
else if( pExpr->op==TK_IN
&& pTerm->u.x.iField==0
&& pExpr->pLeft->op==TK_VECTOR
&& ALWAYS( ExprUseXSelect(pExpr) )
&& pExpr->x.pSelect->pPrior==0
#ifndef SQLITE_OMIT_WINDOWFUNC
&& pExpr->x.pSelect->pWin==0
@ -1543,7 +1551,7 @@ Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
if( p->pRight ){
mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
assert( p->x.pList==0 );
}else if( ExprHasProperty(p, EP_xIsSelect) ){
}else if( ExprUseXSelect(p) ){
if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
}else if( p->x.pList ){

View File

@ -1030,7 +1030,9 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
** window function - one for the accumulator, another for interim
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
ExprList *pArgs = pWin->pOwner->x.pList;
ExprList *pArgs;
assert( ExprUseXList(pWin->pOwner) );
pArgs = pWin->pOwner->x.pList;
if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
@ -1423,8 +1425,11 @@ void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
** regApp+1: integer value used to ensure keys are unique
** regApp+2: output of MakeRecord
*/
ExprList *pList = pWin->pOwner->x.pList;
KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
ExprList *pList;
KeyInfo *pKeyInfo;
assert( ExprUseXList(pWin->pOwner) );
pList = pWin->pOwner->x.pList;
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
pWin->csrApp = pParse->nTab++;
pWin->regApp = pParse->nMem+1;
pParse->nMem += 3;
@ -1512,7 +1517,9 @@ static void windowCheckValue(Parse *pParse, int reg, int eCond){
** with the object passed as the only argument to this function.
*/
static int windowArgCount(Window *pWin){
ExprList *pList = pWin->pOwner->x.pList;
const ExprList *pList;
assert( ExprUseXList(pWin->pOwner) );
pList = pWin->pOwner->x.pList;
return (pList ? pList->nExpr : 0);
}
@ -1697,6 +1704,7 @@ static void windowAggStep(
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
@ -1710,6 +1718,7 @@ static void windowAggStep(
int iOp = sqlite3VdbeCurrentAddr(v);
int iEnd;
assert( ExprUseXList(pWin->pOwner) );
nArg = pWin->pOwner->x.pList->nExpr;
regArg = sqlite3GetTempRange(pParse, nArg);
sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
@ -1724,6 +1733,7 @@ static void windowAggStep(
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl;
assert( nArg>0 );
assert( ExprUseXList(pWin->pOwner) );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
@ -1909,6 +1919,7 @@ static void windowReturnOneRow(WindowCodeArg *p){
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
assert( ExprUseXList(pWin->pOwner) );
if( pFunc->zName==nth_valueName
|| pFunc->zName==first_valueName
){