]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes to allow DELETE operations on virtual tables to use the onepass strategy...
authordan <dan@noemail.net>
Mon, 28 Sep 2015 15:20:58 +0000 (15:20 +0000)
committerdan <dan@noemail.net>
Mon, 28 Sep 2015 15:20:58 +0000 (15:20 +0000)
FossilOrigin-Name: e73f919fae1833c6ffb36eddbc76d9a8d9324214

manifest
manifest.uuid
src/build.c
src/delete.c
src/sqlite.h.in
src/where.c

index faf2febc41d1afe551c59e167b0495501147b92c..d8a00a1ea3aec0b12fd2f31828ed6a57eb0f8df7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -285,13 +285,13 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
 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
@@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91
 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
@@ -417,7 +417,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
 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
@@ -1388,7 +1388,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 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
index caba2b4da52492e3316c11a61f8365bb3d69fd51..a16e4473137091266384c00260a63ceb53a86575 100644 (file)
@@ -1 +1 @@
-5c14d447055bb337428eb1fe0a2934abee381829
\ No newline at end of file
+e73f919fae1833c6ffb36eddbc76d9a8d9324214
\ No newline at end of file
index 6a9c6131659f95515cf6a6342ce801ef66787c39..c0bd81b1a0444a09e3bea4c5a95731e21c90d454 100644 (file)
@@ -192,6 +192,8 @@ void sqlite3FinishCoding(Parse *pParse){
           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++){
index c387c20befd5293449e252c1bb10c197a8194144..9c928f8d511822cc07141f91b8f8ed607777dfc7 100644 (file)
@@ -411,7 +411,7 @@ void sqlite3DeleteFrom(
     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 */
@@ -465,7 +465,7 @@ void sqlite3DeleteFrom(
   
     /* 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);
@@ -494,7 +494,7 @@ void sqlite3DeleteFrom(
     */
     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);
@@ -516,7 +516,11 @@ void sqlite3DeleteFrom(
       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
     {
@@ -531,8 +535,10 @@ void sqlite3DeleteFrom(
   
     /* 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);
index 0f7d3a21bf18111aee1cd98329e9745cc1896933..4a1312863e0de177da01d145a90310532b883cf0 100644 (file)
@@ -5668,8 +5668,15 @@ struct sqlite3_index_info {
   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
 **
index dfff3ca5c4311ecc89004d57959bc2231aa70334..1175496a2a61474adefda39af5936285b3e4b91f 100644 (file)
@@ -2832,6 +2832,7 @@ static int whereLoopAddVirtual(
     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;
@@ -2877,6 +2878,7 @@ static int whereLoopAddVirtual(
           ** (2) Multiple outputs from a single IN value will not merge
           ** together.  */
           pIdxInfo->orderByConsumed = 0;
+          pIdxInfo->flags &= ~SQLITE_INDEX_SCAN_UNIQUE;
         }
       }
     }
@@ -2892,6 +2894,14 @@ static int whereLoopAddVirtual(
       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);