-C Tables\sand\sindices\suse\sthe\ssame\srecord\sformat.\s(CVS\s1481)
-D 2004-05-28T08:21:02
+C Tables\sand\sindices\suse\sthe\ssame\srecord\sformat.\s(CVS\s1482)
+D 2004-05-28T08:21:06
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
F src/vdbe.c c661752ea19a8b5a041d8c4f234e1524f6b3250e
F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
-F src/vdbeInt.h 57b649105aeab1e39e77bdb3de3c1560deddc69e
+F src/vdbeInt.h c2bcd6e5a6e6a3753e4c5a368629c3a625719bfc
F src/vdbeapi.c b0bb1f98c899ba00c8a5cbca612c2a28a1bb79de
-F src/vdbeaux.c 97f240824de0d347967ea1616c5f59bbcf933591
-F src/vdbemem.c b487e8a903012de1c0b7f603e8efeede2b51b21d
+F src/vdbeaux.c 75428f01c80382b5e2c91ba424c2f73db7645cbc
+F src/vdbemem.c c97c145ff6d9fc5b4236704c04a65849117e6214
F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 321f8c463520e99681de878b743027c570b73e35
-R b41c78025f27adccaab04283941e1081
+P ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c
+R b3ce60af64a3cb61111b582624bafa84
U drh
-Z 03b836ac44307f3719b7ddd6c55ebe4b
+Z 4321dd90c98a1981140d1a57a35baa0c
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
- KeyInfo *pKeyInfo = (KeyInfo*)userData;
- int offset1 = 0;
- int offset2 = 0;
- int i = 0;
- int rc = 0;
- const unsigned char *aKey1 = (const unsigned char *)pKey1;
- const unsigned char *aKey2 = (const unsigned char *)pKey2;
-
- assert( pKeyInfo!=0 );
- while( offset1<nKey1 && offset2<nKey2 ){
- Mem mem1;
- Mem mem2;
- u32 serial_type1;
- u32 serial_type2;
-
- /* Read the serial types for the next element in each key. */
- offset1 += sqlite3GetVarint32(&aKey1[offset1], &serial_type1);
- offset2 += sqlite3GetVarint32(&aKey2[offset2], &serial_type2);
-
- /* If either of the varints just read in are 0 (not a type), then
- ** this is the end of the keys. The remaining data in each key is
- ** the varint rowid. Compare these as signed integers and return
- ** the result.
- */
- if( !serial_type1 || !serial_type2 ){
- assert( !serial_type1 && !serial_type2 );
- sqlite3GetVarint32(&aKey1[offset1], &serial_type1);
- sqlite3GetVarint32(&aKey2[offset2], &serial_type2);
- if( serial_type1 < serial_type2 ){
- rc = -1;
- }else if( serial_type1 > serial_type2 ){
- rc = +1;
- }else{
- rc = 0;
- }
- return rc;
- }
-
- assert( i<pKeyInfo->nField );
-
- /* Assert that there is enough space left in each key for the blob of
- ** data to go with the serial type just read. This assert may fail if
- ** the file is corrupted. Then read the value from each key into mem1
- ** and mem2 respectively.
- */
- offset1 += sqlite3VdbeSerialGet(&aKey1[offset1], serial_type1, &mem1);
- offset2 += sqlite3VdbeSerialGet(&aKey2[offset2], serial_type2, &mem2);
-
- rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
- if( mem1.flags&MEM_Dyn ){
- sqliteFree(mem1.z);
- }
- if( mem2.flags&MEM_Dyn ){
- sqliteFree(mem2.z);
- }
- 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 ){
- assert( offset2==nKey2 );
- rc = -1;
- }else if( offset1<nKey1 ){
- rc = 1;
- }else if( offset2<nKey2 ){
- rc = -1;
- }
- }
-
- if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
- rc = -rc;
- }
-
- return rc;
+ return sqlite3VdbeRowCompare(userData,nKey1,pKey1,nKey2,pKey2);
}
/*
idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
d2 = szHdr2;
nField = pKeyInfo->nField;
- while( idx1<szHdr1 && idx2<szHdr2 && d1<nKey1 && d2<nKey2 && i<nField ){
+ while( idx1<szHdr1 && idx2<szHdr2 ){
Mem mem1;
Mem mem2;
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
+ if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
+ if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
/* Assert that there is enough space left in each key for the blob of
** data to go with the serial type just read. This assert may fail if
d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
- rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
+ rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
if( mem1.flags&MEM_Dyn ){
sqliteFree(mem1.z);
}
*/
if( rc==0 ){
if( pKeyInfo->incrKey ){
- assert( d2==nKey2 );
rc = -1;
}else if( d1<nKey1 ){
rc = 1;
return rc;
}
+
+/*
+** The argument is an index key that contains the ROWID at the end.
+** Return the length of the rowid.
+*/
+int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
+ u32 szHdr; /* Size of the header */
+ u32 typeRowid; /* Serial type of the rowid */
+
+ sqlite3GetVarint32(aKey, &szHdr);
+ sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);
+ return sqlite3VdbeSerialTypeLen(typeRowid);
+}
/*
** everything works, or an error code otherwise.
*/
int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
- i64 sz;
+ u64 nCellKey;
int rc;
- char buf[10];
- int len;
- u64 r;
+ u32 szHdr; /* Size of the header */
+ u32 typeRowid; /* Serial type of the rowid */
+ u32 lenRowid; /* Size of the rowid */
+ Mem m, v;
- rc = sqlite3BtreeKeySize(pCur, &sz);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- len = ((sz>10)?10:sz);
-
- /* If there are less than 2 bytes in the key, this cannot be
- ** a valid index entry. In practice this comes up for a query
- ** of the sort "SELECT max(x) FROM t1;" when t1 is an empty table
- ** with an index on x. In this case just call the rowid 0.
- */
- if( len<2 ){
- *rowid = 0;
- return SQLITE_OK;
+ sqlite3BtreeKeySize(pCur, &nCellKey);
+ if( nCellKey<=0 ){
+ return SQLITE_CORRUPT;
}
-
- rc = sqlite3BtreeKey(pCur, sz-len, len, buf);
- if( rc!=SQLITE_OK ){
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
+ if( rc ){
return rc;
}
-
- len--;
- while( buf[len-1] && --len );
-
- sqlite3GetVarint(&buf[len], &r);
- *rowid = r;
+ sqlite3GetVarint32(m.z, &szHdr);
+ sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
+ lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
+ sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
+ *rowid = v.i;
+ if( m.flags & MEM_Dyn ){
+ sqliteFree(m.z);
+ }
return SQLITE_OK;
}
** that is negative, zero, or positive if pC is less than, equal to,
** or greater than pKey. Return SQLITE_OK on success.
**
-** pKey might contain fewer terms than the cursor.
+** pKey is either created without a rowid or is truncated so that it
+** omits the rowid at the end. The rowid at the end of the index entry
+** is ignored as well.
*/
int sqlite3VdbeIdxKeyCompare(
Cursor *pC, /* The cursor to compare against */
int nKey, const u8 *pKey, /* The key to compare */
int *res /* Write the comparison result here */
){
- unsigned char *pCellKey;
u64 nCellKey;
- int freeCellKey = 0;
int rc;
- int len;
BtCursor *pCur = pC->pCursor;
+ int lenRowid;
+ Mem m;
sqlite3BtreeKeySize(pCur, &nCellKey);
if( nCellKey<=0 ){
*res = 0;
return SQLITE_OK;
}
-
- pCellKey = (unsigned char *)sqlite3BtreeKeyFetch(pCur, nCellKey);
- if( !pCellKey ){
- pCellKey = (unsigned char *)sqliteMallocRaw(nCellKey);
- if( !pCellKey ){
- return SQLITE_NOMEM;
- }
- freeCellKey = 1;
- rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
- if( rc!=SQLITE_OK ){
- sqliteFree(pCellKey);
- return rc;
- }
+ rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
+ if( rc ){
+ return rc;
}
-
- len = nCellKey-2;
- while( pCellKey[len] && --len );
-
- *res = sqlite3VdbeKeyCompare(pC->pKeyInfo, len, pCellKey, nKey, pKey);
-
- if( freeCellKey ){
- sqliteFree(pCellKey);
+ lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
+ *res = sqlite3VdbeKeyCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
+ if( m.flags & MEM_Dyn ){
+ sqliteFree(m.z);
}
return SQLITE_OK;
}
return rc;
}
+/*
+** Move data out of a btree key or data field and into a Mem structure.
+** The data or key is taken from the entry that pCur is currently pointing
+** to. offset and amt determine what portion of the data or key to retrieve.
+** key is true to get the key or false to get data. The result is written
+** into the pMem element.
+**
+** The pMem structure is assumed to be uninitialized. Any prior content
+** is overwritten without being freed.
+**
+** If this routine fails for any reason (malloc returns NULL or unable
+** to read from the disk) then the pMem is left in an inconsistent state.
+*/
+int sqlite3VdbeMemFromBtree(
+ BtCursor *pCur, /* Cursor pointing at record to retrieve. */
+ int offset, /* Offset from the start of data to return bytes from. */
+ int amt, /* Number of bytes to return. */
+ int key, /* If true, retrieve from the btree key, not data. */
+ Mem *pMem /* OUT: Return data in this Mem structure. */
+){
+ char *zData;
+
+ if( key ){
+ zData = (char *)sqlite3BtreeKeyFetch(pCur, offset+amt);
+ }else{
+ zData = (char *)sqlite3BtreeDataFetch(pCur, offset+amt);
+ }
+
+ pMem->n = amt;
+ if( zData ){
+ pMem->z = &zData[offset];
+ pMem->flags = MEM_Blob|MEM_Ephem;
+ }else{
+ int rc;
+ if( amt>NBFS-2 ){
+ zData = (char *)sqliteMallocRaw(amt+2);
+ if( !zData ){
+ return SQLITE_NOMEM;
+ }
+ pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
+ }else{
+ zData = &(pMem->zShort[0]);
+ pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
+ }
+ pMem->z = zData;
+ pMem->enc = 0;
+ pMem->type = SQLITE3_BLOB;
+
+ if( key ){
+ rc = sqlite3BtreeKey(pCur, offset, amt, zData);
+ }else{
+ rc = sqlite3BtreeData(pCur, offset, amt, zData);
+ }
+ zData[amt] = 0;
+ zData[amt+1] = 0;
+ if( rc!=SQLITE_OK ){
+ if( amt>NBFS ){
+ sqliteFree(zData);
+ }
+ return rc;
+ }
+ }
+
+ return SQLITE_OK;
+}
+
#ifndef NDEBUG
/*
** Perform various checks on the memory cell pMem. An assert() will
|| (pMem->flags&MEM_Null)==0 );
}
#endif
-