]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the {quote: IdxDelete} opcode so that it takes an array of registers rather
authordrh <drh@noemail.net>
Tue, 25 Mar 2008 17:23:32 +0000 (17:23 +0000)
committerdrh <drh@noemail.net>
Tue, 25 Mar 2008 17:23:32 +0000 (17:23 +0000)
than a record formed using {quote: MakeRecord.}  This avoids a needless packing
and unpacking of the record to be deleted. (CVS 4916)

FossilOrigin-Name: ee381b43563e1b0637ee74389d076dff77deddf9

14 files changed:
manifest
manifest.uuid
src/btree.c
src/btree.h
src/build.c
src/delete.c
src/pragma.c
src/select.c
src/sqliteInt.h
src/test3.c
src/vdbe.c
src/vdbe.h
src/vdbeInt.h
src/vdbeaux.c

index 1afbe0a6930a61a210e216eac4dd3dc9a236d5ac..3b3666328914d7c0682616bb4c54f886c428d1f2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Test\sstring\svalues\spassed\sto\sbind_text()\sand\sresult_text()\sfor\sa\snul-terminator.\s(CVS\s4915)
-D 2008-03-25T16:16:29
+C Modify\sthe\s{quote:\sIdxDelete}\sopcode\sso\sthat\sit\stakes\san\sarray\sof\sregisters\srather\r\nthan\sa\srecord\sformed\susing\s{quote:\sMakeRecord.}\s\sThis\savoids\sa\sneedless\spacking\r\nand\sunpacking\sof\sthe\srecord\sto\sbe\sdeleted.\s(CVS\s4916)
+D 2008-03-25T17:23:33
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in cf434ce8ca902e69126ae0f94fc9f7dc7428a5fa
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -86,14 +86,14 @@ F src/attach.c bdc75e759ca25a16f4dc7fbdbc6d37ad2561bb24
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/bitvec.c 49817d442e51e4123585f3cf3c2afc293a3c91e2
 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
-F src/btree.c 366f5f66ebb3dfdc8513242d4aecbfb402dcc0a9
-F src/btree.h e02869e1e7753ad5b3c7cb7852e952c95c2e609a
+F src/btree.c 6e60d634d236232efbb289b800dd76e72a5ecf9d
+F src/btree.h c66cb17c6fffa84a88926dbef173bab4ae692fd4
 F src/btreeInt.h d232be68a7ab2a24376dc6332a869e717551b0bd
-F src/build.c d0715b3454b140cb405412e3029ec7c0fb434efd
+F src/build.c 4e6321d112f0ed1070c579677573e4eb76cda1fd
 F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
 F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
 F src/date.c e41ce4513fb0e359dc678d6bddb4ace135fe365d
-F src/delete.c 526b783b71b9885b201d74720d44a386b971dc01
+F src/delete.c 3dc7d7cc46c8675219a7776b7c67b626bba530df
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 7e56d2a24af8137f4bebbfa1d7dd1dcf70107c88
 F src/fault.c c28478c7190daef16be09d261c5461638b4d686c
@@ -131,22 +131,22 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c 22241b59c80ca083a96816df434adb8c097afcd4
 F src/pager.h b1e2258f03878c14b06a95bfa362e8c5c9638170
 F src/parse.y b0ee84d94218046ea88c2a6561005710d127ca7d
-F src/pragma.c f64eed914518c28d1863356163dea1e6f58e28f2
+F src/pragma.c 99cec6d99d0241436494aab15b05da97b0e70683
 F src/prepare.c 185fb47f1fb3e45a345d523eb391d673f5eb367c
 F src/printf.c 05d2b44d7b5b80c8a4a09108ddad9c20e254370d
 F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a
-F src/select.c c06849a0d0ad408fbdd8180439176e94aae43e56
+F src/select.c 831714d4f09f4b9f4be43d2399eff12dcf281c86
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 22297fffa6f00a6c6d44020fa13b1184a1bb372d
 F src/sqlite.h.in 61d8d1cefcbf0803c03c2179be138a78bfd1d335
 F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3
