-C Add\stest\scases\sto\sthe\sONEPASS\soptimization\scorruption\sproblem\sfixed\sby\sthe\nprevious\scheck-in.
-D 2015-09-28T15:08:28.795
+C Changes\sto\sallow\sDELETE\soperations\son\svirtual\stables\sto\suse\sthe\sonepass\sstrategy\sunder\ssome\scircumstances.
+D 2015-09-28T15:20:58.913
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2143eeef6d0cc26006ae5fc4bb242a4a8b973412
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/btree.c 164583151135a3764672c2c25aa8e4fa06bdb12b
F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7
F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0
-F src/build.c edc5a29cd55257b05be837c3613e2cade02b3e03
+F src/build.c 361f58b73aad7804f5706bf62d210bd9cd608041
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b
F src/date.c fb1c99172017dcc8e237339132c91a21a0788584
F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7
-F src/delete.c 371df4fc86e96efeaed3d37565aef77f956be109
+F src/delete.c b454df59d57cb3f07118dfc68821760593fcaab3
F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 33230303f5f32430ee971a6fcc6a370e4a93ae1a
F src/shell.c a11b20da4c6630e0e8f83c47ce36f717dd0422f0
-F src/sqlite.h.in 02f6ed7de3a96d10bd1e6e5803e4e4b786dff014
+F src/sqlite.h.in eade8bcc0456ff4d3f7ecfbbd3c4eec117314f26
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 64350bf36833a56ad675e27392a913f417c5c308
F src/sqliteInt.h 5afc6e50402be1e0a870f28e1cd8b32eb9db590f
F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba
-F src/where.c f2c4905e47fe80043a0c45f374f555615da365ba
+F src/where.c d07fb77010949be9b96e9120b4653712bf9f74ae
F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647
F src/wherecode.c 7660e1ad16817a921b099af553f3e1349352d16f
F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 9d057f52217e7ef9c3f3eb84117abe3365503f44
-R 075466467a3c577c7bea65d16a397b4e
-U drh
-Z a775dc5a399b71fca215b8951f694541
+P 5c14d447055bb337428eb1fe0a2934abee381829
+R 3d1a8d879c965d0f75999b9c5903a435
+T *branch * vtab-onepass
+T *sym-vtab-onepass *
+T -sym-trunk *
+U dan
+Z 049fa8c468f3a0165cbcd245b0299bac
-5c14d447055bb337428eb1fe0a2934abee381829
\ No newline at end of file
+e73f919fae1833c6ffb36eddbc76d9a8d9324214
\ No newline at end of file
db->aDb[iDb].pSchema->iGeneration /* P4 */
);
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
+ VdbeComment((v,
+ "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<pParse->nVtabLock; i++){
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
- assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
+ assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
/* Keep track of the number of rows to be deleted */
/* If this DELETE cannot use the ONEPASS strategy, this is the
** end of the WHERE loop */
- if( eOnePass!=ONEPASS_OFF ){
+ if( eOnePass!=ONEPASS_OFF && !IsVirtual(pTab) ){
addrBypass = sqlite3VdbeMakeLabel(v);
}else{
sqlite3WhereEnd(pWInfo);
*/
if( eOnePass!=ONEPASS_OFF ){
assert( nKey==nPk ); /* OP_Found will use an unpacked key */
- if( aToOpen[iDataCur-iTabCur] ){
+ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 || pTab->pSelect!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
VdbeCoverage(v);
sqlite3VtabMakeWritable(pParse, pTab);
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
+ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
sqlite3MayAbort(pParse);
+ if( eOnePass==ONEPASS_SINGLE && pParse==sqlite3ParseToplevel(pParse) ){
+ pParse->isMultiWrite = 0;
+ }
}else
#endif
{
/* End of the loop over all rowids/primary-keys. */
if( eOnePass!=ONEPASS_OFF ){
- sqlite3VdbeResolveLabel(v, addrBypass);
- sqlite3WhereEnd(pWInfo);
+ if( !IsVirtual(pTab) ){
+ sqlite3VdbeResolveLabel(v, addrBypass);
+ sqlite3WhereEnd(pWInfo);
+ }
}else if( pPk ){
sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrLoop);
double estimatedCost; /* Estimated cost of using this index */
/* Fields below are only available in SQLite 3.8.2 and later */
sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
+ /* Fields below are only available in SQLite 3.8.12 and later */
+ int flags; /* Mask of SQLITE_INDEX_SCAN_* flags */
};
+/*
+** CAPI3REF: Virtual Table Scan Flags
+*/
+#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
+
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
pIdxInfo->orderByConsumed = 0;
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
+ pIdxInfo->flags = 0;
rc = vtabBestIndex(pParse, pTab, pIdxInfo);
if( rc ) goto whereLoopAddVtab_exit;
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
** (2) Multiple outputs from a single IN value will not merge
** together. */
pIdxInfo->orderByConsumed = 0;
+ pIdxInfo->flags &= ~SQLITE_INDEX_SCAN_UNIQUE;
}
}
}
pNew->rSetup = 0;
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+
+ /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
+ ** that the scan will visit at most one row. Clear it otherwise. */
+ if( pIdxInfo->flags & SQLITE_INDEX_SCAN_UNIQUE ){
+ pNew->wsFlags |= WHERE_ONEROW;
+ }else{
+ pNew->wsFlags &= ~WHERE_ONEROW;
+ }
whereLoopInsert(pBuilder, pNew);
if( pNew->u.vtab.needFree ){
sqlite3_free(pNew->u.vtab.idxStr);