]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change BtreeMoveto so that it can be biased to the right or to the center.
authordrh <drh@noemail.net>
Thu, 29 Mar 2007 05:51:49 +0000 (05:51 +0000)
committerdrh <drh@noemail.net>
Thu, 29 Mar 2007 05:51:49 +0000 (05:51 +0000)
Use a right bias when appending and a center bias when searching.  This
gives about a 15% reduction in calls to sqlite3VdbeRecordCompare. (CVS 3741)

FossilOrigin-Name: ad4a6b1a91bcefd8a4c75e8dc99c1153c72c31a3

13 files changed:
manifest
manifest.uuid
src/analyze.c
src/btree.c
src/btree.h
src/build.c
src/insert.c
src/select.c
src/sqliteInt.h
src/test3.c
src/update.c
src/vdbe.c
src/vdbeaux.c

index d0324205cb918a6a1ac44d9d8719bf6295e1072c..6fdaea8eafc17ca69bbce7b932eb9be69dee7b31 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bias\sthe\sb-tree\sbinary\ssearch\stoward\sthe\shigh\send.\s\sThe\scommon\scase\sis\sto\nappend\sdata\sand\sthis\sheuristic\smakes\sappend\srun\smuch\sfaster\sbecause\sthere\nare\sfewer\scomparisons.\s(CVS\s3740)
-D 2007-03-29T04:43:26
+C Change\sBtreeMoveto\sso\sthat\sit\scan\sbe\sbiased\sto\sthe\sright\sor\sto\sthe\scenter.\nUse\sa\sright\sbias\swhen\sappending\sand\sa\scenter\sbias\swhen\ssearching.\s\sThis\ngives\sabout\sa\s15%\sreduction\sin\scalls\sto\ssqlite3VdbeRecordCompare.\s(CVS\s3741)
+D 2007-03-29T05:51:49
 F Makefile.in 1fe3d0b46e40fd684e1e61f8e8056cefed16de9f
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -55,12 +55,12 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
 F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
 F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
-F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
+F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651
 F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c
 F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f
-F src/btree.c 434a3584766e85ca3b23d37adb9c457d83f5cf19
-F src/btree.h 066444ee25bd6e6accb997bfd2cf5ace14dbcd00
-F src/build.c d178bd7c8117f5f47694da9a0d5f336e85528180
+F src/btree.c 6619f15c3afacd19e42c7e01ad14df41bf2dc55d
+F src/btree.h 540dcbbf83435b77d4b6ef87f909c6cecad4dac9
+F src/build.c ad3374b5409554e504300f77e1fbc6b4c106a57f
 F src/callback.c 31d22b4919c7645cbcbb1591ce2453e8c677c558
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c 393c73fc027597e008dcd81454544659e978b05c
@@ -70,7 +70,7 @@ F src/expr.c a8740c24af3f39f2d502be1a1c640c96435eaac0
 F src/func.c 94372fe3cf26b81d4dcdc15f98ff240c37c8c708
 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
-F src/insert.c 80b1cc840c769b283475ae4a7b4771ba1f7659a2
+F src/insert.c bdd1e2b48fede8ed1c25ca32747b9050bcbe2594
 F src/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6
 F src/loadext.c c186ad5c9e8a0aaa73d0caf5f604d112e45e8b89
 F src/main.c ed005bbc1d94670c8d9e2b93d446bd493119c44c
@@ -93,17 +93,17 @@ F src/pragma.c 9cb8b94e7d38ba35a86037bd517d07ba9870b4b2
 F src/prepare.c 37207b2b2ccb41d379b01dd62231686bcc48ef1f
 F src/printf.c aade23a789d7cc88b397ec0d33a0a01a33a7a9c1
 F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
