1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Fix some cases involving row values and virtual tables.

FossilOrigin-Name: 156a41f30a0afd9a70e6c26470dcc468a11bd402
This commit is contained in:
dan
2016-08-08 20:15:41 +00:00
parent 1d9bc9b7a0
commit 6256c1c242
4 changed files with 41 additions and 16 deletions

View File

@ -1,5 +1,5 @@
C Fix\sthe\sEXPLAIN\sQUERY\sPLAN\soutput\sfor\srow\svalue\srange\sconstaints\sthat\suse\san\sindex. C Fix\ssome\scases\sinvolving\srow\svalues\sand\svirtual\stables.
D 2016-08-08T18:42:08.741 D 2016-08-08T20:15:41.766
F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088 F Makefile.in cfd8fb987cd7a6af046daa87daa146d5aad0e088
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@ -463,9 +463,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2 F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c f60310d9fa2dd275698f3a768d2c63917353f22d F src/where.c 457a2c8cd94a1dbe8d2e5113f6078f2e6b9067d5
F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
F src/wherecode.c c24645572eba538c04c5ff8b8f6e9c0278107563 F src/wherecode.c 92202261a6e41f897a595417c5b0c75c8acf713d
F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094 F src/whereexpr.c 4a8cefc7c122132ac9f3ed125c61629a0e3de094
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@ -1514,7 +1514,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0e927a7e0250a65fd8e97b322cd69e93fadd13f0 P bb60651163553c5e46bf7b2805490570cea647b8
R c87cf26a8b83e76d6d485dba242f3437 R 874f48b6764b2a2fd58ccae5d488cbf6
U dan U dan
Z eb833a77a96d41ac0d9eabbd9e7d8788 Z 25cd4c4731603d2ae10da74afc2be17b

View File

@ -1 +1 @@
bb60651163553c5e46bf7b2805490570cea647b8 156a41f30a0afd9a70e6c26470dcc468a11bd402

View File

