Index: ext/rtree/rtree.c ================================================================== --- ext/rtree/rtree.c +++ ext/rtree/rtree.c @@ -1849,10 +1849,11 @@ ** sqlite uses an internal cost of 0.0). It is expected to return ** a single row. */ pIdxInfo->estimatedCost = 30.0; pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; return SQLITE_OK; } if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ u8 op; Index: src/delete.c ================================================================== --- src/delete.c +++ src/delete.c @@ -477,10 +477,13 @@ memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ) sqlite3VdbeAddOp1(v, OP_Close, iTabCur); +#endif }else{ if( pPk ){ /* Add the PK key for this row to the temporary table */ iKey = ++pParse->nMem; nKey = 0; /* Zero tells OP_Found to use a composite key */ Index: src/update.c ================================================================== --- src/update.c +++ src/update.c @@ -862,17 +862,18 @@ /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); + /* End the virtual table scan */ + sqlite3WhereEnd(pWInfo); } + /* Make sure the scan cursor is closed prior to doing the update */ + sqlite3VdbeAddOp1(v, OP_Close, iCsr); if( bOnePass==0 ){ - /* End the virtual table scan */ - sqlite3WhereEnd(pWInfo); - /* Begin scannning through the ephemeral table. */ addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); /* Extract arguments from the current row of the ephemeral table and ** invoke the VUpdate method. */ @@ -888,11 +889,11 @@ /* End of the ephemeral table scan. Or, if using the onepass strategy, ** jump to here if the scan visited zero rows. */ if( bOnePass==0 ){ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); - sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); + sqlite3VdbeAddOp1(v, OP_Close, ephemTab); }else{ sqlite3WhereEnd(pWInfo); } } #endif /* SQLITE_OMIT_VIRTUALTABLE */