-F src/select.c 4d68a0d7f98fb59bcedd0be69750e0445b05899c
+F src/select.c 30af458c6a0a4a283c67b56c70ff0712b67d42ae
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 3ae4654560e91220a95738a73d135d91d937cda1
 F src/sqlite.h.in 02d1159bc8f7387008df9766c79038fce8a9d3a7
 F src/sqlite3ext.h 832e13de075d920e2c76584e2b7af1054bb212df
-F src/sqliteInt.h ace601a40db30d667422c79a7db57e7dabb48038
+F src/sqliteInt.h c8d0e5ce27a862836de70fc3eadc1e65cea7e3d8
 F src/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
 F src/tclsqlite.c cd2b3b86ab07c0e0779f6c6e71e72c6c7dc1e704
 F src/test1.c 439bba8da10fbc61c731019cf2894e6057578878
 F src/test2.c dc48c84ce68b3bc2f2d01871d709f20dc77003b0
-F src/test3.c b40ca2eb1390a4c5a41bc8c545284a32aca69991
+F src/test3.c 65f92247cf8592854e9bf5115b3fb711f8b33280
 F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
 F src/test6.c 5957d249d437e4db74045ce2f1f661648d94bf94
@@ -118,15 +118,15 @@ F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
 F src/test_tclvar.c 315e77c17f128ff8c06b38c08617fd07c825a95b
 F src/tokenize.c bb1732ef2b6fc2143f93ff28a45d3dcb04c1d396
 F src/trigger.c 8c55d31876013ed4e97ee7ce24478fbe00db49bb
-F src/update.c 876b3142b8db9ce6ddf8374a2ced65e576acabc7
+F src/update.c 3359041db390a8f856d67272f299600e2104f350
 F src/utf.c 67ecb1032bc0b42c105e88d65ef9d9f626eb0e1f
 F src/util.c 8e8180ee5597f2474c1da311ff3c464b6966c0f1
 F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef
-F src/vdbe.c 9fc4520600f364ec510e7c74733dc2b77430b92a
+F src/vdbe.c e214ce8f760f839d7171714f895e362facaae4dd
 F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691
 F src/vdbeInt.h b2ca85ca8abfbba86e380b06c7673dc81c6784c3
 F src/vdbeapi.c 6cff63a5b3a52af04b2bef0f7e27ed7ea6f85183
-F src/vdbeaux.c 1a50dce809a2f5c2d32e8096166b59016dab1b45
+F src/vdbeaux.c 2cf328d44683f1d6b537809536873b1999be6f20
 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f
 F src/vdbemem.c 58a8be2231b0b13e2e77098debe173e79d22f791
 F src/vtab.c 7fbda947e28cbe7adb3ba752a76ca9ef29936750
@@ -442,7 +442,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P e72c81dbb309709462e49c4e3e90c3e16ead1265
-R 2f8c0ebcc5b977db1cd11a734857a630
+P a9877f616b24737152627841fcbd80cc28426f1e
+R 63136fc2c62ce921e31331d55ad9708c
 U drh
-Z f092376d9c3cfc91e80b8841598ffc58
+Z ae6ac3fd2b6690aaaa258fb90ac6d9d8
index 1de5ee3b4c9e7007d32d33b584d7e2665ad9a106..8a897835924a4a11405beac9bc3e779283a0887a 100644 (file)
@@ -1 +1 @@
-a9877f616b24737152627841fcbd80cc28426f1e
\ No newline at end of file
+ad4a6b1a91bcefd8a4c75e8dc99c1153c72c31a3
\ No newline at end of file
index 3d27134e4ac212d26677b59087967952a13f0e79..abbbf0fd52712bc47415df61e21365cfd0b01e7a 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code associated with the ANALYZE command.
 **
-** @(#) $Id: analyze.c,v 1.16 2006/01/10 17:58:23 danielk1977 Exp $
+** @(#) $Id: analyze.c,v 1.17 2007/03/29 05:51:49 drh Exp $
 */
 #ifndef SQLITE_OMIT_ANALYZE
 #include "sqliteInt.h"
@@ -211,7 +211,7 @@ static void analyzeOneTable(
       }
     }
     sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
-    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, OPFLAG_APPEND);
     sqlite3VdbeJumpHere(v, addr);
   }
 }