-F src/sqliteInt.h 07b472437b2d7297c300f8b7cea5205984fa64d1
+F src/sqliteInt.h 50a9313829041721d34f20c8be4562c3197dcff9
 F src/sqliteLimit.h eecbc288b410ae5565e71aaa4a439aae57bb0707
 F src/table.c 2c48c575dd59b3a6c5c306bc55f51a9402cf429a
 F src/tclsqlite.c 1367762764772a233643524c3585b4711a9adcda
 F src/test1.c 342a2628310fa709074d979e695a28a3bb570834
 F src/test2.c f0808cc643528b9620e4059ca9bda8346f526121
-F src/test3.c 31027a4a190d2f3c1e479ea2d750e696160bbf04
+F src/test3.c c715b5a8a6415d7b2c67f97c394eef488b6f7e63
 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
 F src/test6.c 62281c0a9ac0265e579065942f7de4e080f8eb05
@@ -174,11 +174,11 @@ F src/update.c 2aefd3c9277792e9fa2414dfe14202119fa49fe7
 F src/utf.c 32b00d6e19010025e58f2ecb2f921d5e126771b4
 F src/util.c dba9e04121eb17ec4643d6ca231ff859452cf0e2
 F src/vacuum.c 3524411bfb58aac0d87eadd3e5b7cd532772af30
-F src/vdbe.c bdcbf54cf944a99b004e87a523736dd326fa34be
-F src/vdbe.h 0fef6798be121ed2b5a547a5cb85e0824ec3971f
-F src/vdbeInt.h 4bbec80d55d179ab8438ac9822416d9111638919
+F src/vdbe.c 0068703495a197e7b77dbdff604b42896722a1cc
+F src/vdbe.h ecca2e1c1ac1066f4e68ad38068a20ea32ea7063
+F src/vdbeInt.h 4d767f189a1d13ff8d4881de60aacc470e54f5b8
 F src/vdbeapi.c b9e9d7a58690c1e1ae66de7232edccf4793ad817
-F src/vdbeaux.c c071014d81c1d4b2c381247c16a3e86182951e51
+F src/vdbeaux.c e45929a3b5e59e8f2d69b7d6164c9a636149e1df
 F src/vdbeblob.c cc713c142c3d4952b380c98ee035f850830ddbdb
 F src/vdbefifo.c a30c237b2a3577e1415fb6e288cbb6b8ed1e5736
 F src/vdbemem.c d48a71d66a7afd564b6537ab7e7442f7729fa5af
@@ -617,7 +617,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P fe1bc0f3b7cd87cd65f7d03b91095b59788a6f8d
-R 033bb4545035899c2c5396ecb143bb5f
-U danielk1977
-Z 09f5af34fae3a95557976f8d7d3936e3
+P 24c3ebc0c5c53c234516d16dce761d713fb29578
+R 66dfc33f9c0d1eba54064363b17cc27e
+U drh
+Z 040d5190ae2e9926a42f3065a9864529
index 8bf67601edeea20bbfaf79324101f9920ff3ab72..6d2ac4b6161a2ceb0238e80c002f7574519f3b95 100644 (file)
@@ -1 +1 @@
-24c3ebc0c5c53c234516d16dce761d713fb29578
\ No newline at end of file
+ee381b43563e1b0637ee74389d076dff77deddf9
\ No newline at end of file
index 27450094f324e9f62baa0b7b2777df57be5ac7ff..b889096a65e63c838d659addd8d1e91ee268cb5e 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.446 2008/03/25 14:24:57 danielk1977 Exp $
+** $Id: btree.c,v 1.447 2008/03/25 17:23:33 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -379,7 +379,7 @@ int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
   }
 #endif
   pCur->eState = CURSOR_INVALID;
-  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip);
+  rc = sqlite3BtreeMoveto(pCur, pCur->pKey, 0, pCur->nKey, 0, &pCur->skip);
   if( rc==SQLITE_OK ){
     sqlite3_free(pCur->pKey);
     pCur->pKey = 0;
@@ -3548,12 +3548,13 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
   return rc;
 }
 
-/* Move the cursor so that it points to an entry near pKey/nKey.
-** Return a success code.
+/* Move the cursor so that it points to an entry near the key 
+** specified by pKey/nKey/pUnKey. Return a success code.
 **
-** For INTKEY tables, only the nKey parameter is used.  pKey is
-** ignored.  For other tables, nKey is the number of bytes of data
-** in pKey.
+** For INTKEY tables, only the nKey parameter is used.  pKey 
+** and pUnKey must be NULL.  For index tables, either pUnKey
+** must point to a key that has already been unpacked, or else
+** pKey/nKey describes a blob containing the key.
 **
 ** If an exact match is not found, then the cursor is always
 ** left pointing at a leaf page which would hold the entry if it
@@ -3578,12 +3579,12 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
 int sqlite3BtreeMoveto(
   BtCursor *pCur,        /* The cursor to be moved */
   const void *pKey,      /* The key content for indices.  Not used by tables */
