Add a NEVER() to the code generator. Change the parameter name "mExtra"
to "mPrereq" in the query planner, to more closely reflect its meaning. FossilOrigin-Name: 721ae51e443647291f3a8f7f2128aa410fee2682
This commit is contained in:
parent
fb826b8c13
commit
599d576456
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Changes\sso\sthat\ssome\sassert()s\sin\sthe\svirtual\stable\squery\splanner\sare\ncorrect\seven\sfollowing\san\sOOM\serror.
|
||||
D 2016-03-08T00:39:58.482
|
||||
C Add\sa\sNEVER()\sto\sthe\scode\sgenerator.\s\sChange\sthe\sparameter\sname\s"mExtra"\nto\s"mPrereq"\sin\sthe\squery\splanner,\sto\smore\sclosely\sreflect\sits\smeaning.
|
||||
D 2016-03-08T01:11:51.292
|
||||
F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
|
||||
@ -428,9 +428,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
|
||||
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
|
||||
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
|
||||
F src/where.c ccc62c39af1e6340f6af36fcf68efb96482d4c3a
|
||||
F src/where.c 3787158e3b365eec7553d6f1d6596b7fa64ea6de
|
||||
F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
|
||||
F src/wherecode.c 36ea3526e4d297b8438453689176c6543fe67b3a
|
||||
F src/wherecode.c 863aedf086131743763c1960637fde904eadc442
|
||||
F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
|
||||
@ -1454,7 +1454,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P cddf69dbc46f10ee7e87538dd850e086386b544c
|
||||
R eadc238ea6455af5bdaa5c7ea27cb6ae
|
||||
P 9805f6f85211dcb5a0ab3ceca204e6f2e48530ea
|
||||
R ee7409507ed80149a169811d9e037a32
|
||||
U drh
|
||||
Z 93924e30a271561dfe424f31cad070b7
|
||||
Z 2ec5edc1158dca51232e491f1a3a4594
|
||||
|
@ -1 +1 @@
|
||||
9805f6f85211dcb5a0ab3ceca204e6f2e48530ea
|
||||
721ae51e443647291f3a8f7f2128aa410fee2682
|
66
src/where.c
66
src/where.c
@ -2554,7 +2554,7 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
|
||||
*/
|
||||
static int whereLoopAddBtree(
|
||||
WhereLoopBuilder *pBuilder, /* WHERE clause information */
|
||||
Bitmask mExtra /* Extra prerequesites for using this table */
|
||||
Bitmask mPrereq /* Extra prerequesites for using this table */
|
||||
){
|
||||
WhereInfo *pWInfo; /* WHERE analysis context */
|
||||
Index *pProbe; /* An index we are evaluating */
|
||||
@ -2654,7 +2654,7 @@ static int whereLoopAddBtree(
|
||||
pNew->nOut = 43; assert( 43==sqlite3LogEst(20) );
|
||||
pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
|
||||
pNew->wsFlags = WHERE_AUTO_INDEX;
|
||||
pNew->prereq = mExtra | pTerm->prereqRight;
|
||||
pNew->prereq = mPrereq | pTerm->prereqRight;
|
||||
rc = whereLoopInsert(pBuilder, pNew);
|
||||
}
|
||||
}
|
||||
@ -2675,7 +2675,7 @@ static int whereLoopAddBtree(
|
||||
pNew->nLTerm = 0;
|
||||
pNew->iSortIdx = 0;
|
||||
pNew->rSetup = 0;
|
||||
pNew->prereq = mExtra;
|
||||
pNew->prereq = mPrereq;
|
||||
pNew->nOut = rSize;
|
||||
pNew->u.btree.pIndex = pProbe;
|
||||
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
|
||||
@ -2762,7 +2762,7 @@ static int whereLoopAddBtree(
|
||||
** * It is not one of the operators specified in the mExclude mask passed
|
||||
** as the fourth argument (which in practice is either WO_IN or 0).
|
||||
**
|
||||
** Argument mExtra is a mask of tables that must be scanned before the
|
||||
** Argument mPrereq is a mask of tables that must be scanned before the
|
||||
** virtual table in question. These are added to the plans prerequisites
|
||||
** before it is added to pBuilder.
|
||||
**
|
||||
@ -2771,7 +2771,7 @@ static int whereLoopAddBtree(
|
||||
*/
|
||||
static int whereLoopAddVirtualOne(
|
||||
WhereLoopBuilder *pBuilder,
|
||||
Bitmask mExtra, /* Mask of tables that must be used. */
|
||||
Bitmask mPrereq, /* Mask of tables that must be used. */
|
||||
Bitmask mUsable, /* Mask of usable prereqs */
|
||||
u16 mExclude, /* Exclude terms for this operator */
|
||||
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
|
||||
@ -2788,9 +2788,9 @@ static int whereLoopAddVirtualOne(
|
||||
struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab];
|
||||
int nConstraint = pIdxInfo->nConstraint;
|
||||
|
||||
assert( (mUsable & mExtra)==mExtra );
|
||||
assert( (mUsable & mPrereq)==mPrereq );
|
||||
*pbIn = 0;
|
||||
pNew->prereq = mExtra;
|
||||
pNew->prereq = mPrereq;
|
||||
|
||||
/* Set the usable flag on the subset of constraints identified by
|
||||
** arguments mUsable and mExclude. */
|
||||
@ -2897,8 +2897,8 @@ static int whereLoopAddVirtualOne(
|
||||
** Add all WhereLoop objects for a table of the join identified by
|
||||
** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
|
||||
**
|
||||
** If there are no LEFT or CROSS JOIN joins in the query, both mExtra and
|
||||
** mUnusable are set to 0. Otherwise, mExtra is a mask of all FROM clause
|
||||
** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and
|
||||
** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause
|
||||
** entries that occur before the virtual table in the FROM clause and are
|
||||
** separated from it by at least one LEFT or CROSS JOIN. Similarly, the
|
||||
** mUnusable mask contains all FROM clause entries that occur after the
|
||||
@ -2909,18 +2909,18 @@ static int whereLoopAddVirtualOne(
|
||||
**
|
||||
** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6;
|
||||
**
|
||||
** then mExtra corresponds to (t1, t2) and mUnusable to (t5, t6).
|
||||
** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6).
|
||||
**
|
||||
** All the tables in mExtra must be scanned before the current virtual
|
||||
** All the tables in mPrereq must be scanned before the current virtual
|
||||
** table. So any terms for which all prerequisites are satisfied by
|
||||
** mExtra may be specified as "usable" in all calls to xBestIndex.
|
||||
** mPrereq may be specified as "usable" in all calls to xBestIndex.
|
||||
** Conversely, all tables in mUnusable must be scanned after the current
|
||||
** virtual table, so any terms for which the prerequisites overlap with
|
||||
** mUnusable should always be configured as "not-usable" for xBestIndex.
|
||||
*/
|
||||
static int whereLoopAddVirtual(
|
||||
WhereLoopBuilder *pBuilder, /* WHERE clause information */
|
||||
Bitmask mExtra, /* Tables that must be scanned before this one */
|
||||
Bitmask mPrereq, /* Tables that must be scanned before this one */
|
||||
Bitmask mUnusable /* Tables that must be scanned after this one */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
@ -2934,7 +2934,7 @@ static int whereLoopAddVirtual(
|
||||
WhereLoop *pNew;
|
||||
Bitmask mBest; /* Tables used by best possible plan */
|
||||
|
||||
assert( (mExtra & mUnusable)==0 );
|
||||
assert( (mPrereq & mUnusable)==0 );
|
||||
pWInfo = pBuilder->pWInfo;
|
||||
pParse = pWInfo->pParse;
|
||||
pWC = pBuilder->pWC;
|
||||
@ -2954,8 +2954,8 @@ static int whereLoopAddVirtual(
|
||||
}
|
||||
|
||||
/* First call xBestIndex() with all constraints usable. */
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mExtra, (Bitmask)(-1), 0, p, &bIn);
|
||||
mBest = pNew->prereq & ~mExtra;
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, (Bitmask)(-1), 0, p, &bIn);
|
||||
mBest = pNew->prereq & ~mPrereq;
|
||||
|
||||
/* If the call to xBestIndex() with all terms enabled produced a plan
|
||||
** that does not require any source tables, there is no point in making
|
||||
@ -2971,15 +2971,15 @@ static int whereLoopAddVirtual(
|
||||
/* If the plan produced by the earlier call uses an IN(...) term, call
|
||||
** xBestIndex again, this time with IN(...) terms disabled. */
|
||||
if( rc==SQLITE_OK && bIn ){
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mExtra, (Bitmask)-1, WO_IN, p,&bIn);
|
||||
mBestNoIn = pNew->prereq & ~mExtra;
|
||||
rc = whereLoopAddVirtualOne(pBuilder,mPrereq,(Bitmask)-1,WO_IN,p,&bIn);
|
||||
mBestNoIn = pNew->prereq & ~mPrereq;
|
||||
if( mBestNoIn==0 ){
|
||||
seenZero = 1;
|
||||
if( bIn==0 ) seenZeroNoIN = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call xBestIndex once for each distinct value of (prereqRight & ~mExtra)
|
||||
/* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq)
|
||||
** in the set of terms that apply to the current virtual table. */
|
||||
while( rc==SQLITE_OK ){
|
||||
int i;
|
||||
@ -2987,15 +2987,15 @@ static int whereLoopAddVirtual(
|
||||
assert( mNext>0 );
|
||||
for(i=0; i<nConstraint; i++){
|
||||
Bitmask mThis = (
|
||||
pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mExtra
|
||||
pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
|
||||
);
|
||||
if( mThis>mPrev && mThis<mNext ) mNext = mThis;
|
||||
}
|
||||
mPrev = mNext;
|
||||
if( mNext==(Bitmask)(-1) ) break;
|
||||
if( mNext==mBest || mNext==mBestNoIn ) continue;
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mExtra, mNext|mExtra, 0, p, &bIn);
|
||||
if( pNew->prereq==mExtra ){
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn);
|
||||
if( pNew->prereq==mPrereq ){
|
||||
seenZero = 1;
|
||||
if( bIn==0 ) seenZeroNoIN = 1;
|
||||
}
|
||||
@ -3005,7 +3005,7 @@ static int whereLoopAddVirtual(
|
||||
** that requires no source tables at all (i.e. one guaranteed to be
|
||||
** usable), make a call here with all source tables disabled */
|
||||
if( rc==SQLITE_OK && seenZero==0 ){
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mExtra, mExtra, 0, p, &bIn);
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn);
|
||||
if( bIn==0 ) seenZeroNoIN = 1;
|
||||
}
|
||||
|
||||
@ -3013,7 +3013,7 @@ static int whereLoopAddVirtual(
|
||||
** that requires no source tables at all and does not use an IN(...)
|
||||
** operator, make a final call to obtain one here. */
|
||||
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mExtra, mExtra, WO_IN, p, &bIn);
|
||||
rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3029,7 +3029,7 @@ static int whereLoopAddVirtual(
|
||||
*/
|
||||
static int whereLoopAddOr(
|
||||
WhereLoopBuilder *pBuilder,
|
||||
Bitmask mExtra,
|
||||
Bitmask mPrereq,
|
||||
Bitmask mUnusable
|
||||
){
|
||||
WhereInfo *pWInfo = pBuilder->pWInfo;
|
||||
@ -3090,14 +3090,14 @@ static int whereLoopAddOr(
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pItem->pTab) ){
|
||||
rc = whereLoopAddVirtual(&sSubBuild, mExtra, mUnusable);
|
||||
rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
rc = whereLoopAddBtree(&sSubBuild, mExtra);
|
||||
rc = whereLoopAddBtree(&sSubBuild, mPrereq);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = whereLoopAddOr(&sSubBuild, mExtra, mUnusable);
|
||||
rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
|
||||
}
|
||||
assert( rc==SQLITE_OK || sCur.n==0 );
|
||||
if( sCur.n==0 ){
|
||||
@ -3154,7 +3154,7 @@ static int whereLoopAddOr(
|
||||
*/
|
||||
static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
WhereInfo *pWInfo = pBuilder->pWInfo;
|
||||
Bitmask mExtra = 0;
|
||||
Bitmask mPrereq = 0;
|
||||
Bitmask mPrior = 0;
|
||||
int iTab;
|
||||
SrcList *pTabList = pWInfo->pTabList;
|
||||
@ -3175,7 +3175,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
|
||||
/* This condition is true when pItem is the FROM clause term on the
|
||||
** right-hand-side of a LEFT or CROSS JOIN. */
|
||||
mExtra = mPrior;
|
||||
mPrereq = mPrior;
|
||||
}
|
||||
priorJointype = pItem->fg.jointype;
|
||||
if( IsVirtual(pItem->pTab) ){
|
||||
@ -3185,12 +3185,12 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
|
||||
mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
|
||||
}
|
||||
}
|
||||
rc = whereLoopAddVirtual(pBuilder, mExtra, mUnusable);
|
||||
rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable);
|
||||
}else{
|
||||
rc = whereLoopAddBtree(pBuilder, mExtra);
|
||||
rc = whereLoopAddBtree(pBuilder, mPrereq);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = whereLoopAddOr(pBuilder, mExtra, mUnusable);
|
||||
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
|
||||
}
|
||||
mPrior |= pNew->maskSelf;
|
||||
if( rc || db->mallocFailed ) break;
|
||||
|
@ -882,7 +882,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
for(j=0; j<nConstraint; j++){
|
||||
int iTarget = iReg+j+2;
|
||||
pTerm = pLoop->aLTerm[j];
|
||||
if( pTerm==0 ) continue;
|
||||
if( NEVER(pTerm==0) ) continue;
|
||||
if( pTerm->eOperator & WO_IN ){
|
||||
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
|
||||
addrNotFound = pLevel->addrNxt;
|
||||
|
Loading…
x
Reference in New Issue
Block a user