index f75cbe376ebc02e3b52595111f521d7c2d94d76a..ac999e1cd25b98b01eb71bf6ac8ae9d842a5caf4 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.344 2007/03/29 04:43:26 drh Exp $
+** $Id: btree.c,v 1.345 2007/03/29 05:51:49 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -728,7 +728,7 @@ static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
   assert( pCur->eState==CURSOR_REQUIRESEEK );
   pCur->eState = CURSOR_INVALID;
   if( doSeek ){
-    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
+    rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
   }
   if( rc==SQLITE_OK ){
     sqliteFree(pCur->pKey);
@@ -3303,7 +3303,13 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
 **     *pRes>0      The cursor is left pointing at an entry that
 **                  is larger than pKey.
 */
-int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
+int sqlite3BtreeMoveto(
+  BtCursor *pCur,        /* The cursor to be moved */
+  const void *pKey,      /* The key content for indices.  Not used by tables */
+  i64 nKey,              /* Size of pKey.  Or the key for tables */
+  int biasRight,         /* If true, bias the search to the high end */
+  int *pRes              /* Search result flag */
+){
   int rc;
   rc = moveToRoot(pCur);
   if( rc ) return rc;
@@ -3324,7 +3330,11 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){
     if( !pPage->intKey && pKey==0 ){
       return SQLITE_CORRUPT_BKPT;
     }
-    pCur->idx = upr;
+    if( biasRight ){
+      pCur->idx = upr;
+    }else{
+      pCur->idx = (upr+lwr)/2;
+    }
     if( lwr<=upr ) for(;;){
       void *pCellKey;
       i64 nCellKey;
@@ -5182,7 +5192,8 @@ static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
 int sqlite3BtreeInsert(
   BtCursor *pCur,                /* Insert data into the table of this cursor */
   const void *pKey, i64 nKey,    /* The key of the new record */
-  const void *pData, int nData   /* The data of the new record */
+  const void *pData, int nData,  /* The data of the new record */
+  int appendBias                 /* True if this is likely an append */
 ){
   int rc;
   int loc;
@@ -5208,7 +5219,7 @@ int sqlite3BtreeInsert(
   restoreOrClearCursorPosition(pCur, 0);
   if( 
     SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
-    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, &loc))
+    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
   ){
     return rc;
   }
index 8a05759ee97b2a226deccf2d18e03a18af93ecdf..513e9a082681cc3f21eb8a488ef237d844bffe47 100644 (file)
@@ -13,7 +13,7 @@
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.72 2007/01/27 02:24:55 drh Exp $
+** @(#) $Id: btree.h,v 1.73 2007/03/29 05:51:49 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -114,10 +114,10 @@ void sqlite3BtreeSetCompare(
 );
 
 int sqlite3BtreeCloseCursor(BtCursor*);
-int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
+int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes);
 int sqlite3BtreeDelete(BtCursor*);
 int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
-                                  const void *pData, int nData);
+                                  const void *pData, int nData, int bias);
 int sqlite3BtreeFirst(BtCursor*, int *pRes);
 int sqlite3BtreeLast(BtCursor*, int *pRes);
 int sqlite3BtreeNext(BtCursor*, int *pRes);
index de3629be7cafdf08061db0318ee16c2e0e16fb77..cc38cf72ec94978ee614db79c72a4843adc248dc 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.417 2007/03/27 13:36:37 drh Exp $
+** $Id: build.c,v 1.418 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -887,7 +887,7 @@ void sqlite3StartTable(
     sqlite3VdbeAddOp(v, OP_NewRowid, 0, 0);
     sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
     sqlite3VdbeAddOp(v, OP_Null, 0, 0);
-    sqlite3VdbeAddOp(v, OP_Insert, 0, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, 0, OPFLAG_APPEND);
     sqlite3VdbeAddOp(v, OP_Close, 0, 0);
     sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
   }
