From: drh Date: Fri, 28 May 2004 08:21:05 +0000 (+0000) Subject: Tables and indices use the same record format. (CVS 1482) X-Git-Tag: version-3.0.0~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5788201543b12f62308732cb6ff31ab32933e72;p=thirdparty%2Fsqlite.git Tables and indices use the same record format. (CVS 1482) FossilOrigin-Name: 1b15b32bdbccae555243e67aa011139c50dc2fb3 --- diff --git a/manifest b/manifest index 88f873d24b..8ebddf2f8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -71,10 +71,10 @@ F src/util.c d299404febd509556e720fbecadd880756b0f899 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 @@ -203,7 +203,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 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 diff --git a/manifest.uuid b/manifest.uuid index 8acdec43de..300624b696 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c \ No newline at end of file +1b15b32bdbccae555243e67aa011139c50dc2fb3 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 5244a4d43a..d41dbdd3bb 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -350,6 +350,7 @@ int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*); int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*); +int sqlite3VdbeIdxRowidLen(int,const u8*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); @@ -364,6 +365,7 @@ int sqlite3VdbeMemDynamicify(Mem*); int sqlite3VdbeMemStringify(Mem*, int); int sqlite3VdbeMemIntegerify(Mem*); int sqlite3VdbeMemRealify(Mem*); +int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); #ifndef NDEBUG void sqlite3VdbeMemSanity(Mem*, u8); #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0873dd0ae1..e643284b04 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1329,87 +1329,7 @@ int sqlite3VdbeKeyCompare( 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 serial_type2 ){ - rc = +1; - }else{ - rc = 0; - } - return rc; - } - - assert( inField ); - - /* 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( offset1aSortOrder && inField && pKeyInfo->aSortOrder[i] ){ - rc = -rc; - } - - return rc; + return sqlite3VdbeRowCompare(userData,nKey1,pKey1,nKey2,pKey2); } /* @@ -1442,7 +1362,7 @@ int sqlite3VdbeRowCompare( idx2 = sqlite3GetVarint32(pKey2, &szHdr2); d2 = szHdr2; nField = pKeyInfo->nField; - while( idx1=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 @@ -1460,7 +1382,7 @@ int sqlite3VdbeRowCompare( 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, iaColl[i] : 0); if( mem1.flags&MEM_Dyn ){ sqliteFree(mem1.z); } @@ -1479,7 +1401,6 @@ int sqlite3VdbeRowCompare( */ if( rc==0 ){ if( pKeyInfo->incrKey ){ - assert( d2==nKey2 ); rc = -1; }else if( d110)?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; } @@ -1543,47 +1468,34 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ ** 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; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 205150e038..d3e3860ffc 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -443,6 +443,72 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ 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 @@ -481,4 +547,3 @@ void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){ || (pMem->flags&MEM_Null)==0 ); } #endif -