1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-18 10:21:03 +03:00

For UPDATE and DELETE, use OP_DeferredSeek always. If the seek must later

be resolved, add the OP_FinishSeek opcode after all WHERE clause terms have
been processed.  This obviates the need for the WHERE_SEEK_TABLE and
WHERE_SEEK_UNIQ_TABLE flags to sqlite3WhereBegin() and the ensuing
complication, and it allows the covering index optimization to be used
further into WHERE clause processing.

FossilOrigin-Name: a495f60d315e34b1a1bc5fb1336e05047add52c8fb2710b577c97b10a5e734f6
This commit is contained in:
drh
2020-08-14 20:04:26 +00:00
parent 5e6d90fe15
commit 68c0c71065
6 changed files with 23 additions and 38 deletions

View File

@@ -1909,17 +1909,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)
|| ( (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)!=0
&& (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) )
){
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
VdbeCoverage(v);
}else{
codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
}
codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
}else if( iCur!=iIdxCur ){
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
@@ -2046,7 +2036,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
int iRetInit; /* Address of regReturn init */
int untestedTerms = 0; /* Some terms not completely tested */
int ii; /* Loop counter */
u16 wctrlFlags; /* Flags for sub-WHERE clause */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
Table *pTab = pTabItem->pTab;
@@ -2147,7 +2136,6 @@ Bitmask sqlite3WhereCodeOneLoopStart(
** eliminating duplicates from other WHERE clauses, the action for each
** sub-WHERE clause is to to invoke the main loop body as a subroutine.
*/
wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE);
ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR"));
for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii];
@@ -2166,7 +2154,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
wctrlFlags, iCovCur);
WHERE_OR_SUBCLAUSE, iCovCur);
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){
WhereLoop *pSubLoop;
@@ -2264,6 +2252,9 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}else{
pCov = 0;
}
if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){
pWInfo->bDeferredSeek = 1;
}
/* Finish the loop through table entries that match term pOrTerm. */
sqlite3WhereEnd(pSubWInfo);