index e69f9c85cd3e100aad2bd3f7eefce86e500dc818..0d0bc0782a2310a74be679ac68d5c516ec39e225 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.179 2007/03/29 00:08:25 drh Exp $
+** $Id: insert.c,v 1.180 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -205,7 +205,7 @@ static void autoIncEnd(
     sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
     sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0);
     sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
-    sqlite3VdbeAddOp(v, OP_Insert, iCur, 0);
+    sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND);
     sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
   }
 }
@@ -346,6 +346,7 @@ void sqlite3Insert(
   int newIdx = -1;      /* Cursor for the NEW table */
   Db *pDb;              /* The database containing table being inserted into */
   int counterMem = 0;   /* Memory cell holding AUTOINCREMENT counter */
+  int appendFlag = 0;   /* True if the insert is likely to be an append */
   int iDb;
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -489,7 +490,7 @@ void sqlite3Insert(
       sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
       sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND);
       sqlite3VdbeAddOp(v, OP_Return, 0, 0);
 
       /* The following code runs first because the GOTO at the very top
@@ -701,19 +702,30 @@ void sqlite3Insert(
       }else if( pSelect ){
         sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
       }else{
+        VdbeOp *pOp;
         sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
+        pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
+        if( pOp->opcode==OP_Null ){
+          appendFlag = 1;
+          pOp->opcode = OP_NewRowid;
+          pOp->p1 = base;
+          pOp->p2 = counterMem;
+        }
       }
       /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
       ** to generate a unique primary key value.
       */
-      sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
-      sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
-      sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
-      sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+      if( !appendFlag ){
+        sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
+        sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
+        sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+        sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
+      }
     }else if( IsVirtual(pTab) ){
       sqlite3VdbeAddOp(v, OP_Null, 0, 0);
     }else{
       sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
+      appendFlag = 1;
     }
     autoIncStep(pParse, counterMem);
 
@@ -761,7 +773,8 @@ void sqlite3Insert(
       sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
                                      0, onError, endOfLoop);
       sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
-                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
+                            (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1,
+                            appendFlag);
     }
   }
 
@@ -1172,7 +1185,8 @@ void sqlite3CompleteInsertion(
   char *aIdxUsed,     /* Which indices are used.  NULL means all are used */
   int rowidChng,      /* True if the record number will change */
   int isUpdate,       /* True for UPDATE, False for INSERT */
-  int newIdx          /* Index of NEW table for triggers.  -1 if none */
+  int newIdx,         /* Index of NEW table for triggers.  -1 if none */
+  int appendBias      /* True if this is likely to be an append */
 ){
   int i;
   Vdbe *v;
@@ -1203,6 +1217,9 @@ void sqlite3CompleteInsertion(
     pik_flags = OPFLAG_NCHANGE;
     pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
   }
+  if( appendBias ){
+    pik_flags |= OPFLAG_APPEND;
+  }
   sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
   if( !pParse->nested ){
     sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
@@ -1515,7 +1532,8 @@ static int xferOptimization(
     addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
   }
   sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0);
-  sqlite3VdbeOp3(v, OP_Insert, iDest, OPFLAG_NCHANGE|OPFLAG_LASTROWID,
+  sqlite3VdbeOp3(v, OP_Insert, iDest,
+                    OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
                     pDest->zName, 0);
   sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1);
   autoIncEnd(pParse, iDbDest, pDest, counterMem);
@@ -1545,7 +1563,7 @@ static int xferOptimization(
                     "UNIQUE constraint failed", P3_STATIC);
       sqlite3VdbeJumpHere(v, addr2);
     }
-    sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 0);
+    sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1);
     sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1);
     sqlite3VdbeJumpHere(v, addr1);
   }
