Compare commits
1 Commits
echo-sql
...
smaller-expr
| Author | SHA1 | Date | |
|---|---|---|---|
| ee07978c9a |
@@ -1,5 +1,5 @@
|
||||
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
|
||||
@@ -160,7 +160,7 @@ F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494
|
||||
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
|
||||
@@ -174,10 +174,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||
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
|
||||
@@ -210,7 +210,7 @@ F src/os_win.c 485d06a93965f306c7281fca0937829292367234
|
||||
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
|
||||
@@ -218,14 +218,14 @@ F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897
|
||||
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
|
||||
@@ -293,8 +293,8 @@ F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
|
||||
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
|
||||
@@ -1168,7 +1168,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
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
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
c1ab9092e29bc9d172c1f1a3becbcc83b79f2080
|
||||
8ad0a123a2046e4bf95b4f9c28f26221afb3fc43
|
||||
+4
-4
@@ -524,14 +524,14 @@ int sqlite3FixExpr(
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
+87
-53
@@ -36,7 +36,7 @@ char sqlite3ExprAffinity(Expr *pExpr){
|
||||
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
|
||||
@@ -96,7 +96,7 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
|
||||
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;
|
||||
@@ -148,8 +148,8 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *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;
|
||||
@@ -200,8 +200,8 @@ static char comparisonAffinity(Expr *pExpr){
|
||||
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 ){
|
||||
@@ -359,10 +359,12 @@ static void heightOfSelect(Select *p, int *pnHeight){
|
||||
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;
|
||||
@@ -489,8 +491,8 @@ void sqlite3ExprAttachSubtrees(
|
||||
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;
|
||||
@@ -593,7 +595,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
||||
return 0;
|
||||
}
|
||||
pNew->x.pList = pList;
|
||||
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
|
||||
ExprSetProperty(pNew, EP_xIsList);
|
||||
sqlite3ExprSetHeight(pParse, pNew);
|
||||
return pNew;
|
||||
}
|
||||
@@ -690,14 +692,16 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
@@ -766,7 +770,6 @@ static int dupedExprStructSize(Expr *p, int flags){
|
||||
if( p->pLeft || p->x.pList ){
|
||||
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
|
||||
}else{
|
||||
assert( p->pRight==0 );
|
||||
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
|
||||
}
|
||||
}
|
||||
@@ -804,7 +807,10 @@ static int dupedExprSize(Expr *p, int flags){
|
||||
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;
|
||||
@@ -814,7 +820,7 @@ static int dupedExprSize(Expr *p, int flags){
|
||||
** 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.
|
||||
*/
|
||||
@@ -874,17 +880,20 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
|
||||
/* 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;
|
||||
@@ -892,7 +901,10 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
|
||||
}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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2530,8 +2542,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
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);
|
||||
@@ -2548,9 +2561,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
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);
|
||||
@@ -2582,7 +2596,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
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 );
|
||||
@@ -2656,10 +2671,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
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;
|
||||
@@ -2926,7 +2941,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
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;
|
||||
@@ -2938,6 +2953,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1));
|
||||
testcase( regFree1==0 );
|
||||
opCompare.op = TK_EQ;
|
||||
opCompare.flags = 0;
|
||||
opCompare.pLeft = &tempX;
|
||||
pTest = &opCompare;
|
||||
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
|
||||
@@ -2950,7 +2966,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
sqlite3ExprCachePush(pParse);
|
||||
if( pX ){
|
||||
assert( pTest!=0 );
|
||||
opCompare.pRight = aListelem[i].pExpr;
|
||||
opCompare.x.pRight = aListelem[i].pExpr;
|
||||
}else{
|
||||
pTest = aListelem[i].pExpr;
|
||||
}
|
||||
@@ -3364,7 +3380,8 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *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);
|
||||
@@ -3482,17 +3499,20 @@ static void exprCodeBetween(
|
||||
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);
|
||||
@@ -3543,7 +3563,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int 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;
|
||||
@@ -3552,7 +3573,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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;
|
||||
}
|
||||
@@ -3569,8 +3591,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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);
|
||||
@@ -3587,9 +3610,10 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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);
|
||||
@@ -3698,7 +3722,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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;
|
||||
}
|
||||
@@ -3707,7 +3732,8 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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;
|
||||
@@ -3725,8 +3751,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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);
|
||||
@@ -3743,9 +3770,10 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
|
||||
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);
|
||||
@@ -3848,10 +3876,16 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
|
||||
}
|
||||
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
|
||||
@@ -3916,7 +3950,7 @@ int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
|
||||
}
|
||||
if( pE2->op==TK_OR
|
||||
&& (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
|
||||
|| sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
|
||||
|| sqlite3ExprImpliesExpr(pE1, pE2->x.pRight, iTab) )
|
||||
){
|
||||
return 1;
|
||||
}
|
||||
@@ -4119,7 +4153,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
|
||||
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;
|
||||
|
||||
+4
-6
@@ -1606,7 +1606,7 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
}
|
||||
|
||||
/*
|
||||
** 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
|
||||
@@ -1614,13 +1614,11 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
||||
*/
|
||||
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);
|
||||
|
||||
+6
-2
@@ -942,8 +942,9 @@ expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -997,6 +998,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
||||
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);
|
||||
}
|
||||
@@ -1051,6 +1053,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.pList = Y;
|
||||
ExprSetProperty(A.pExpr, EP_xIsList);
|
||||
sqlite3ExprSetHeight(pParse, A.pExpr);
|
||||
}else{
|
||||
sqlite3ExprListDelete(pParse->db, Y);
|
||||
@@ -1118,6 +1121,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
||||
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);
|
||||
|
||||
+11
-7
@@ -197,7 +197,7 @@ int sqlite3MatchSpanName(
|
||||
** 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
|
||||
@@ -415,7 +415,7 @@ static int lookupName(
|
||||
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;
|
||||
@@ -495,8 +495,10 @@ static int lookupName(
|
||||
*/
|
||||
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 ){
|
||||
@@ -655,16 +657,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
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);
|
||||
}
|
||||
@@ -683,7 +687,7 @@ static int resolveExprStep(Walker *pWalker, Expr *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);
|
||||
|
||||
+16
-12
@@ -340,7 +340,7 @@ static void setJoinExpr(Expr *p, int iTable){
|
||||
ExprSetVVAProperty(p, EP_NoReduce);
|
||||
p->iRightJoinTable = (i16)iTable;
|
||||
setJoinExpr(p->pLeft, iTable);
|
||||
p = p->pRight;
|
||||
p = ExprUsesRight(p) ? p->x.pRight : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1562,7 +1562,8 @@ static int selectColumnsFromExprList(
|
||||
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) ){
|
||||
@@ -2994,17 +2995,19 @@ static Expr *substExpr(
|
||||
}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);
|
||||
}
|
||||
}
|
||||
@@ -4054,9 +4057,9 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
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 ){
|
||||
/*
|
||||
@@ -4079,7 +4082,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
|
||||
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.
|
||||
@@ -4376,7 +4379,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->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");
|
||||
@@ -4400,7 +4403,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
|
||||
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);
|
||||
}
|
||||
@@ -4424,7 +4427,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
||||
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);
|
||||
@@ -4899,7 +4902,8 @@ int sqlite3Select(
|
||||
}
|
||||
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;
|
||||
|
||||
+11
-5
@@ -1871,8 +1871,8 @@ struct Expr {
|
||||
*********************************************************************/
|
||||
|
||||
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;
|
||||
@@ -1882,13 +1882,13 @@ struct Expr {
|
||||
** 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[] */
|
||||
@@ -1914,7 +1914,6 @@ struct Expr {
|
||||
#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 */
|
||||
@@ -1923,6 +1922,9 @@ struct Expr {
|
||||
#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
|
||||
@@ -1933,6 +1935,10 @@ struct Expr {
|
||||
#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.
|
||||
|
||||
+4
-2
@@ -45,10 +45,12 @@ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
+52
-31
@@ -260,7 +260,8 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
|
||||
whereClauseInsert(pWC, pExpr, 0);
|
||||
}else{
|
||||
whereSplit(pWC, pExpr->pLeft, op);
|
||||
whereSplit(pWC, pExpr->pRight, op);
|
||||
assert( ExprUsesRight(pExpr) );
|
||||
whereSplit(pWC, pExpr->x.pRight, op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,11 +312,13 @@ static Bitmask exprTableUsage(WhereMaskSet *pMaskSet, Expr *p){
|
||||
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;
|
||||
@@ -382,15 +385,16 @@ static int allowedOp(int op){
|
||||
** 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
|
||||
@@ -398,7 +402,7 @@ static void exprCommute(Parse *pParse, Expr *pExpr){
|
||||
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 );
|
||||
@@ -459,7 +463,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
&& 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
|
||||
@@ -482,16 +487,16 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
|
||||
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]
|
||||
){
|
||||
@@ -1016,7 +1021,8 @@ static void exprAnalyzeOrTerm(
|
||||
** 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;
|
||||
@@ -1042,7 +1048,8 @@ static void exprAnalyzeOrTerm(
|
||||
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;
|
||||
}
|
||||
@@ -1052,7 +1059,7 @@ static void exprAnalyzeOrTerm(
|
||||
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 );
|
||||
@@ -1116,16 +1123,16 @@ static void exprAnalyze(
|
||||
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) ){
|
||||
@@ -1140,14 +1147,17 @@ static void exprAnalyze(
|
||||
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 */
|
||||
@@ -1673,7 +1683,8 @@ static void constructAutomaticIndex(
|
||||
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++;
|
||||
}
|
||||
@@ -2103,7 +2114,8 @@ static int whereRangeScanEst(
|
||||
/* 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 ){
|
||||
@@ -2118,7 +2130,8 @@ static int whereRangeScanEst(
|
||||
/* 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 ){
|
||||
@@ -2388,7 +2401,8 @@ static int codeEqualityTerm(
|
||||
|
||||
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);
|
||||
@@ -2571,7 +2585,8 @@ static int codeAllEqualityTerms(
|
||||
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);
|
||||
@@ -2848,7 +2863,8 @@ static Bitmask codeOneLoopStart(
|
||||
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);
|
||||
@@ -2939,7 +2955,8 @@ static Bitmask codeOneLoopStart(
|
||||
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);
|
||||
@@ -2962,7 +2979,8 @@ static Bitmask codeOneLoopStart(
|
||||
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{
|
||||
@@ -3126,7 +3144,8 @@ static Bitmask codeOneLoopStart(
|
||||
/* 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)
|
||||
@@ -3170,7 +3189,8 @@ static Bitmask codeOneLoopStart(
|
||||
*/
|
||||
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
|
||||
@@ -4229,7 +4249,8 @@ static int whereLoopAddBtreeIndex(
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user