]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove the vdbeRecordCompareLargeHeader function. Fix some other details.
authordan <dan@noemail.net>
Sat, 1 Mar 2014 19:44:56 +0000 (19:44 +0000)
committerdan <dan@noemail.net>
Sat, 1 Mar 2014 19:44:56 +0000 (19:44 +0000)
FossilOrigin-Name: 3861e853105cb8da344c7eebd2e455622b26395e

manifest
manifest.uuid
src/btree.c
src/sqliteInt.h
src/vdbe.h
src/vdbeaux.c
src/vdbesort.c
src/where.c

index f20f7a0353bdedf934c127a0a6ccdec8b74f49b5..08b453f3122e89ab220801de656d4d1e974f45b9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\ssome\stest\scases\sthat\sdeal\swith\scorrupt\sdatabases.
-D 2014-02-28T18:39:51.462
+C Remove\sthe\svdbeRecordCompareLargeHeader\sfunction.\sFix\ssome\sother\sdetails.
+D 2014-03-01T19:44:56.574
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -163,7 +163,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c 77f175987c80ebec063f8653cb7d300776411413
+F src/btree.c d288e668614449571ec269535dc4aaf216a23db2
 F src/btree.h 9e0f97c01b972f779eb7655cfb4f8727fd6dc26f
 F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
 F src/build.c 00ce613bc2256e525c9195cb10d0df7bcc48d1f0
@@ -221,7 +221,7 @@ F src/shell.c bf75ce6bea4c8f56c1b46bee201c25acddffb675
 F src/sqlite.h.in a2ef671f92747a5a1c8a47bad5c585a8dd9eca80
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 843e23d43ee2ab9369e68eb778815ba02835da59
+F src/sqliteInt.h b06500d391d4b7bf4c69fc110e37dd45719b760c
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -278,19 +278,19 @@ F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
 F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
 F src/vdbe.c ab910206dd8c9c5c1455f82953934bdbfe0bcc2a
-F src/vdbe.h 6833579fc0fbdc1c933e34519064841abda5b9b3
+F src/vdbe.h c6dc01f85cf3bdcc992d244aeff952c033fd5ad0
 F src/vdbeInt.h 5286af9067cabdb8ba57b87c0c988a931be6c6c8
 F src/vdbeapi.c 5bc41aaea448a7fc250902c418f1795859be3820
-F src/vdbeaux.c aad5345869c110f45074e2c1ca230e623b1ba182
+F src/vdbeaux.c da0979ce81ecdf3d018be9ee1e8998110181fb12
 F src/vdbeblob.c d939997de046b8fcc607cfee4248f3d33dbcca50
 F src/vdbemem.c 93fc3f13ebe6809ebaac8d0a17c812ec053ba233
-F src/vdbesort.c 72290f12428973c2c6b9d4f95ad0a7c8181e1280
+F src/vdbesort.c 46801acb342e5e4c07ba1777fe58880c143abb59
 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
 F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
 F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
-F src/where.c 6042e1a377cf7dc72c10493269ed75e276275cd8
+F src/where.c 36ef94b653a10944b39e34938ee4c758f3f42879
 F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -1152,7 +1152,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 284bde0ee20261737446eb8f5b6b36ad9bc3f355
-R 75b55639e7bdd048d8263d0acfa3cf8a
+P 3a09f5605ac7c6e503eb10acfdc607010414d917
+R b23b5e438c1d698174ad52d7cfba370e
 U dan