index d7fb3f1790dd13c9658647b5f2feff05d19e2348..b5062393a37f42f18c37d909af35d417fd4e0ab6 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.330 2007/03/02 07:27:00 danielk1977 Exp $
+** $Id: select.c,v 1.331 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -535,7 +535,7 @@ static int selectInnerLoop(
       }else{
         sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-        sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+        sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
       }
       break;
     }
@@ -714,7 +714,7 @@ static void generateSortTail(
     case SRT_EphemTab: {
       sqlite3VdbeAddOp(v, OP_NewRowid, iParm, 0);
       sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
-      sqlite3VdbeAddOp(v, OP_Insert, iParm, 0);
+      sqlite3VdbeAddOp(v, OP_Insert, iParm, OPFLAG_APPEND);
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
index 354e242e9262c1b7d8bc65f4de2c3887b7392dcc..71c21eac28a869ec8d0c5c8672f097eea61d83bd 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.546 2007/03/28 14:30:07 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.547 2007/03/29 05:51:49 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1376,6 +1376,7 @@ struct AuthContext {
 #define OPFLAG_NCHANGE   1    /* Set to update db->nChange */
 #define OPFLAG_LASTROWID 2    /* Set to update db->lastRowid */
 #define OPFLAG_ISUPDATE  4    /* This OP_Insert is an sql UPDATE */
+#define OPFLAG_APPEND    8    /* This is likely to be an append */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
@@ -1692,7 +1693,7 @@ void sqlite3GenerateRowDelete(sqlite3*, Vdbe*, Table*, int, int);
 void sqlite3GenerateRowIndexDelete(Vdbe*, Table*, int, char*);
 void sqlite3GenerateIndexKey(Vdbe*, Index*, int);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
-void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int);
+void sqlite3CompleteInsertion(Parse*, Table*, int, char*, int, int, int, int);
 void sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
 void sqlite3BeginWriteOperation(Parse*, int, int);
 Expr *sqlite3ExprDup(Expr*);
index 8dd510a9b2119c8caba30652f918ff323b85246f..fba3fa2ecac3c574e8b659bfe76dc53384f3c0a1 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.72 2007/03/26 22:05:02 drh Exp $
+** $Id: test3.c,v 1.73 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -706,9 +706,9 @@ static int btree_move_to(
   if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
     int iKey;
     if( Tcl_GetInt(interp, argv[2], &iKey) ) return TCL_ERROR;
-    rc = sqlite3BtreeMoveto(pCur, 0, iKey, &res);
+    rc = sqlite3BtreeMoveto(pCur, 0, iKey, 0, &res);
   }else{
-    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);  
+    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res);  
   }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
@@ -775,7 +775,7 @@ static int btree_insert(
     unsigned char *pBuf;
     if( Tcl_GetWideIntFromObj(interp, objv[2], &iKey) ) return TCL_ERROR;
     pBuf = Tcl_GetByteArrayFromObj(objv[3], &len);
-    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len);
+    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len, 0);
   }else{
     int keylen;
     int dlen;
@@ -783,7 +783,7 @@ static int btree_insert(
     unsigned char *pDBuf;
     pKBuf = Tcl_GetByteArrayFromObj(objv[2], &keylen);
     pDBuf = Tcl_GetByteArrayFromObj(objv[3], &dlen);
-    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen);
+    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen, 0);
   }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
index bff7bdf0338ec2c198563997deb55bd8ad4fa312..b1896a2c12f233f9ee1bd554d4add1283082ac8e 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.136 2007/02/21 17:04:04 danielk1977 Exp $
+** $Id: update.c,v 1.137 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -465,7 +465,7 @@ void sqlite3Update(
 
     /* Create the new index entries and the new record.
     */
-    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1);
+    sqlite3CompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRowid, 1, -1, 0);
   }
 
   /* Increment the row counter 
index ad0588a7c20532eb317d63293bfa8f3202209842..535c4118b5362412fcbea6ae023230e70e3f9cfd 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.595 2007/03/28 14:30:07 drh Exp $
+** $Id: vdbe.c,v 1.596 2007/03/29 05:51:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -2834,7 +2834,7 @@ case OP_MoveGt: {       /* no-push */
         pTos--;
         break;
       }
