mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Fix some cases involving row values and virtual tables.
FossilOrigin-Name: 156a41f30a0afd9a70e6c26470dcc468a11bd402
This commit is contained in:
14
manifest
14
manifest
@ -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
|
||||||
|
@ -1 +1 @@
|
|||||||
bb60651163553c5e46bf7b2805490570cea647b8
|
156a41f30a0afd9a70e6c26470dcc468a11bd402
|
34
src/where.c
34
src/where.c
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user