]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Tables and indices use the same record format. (CVS 1482)
authordrh <drh@noemail.net>
Fri, 28 May 2004 08:21:05 +0000 (08:21 +0000)
committerdrh <drh@noemail.net>
Fri, 28 May 2004 08:21:05 +0000 (08:21 +0000)
FossilOrigin-Name: 1b15b32bdbccae555243e67aa011139c50dc2fb3

manifest
manifest.uuid
src/vdbeInt.h
src/vdbeaux.c
src/vdbemem.c

index 88f873d24b0c7b44ca158abb262734536701b579..8ebddf2f8fb3c61c8ec9a8008319788860a22ea8 100644 (file)
--- 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
index 8acdec43de38a4b9ed8788861b802769073b6312..300624b696a5d18a27cdc004d9b7c27308deaa8d 100644 (file)
@@ -1 +1 @@
-ebd564d10b0ecd7ff15cbd6cd2b979c9f767476c
\ No newline at end of file
+1b15b32bdbccae555243e67aa011139c50dc2fb3
\ No newline at end of file
index 5244a4d43a4b6e37dc20b52d0a007fac841bba63..d41dbdd3bb8b49617ee766d658fed68ac6edfbba 100644 (file)
@@ -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
index 0873dd0ae1ccc38a4ca0a7cf83c131bcbd4023d2..e643284b041cd4883d897ae3f4dcdbe97ad65ad1 100644 (file)
@@ -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<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);
 }
 
 /*
@@ -1442,7 +1362,7 @@ int sqlite3VdbeRowCompare(
   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;
@@ -1450,7 +1370,9 @@ int sqlite3VdbeRowCompare(
 
     /* 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
@@ -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, i<nField ? pKeyInfo->aColl[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( d1<nKey1 ){
       rc = 1;
@@ -1494,6 +1415,19 @@ int sqlite3VdbeRowCompare(
 
   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);
+}
   
 
 /*
@@ -1502,38 +1436,29 @@ int sqlite3VdbeRowCompare(
 ** 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;
 }
 
@@ -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;
 }
index 205150e03887d5a5742ec801a4076d2e207faf4f..d3e3860ffcbed995d73cc5241e24d293849f199a 100644 (file)
@@ -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
-