-      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
@@ -2843,7 +2843,7 @@ case OP_MoveGt: {       /* no-push */
     }else{
       assert( pTos->flags & MEM_Blob );
       /* Stringify(pTos, encoding); */
-      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
@@ -2950,7 +2950,7 @@ case OP_Found: {        /* no-push */
     int res, rx;
     assert( pC->isTable==0 );
     Stringify(pTos, encoding);
-    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+    rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, 0, &res);
     alreadyExists = rx==SQLITE_OK && res==0;
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
@@ -3028,7 +3028,7 @@ case OP_IsUnique: {        /* no-push */
     */
     assert( pCx->deferredMoveto==0 );
     pCx->cacheStatus = CACHE_STALE;
-    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, 0, &res);
     if( rc!=SQLITE_OK ){
       goto abort_due_to_error;
     }
@@ -3098,7 +3098,7 @@ case OP_NotExists: {        /* no-push */
     assert( pTos->flags & MEM_Int );
     assert( p->apCsr[i]->isTable );
     iKey = intToKey(pTos->i);
-    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, 0,&res);
     pC->lastRowid = pTos->i;
     pC->rowidIsValid = res==0;
     pC->nullRow = 0;
@@ -3270,7 +3270,7 @@ case OP_NewRowid: {
         }
         if( v==0 ) continue;
         x = intToKey(v);
-        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
+        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, 0, &res);
         cnt++;
       }while( cnt<1000 && rx==SQLITE_OK && res==0 );
       db->priorNewRowid = v;
@@ -3350,7 +3350,9 @@ case OP_Insert: {         /* no-push */
       }
       pC->nullRow = 0;
     }else{
-      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pTos->z, pTos->n);
+      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
+                              pTos->z, pTos->n,
+                              pOp->p2 & OPFLAG_APPEND);
     }
     
     pC->rowidIsValid = 0;
@@ -3704,12 +3706,15 @@ case OP_Next: {        /* no-push */
   break;
 }
 
-/* Opcode: IdxInsert P1 * *
+/* Opcode: IdxInsert P1 P2 *
 **
 ** The top of the stack holds a SQL index key made using either the
 ** MakeIdxRec or MakeRecord instructions.  This opcode writes that key
 ** into the index P1.  Data for the entry is nil.
 **
+** P2 is a flag that provides a hint to the b-tree layer that this
+** insert is likely to be an append.
+**
 ** This instruction only works for indices.  The equivalent instruction
 ** for tables is OP_Insert.
 */
@@ -3721,12 +3726,11 @@ case OP_IdxInsert: {        /* no-push */
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   assert( pTos->flags & MEM_Blob );
-  assert( pOp->p2==0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int nKey = pTos->n;
     const char *zKey = pTos->z;
     assert( pC->isTable==0 );
-    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
+    rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, pOp->p2);
     assert( pC->deferredMoveto==0 );
     pC->cacheStatus = CACHE_STALE;
   }
@@ -3751,7 +3755,7 @@ case OP_IdxDelete: {        /* no-push */
   assert( p->apCsr[i]!=0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int res;
-    rc = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, pTos->z, pTos->n, 0, &res);
     if( rc==SQLITE_OK && res==0 ){
       rc = sqlite3BtreeDelete(pCrsr);
     }
index 7172766031bd25417d174107d9360c9783511b42..70977f8df4132c82746089d21fd05d65d70a43fe 100644 (file)
@@ -1663,10 +1663,10 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
 #endif
     assert( p->isTable );
     if( p->isTable ){
-      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
+      rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, 0, &res);
     }else{
       rc = sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,
-                              sizeof(i64),&res);
+                              sizeof(i64), 0, &res);
     }
     if( rc ) return rc;
     *p->pIncrKey = 0;