-C When\sbuilding\sfor\sWindows\s8.0\susing\sVisual\sStudio\s2013,\smake\ssure\sthe\scross-compilation\snative\slibrary\spath\sis\sset\scorrectly.
-D 2014-05-05T22:43:17.621
+C Experimental\schanges\sthat\sreduce\sthe\ssize\sof\sExpr\sobjects\sfrom\s72\sto\s64\nbytes\seach\son\sx64\sand\sfrom\s48\sto\s44\sbytes\seach\son\sx32.
+D 2014-05-06T15:28:56.475
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1
F src/analyze.c 3596f863bb80126fe56ba217df5932749271efc8
-F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
+F src/attach.c a1ada8e4177827c5873aa356b933f2d4d1293a9a
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf
-F src/expr.c 4f9e497c66e2f25a4d139357a778c84d5713207c
+F src/expr.c 78326e5d1fa27a88a6c037fabc6c63359695e937
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 5269ef07b100763134f71b889327c333bd0989cf
-F src/func.c 2945bb2c4cdc0ac43733046285a4434310be1811
+F src/func.c 863735228a1ff6e225a8904169644a4fd40df43c
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
F src/pager.c ab62a24218d87dda1be641f6c5ad291bff78fd94
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
-F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0
+F src/parse.y b9adfa13ce569c12aa157c8ebc5fdc670f1a0acb
F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c e5a0005f8b3de21f85da6a709d2fbee76775bf4b
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
-F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
+F src/resolve.c 06b706383c66ba05f515014fb7f37e84a22fdf96
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
-F src/select.c 089c4d46f067a5cccae93524c6377f981ba99bd9
+F src/select.c 109d659ed3f949e11de6bc74afe6a56b68ff3b80
F src/shell.c 2afe7a7154e97be0c74c5feacf09626bda8493be
F src/sqlite.h.in bde98816e1ba0c9ffef50afe7b32f4e5a8f54fe0
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h b2947801eccefd7ba3e5f14e1353289351a83cf3
+F src/sqliteInt.h 23b03ab00dac71f2402eb9fd977aaed735d42c0c
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
-F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
-F src/where.c 91dfd382273c3f67fcdc0ac4728f9140f91c6ab3
+F src/walker.c 4a73ee39c361017532530ef18066d7e87e0d9bd0
+F src/where.c b8df0204d0e7bfe735f7892d8e96493652d607ac
F src/whereInt.h 6804c2e5010378568c2bb1350477537755296a46
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 9a06773acc181e981f61f476a8e56417b98beba9
-R e91b1cf1dddb5793408fd6de2be74034
-U mistachkin
-Z b713eaa9517cf3b104e3dc82bdd65124
+P c1ab9092e29bc9d172c1f1a3becbcc83b79f2080
+R 4b8f36fa136ae7cf835aa3d588ac1c25
+T *branch * smaller-expr
+T *sym-smaller-expr *
+T -sym-trunk *
+U drh
+Z 8672a4e9e0a77fa3f766205961da49e1
-c1ab9092e29bc9d172c1f1a3becbcc83b79f2080
\ No newline at end of file
+8ad0a123a2046e4bf95b4f9c28f26221afb3fc43
\ No newline at end of file
}
}
if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( ExprUsesRight(pExpr) ){
+ if( sqlite3FixExpr(pFix, pExpr->x.pRight) ) return 1;
+ }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
}
- if( sqlite3FixExpr(pFix, pExpr->pRight) ){
- return 1;
- }
pExpr = pExpr->pLeft;
}
return 0;
if( pExpr->flags & EP_Generic ) return SQLITE_AFF_NONE;
op = pExpr->op;
if( op==TK_SELECT ){
- assert( pExpr->flags&EP_xIsSelect );
+ assert( ExprHasProperty(pExpr, EP_xIsSelect) );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
#ifndef SQLITE_OMIT_CAST
Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
if( ExprHasProperty(pExpr, EP_Unlikely) ){
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
if( p->flags & EP_Collate ){
if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
p = p->pLeft;
- }else{
- p = p->pRight;
+ }else if( ExprUsesRight(p) ){
+ p = p->x.pRight;
}
}else{
break;
pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
assert( pExpr->pLeft );
aff = sqlite3ExprAffinity(pExpr->pLeft);
- if( pExpr->pRight ){
- aff = sqlite3CompareAffinity(pExpr->pRight, aff);
+ if( ExprUsesRight(pExpr) ){
+ aff = sqlite3CompareAffinity(pExpr->x.pRight, aff);
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
}else if( !aff ){
static void exprSetHeight(Expr *p){
int nHeight = 0;
heightOfExpr(p->pLeft, &nHeight);
- heightOfExpr(p->pRight, &nHeight);
- if( ExprHasProperty(p, EP_xIsSelect) ){
+ if( ExprUsesRight(p) ){
+ heightOfExpr(p->x.pRight, &nHeight);
+ }else if( ExprHasProperty(p, EP_xIsSelect) ){
heightOfSelect(p->x.pSelect, &nHeight);
}else{
+ assert( ExprHasProperty(p, EP_xIsList) );
heightOfExprList(p->x.pList, &nHeight);
}
p->nHeight = nHeight + 1;
sqlite3ExprDelete(db, pRight);
}else{
if( pRight ){
- pRoot->pRight = pRight;
- pRoot->flags |= EP_Collate & pRight->flags;
+ pRoot->x.pRight = pRight;
+ pRoot->flags |= (EP_Collate & pRight->flags);
}
if( pLeft ){
pRoot->pLeft = pLeft;
return 0;
}
pNew->x.pList = pList;
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
+ ExprSetProperty(pNew, EP_xIsList);
sqlite3ExprSetHeight(pParse, pNew);
return pNew;
}
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
if( !ExprHasProperty(p, EP_TokenOnly) ){
- /* The Expr.x union is never used at the same time as Expr.pRight */
- assert( p->x.pList==0 || p->pRight==0 );
sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
- if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
- if( ExprHasProperty(p, EP_xIsSelect) ){
+ if( ExprHasProperty(p, EP_MemToken) ){
+ sqlite3DbFree(db, p->u.zToken);
+ }
+ if( ExprUsesRight(p) ){
+ sqlite3ExprDelete(db, p->x.pRight);
+ }else if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
+ assert( ExprHasProperty(p, EP_xIsList) );
sqlite3ExprListDelete(db, p->x.pList);
}
}
if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
- assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
- nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
+ nByte += dupedExprSize(p->pLeft, flags);
+ if( ExprUsesRight(p) ){
+ nByte += dupedExprSize(p->x.pRight, flags);
+ }
}
}
return nByte;
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
** to store the copy of expression p, the copies of p->u.zToken
-** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
+** (if applicable), and the copies of the p->pLeft and p->x.pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte passed the
** portion of the buffer copied into by this function.
*/
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
- }else{
+ }else if( ExprHasProperty(p, EP_xIsList) ){
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, isReduced);
}
}
- /* Fill in pNew->pLeft and pNew->pRight. */
+ /* Fill in pNew->pLeft and pNew->x.pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
- pNew->pRight = exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc);
+ if( ExprUsesRight(p) ){
+ assert( ExprUsesRight(p) );
+ pNew->x.pRight = exprDup(db, p->x.pRight, EXPRDUP_REDUCE, &zAlloc);
+ }
}
if( pzBuffer ){
*pzBuffer = zAlloc;
}else{
if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ if( ExprUsesRight(p) ){
+ assert( ExprUsesRight(pNew) );
+ pNew->x.pRight = sqlite3ExprDup(db, p->x.pRight, 0);
+ }
}
}
case TK_NE:
case TK_EQ: {
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, inReg, SQLITE_STOREP2);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
testcase( op==TK_IS );
testcase( op==TK_ISNOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
op = (op==TK_IS) ? TK_EQ : TK_NE;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
sqlite3VdbeAddOp3(v, op, r2, r1, target);
testcase( regFree1==0 );
testcase( regFree2==0 );
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
+ assert( ExprHasProperty(pExpr, EP_xIsList) && pExpr->x.pList );
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1));
testcase( regFree1==0 );
opCompare.op = TK_EQ;
+ opCompare.flags = 0;
opCompare.pLeft = &tempX;
pTest = &opCompare;
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
sqlite3ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
- opCompare.pRight = aListelem[i].pExpr;
+ opCompare.x.pRight = aListelem[i].pExpr;
}else{
pTest = aListelem[i].pExpr;
}
sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
sqlite3ExplainExpr(pOut, pExpr->pLeft);
sqlite3ExplainPrintf(pOut,",");
- sqlite3ExplainExpr(pOut, pExpr->pRight);
+ assert( ExprUsesRight(pExpr) );
+ sqlite3ExplainExpr(pOut, pExpr->x.pRight);
sqlite3ExplainPrintf(pOut,")");
}else if( zUniOp ){
sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND;
+ exprAnd.flags = 0;
exprAnd.pLeft = &compLeft;
- exprAnd.pRight = &compRight;
+ exprAnd.x.pRight = &compRight;
compLeft.op = TK_GE;
+ compLeft.flags = 0;
compLeft.pLeft = &exprX;
- compLeft.pRight = pExpr->x.pList->a[0].pExpr;
+ compLeft.x.pRight = pExpr->x.pList->a[0].pExpr;
compRight.op = TK_LE;
+ compRight.flags = 0;
compRight.pLeft = &exprX;
- compRight.pRight = pExpr->x.pList->a[1].pExpr;
+ compRight.x.pRight = pExpr->x.pList->a[1].pExpr;
exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, ®Free1));
if( jumpIfTrue ){
sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprCachePush(pParse);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ assert( ExprUsesRight(pExpr) );
+ sqlite3ExprIfTrue(pParse, pExpr->x.pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse);
break;
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprCachePush(pParse);
- sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ assert( ExprUsesRight(pExpr) );
+ sqlite3ExprIfTrue(pParse, pExpr->x.pRight, dest, jumpIfNull);
sqlite3ExprCachePop(pParse);
break;
}
case TK_EQ: {
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
testcase( op==TK_IS );
testcase( op==TK_ISNOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
op = (op==TK_IS) ? TK_EQ : TK_NE;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprCachePush(pParse);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ assert( ExprUsesRight(pExpr) );
+ sqlite3ExprIfFalse(pParse, pExpr->x.pRight, dest, jumpIfNull);
sqlite3ExprCachePop(pParse);
break;
}
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprCachePush(pParse);
- sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ assert( ExprUsesRight(pExpr) );
+ sqlite3ExprIfFalse(pParse, pExpr->x.pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse);
break;
case TK_EQ: {
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, dest, jumpIfNull);
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_ISNOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2);
+ assert( ExprUsesRight(pExpr) );
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->x.pRight, ®Free2);
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
+ codeCompare(pParse, pExpr->pLeft, pExpr->x.pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
VdbeCoverageIf(v, op==TK_EQ);
VdbeCoverageIf(v, op==TK_NE);
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
- if( combinedFlags & EP_xIsSelect ) return 2;
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
- if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
- if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+ if( (pA->flags&EP_xMask)!=(pB->flags&EP_xMask) ) return 2;
+ if( ExprUsesRight(pA) ){
+ if( sqlite3ExprCompare(pA->x.pRight, pB->x.pRight, iTab) ) return 2;
+ }else if( ExprHasProperty(pA, EP_xIsSelect) ){
+ return 2;
+ }else{
+ assert( ExprHasProperty(pA, EP_xIsList) );
+ if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+ }
if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
}
if( pE2->op==TK_OR
&& (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
- || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
+ || sqlite3ExprImpliesExpr(pE1, pE2->x.pRight, iTab) )
){
return 1;
}
u8 enc = ENC(pParse->db);
i = addAggInfoFunc(pParse->db, pAggInfo);
if( i>=0 ){
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
}
/*
-** pExpr points to an expression which implements a function. If
+** pExpr might point to an expression which implements a function. If
** it is appropriate to apply the LIKE optimization to that function
** then set aWc[0] through aWc[2] to the wildcard characters and
** return TRUE. If the function is not a LIKE-style function then
*/
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION
- || !pExpr->x.pList
- || pExpr->x.pList->nExpr!=2
- ){
+ if( pExpr->op!=TK_FUNCTION ) return 0;
+ assert( ExprHasProperty(pExpr, EP_xIsList) || pExpr->x.pList==0 );
+ if( !pExpr->x.pList || pExpr->x.pList->nExpr!=2 ){
return 0;
}
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
pDef = sqlite3FindFunction(db, pExpr->u.zToken,
sqlite3Strlen30(pExpr->u.zToken),
2, SQLITE_UTF8, 0);
sqlite3 *db = pParse->db;
if( db->mallocFailed==0 && pY->op==TK_NULL ){
pA->op = (u8)op;
- sqlite3ExprDelete(db, pA->pRight);
- pA->pRight = 0;
+ assert( ExprUsesRight(pA) );
+ sqlite3ExprDelete(db, pA->x.pRight);
+ pA->x.pRight = 0;
}
}
}
A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, W.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = pList;
+ ExprSetProperty(A.pExpr, EP_xIsList);
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Y;
+ ExprSetProperty(A.pExpr, EP_xIsList);
sqlite3ExprSetHeight(pParse, A.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, Y);
A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
+ ExprSetProperty(A.pExpr, EP_xIsList);
sqlite3ExprSetHeight(pParse, A.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, Y);
** pExpr->iColumn Set to the column number within the table.
** pExpr->op Set to TK_COLUMN.
** pExpr->pLeft Any expression this points to is deleted
-** pExpr->pRight Any expression this points to is deleted.
+** pExpr->x.pRight Any expression this points to is deleted.
**
** The zDb variable is the name of the database (the "X"). This value may be
** NULL meaning that name is of the form Y.Z or Z. Any available database
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ assert( pExpr->pLeft==0 && pExpr->x.pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
*/
sqlite3ExprDelete(db, pExpr->pLeft);
pExpr->pLeft = 0;
- sqlite3ExprDelete(db, pExpr->pRight);
- pExpr->pRight = 0;
+ if( ExprUsesRight(pExpr) ){
+ sqlite3ExprDelete(db, pExpr->x.pRight);
+ pExpr->x.pRight = 0;
+ }
pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN);
lookupname_end:
if( cnt==1 ){
Expr *pRight;
/* if( pSrcList==0 ) break; */
- pRight = pExpr->pRight;
+ assert( ExprUsesRight(pExpr) );
+ pRight = pExpr->x.pRight;
if( pRight->op==TK_ID ){
zDb = 0;
zTable = pExpr->pLeft->u.zToken;
zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
+ assert( ExprUsesRight(pRight) );
zDb = pExpr->pLeft->u.zToken;
zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
+ zColumn = pRight->x.pRight->u.zToken;
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pExpr, EP_xIsList) || pList==0 );
notValidPartIdxWhere(pParse, pNC, "functions");
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
- p = p->pRight;
+ p = ExprUsesRight(p) ? p->x.pRight : 0;
}
}
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ){
- pColExpr = pColExpr->pRight;
+ assert( ExprUsesRight(pColExpr) );
+ pColExpr = pColExpr->x.pRight;
assert( pColExpr!=0 );
}
if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
}else{
Expr *pNew;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
- assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ assert( pExpr->pLeft==0 && pExpr->x.pRight==0 );
pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
}
}else{
pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
- pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( ExprUsesRight(pExpr) ){
+ pExpr->x.pRight = substExpr(db, pExpr->x.pRight, iTable, pEList);
+ }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(db, pExpr->x.pSelect, iTable, pEList);
}else{
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
substExprList(db, pExpr->x.pList, iTable, pEList);
}
}
for(k=0; k<pEList->nExpr; k++){
pE = pEList->a[k].pExpr;
if( pE->op==TK_ALL ) break;
- assert( pE->op!=TK_DOT || pE->pRight!=0 );
+ assert( pE->op!=TK_DOT || !ExprUsesRight(pE) || pE->x.pRight!=0 );
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
- if( pE->op==TK_DOT && pE->pRight->op==TK_ALL ) break;
+ if( pE->op==TK_DOT && pE->x.pRight->op==TK_ALL ) break;
}
if( k<pEList->nExpr ){
/*
for(k=0; k<pEList->nExpr; k++){
pE = a[k].pExpr;
- pRight = pE->pRight;
+ pRight = ExprUsesRight(pE) ? pE->x.pRight : 0;
assert( pE->op!=TK_DOT || pRight!=0 );
if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
/* This particular expression does not need to be expanded.
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
- assert( !ExprHasProperty(pE, EP_xIsSelect) );
+ assert( ExprHasProperty(pE, EP_xIsList) || pE->x.pList==0 );
if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
"argument");
struct AggInfo_func *pF;
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pF->pExpr, EP_xIsList) || pList==0 );
sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
(void*)pF->pFunc, P4_FUNCDEF);
}
int addrNext = 0;
int regAgg;
ExprList *pList = pF->pExpr->x.pList;
- assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(pF->pExpr, EP_xIsList) || pList==0 );
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
- assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
+ assert( ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsList)
+ || sAggInfo.aFunc[i].pExpr->x.pList==0 );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
*********************************************************************/
Expr *pLeft; /* Left subnode */
- Expr *pRight; /* Right subnode */
union {
+ Expr *pRight; /* Right subnode */
ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */
} x;
** access them will result in a segfault or malfunction.
*********************************************************************/
-#if SQLITE_MAX_EXPR_DEPTH>0
- int nHeight; /* Height of the tree headed by this node */
-#endif
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old
** EP_Unlikely: 1000 times likelihood */
+#if SQLITE_MAX_EXPR_DEPTH>0
+ int nHeight; /* Height of the tree headed by this node */
+#endif
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
** TK_VARIABLE: variable number (always >= 1). */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_Constant 0x080000 /* Node is a constant */
+#define EP_xIsSelect 0x100000 /* Use x.pSelect, not x.pList or x.pRight */
+#define EP_xIsList 0x200000 /* Use x.pList, not x.pSelect or x.pRight */
+#define EP_xMask 0x300000 /* Combination of xIsSelect and xIsList */
/*
** These macros can be used to test, set, or clear bits in the
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
+/* True if the x.pRight field of Expr E is valid */
+#define ExprUsesRight(E) (((E)->flags&EP_xMask)==0)
+
+
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
** processes but is a no-op for delivery.
if( rc==WRC_Continue
&& !ExprHasProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( ExprUsesRight(pExpr) ){
+ if( sqlite3WalkExpr(pWalker, pExpr->x.pRight) ) return WRC_Abort;
+ }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else{
+ assert( ExprHasProperty(pExpr, EP_xIsList) );
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
}
whereClauseInsert(pWC, pExpr, 0);
}else{
whereSplit(pWC, pExpr->pLeft, op);
- whereSplit(pWC, pExpr->pRight, op);
+ assert( ExprUsesRight(pExpr) );
+ whereSplit(pWC, pExpr->x.pRight, op);
}
}
mask = getMask(pMaskSet, p->iTable);
return mask;
}
- mask = exprTableUsage(pMaskSet, p->pRight);
- mask |= exprTableUsage(pMaskSet, p->pLeft);
- if( ExprHasProperty(p, EP_xIsSelect) ){
+ mask = exprTableUsage(pMaskSet, p->pLeft);
+ if( ExprUsesRight(p) ){
+ mask |= exprTableUsage(pMaskSet, p->x.pRight);
+ }else if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectTableUsage(pMaskSet, p->x.pSelect);
}else{
+ assert( ExprHasProperty(p, EP_xIsList) );
mask |= exprListTableUsage(pMaskSet, p->x.pList);
}
return mask;
** is not commuted.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
- u16 expRight = (pExpr->pRight->flags & EP_Collate);
+ u16 expRight = (pExpr->x.pRight->flags & EP_Collate);
u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
+ assert( ExprUsesRight(pExpr) );
assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
if( expRight==expLeft ){
/* Either X and Y both have COLLATE operator or neither do */
if( expRight ){
/* Both X and Y have COLLATE operators. Make sure X is always
** used by clearing the EP_Collate flag from Y. */
- pExpr->pRight->flags &= ~EP_Collate;
+ pExpr->x.pRight->flags &= ~EP_Collate;
}else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
/* Neither X nor Y have COLLATE operators, but X has a non-default
** collating sequence. So add the EP_Collate marker on X to cause
pExpr->pLeft->flags |= EP_Collate;
}
}
- SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
+ SWAP(Expr*,pExpr->x.pRight,pExpr->pLeft);
if( pExpr->op>=TK_GT ){
assert( TK_LT==TK_GT+2 );
assert( TK_GE==TK_LE+2 );
&& pScan->nEquiv<ArraySize(pScan->aEquiv)
){
int j;
- pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
+ assert( ExprUsesRight(pTerm->pExpr) );
+ pX = sqlite3ExprSkipCollate(pTerm->pExpr->x.pRight);
assert( pX->op==TK_COLUMN );
for(j=0; j<pScan->nEquiv; j+=2){
if( pScan->aEquiv[j]==pX->iTable
if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
continue;
}
- assert(pX->pLeft);
- pColl = sqlite3BinaryCompareCollSeq(pParse,
- pX->pLeft, pX->pRight);
+ assert( pX->pLeft!=0 );
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft,
+ ExprUsesRight(pX) ? pX->x.pRight : 0);
if( pColl==0 ) pColl = pParse->db->pDfltColl;
if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
continue;
}
}
if( (pTerm->eOperator & WO_EQ)!=0
- && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
+ && (pX = pTerm->pExpr->x.pRight)->op==TK_COLUMN
&& pX->iTable==pScan->aEquiv[0]
&& pX->iColumn==pScan->aEquiv[1]
){
** of both right and left sides must be such that no type
** conversions are required on the right. (Ticket #2249)
*/
- affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight);
+ assert( ExprUsesRight(pOrTerm->pExpr) );
+ affRight = sqlite3ExprAffinity(pOrTerm->pExpr->x.pRight);
affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft);
if( affRight!=0 && affRight!=affLeft ){
okToChngToIN = 0;
assert( pOrTerm->eOperator & WO_EQ );
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
- pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
+ assert( ExprUsesRight(pOrTerm->pExpr) );
+ pDup = sqlite3ExprDup(db, pOrTerm->pExpr->x.pRight, 0);
pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
+ ExprSetProperty(pNew, EP_xIsList);
pNew->x.pList = pList;
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
op = pExpr->op;
if( op==TK_IN ){
- assert( pExpr->pRight==0 );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
}else{
+ assert( ExprHasProperty(pExpr, EP_xIsList) || pExpr->x.pList==0 );
pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->x.pList);
}
}else if( op==TK_ISNULL ){
pTerm->prereqRight = 0;
- }else{
- pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
+ }else if( ExprUsesRight(pExpr) ){
+ pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->x.pRight);
}
prereqAll = exprTableUsage(pMaskSet, pExpr);
if( ExprHasProperty(pExpr, EP_FromJoin) ){
pTerm->eOperator = 0;
if( allowedOp(op) ){
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
- Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
+ Expr *pRight;
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable;
pTerm->u.leftColumn = pLeft->iColumn;
pTerm->eOperator = operatorMask(op) & opMask;
}
- if( pRight && pRight->op==TK_COLUMN ){
+ if( ExprUsesRight(pExpr)
+ && (pRight = sqlite3ExprSkipCollate(pExpr->x.pRight))!=0
+ && pRight->op==TK_COLUMN
+ ){
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
pIdx->aiColumn[n] = pTerm->u.leftColumn;
- pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
+ assert( ExprUsesRight(pX) );
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->x.pRight);
pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
n++;
}
/* If possible, improve on the iLower estimate using ($P:$L). */
if( pLower ){
int bOk; /* True if value is extracted from pExpr */
- Expr *pExpr = pLower->pExpr->pRight;
+ Expr *pExpr = pLower->pExpr->x.pRight;
+ assert( ExprUsesRight(pLower->pExpr) );
assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
/* If possible, improve on the iUpper estimate using ($P:$U). */
if( pUpper ){
int bOk; /* True if value is extracted from pExpr */
- Expr *pExpr = pUpper->pExpr->pRight;
+ Expr *pExpr = pUpper->pExpr->x.pRight;
+ assert( ExprUsesRight(pUpper->pExpr) );
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
if( rc==SQLITE_OK && bOk ){
assert( iTarget>0 );
if( pX->op==TK_EQ ){
- iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
+ assert( ExprUsesRight(pX) );
+ iReg = sqlite3ExprCodeTarget(pParse, pX->x.pRight, iTarget);
}else if( pX->op==TK_ISNULL ){
iReg = iTarget;
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IN );
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
- Expr *pRight = pTerm->pExpr->pRight;
+ Expr *pRight = pTerm->pExpr->x.pRight;
+ assert( ExprUsesRight(pTerm->pExpr) );
if( sqlite3ExprCanBeNull(pRight) ){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
VdbeCoverage(v);
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
addrNotFound = pLevel->addrNxt;
}else{
- sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
+ assert( ExprUsesRight(pTerm->pExpr) );
+ sqlite3ExprCode(pParse, pTerm->pExpr->x.pRight, iTarget);
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
pX = pStart->pExpr;
assert( pX!=0 );
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+ assert( ExprUsesRight(pX) );
+ r1 = sqlite3ExprCodeTemp(pParse, pX->x.pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
- sqlite3ExprCode(pParse, pX->pRight, memEndValue);
+ assert( ExprUsesRight(pX) );
+ sqlite3ExprCode(pParse, pX->x.pRight, memEndValue);
if( pX->op==TK_LT || pX->op==TK_GT ){
testOp = bRev ? OP_Le : OP_Ge;
}else{
/* Seek the index cursor to the start of the range. */
nConstraint = nEq;
if( pRangeStart ){
- Expr *pRight = pRangeStart->pExpr->pRight;
+ Expr *pRight = pRangeStart->pExpr->x.pRight;
+ assert( ExprUsesRight(pRangeStart->pExpr) );
sqlite3ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeStart->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
*/
nConstraint = nEq;
if( pRangeEnd ){
- Expr *pRight = pRangeEnd->pExpr->pRight;
+ Expr *pRight = pRangeEnd->pExpr->x.pRight;
+ assert( ExprUsesRight(pRangeEnd->pExpr) );
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
testcase( eOp & WO_EQ );
testcase( eOp & WO_ISNULL );
- rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
+ assert( ExprUsesRight(pExpr) );
+ rc = whereEqualScanEst(pParse, pBuilder, pExpr->x.pRight, &nOut);
}else{
rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
}