-Z d116a418c5c97c83b8ebfe7a3e655c3c
+Z 35d9cecacf0cc917a2c2ed9a75b36eab
index 9cb218f1b4e12ebd8fa2beb62503d22abc9423d3..54a81caa104e31bd29136c4afa2b6cfb814e7e25 100644 (file)
@@ -1 +1 @@
-3a09f5605ac7c6e503eb10acfdc607010414d917
\ No newline at end of file
+3861e853105cb8da344c7eebd2e455622b26395e
\ No newline at end of file
index c0b04cc08cd81eb35a35f1ee3ab23dc31375e67e..4d42969be8b0151276ba12791cf95d166ad2a65c 100644 (file)
@@ -4661,14 +4661,14 @@ int sqlite3BtreeMovetoUnpacked(
           ** single byte varint and the record fits entirely on the main
           ** b-tree page.  */
           testcase( pCell+nCell+1==pPage->aDataEnd );
-          c = xRecordCompare(nCell, (void*)&pCell[1], pCell[1], 1, pIdxKey);
+          c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0);
         }else if( !(pCell[1] & 0x80) 
           && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
         ){
           /* The record-size field is a 2 byte varint and the record 
           ** fits entirely on the main b-tree page.  */
           testcase( pCell+nCell+2==pPage->aDataEnd );
-          c = xRecordCompare(nCell, (void*)&pCell[2], pCell[2], 1, pIdxKey);
+          c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0);
         }else{
           /* The record flows over onto one or more overflow pages. In
           ** this case the whole cell needs to be parsed, a buffer allocated
@@ -4689,7 +4689,7 @@ int sqlite3BtreeMovetoUnpacked(
             sqlite3_free(pCellKey);
             goto moveto_finish;
           }
-          c = xRecordCompare(nCell, pCellKey, ((u8*)pCellKey)[0], 1, pIdxKey);
+          c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
           sqlite3_free(pCellKey);
         }
         if( c<0 ){
index eece50f7a196061c10456447cc0acbb34271c05a..a368b96c6315c95873c9086777be00f9bef07daa 100644 (file)
@@ -1586,14 +1586,17 @@ struct KeyInfo {
 **
 ** This structure holds a record that has already been disassembled
 ** into its constituent fields.
+**
+** The r1 and r2 member variables are only used by the optimized comparison
+** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
 */
 struct UnpackedRecord {
   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
   u16 nField;         /* Number of entries in apMem[] */
   char default_rc;    /* Comparison result if keys are equal */
   Mem *aMem;          /* Values */
-  int r1;
-  int r2;
+  int r1;             /* Value to return if (lhs > rhs) */
+  int r2;             /* Value to return if (rhs < lhs) */
 };
 
 
index c08512e7aad1b04dd8d12c955c6660ea9fed86db..389c1d5ffb27db56db13f70e849469562dad5008 100644 (file)
@@ -211,12 +211,11 @@ void sqlite3VdbeSetVarmask(Vdbe*, int);
 #endif
 
 void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
-int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
 UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
 
-typedef int (*RecordCompare)(int,const void*,int,u32,UnpackedRecord*);
+typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int);
 RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
-RecordCompare sqlite3VdbeFindSorterCompare(KeyInfo*);
 
 #ifndef SQLITE_OMIT_TRIGGER
 void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
index 007f4e650d3b17ded3ea6556a93befe790da0c5f..f15f5e95be521b4a6307587d66372b82e967cc6d 100644 (file)
@@ -3123,24 +3123,16 @@ void sqlite3VdbeRecordUnpack(
   p->nField = u;
 }
 
+#if SQLITE_DEBUG
 /*
-** This function compares the two table rows or index records
-** specified by {nKey1, pKey1} and pPKey2.  It returns a negative, zero
-** or positive integer if key1 is less than, equal to or 
-** greater than key2.  The {nKey1, pKey1} key must be a blob
-** created by th OP_MakeRecord opcode of the VDBE.  The pPKey2
-** key must be a parsed key such as obtained from
-** sqlite3VdbeParseRecord.
-**
-** Key1 and Key2 do not have to contain the same number of fields.
-** The key with fewer fields is usually compares less than the 
-** longer key.  However if the UNPACKED_INCRKEY flags in pPKey2 is set
-** and the common prefixes are equal, then key1 is less than key2.
-** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
-** equal, then the keys are considered to be equal and
-** the parts beyond the common prefix are ignored.
+** This function compares two index or table record keys in the same way
+** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
+** this function deserializes and compares values using the
+** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
+** in assert() statements to ensure that the optimized code in
+** sqlite3VdbeRecordCompare() returns results with these two primitives.
 */
