aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-01-04 19:19:54 +0000
committerdrh <drh@noemail.net>2020-01-04 19:19:54 +0000
commit0ad4f792a9ad661021fbca0c845711675dba1fcb (patch)
tree8e99b1c8ec82cb0d02ba36bd3596621ac7b08ca2 /src
parentaf232366605cb2a6ef192c58daf3a99d2ecb4ff2 (diff)
parent2e5beddb34c20868fb45ff5e3bbb6fb9e603042c (diff)
downloadsqlite-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.c2
-rw-r--r--src/dbstat.c10
-rw-r--r--src/vdbe.c22
-rw-r--r--src/where.c24
-rw-r--r--src/whereInt.h8
-rw-r--r--src/wherecode.c2
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;