+  UnpackedRecord *pUnKey,/* Unpacked version of pKey */
   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;
-  VdbeParsedRecord *pPKey;
   char aSpace[200];
 
   assert( cursorHoldsMutex(pCur) );
@@ -3600,11 +3601,22 @@ int sqlite3BtreeMoveto(
     return SQLITE_OK;
   }
   if( pCur->pPage->intKey ){
-    pPKey = 0;
-  }else{
-    pPKey = sqlite3VdbeRecordParse(pCur->pKeyInfo, nKey, pKey,
+    /* We are given an SQL table to search.  The key is the integer
+    ** rowid contained in nKey.  pKey and pUnKey should both be NULL */
+    assert( pUnKey==0 );
+    assert( pKey==0 );
+  }else if( pUnKey==0 ){
+    /* We are to search an SQL index using a key encoded as a blob.
+    ** The blob is found at pKey and is nKey bytes in length.  Unpack
+    ** this key so that we can use it. */
+    assert( pKey!=0 );
+    pUnKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, nKey, pKey,
                                    aSpace, sizeof(aSpace));
-    if( pPKey==0 ) return SQLITE_NOMEM;
+    if( pUnKey==0 ) return SQLITE_NOMEM;
+  }else{
+    /* We are to search an SQL index using a key that is already unpacked
+    ** and handed to us in pUnKey. */
+    assert( pKey==0 );
   }
   for(;;){
     int lwr, upr;
@@ -3613,7 +3625,7 @@ int sqlite3BtreeMoveto(
     int c = -1;  /* pRes return if table is empty must be -1 */
     lwr = 0;
     upr = pPage->nCell-1;
-    if( !pPage->intKey && pKey==0 ){
+    if( !pPage->intKey && pUnKey==0 ){
       rc = SQLITE_CORRUPT_BKPT;
       goto moveto_finish;
     }
@@ -3646,7 +3658,7 @@ int sqlite3BtreeMoveto(
         pCellKey = (void *)fetchPayload(pCur, &available, 0);
         nCellKey = pCur->info.nKey;
         if( available>=nCellKey ){
-          c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey);
+          c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey);
         }else{
           pCellKey = sqlite3_malloc( nCellKey );
           if( pCellKey==0 ){
@@ -3654,7 +3666,7 @@ int sqlite3BtreeMoveto(
             goto moveto_finish;
           }
           rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
-          c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey);
+          c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey);
           sqlite3_free(pCellKey);
           if( rc ) goto moveto_finish;
         }
@@ -3701,7 +3713,11 @@ int sqlite3BtreeMoveto(
     if( rc ) goto moveto_finish;
   }
 moveto_finish:
-  sqlite3VdbeRecordUnparse(pPKey);
+  if( pKey ){
+    /* If we created our own unpacked key at the top of this
+    ** procedure, then destroy that key before returning. */
+    sqlite3VdbeDeleteUnpackedRecord(pUnKey);
+  }
   return rc;
 }
 
@@ -5619,7 +5635,7 @@ int sqlite3BtreeInsert(
   clearCursorPosition(pCur);
   if( 
     SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
-    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
+    SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, 0, nKey, appendBias, &loc))
   ){
     return rc;
   }
index 97298da0e5934f1786e895775266f2fc852b5a32..2f9bbcd080c909f0d26bca7b5f012ae3328ba77e 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.96 2008/03/25 09:47:35 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.97 2008/03/25 17:23:33 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -127,6 +127,8 @@ int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
 int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
 void sqlite3BtreeTripAllCursors(Btree*, int);
 
