]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enable the WHERE_ONEPASS_DESIRED optimization for UPDATE operations on
authordrh <drh@noemail.net>
Thu, 7 Nov 2013 21:25:13 +0000 (21:25 +0000)
committerdrh <drh@noemail.net>
Thu, 7 Nov 2013 21:25:13 +0000 (21:25 +0000)
WITHOUT ROWID tables.

FossilOrigin-Name: 215307985590c2f3f7aa0d5a0b7799155a506045

manifest
manifest.uuid
src/update.c
src/where.c

index ed50f198f97291f9380557fc7272fc9b510b12d8..bdbe0c7818e44a79a7bb1460c9becfa8816f3e21 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\s--stats\sand\s--summary\soptions\sto\sthe\swordcount.c\stest\sprogram.
-D 2013-11-07T19:43:21.798
+C Enable\sthe\sWHERE_ONEPASS_DESIRED\soptimization\sfor\sUPDATE\soperations\son\nWITHOUT\sROWID\stables.
+D 2013-11-07T21:25:13.536
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in d12e4455cf7a36e42d3949876c1c3b88ff70867a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -275,7 +275,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
 F src/trigger.c 53d6b5d50b3b23d4fcd0a36504feb5cff9aed716
-F src/update.c 516e0ea0f853bfb852e098f3b643a3f2bfd423ef
+F src/update.c a1580fb4ad99246d4a286348e80c806385dd102f
 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
@@ -292,7 +292,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
-F src/where.c 1a99f1275fb5db2d76b0093ae1c1936c3b036aa0
+F src/where.c 30462cf04157b872b4443724739ef617b1535686
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1135,7 +1135,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 9ad5b74c26c5a18068a2418a2092a05c226912c2
-R 7eb08ca6a9c5e8c1ab9bbee56e904b5c
+P 8aa21e6791d408c8f018bd779e09cb7e7179f884
+R 90320f23fbcc029ca5605efdad336f38
 U drh
-Z ae0666d0d2115aaaa9008a758df6593e
+Z eb9342f786dc77889731ffb09a64422a
index fbffe55460201a9f8335d9c72c6141d59fbbb575..e84b0157103e2275deac658367c1c59a9593794d 100644 (file)
@@ -1 +1 @@
-8aa21e6791d408c8f018bd779e09cb7e7179f884
\ No newline at end of file
+215307985590c2f3f7aa0d5a0b7799155a506045
\ No newline at end of file
index 065e5d6158dfc4a575f05490cdb5958631932ddc..9b6671eb2fb12578103345e9f6d01e6f283b910f 100644 (file)
@@ -128,6 +128,7 @@ void sqlite3Update(
 #endif
   int newmask;           /* Mask of NEW.* columns accessed by BEFORE triggers */
   int iEph = 0;          /* Ephemeral table holding all primary key values */
+  int nKey;              /* Number of elements in regKey */
 
   /* Register Allocations */
   int regRowCount = 0;   /* A count of rows changed */
@@ -353,6 +354,7 @@ void sqlite3Update(
   }else{
     int iPk;         /* First of nPk memory cells holding PRIMARY KEY value */
     i16 nPk;         /* Number of components of the PRIMARY KEY */
+    int addrOpen;    /* Address of the OpenEphemeral instruction */
 
     assert( pPk!=0 );
     nPk = pPk->nKeyCol;
@@ -360,19 +362,28 @@ void sqlite3Update(
     pParse->nMem += nPk;
     regKey = ++pParse->nMem;
     iEph = pParse->nTab++;
-    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+    sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+    addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
     sqlite3VdbeSetP4KeyInfo(pParse, pPk);
-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
+    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 
+                               WHERE_ONEPASS_DESIRED, 0);
     if( pWInfo==0 ) goto update_cleanup;
+    okOnePass = sqlite3WhereOkOnePass(pWInfo);
     for(i=0; i<nPk; i++){
       sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
                                       iPk+i);
     }
-    sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
-                      sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
-    sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+    if( okOnePass ){
+      sqlite3VdbeChangeToNoop(v, addrOpen);
+      nKey = nPk;
+      regKey = iPk;
+    }else{
+      sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+                        sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+      sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+      nKey = 0;
+    }
     sqlite3WhereEnd(pWInfo);
-    okOnePass = 0;
   }
 
   /* Initialize the count of updated rows
@@ -417,14 +428,17 @@ void sqlite3Update(
 
   /* Top of the update loop */
   labelBreak = sqlite3VdbeMakeLabel(v);
-  if( pPk ){
+  if( okOnePass ){
+    labelContinue = labelBreak;
+    sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+    if( pPk ){
+      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+    }
+  }else if( pPk ){
     labelContinue = sqlite3VdbeMakeLabel(v);
     sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
     addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
     sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
-  }else if( okOnePass ){
-    labelContinue = labelBreak;
-    sqlite3VdbeAddOp2(v, OP_IsNull, regOldRowid, labelBreak);
   }else{
     labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
                              regOldRowid);
@@ -516,7 +530,7 @@ void sqlite3Update(
     ** documentation.
     */
     if( pPk ){
-      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
     }else{
       sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
     }
@@ -548,7 +562,7 @@ void sqlite3Update(
 
     /* Delete the index entries associated with the current record.  */
     if( pPk ){
-      j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, 0);
+      j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
     }else{
       j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
     }
@@ -592,10 +606,12 @@ void sqlite3Update(
   /* Repeat the above with the next record to be updated, until
   ** all record selected by the WHERE clause have been updated.
   */
-  if( pPk ){
+  if( okOnePass ){
+    /* Nothing to do at end-of-loop for a single-pass */
+  }else if( pPk ){
     sqlite3VdbeResolveLabel(v, labelContinue);
     sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
-  }else if( !okOnePass ){
+  }else{
     sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
   }
   sqlite3VdbeResolveLabel(v, labelBreak);
index 02bec9549c941ac64fadc37d583cc6e813018dd5..c26465e97076fd23054d9748ddf4cef72e74c38d 100644 (file)
@@ -4639,9 +4639,10 @@ static int whereLoopAddBtree(
 
       /* Full scan via index */
       if( b
+       || !HasRowid(pTab)
        || ( m==0
          && pProbe->bUnordered==0
-         && (!HasRowid(pTab) || pProbe->szIdxRow<pTab->szTabRow)
+         && (pProbe->szIdxRow<pTab->szTabRow)
          && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
          && sqlite3GlobalConfig.bUseCis
          && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
@@ -4657,7 +4658,6 @@ static int whereLoopAddBtree(
           pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 +
                         (15*pProbe->szIdxRow)/pTab->szTabRow;
         }else{
-          assert( b!=0 ); 
           /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
           ** which we will simplify to just N*log2(N) */
           pNew->rRun = rSize + rLogSize;
@@ -5990,7 +5990,9 @@ WhereInfo *sqlite3WhereBegin(
   if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
    && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
     pWInfo->okOnePass = 1;
-    pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+    if( HasRowid(pTabList->a[0].pTab) ){
+      pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+    }
   }
 
   /* Open all tables in the pTabList and any indices selected for