diff options
author | drh <drh@noemail.net> | 2020-01-04 19:19:54 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2020-01-04 19:19:54 +0000 |
commit | 0ad4f792a9ad661021fbca0c845711675dba1fcb (patch) | |
tree | 8e99b1c8ec82cb0d02ba36bd3596621ac7b08ca2 /src | |
parent | af232366605cb2a6ef192c58daf3a99d2ecb4ff2 (diff) | |
parent | 2e5beddb34c20868fb45ff5e3bbb6fb9e603042c (diff) | |
download | sqlite-0ad4f792a9ad661021fbca0c845711675dba1fcb.tar.gz sqlite-0ad4f792a9ad661021fbca0c845711675dba1fcb.zip |
Merge all fixes and enhancements from trunk.
FossilOrigin-Name: b878c30f03e895bbc5c4c99c0f727d49093bb78bdc275593cf4852148579ae69
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 2 | ||||
-rw-r--r-- | src/dbstat.c | 10 | ||||
-rw-r--r-- | src/vdbe.c | 22 | ||||
-rw-r--r-- | src/where.c | 24 | ||||
-rw-r--r-- | src/whereInt.h | 8 | ||||
-rw-r--r-- | src/wherecode.c | 2 |
6 files changed, 50 insertions, 18 deletions
diff --git a/src/btree.c b/src/btree.c index 9c42d3375..53ea3148b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7104,7 +7104,7 @@ static int pageFreeArray( } pFree = pCell; szFree = sz; - if( NEVER(pFree+sz>pEnd) ) return 0; + if( pFree+sz>pEnd ) return 0; }else{ pFree = pCell; szFree += sz; diff --git a/src/dbstat.c b/src/dbstat.c index 262da7c37..d0ce82e8c 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -237,18 +237,14 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ i = 0; if( iSchema>=0 ){ pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i; - pIdxInfo->aConstraintUsage[iSchema].omit = 1; pIdxInfo->idxNum |= 0x01; } if( iName>=0 ){ pIdxInfo->aConstraintUsage[iName].argvIndex = ++i; - pIdxInfo->aConstraintUsage[iName].omit = 1; pIdxInfo->idxNum |= 0x02; } if( iAgg>=0 ){ pIdxInfo->aConstraintUsage[iAgg].argvIndex = ++i; - /* As of ticket [727074e2], this constraint is not omitted. */ - /* pIdxInfo->aConstraintUsage[iAgg].omit = 1; */ pIdxInfo->idxNum |= 0x04; } pIdxInfo->estimatedCost = 1.0; @@ -704,9 +700,9 @@ static int statFilter( const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]); pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase); if( pCsr->iDb<0 ){ - sqlite3_free(pCursor->pVtab->zErrMsg); - pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase); - return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT; + pCsr->iDb = 0; + pCsr->isEof = 1; + return SQLITE_OK; } }else{ pCsr->iDb = pTab->iDb; diff --git a/src/vdbe.c b/src/vdbe.c index 5479a311b..b677285a4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4374,7 +4374,7 @@ seek_not_found: ** Synopsis: seekHit=P2 ** ** Set the seekHit flag on cursor P1 to the value in P2. -** The seekHit flag is used by the IfNoHope opcode. +* The seekHit flag is used by the IfNoHope opcode. ** ** P1 must be a valid b-tree cursor. P2 must be a boolean value, ** either 0 or 1. @@ -4389,6 +4389,20 @@ case OP_SeekHit: { break; } +/* Opcode: IfNotOpen P1 P2 * * * +** Synopsis: if( !csr[P1] ) goto P2 +** +** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. +*/ +case OP_IfNotOpen: { /* jump */ + assert( pOp->p1>=0 && pOp->p1<p->nCursor ); + VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2); + if( !p->apCsr[pOp->p1] ){ + goto jump_to_p2_and_check_for_interrupt; + } + break; +} + /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -7914,6 +7928,12 @@ default: { /* This is really OP_Noop, OP_Explain */ if( opProperty & OPFLG_OUT3 ){ registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); } + if( opProperty==0xff ){ + /* Never happens. This code exists to avoid a harmless linkage + ** warning aboud sqlite3VdbeRegisterDump() being defined but not + ** used. */ + sqlite3VdbeRegisterDump(p); + } } #endif /* SQLITE_DEBUG */ #endif /* NDEBUG */ diff --git a/src/where.c b/src/where.c index 0877b80dd..075276168 100644 --- a/src/where.c +++ b/src/where.c @@ -5273,10 +5273,26 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); - sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, - sqlite3VdbeCurrentAddr(v)+2, - pIn->iBase, pIn->nPrefix); - VdbeCoverage(v); + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0), + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + } + if( pLevel->iLeftJoin ){ + /* For LEFT JOIN queries, cursor pIn->iCur may not have been + ** opened yet. This occurs for WHERE clauses such as + ** "a = ? AND b IN (...)", where the index is on (a, b). If + ** the RHS of the (a=?) is NULL, then the "b IN (...)" may + ** never have been coded, but the body of the loop run to + ** return the null-row. So, if the cursor is not open yet, + ** jump over the OP_Next or OP_Prev instruction about to + ** be coded. */ + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 + ); + VdbeCoverage(v); + } } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); diff --git a/src/whereInt.h b/src/whereInt.h index ad433652f..dbc6f1872 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -473,10 +473,10 @@ struct WhereInfo { i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ - u8 bDeferredSeek : 1; /* Uses OP_DeferredSeek */ - u8 untestedTerms : 1; /* Not all WHERE terms resolved by outer loop */ - u8 bOrderedInnerLoop : 1; /* True if only the inner-most loop is ordered */ - u8 sorted : 1; /* True if really sorted (not just grouped) */ + unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ + unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ + unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ + unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ WhereLoop *pLoops; /* List of all WhereLoop objects */ diff --git a/src/wherecode.c b/src/wherecode.c index beb23e0c1..03e393498 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -593,7 +593,7 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; - if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + if( iEq>0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; pLoop->wsFlags |= WHERE_IN_EARLYOUT; |