-static int vdbeRecordComparePrev(
+static int vdbeRecordCompareDebug(
   int nKey1, const void *pKey1, /* Left key */
   UnpackedRecord *pPKey2        /* Right key */
 ){
@@ -3220,10 +3212,17 @@ static int vdbeRecordComparePrev(
   ** value.  */
   return pPKey2->default_rc;
 }
+#endif
 
+/*
+** Both *pMem1 and *pMem2 contain string values. Compare the two values
+** using the collation sequence pColl. As usual, return a negative , zero
+** or positive value if *pMem1 is less than, equal to or greater than 
+** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);".
+*/
 static int vdbeCompareMemString(
-  const Mem *pMem1, 
-  const Mem *pMem2, 
+  const Mem *pMem1,
+  const Mem *pMem2,
   const CollSeq *pColl
 ){
   if( pMem1->enc==pColl->enc ){
@@ -3344,8 +3343,17 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
 }
 
 
+/*
+** The first argument passed to this function is a serial-type that
+** corresponds to an integer - all values between 1 and 9 inclusive 
+** except 7. The second points to a buffer containing an integer value
+** serialized according to serial_type. This function deserializes
+** and returns the value.
+*/
 static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
+  assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
   switch( serial_type ){
+    case 0:
     case 1:
       return (char)aKey[0];
     case 2:
@@ -3354,13 +3362,11 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
       return ((char)aKey[0] << 16) | (aKey[1] << 8) | aKey[2];
     case 4:
       return ((char)aKey[0]<<24) | (aKey[1]<<16) | (aKey[2]<<8)| aKey[3];
-
     case 5: {
       i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
       u32 lsw = (aKey[4] << 8) | aKey[5];
       return (i64)( msw << 16 | (u64)lsw );
     }
-
     case 6: {
       i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
       u32 lsw = ((unsigned)aKey[4]<<24)|(aKey[5]<<16)|(aKey[6]<<8)|aKey[7];
@@ -3371,36 +3377,51 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
   return (serial_type - 8);
 }
 
-static int vdbeRecordCompare(
-  int nKey1, const void *pKey1, /* Left key */
-  int szHdr1,                   /* Size of record header in bytes */
-  u32 idx1,                     /* Offset of first type in header */
-  UnpackedRecord *const pPKey2  /* Right key */
+/*
+** This function compares the two table rows or index records
+** specified by {nKey1, pKey1} and pPKey2.  It returns a negative, zero
+** or positive integer if key1 is less than, equal to or 
+** greater than key2.  The {nKey1, pKey1} key must be a blob
+** created by th OP_MakeRecord opcode of the VDBE.  The pPKey2
+** key must be a parsed key such as obtained from
+** sqlite3VdbeParseRecord.
+**
+** If argument bSkip is non-zero, it is assumed that the caller has already
+** determined that the first fields of the keys are equal.
+**
+** Key1 and Key2 do not have to contain the same number of fields. If all 
+** fields that appear in both keys are equal, then pPKey2->default_rc is 
+** returned.
+*/
+int sqlite3VdbeRecordCompare(
+  int nKey1, const void *pKey1,   /* Left key */
+  UnpackedRecord *const pPKey2,   /* Right key */
+  int bSkip                       /* If true, skip the first field */
 ){
-  u32 d1 = szHdr1;   /* Offset into aKey[] of next data element */
-  int i = 0;
-  int rc = 0;
-  Mem *pRhs = pPKey2->aMem;
+  u32 d1;                         /* Offset into aKey[] of next data element */
+  int i;                          /* Index of next field to compare */
+  int szHdr1;                     /* Size of record header in bytes */
+  u32 idx1;                       /* Offset of first type in header */
+  int rc = 0;                     /* Return value */
+  Mem *pRhs = pPKey2->aMem;       /* Next field of pPKey2 to compare */
   KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
   const unsigned char *aKey1 = (const unsigned char *)pKey1;
   Mem mem1;
 
-#ifdef SQLITE_DEBUG
-  int expected = vdbeRecordComparePrev(nKey1, pKey1, pPKey2);
-  static int nCall = 0;
-  nCall++;
-#endif
-
-  /* If idx==0, then the caller has already determined that the first two
-  ** elements in the keys are equal. Fix the various stack variables so
+  /* If bSkip is true, then the caller has already determined that the first
+  ** two elements in the keys are equal. Fix the various stack variables so
   ** that this routine begins comparing at the second field. */
-  if( idx1==0 ){
+  if( bSkip ){
     u32 s1;
-    assert( sqlite3VarintLen(szHdr1)==1 );
     idx1 = 1 + getVarint32(&aKey1[1], s1);
-    d1 += sqlite3VdbeSerialTypeLen(s1);
+    szHdr1 = aKey1[0];
+    d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
     i = 1;
     pRhs++;
+  }else{
+    idx1 = getVarint32(aKey1, szHdr1);
+    d1 = szHdr1;
+    i = 0;
   }
 
   VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
@@ -3511,18 +3532,14 @@ static int vdbeRecordCompare(
     }
 
     if( rc!=0 ){
-      assert( mem1.zMalloc==0 );  /* See comment below */
       if( pKeyInfo->aSortOrder[i] ){
         rc = -rc;
-#if 0
-        assert( (rc>0 && (rc^(int)0x80000000)<0) 
-             || (rc<0 && (rc^(int)0x80000000)>0) );
-        assert( sizeof(int)==4 );
-        rc ^= (int)0x80000000;    /* similar in spirit to: "rc = -rc;" */
-        assert( rc!=0 );
-#endif
       }
-      assert( (rc<0 && expected<0) || (rc>0 && expected>0) || CORRUPT_DB );
+      assert( CORRUPT_DB 
+          || (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+          || (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
+      );
+      assert( mem1.zMalloc==0 );  /* See comment below */
       return rc;
     }
 
@@ -3534,31 +3551,38 @@ static int vdbeRecordCompare(
 
   /* No memory allocation is ever used on mem1.  Prove this using
   ** the following assert().  If the assert() fails, it indicates a
-  ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
-  */
+  ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).  */
   assert( mem1.zMalloc==0 );
 
   /* rc==0 here means that one or both of the keys ran out of fields and
   ** all the fields up to that point were equal. Return the the default_rc
   ** value.  */
-  assert( pPKey2->default_rc==expected );
+  assert( CORRUPT_DB 
+       || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2) 
+  );
   return pPKey2->default_rc;
 }
 
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare() 
+** that (a) the first field of pPKey2 is an integer, and (b) the 
+** size-of-header varint at the start of (pKey1/nKey1) fits in a single
+** byte (i.e. is less than 128).
+*/
 static int vdbeRecordCompareInt(
   int nKey1, const void *pKey1, /* Left key */
-  int szHdr,
-  u32 idx1,
-  UnpackedRecord *pPKey2        /* Right key */
+  UnpackedRecord *pPKey2,       /* Right key */
+  int bSkip                     /* Ignored */
 ){
-  const u8 *aKey = &((const u8*)pKey1)[szHdr];
+  const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1];
   int serial_type = ((const u8*)pKey1)[1];
   int res;
   i64 v = pPKey2->aMem[0].u.i;
   i64 lhs;
 
-  switch( serial_type ){
+  assert( bSkip==0 );
 
+  switch( serial_type ){
     case 1:
       lhs = (char)(aKey[0]);
       break;
@@ -3571,25 +3595,21 @@ static int vdbeRecordCompareInt(
     case 4:
       lhs = (int)(((u32)aKey[0]<<24) | (aKey[1]<<16) | (aKey[2]<<8)| aKey[3]);
       break;
-
     case 5: {
       i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
       u32 lsw = (aKey[4] << 8) | aKey[5];
       lhs = (i64)( msw << 16 | (u64)lsw );
       break;
     }
-
     case 6: {
       i64 msw = ((char)aKey[0]<<24)|(aKey[1]<<16)|(aKey[2]<<8)|aKey[3];
       u32 lsw = ((unsigned)aKey[4]<<24)|(aKey[5]<<16)|(aKey[6]<<8)|aKey[7];
       lhs = (i64)( msw << 32 | (u64)lsw );
       break;
     }
-
     case 8: 
       lhs = 0;
       break;
-
     case 9:
       lhs = 1;
       break;
@@ -3601,10 +3621,10 @@ static int vdbeRecordCompareInt(
     ** (as gcc is clever enough to combine the two like cases). Other 
     ** compilers might be similar.  */ 
     case 0: case 7:
-      return vdbeRecordCompare(nKey1, pKey1, szHdr, 1, pPKey2);
+      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
 
     default:
-      return vdbeRecordCompare(nKey1, pKey1, szHdr, 1, pPKey2);
+      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
   }
 
   if( v>lhs ){
@@ -3614,31 +3634,37 @@ static int vdbeRecordCompareInt(
   }else if( pPKey2->nField>1 ){
     /* The first fields of the two keys are equal. Compare the trailing 
     ** fields.  */
-    res = vdbeRecordCompare(nKey1, pKey1, szHdr, 0, pPKey2);
+    res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
   }else{
     /* The first fields of the two keys are equal and there are no trailing
     ** fields. Return pPKey2->default_rc in this case. */
     res = pPKey2->default_rc;
   }
 
-  assert( (res==0 && vdbeRecordComparePrev(nKey1, pKey1, pPKey2)==0)
-       || (res<0 && vdbeRecordComparePrev(nKey1, pKey1, pPKey2)<0)
-       || (res>0 && vdbeRecordComparePrev(nKey1, pKey1, pPKey2)>0)
+  assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
+       || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+       || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
        || CORRUPT_DB
   );
   return res;
 }
 
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare() 
+** that (a) the first field of pPKey2 is a string, that (b) the first field
+** uses the collation sequence BINARY and (c) that the size-of-header varint 
+** at the start of (pKey1/nKey1) fits in a single byte.
+*/
 static int vdbeRecordCompareString(
   int nKey1, const void *pKey1, /* Left key */
-  int szHdr,
-  u32 idx1,
-  UnpackedRecord *pPKey2        /* Right key */
+  UnpackedRecord *pPKey2,       /* Right key */
+  int bSkip
 ){
   const u8 *aKey1 = (const u8*)pKey1;
   int serial_type;
   int res;
 
+  assert( bSkip==0 );
   getVarint32(&aKey1[1], serial_type);
 
   if( serial_type<12 ){
@@ -3648,18 +3674,18 @@ static int vdbeRecordCompareString(
   }else{
     int nCmp;
     int nStr;
-    aKey1 = &aKey1[szHdr];
+    int szHdr = aKey1[0];
 
     nStr = (serial_type-12) / 2;
     if( (szHdr + nStr) > nKey1 ) return 0;    /* Corruption */
     nCmp = MIN( pPKey2->aMem[0].n, nStr );
-    res = memcmp(aKey1, pPKey2->aMem[0].z, nCmp);
+    res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
 
     if( res==0 ){
       res = nStr - pPKey2->aMem[0].n;
       if( res==0 ){
         if( pPKey2->nField>1 ){
-          res = vdbeRecordCompare(nKey1, pKey1, szHdr, 0, pPKey2);
+          res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
         }else{
           res = pPKey2->default_rc;
         }
@@ -3675,30 +3701,26 @@ static int vdbeRecordCompareString(
     }
   }
 
-  assert( (res==0 && sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2)==0)
-       || (res<0 && sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2)<0)
-       || (res>0 && sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2)>0)
+  assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
+       || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+       || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
        || CORRUPT_DB
   );
   return res;
 }
 
-
-int vdbeRecordCompareLargeHeader(
-  int nKey1, const void *pKey1, /* Left key */
-  int dummy1, u32 dummy2,       /* Unused arguments */
-  UnpackedRecord *pPKey2        /* Right key */
-){
-  int szHdr;
-  u32 idx1;
-  idx1 = getVarint32(((u8*)pKey1), szHdr);
-  return vdbeRecordCompare(nKey1, pKey1, szHdr, idx1, pPKey2);
-}
-
+/*
+** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
+** suitable for comparing serialized records to the unpacked record passed
+** as the only argument.
+*/
 RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
-  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField) > 10 ){
-    return vdbeRecordCompareLargeHeader;
-  }else{
+  /* As the varints that make up a record header are all 5 bytes in size
+  ** or less, if the binary keys being compared have 25 or fewer fields 
+  ** then it is guaranteed that the varint at the start of every record 
+  ** (the record-header size in bytes) fits in a single byte. If this
+  ** is not the case, then sqlite3VdbeRecordCompare() must be used.  */
+  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=25 ){
     int flags = p->aMem[0].flags;
     if( p->pKeyInfo->aSortOrder[0] ){
       p->r1 = 1;
@@ -3717,25 +3739,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
     }
   }
 
-  return vdbeRecordCompare;
-}
-
-RecordCompare sqlite3VdbeFindSorterCompare(KeyInfo *pKeyInfo){
-  if( (pKeyInfo->nField + pKeyInfo->nXField) > 10 ){
-    return vdbeRecordCompareLargeHeader;
-  }
-  return vdbeRecordCompare;
-}
-
-int sqlite3VdbeRecordCompare(
-  int nKey1, const void *pKey1, /* Left key */
-  UnpackedRecord *pPKey2        /* Right key */
-){
-  int szHdr;
-  u32 idx1;
-
-  idx1 = getVarint32(((u8*)pKey1), szHdr);
-  return vdbeRecordCompare(nKey1, pKey1, szHdr, idx1, pPKey2);
+  return sqlite3VdbeRecordCompare;
 }
 
 /*
@@ -3850,7 +3854,7 @@ int sqlite3VdbeIdxKeyCompare(
   if( rc ){
     return rc;
   }
-  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
+  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked, 0);
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
 }
index be5a6064c25138aa70134ce8117de90ba7ec43a1..b9ed97e8b3a4ba75b38f16e0f047fea2553e4572 100644 (file)
@@ -105,7 +105,6 @@ struct VdbeSorter {
   sqlite3_file *pTemp1;           /* PMA file 1 */
   SorterRecord *pRecord;          /* Head of in-memory record list */
   UnpackedRecord *pUnpacked;      /* Used to unpack keys */
-  RecordCompare xRecordCompare;   /* Record compare function */
 };
 
 /*
@@ -413,10 +412,7 @@ static void vdbeSorterCompare(
     assert( r2->default_rc==0 );
   }
 
-#if 0
-  *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
-#endif
-  *pRes = pSorter->xRecordCompare(nKey1, pKey1, *((u8*)pKey1), 1, r2);
+  *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
 }
 
 /*
@@ -492,7 +488,6 @@ int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
     if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
     pSorter->mxPmaSize = mxCache * pgsz;
   }
-  pSorter->xRecordCompare = sqlite3VdbeFindSorterCompare(pCsr->pKeyInfo);
 
   return SQLITE_OK;
 }
index a5dd7b59e711b522592de1b4a318aebc7a185df4..4ce0cb7ded0eb19d5cd187c76f1d945edc98a713 100644 (file)
@@ -1913,7 +1913,7 @@ static void whereKeyStats(
   assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
   do{
     iTest = (iMin+i)/2;
-    res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);
+    res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec, 0);
     if( res<0 ){
       iMin = iTest+1;
     }else{
@@ -1928,16 +1928,16 @@ static void whereKeyStats(
   if( res==0 ){
     /* If (res==0) is true, then sample $i must be equal to pRec */
     assert( i<pIdx->nSample );
-    assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
+    assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)
          || pParse->db->mallocFailed );
   }else{
     /* Otherwise, pRec must be smaller than sample $i and larger than
     ** sample ($i-1).  */
     assert( i==pIdx->nSample 
-         || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+         || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)>0
          || pParse->db->mallocFailed );
     assert( i==0
-         || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+         || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec, 0)<0
          || pParse->db->mallocFailed );
   }
 #endif /* ifdef SQLITE_DEBUG */