@ -826,7 +826,8 @@ static sqlite3_index_info *allocateIndexInfo(
WhereClause *pWC, WhereClause *pWC,
Bitmask mUnusable, /* Ignore terms with these prereqs */ Bitmask mUnusable, /* Ignore terms with these prereqs */
struct SrcList_item *pSrc, struct SrcList_item *pSrc,
ExprList *pOrderBy ExprList *pOrderBy,
u16 *pmNoOmit /* Mask of terms not to omit */
){ ){
int i, j; int i, j;
int nTerm; int nTerm;
@ -836,6 +837,7 @@ static sqlite3_index_info *allocateIndexInfo(
WhereTerm *pTerm; WhereTerm *pTerm;
int nOrderBy; int nOrderBy;
sqlite3_index_info *pIdxInfo; sqlite3_index_info *pIdxInfo;
u16 mNoOmit = 0;
/* Count the number of possible WHERE clause constraints referring /* Count the number of possible WHERE clause constraints referring
** to this virtual table */ ** to this virtual table */
@ -924,6 +926,15 @@ static sqlite3_index_info *allocateIndexInfo(
assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH ); assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) ); assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
&& sqlite3ExprIsVector(pTerm->pExpr->pRight)
){
if( i<16 ) mNoOmit |= (1 << i);
if( op==WO_LT ) pIdxCons[j].op = WO_LE;
if( op==WO_GT ) pIdxCons[j].op = WO_GE;
}
j++; j++;
} }
for(i=0; i<nOrderBy; i++){ for(i=0; i<nOrderBy; i++){
@ -932,6 +943,7 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
} }
*pmNoOmit = mNoOmit;
return pIdxInfo; return pIdxInfo;
} }
@ -2943,6 +2955,7 @@ static int whereLoopAddVirtualOne(
Bitmask mUsable, /* Mask of usable tables */ Bitmask mUsable, /* Mask of usable tables */
u16 mExclude, /* Exclude terms using these operators */ u16 mExclude, /* Exclude terms using these operators */
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
u16 mNoOmit, /* Do not omit these constraints */
int *pbIn /* OUT: True if plan uses an IN(...) op */ int *pbIn /* OUT: True if plan uses an IN(...) op */
){ ){
WhereClause *pWC = pBuilder->pWC; WhereClause *pWC = pBuilder->pWC;
@ -3031,6 +3044,7 @@ static int whereLoopAddVirtualOne(
} }
} }
} }
pNew->u.vtab.omitMask &= ~mNoOmit;
pNew->nLTerm = mxTerm+1; pNew->nLTerm = mxTerm+1;
assert( pNew->nLTerm<=pNew->nLSlot ); assert( pNew->nLTerm<=pNew->nLSlot );
@ -3104,6 +3118,7 @@ static int whereLoopAddVirtual(
int bIn; /* True if plan uses IN(...) operator */ int bIn; /* True if plan uses IN(...) operator */
WhereLoop *pNew; WhereLoop *pNew;
Bitmask mBest; /* Tables used by best possible plan */ Bitmask mBest; /* Tables used by best possible plan */
u16 mNoOmit;
assert( (mPrereq & mUnusable)==0 ); assert( (mPrereq & mUnusable)==0 );
pWInfo = pBuilder->pWInfo; pWInfo = pBuilder->pWInfo;
@ -3112,7 +3127,8 @@ static int whereLoopAddVirtual(
pNew = pBuilder->pNew; pNew = pBuilder->pNew;
pSrc = &pWInfo->pTabList->a[pNew->iTab]; pSrc = &pWInfo->pTabList->a[pNew->iTab];
assert( IsVirtual(pSrc->pTab) ); assert( IsVirtual(pSrc->pTab) );
p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy); p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
&mNoOmit);
if( p==0 ) return SQLITE_NOMEM_BKPT; if( p==0 ) return SQLITE_NOMEM_BKPT;
pNew->rSetup = 0; pNew->rSetup = 0;
pNew->wsFlags = WHERE_VIRTUALTABLE; pNew->wsFlags = WHERE_VIRTUALTABLE;
@ -3126,7 +3142,7 @@ static int whereLoopAddVirtual(
/* First call xBestIndex() with all constraints usable. */ /* First call xBestIndex() with all constraints usable. */
WHERETRACE(0x40, (" VirtualOne: all usable\n")); WHERETRACE(0x40, (" VirtualOne: all usable\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, &bIn); rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
/* If the call to xBestIndex() with all terms enabled produced a plan /* If the call to xBestIndex() with all terms enabled produced a plan
** that does not require any source tables (IOW: a plan with mBest==0), ** that does not require any source tables (IOW: a plan with mBest==0),
@ -3143,7 +3159,8 @@ static int whereLoopAddVirtual(
** xBestIndex again, this time with IN(...) terms disabled. */ ** xBestIndex again, this time with IN(...) terms disabled. */
if( bIn ){ if( bIn ){
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn); rc = whereLoopAddVirtualOne(
pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
assert( bIn==0 ); assert( bIn==0 );
mBestNoIn = pNew->prereq & ~mPrereq; mBestNoIn = pNew->prereq & ~mPrereq;
if( mBestNoIn==0 ){ if( mBestNoIn==0 ){
@ -3169,7 +3186,8 @@ static int whereLoopAddVirtual(
if( mNext==mBest || mNext==mBestNoIn ) continue; if( mNext==mBest || mNext==mBestNoIn ) continue;
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn); rc = whereLoopAddVirtualOne(
pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
if( pNew->prereq==mPrereq ){ if( pNew->prereq==mPrereq ){
seenZero = 1; seenZero = 1;
if( bIn==0 ) seenZeroNoIN = 1; if( bIn==0 ) seenZeroNoIN = 1;
@ -3181,7 +3199,8 @@ static int whereLoopAddVirtual(
** usable), make a call here with all source tables disabled */ ** usable), make a call here with all source tables disabled */
if( rc==SQLITE_OK && seenZero==0 ){ if( rc==SQLITE_OK && seenZero==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled\n")); WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn); rc = whereLoopAddVirtualOne(
pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
if( bIn==0 ) seenZeroNoIN = 1; if( bIn==0 ) seenZeroNoIN = 1;
} }
@ -3190,7 +3209,8 @@ static int whereLoopAddVirtual(
** operator, make a final call to obtain one here. */ ** operator, make a final call to obtain one here. */
if( rc==SQLITE_OK && seenZeroNoIN==0 ){ if( rc==SQLITE_OK && seenZeroNoIN==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn); rc = whereLoopAddVirtualOne(
pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
} }
} }

View File

@ -1099,7 +1099,12 @@ Bitmask sqlite3WhereCodeOneLoopStart(
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
addrNotFound = pLevel->addrNxt; addrNotFound = pLevel->addrNxt;
}else{ }else{
sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget); Expr *pRight = pTerm->pExpr->pRight;
if( pRight->op==TK_SELECT_COLUMN ){
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
}else{
codeExprOrVector(pParse, pRight, iTarget, 1);
}
} }
} }
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);