diff --git a/manifest b/manifest index f20f7a0353..08b453f312 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 9cb218f1b4..54a81caa10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a09f5605ac7c6e503eb10acfdc607010414d917 \ No newline at end of file +3861e853105cb8da344c7eebd2e455622b26395e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c0b04cc08c..4d42969be8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -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 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index eece50f7a1..a368b96c63 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -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) */ }; diff --git a/src/vdbe.h b/src/vdbe.h index c08512e7aa..389c1d5ffb 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -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 *); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 007f4e650d..f15f5e95be 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -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; } diff --git a/src/vdbesort.c b/src/vdbesort.c index be5a6064c2..b9ed97e8b3 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -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( mxCachemxPmaSize = mxCache * pgsz; } - pSorter->xRecordCompare = sqlite3VdbeFindSorterCompare(pCsr->pKeyInfo); return SQLITE_OK; } diff --git a/src/where.c b/src/where.c index a5dd7b59e7..4ce0cb7ded 100644 --- a/src/where.c +++ b/src/where.c @@ -1913,7 +1913,7 @@ static void whereKeyStats( assert( pRec->nField>0 && iColnSampleCol ); 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( inSample ); - 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 */