+struct UnpackedRecord;  /* Forward declaration.  Definition in vdbeaux.c. */
+
 int sqlite3BtreeCursor(
   Btree*,                              /* BTree containing table to open */
   int iTable,                          /* Index of root page */
@@ -137,7 +139,14 @@ int sqlite3BtreeCursor(
 int sqlite3BtreeCursorSize();
 
 int sqlite3BtreeCloseCursor(BtCursor*);
-int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes);
+int sqlite3BtreeMoveto(
+  BtCursor*,
+  const void *pKey,
+  struct UnpackedRecord *pUnKey,
+  i64 nKey,
+  int bias,
+  int *pRes
+);
 int sqlite3BtreeDelete(BtCursor*);
 int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                   const void *pData, int nData,
index 6b247901fddbbc744dae6b54d840a6a8f2e69d08..72fe620e090a0e097762a9c5965ff30e5a6aa4af 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.476 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: build.c,v 1.477 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2278,7 +2278,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
   regRecord = sqlite3GetTempReg(pParse);
-  regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord);
+  regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
   if( pIndex->onError!=OE_None ){
     int j1, j2;
     int regRowid;
index 6a07384aee2d47766fa20e6b0ba4d73075f22d08..e91ec74a5247d86fd52dc62ae8c0c5c1475c952a 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** in order to generate code for DELETE FROM statements.
 **
-** $Id: delete.c,v 1.163 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: delete.c,v 1.164 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -488,18 +488,16 @@ void sqlite3GenerateRowIndexDelete(
   Index *pIdx;
   int r1;
 
-  r1 = sqlite3GetTempReg(pParse);
   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
-    sqlite3GenerateIndexKey(pParse, pIdx, iCur, r1);
-    sqlite3VdbeAddOp2(pParse->pVdbe, OP_IdxDelete, iCur+i, r1);
+    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, r1, 0);
+    sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
   }
-  sqlite3ReleaseTempReg(pParse, r1);
 }
 
 /*
-** Generate code that will assemble an index key and put it on the top
-** of the tack.  The key with be for index pIdx which is an index on pTab.
+** Generate code that will assemble an index key and put it in register
+** regOut.  The key with be for index pIdx which is an index on pTab.
 ** iCur is the index of a cursor open on the pTab table and pointing to
 ** the entry that needs indexing.
 **
@@ -512,7 +510,8 @@ int sqlite3GenerateIndexKey(
   Parse *pParse,     /* Parsing context */
   Index *pIdx,       /* The index for which to generate a key */
   int iCur,          /* Cursor number for the pIdx->pTable table */
-  int regOut         /* Write the new index key to this register */
+  int regOut,        /* Write the new index key to this register */
+  int doMakeRec      /* Run the OP_MakeRecord instruction if true */
 ){
   Vdbe *v = pParse->pVdbe;
   int j;
@@ -532,8 +531,10 @@ int sqlite3GenerateIndexKey(
       sqlite3ColumnDefault(v, pTab, idx);
     }
   }
-  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
-  sqlite3IndexAffinityStr(v, pIdx);
+  if( doMakeRec ){
+    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
+    sqlite3IndexAffinityStr(v, pIdx);
+  }
   sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
   return regBase;
 }
index 98d7d2a0ffcad834407298bca995c1e21815f172..8c396b3b42679ba44df6b0b944ba7492810e167d 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.172 2008/03/20 11:04:21 danielk1977 Exp $
+** $Id: pragma.c,v 1.173 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -941,7 +941,7 @@ void sqlite3Pragma(
             { OP_IfPos,       1,  0,  0},    /* 9 */
             { OP_Halt,        0,  0,  0},
           };
-          sqlite3GenerateIndexKey(pParse, pIdx, 1, 3);
+          sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 1);
           jmp2 = sqlite3VdbeAddOp3(v, OP_Found, j+2, 0, 3);
           addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
           sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
index 3df5f40559a309cb269f1a9fb3bf61fb525a7ffa..8167056ba4aed606a29750035877d421f83f09be 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.418 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: select.c,v 1.419 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -598,12 +598,7 @@ static void selectInnerLoop(
     ** the temporary table iParm.
     */
     case SRT_Except: {
-      int r1;
-      r1 = sqlite3GetTempReg(pParse);
-      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
-      sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
-      sqlite3VdbeAddOp2(v, OP_IdxDelete, iParm, r1);
-      sqlite3ReleaseTempReg(pParse, r1);
+      sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn);
       break;
     }
 #endif
index 8f6b5bdd622059617d1ae9c6d1340448e4137fef..b5abcd661274203623fd848c4a57aa28454ff40f 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.679 2008/03/21 16:45:47 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.680 2008/03/25 17:23:33 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1863,7 +1863,7 @@ int sqlite3ExprIsInteger(Expr*, int*);
 int sqlite3IsRowid(const char*);
 void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int);
 void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-int sqlite3GenerateIndexKey(Parse*, Index*, int, int);
+int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
 void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                      int*,int,int,int,int);
 void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*,int,int,int,int);
index e3922f67d8bc343a0a856ed429ff6ada36502861..e147bc9c323b7f5ad7ce87b2648b54cf8988da33 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.93 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: test3.c,v 1.94 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include "btreeInt.h"
@@ -788,9 +788,9 @@ static int btree_move_to(
       sqlite3BtreeLeave(pCur->pBtree);
       return TCL_ERROR;
     }
-    rc = sqlite3BtreeMoveto(pCur, 0, iKey, 0, &res);
+    rc = sqlite3BtreeMoveto(pCur, 0, 0, iKey, 0, &res);
   }else{
-    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res);  
+    rc = sqlite3BtreeMoveto(pCur, argv[2], 0, strlen(argv[2]), 0, &res);  
   }
   sqlite3BtreeLeave(pCur->pBtree);
   if( rc ){
index e491340fae206af9e0444b0b9053a00e94d92ca0..72657ce36fd4e42e5aad55a889478e98ef65cf0a 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.717 2008/03/25 09:47:35 danielk1977 Exp $
+** $Id: vdbe.c,v 1.718 2008/03/25 17:23:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -2794,7 +2794,7 @@ case OP_MoveGt: {       /* jump, in3 */
         pC->deferredMoveto = 1;
         break;
       }
-      rc = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, 0, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)iKey, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
@@ -2803,7 +2803,7 @@ case OP_MoveGt: {       /* jump, in3 */
     }else{
       assert( pIn3->flags & MEM_Blob );
       ExpandBlob(pIn3);
-      rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, pIn3->n, 0, &res);
+      rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
@@ -2888,7 +2888,7 @@ case OP_Found: {        /* jump, in3 */
     if( pOp->opcode==OP_Found ){
       pC->pKeyInfo->prefixIsEqual = 1;
     }
-    rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, pIn3->n, 0, &res);
+    rc = sqlite3BtreeMoveto(pC->pCursor, pIn3->z, 0, pIn3->n, 0, &res);
     pC->pKeyInfo->prefixIsEqual = 0;
     if( rc!=SQLITE_OK ){
       break;
@@ -2965,7 +2965,7 @@ case OP_IsUnique: {        /* jump, in3 */
     */
     assert( pCx->deferredMoveto==0 );
     pCx->cacheStatus = CACHE_STALE;
-    rc = sqlite3BtreeMoveto(pCrsr, zKey, len, 0, &res);
+    rc = sqlite3BtreeMoveto(pCrsr, zKey, 0, len, 0, &res);
     if( rc!=SQLITE_OK ){
       goto abort_due_to_error;
     }
@@ -3033,7 +3033,7 @@ case OP_NotExists: {        /* jump, in3 */
     assert( pIn3->flags & MEM_Int );
     assert( p->apCsr[i]->isTable );
     iKey = intToKey(pIn3->u.i);
-    rc = sqlite3BtreeMoveto(pCrsr, 0, iKey, 0,&res);
+    rc = sqlite3BtreeMoveto(pCrsr, 0, 0, iKey, 0,&res);
     pC->lastRowid = pIn3->u.i;
     pC->rowidIsValid = res==0;
     pC->nullRow = 0;
@@ -3203,7 +3203,7 @@ case OP_NewRowid: {           /* out2-prerelease */
         }
         if( v==0 ) continue;
         x = intToKey(v);
-        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, 0, &res);
+        rx = sqlite3BtreeMoveto(pC->pCursor, 0, 0, (u64)x, 0, &res);
         cnt++;
       }while( cnt<100 && rx==SQLITE_OK && res==0 );
       db->priorNewRowid = v;
@@ -3676,22 +3676,29 @@ case OP_IdxInsert: {        /* in2 */
   break;
 }
 
-/* Opcode: IdxDelete P1 P2 * * *
+/* Opcode: IdxDeleteM P1 P2 P3 * *
 **
-** The content of register P2 is an index key built using the 
-** MakeIdxRec opcode. This opcode removes that entry from the 
+** The content of P3 registers starting at register P2 form
+** an unpacked index key. This opcode removes that entry from the 
 ** index opened by cursor P1.
 */
-case OP_IdxDelete: {        /* in2 */
+case OP_IdxDelete: {
   int i = pOp->p1;
   Cursor *pC;
   BtCursor *pCrsr;
-  assert( pIn2->flags & MEM_Blob );
+  assert( pOp->p3>0 );
+  assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem );
   assert( i>=0 && i<p->nCursor );
   assert( p->apCsr[i]!=0 );
   if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
     int res;
-    rc = sqlite3BtreeMoveto(pCrsr, pIn2->z, pIn2->n, 0, &res);
+    UnpackedRecord r;
+    r.pKeyInfo = pC->pKeyInfo;
+    r.nField = pOp->p3;
+    r.needFree = 0;
+    r.needDestroy = 0;
+    r.aMem = &p->aMem[pOp->p2];
+    rc = sqlite3BtreeMoveto(pCrsr, 0, &r, 0, 0, &res);
     if( rc==SQLITE_OK && res==0 ){
       rc = sqlite3BtreeDelete(pCrsr);
     }
index 5a5193ebaa1ef5299b3deba1e9834237eee21a72..ad6d870042a4034124437ca23a19e142b1a5eb94 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.127 2008/03/25 00:22:21 drh Exp $
+** $Id: vdbe.h,v 1.128 2008/03/25 17:23:34 drh Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -34,7 +34,7 @@ typedef struct Vdbe Vdbe;
 */
 typedef struct VdbeFunc VdbeFunc;
 typedef struct Mem Mem;
-typedef struct VdbeParsedRecord VdbeParsedRecord;
+typedef struct UnpackedRecord UnpackedRecord;
 
 /*
 ** A single instruction of the virtual machine has an opcode
@@ -182,9 +182,9 @@ sqlite3 *sqlite3VdbeDb(Vdbe*);
 void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
 void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 
-VdbeParsedRecord *sqlite3VdbeRecordParse(KeyInfo*,int,const void*,void*,int);
-void sqlite3VdbeRecordUnparse(VdbeParsedRecord*);
-int sqlite3VdbeRecordCompareParsed(int,const void*,VdbeParsedRecord*);
+UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int);
+void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*);
+int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
 
 
 #ifndef NDEBUG
index 4985283cc71a73d0abd03a0d57e55ee550ed0c0c..08821f2661c2e85fb970d2a62cff90cf6e60dd8c 100644 (file)
@@ -335,6 +335,28 @@ struct Vdbe {
 #endif
 };
 
+/*
+** An instance of the following structure holds information about a
+** single index record that has already been parsed out into individual
+** values.
+**
+** A record is an object that contains one or more fields of data.
+** Records are used to store the content of a table row and to store
+** the key of an index.  A blob encoding of a record is created by
+** the OP_MakeRecord opcode of the VDBE and is disassemblied by the
+** OP_Column opcode.
+**
+** This structure holds a record that has already been disassembled
+** into its constitutent fields.
+*/
+struct UnpackedRecord {
+  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
+  u16 nField;         /* Number of entries in apMem[] */
+  u8 needFree;        /* True if memory obtained from sqlite3_malloc() */
+  u8 needDestroy;     /* True if apMem[]s should be destroyed on close */
+  Mem *aMem;          /* Values */
+};
+
 /*
 ** The following are allowed values for Vdbe.magic
 */
index 7e7824a0179b03782589e109ea459dfd390ab23a..9399315cf54f23b4e0564d7f6e9e569133a368cb 100644 (file)
@@ -1803,7 +1803,7 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
     extern int sqlite3_search_count;
 #endif
     assert( p->isTable );
-    rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, 0, &res);
+    rc = sqlite3BtreeMoveto(p->pCursor, 0, 0, p->movetoTarget, 0, &res);
     if( rc ) return rc;
     *p->pIncrKey = 0;
     p->lastRowid = keyToInt(p->movetoTarget);
@@ -2143,120 +2143,9 @@ int sqlite3VdbeSerialGet(
 */
 #define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))
 
-#if 0
-/*
-** This function compares the two table rows or index records specified by 
-** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
-** or positive integer if {nKey1, pKey1} is less than, equal to or 
-** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
-** composed by the OP_MakeRecord opcode of the VDBE.
-**
-** Key1 and Key2 do not have to contain the same number of fields.
-** But if the lengths differ, Key2 must be the shorter of the two.
-*/
-int sqlite3VdbeRecordCompare(
-  void *userData,
-  int nKey1, const void *pKey1, 
-  int nKey2, const void *pKey2
-){
-  KeyInfo *pKeyInfo = (KeyInfo*)userData;
-  u32 d1, d2;          /* Offset into aKey[] of next data element */
-  u32 idx1, idx2;      /* Offset into aKey[] of next header element */
-  u32 szHdr1, szHdr2;  /* Number of bytes in header */
-  int i = 0;
-  int nField;
-  int rc = 0;
-  const unsigned char *aKey1 = (const unsigned char *)pKey1;
-  const unsigned char *aKey2 = (const unsigned char *)pKey2;
-
-  Mem mem1;
-  Mem mem2;
-  mem1.enc = pKeyInfo->enc;
-  mem1.db = pKeyInfo->db;
-  mem1.flags = 0;
-  mem2.enc = pKeyInfo->enc;
-  mem2.db = pKeyInfo->db;
-  mem2.flags = 0;
-  
-  idx1 = GetVarint(aKey1, szHdr1);
-  d1 = szHdr1;
-  idx2 = GetVarint(aKey2, szHdr2);
-  d2 = szHdr2;
-  nField = pKeyInfo->nField;
-  while( idx1<szHdr1 && idx2<szHdr2 ){
-    u32 serial_type1;
-    u32 serial_type2;
-
-    /* Read the serial types for the next element in each key. */
-    idx1 += GetVarint( aKey1+idx1, serial_type1 );
-    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
-    idx2 += GetVarint( aKey2+idx2, serial_type2 );
-    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
-
-    /* Extract the values to be compared.
-    */
-    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
-    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
-
-    /* Do the comparison
-    */
-    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
-    if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
-    if( mem2.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
-    if( rc!=0 ){
-      break;
-    }
-    i++;
-  }
-
-  /* One of the keys ran out of fields, but all the fields up to that point
-  ** were equal. If the incrKey flag is true, then the second key is
-  ** treated as larger.
-  */
-  if( rc==0 ){
-    if( pKeyInfo->incrKey ){
-      rc = -1;
-    }else if( !pKeyInfo->prefixIsEqual ){
-      if( d1<nKey1 ){
-        rc = 1;
-      }else if( d2<nKey2 ){
-        rc = -1;  /* Only occurs on a corrupt database file */
-      }
-    }
-  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
-               && pKeyInfo->aSortOrder[i] ){
-    rc = -rc;
-  }
-
-  return rc;
-}
-#endif
-
-/*
-** An instance of the following structure holds information about a
-** single index record that has already been parsed out into individual
-** values.
-**
-** A record is an object that contains one or more fields of data.
-** Records are used to store the content of a table row and to store
-** the key of an index.  A blob encoding of a record is created by
-** the OP_MakeRecord opcode of the VDBE and is disassemblied by the
-** OP_Column opcode.
-**
-** This structure holds a record that has already been disassembled
-** into its constitutent fields.
-*/
-struct VdbeParsedRecord {
-  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
-  u16 nField;         /* Number of entries in apMem[] */
-  u8 needFree;        /* True if memory obtained from sqlite3_malloc() */
-  u8 needDestroy;     /* True if apMem[]s should be destroyed on close */
-  Mem *apMem[1];      /* Values */
-};
-
 /*
 ** Given the nKey-byte encoding of a record in pKey[], parse the
-** record into a VdbeParsedRecord structure.  Return a pointer to
+** record into a UnpackedRecord structure.  Return a pointer to
 ** that structure.
 **
 ** The calling function might provide szSpace bytes of memory
@@ -2265,9 +2154,9 @@ struct VdbeParsedRecord {
 ** not big enough, space is obtained from sqlite3_malloc().
 **
 ** The returned structure should be closed by a call to
-** sqlite3VdbeRecordUnparse().
+** sqlite3VdbeDeleteUnpackedRecord().
 */ 
-VdbeParsedRecord *sqlite3VdbeRecordParse(
+UnpackedRecord *sqlite3VdbeRecordUnpack(
   KeyInfo *pKeyInfo,     /* Information about the record format */
   int nKey,              /* Size of the binary record */
   const void *pKey,      /* The binary record */
@@ -2275,14 +2164,13 @@ VdbeParsedRecord *sqlite3VdbeRecordParse(
   int szSpace            /* Size of pSpace[] in bytes */
 ){
   const unsigned char *aKey = (const unsigned char *)pKey;
-  VdbeParsedRecord *p;
+  UnpackedRecord *p;
   int nByte;
   int i, idx, d;
   u32 szHdr;
   Mem *pMem;
   
-  nByte = sizeof(*p) + sizeof(Mem*)*pKeyInfo->nField
-                     + sizeof(Mem)*(pKeyInfo->nField+1);
+  nByte = sizeof(*p) + sizeof(Mem)*(pKeyInfo->nField+1);
   if( nByte>szSpace ){
     p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
     if( p==0 ) return 0;
@@ -2294,7 +2182,7 @@ VdbeParsedRecord *sqlite3VdbeRecordParse(
   p->pKeyInfo = pKeyInfo;
   p->nField = pKeyInfo->nField + 1;
   p->needDestroy = 1;
-  pMem = (Mem*)&p->apMem[pKeyInfo->nField+1];
+  p->aMem = pMem = (Mem*)&p[1];
   idx = GetVarint(aKey, szHdr);
   d = szHdr;
   i = 0;
@@ -2307,22 +2195,24 @@ VdbeParsedRecord *sqlite3VdbeRecordParse(
     pMem->db = pKeyInfo->db;
     pMem->flags = 0;
     d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
-    p->apMem[i++] = pMem++;
+    pMem++;
+    i++;
   }
   p->nField = i;
   return (void*)p;
 }
 
 /*
-** This routine destroys a VdbeParsedRecord object
+** This routine destroys a UnpackedRecord object
 */
-void sqlite3VdbeRecordUnparse(VdbeParsedRecord *p){
+void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){
   if( p ){
     if( p->needDestroy ){
       int i;
-      for(i=0; i<p->nField; i++){
-        if( p->apMem[i]->flags & MEM_Dyn ){
-          sqlite3VdbeMemRelease(p->apMem[i]);
+      Mem *pMem;
+      for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){
+        if( pMem->flags & MEM_Dyn ){
+          sqlite3VdbeMemRelease(pMem);
         }
       }
     }
@@ -2351,9 +2241,9 @@ void sqlite3VdbeRecordUnparse(VdbeParsedRecord *p){
 ** separately and submit the parsed version.  In this way, we avoid
 ** parsing the same Key2 multiple times in a row.
 */
-int sqlite3VdbeRecordCompareParsed(
+int sqlite3VdbeRecordCompare(
   int nKey1, const void *pKey1, 
-  VdbeParsedRecord *pPKey2
+  UnpackedRecord *pPKey2
 ){
   u32 d1;            /* Offset into aKey[] of next data element */
   u32 idx1;          /* Offset into aKey[] of next header element */
@@ -2386,7 +2276,7 @@ int sqlite3VdbeRecordCompareParsed(
 
     /* Do the comparison
     */
-    rc = sqlite3MemCompare(&mem1, pPKey2->apMem[i],
+    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
                            i<nField ? pKeyInfo->aColl[i] : 0);
     if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
     if( rc!=0 ){
@@ -2483,7 +2373,7 @@ int sqlite3VdbeIdxKeyCompare(
   BtCursor *pCur = pC->pCursor;
   int lenRowid;
   Mem m;
-  VdbeParsedRecord *pRec;
+  UnpackedRecord *pRec;
   char zSpace[200];
 
   sqlite3BtreeKeySize(pCur, &nCellKey);
@@ -2498,13 +2388,13 @@ int sqlite3VdbeIdxKeyCompare(
     return rc;
   }
   lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
-  pRec = sqlite3VdbeRecordParse(pC->pKeyInfo, nKey, pKey,
+  pRec = sqlite3VdbeRecordUnpack(pC->pKeyInfo, nKey, pKey,
                                 zSpace, sizeof(zSpace));
   if( pRec==0 ){
     return SQLITE_NOMEM;
   }
-  *res = sqlite3VdbeRecordCompareParsed(m.n-lenRowid, m.z, pRec);
-  sqlite3VdbeRecordUnparse(pRec);
+  *res = sqlite3VdbeRecordCompare(m.n-lenRowid, m.z, pRec);
+  sqlite3VdbeDeleteUnpackedRecord(pRec);
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
 }