/ Check-in [1b15b32b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Tables and indices use the same record format. (CVS 1482)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1b15b32bdbccae555243e67aa011139c50dc2fb3
User & Date: drh 2004-05-28 08:21:06
Context
2004-05-28
11:37
Allow CREATE TABLE and CREATE INDEX on attached databases. (CVS 1483) check-in: 4984a130 user: danielk1977 tags: trunk
08:21
Tables and indices use the same record format. (CVS 1482) check-in: 1b15b32b user: drh tags: trunk
08:21
Tables and indices use the same record format. (CVS 1481) check-in: ebd564d1 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeInt.h.

   346    346   
   347    347   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   348    348   int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
   349    349   int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
   350    350   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
   351    351   int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*);
   352    352   int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*);
          353  +int sqlite3VdbeIdxRowidLen(int,const u8*);
   353    354   int sqlite3VdbeExec(Vdbe*);
   354    355   int sqlite3VdbeList(Vdbe*);
   355    356   int sqlite3VdbeChangeEncoding(Mem *, int);
   356    357   int sqlite3VdbeMemCopy(Mem*, const Mem*);
   357    358   int sqlite3VdbeMemNulTerminate(Mem*);
   358    359   int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, int);
   359    360   void sqlite3VdbeMemSetInt64(Mem*, long long int);
................................................................................
   360    361   void sqlite3VdbeMemSetDouble(Mem*, double);
   361    362   void sqlite3VdbeMemSetNull(Mem*);
   362    363   int sqlite3VdbeMemMakeWriteable(Mem*);
   363    364   int sqlite3VdbeMemDynamicify(Mem*);
   364    365   int sqlite3VdbeMemStringify(Mem*, int);
   365    366   int sqlite3VdbeMemIntegerify(Mem*);
   366    367   int sqlite3VdbeMemRealify(Mem*);
          368  +int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
   367    369   #ifndef NDEBUG
   368    370   void sqlite3VdbeMemSanity(Mem*, u8);
   369    371   #endif

Changes to src/vdbeaux.c.

  1325   1325   ** compared to.
  1326   1326   */
  1327   1327   int sqlite3VdbeKeyCompare(
  1328   1328     void *userData,
  1329   1329     int nKey1, const void *pKey1, 
  1330   1330     int nKey2, const void *pKey2
  1331   1331   ){
  1332         -  KeyInfo *pKeyInfo = (KeyInfo*)userData;
  1333         -  int offset1 = 0;
  1334         -  int offset2 = 0;
  1335         -  int i = 0;
  1336         -  int rc = 0;
  1337         -  const unsigned char *aKey1 = (const unsigned char *)pKey1;
  1338         -  const unsigned char *aKey2 = (const unsigned char *)pKey2;
  1339         -  
  1340         -  assert( pKeyInfo!=0 );
  1341         -  while( offset1<nKey1 && offset2<nKey2 ){
  1342         -    Mem mem1;
  1343         -    Mem mem2;
  1344         -    u32 serial_type1;
  1345         -    u32 serial_type2;
  1346         -
  1347         -    /* Read the serial types for the next element in each key. */
  1348         -    offset1 += sqlite3GetVarint32(&aKey1[offset1], &serial_type1);
  1349         -    offset2 += sqlite3GetVarint32(&aKey2[offset2], &serial_type2);
  1350         -
  1351         -    /* If either of the varints just read in are 0 (not a type), then
  1352         -    ** this is the end of the keys. The remaining data in each key is
  1353         -    ** the varint rowid. Compare these as signed integers and return
  1354         -    ** the result.
  1355         -    */
  1356         -    if( !serial_type1 || !serial_type2 ){
  1357         -      assert( !serial_type1 && !serial_type2 );
  1358         -      sqlite3GetVarint32(&aKey1[offset1], &serial_type1);
  1359         -      sqlite3GetVarint32(&aKey2[offset2], &serial_type2);
  1360         -      if( serial_type1 < serial_type2 ){
  1361         -        rc = -1;
  1362         -      }else if( serial_type1 > serial_type2 ){
  1363         -        rc = +1;
  1364         -      }else{
  1365         -        rc = 0;
  1366         -      }
  1367         -      return rc;
  1368         -    }
  1369         -
  1370         -    assert( i<pKeyInfo->nField );
  1371         -
  1372         -    /* Assert that there is enough space left in each key for the blob of
  1373         -    ** data to go with the serial type just read. This assert may fail if
  1374         -    ** the file is corrupted.  Then read the value from each key into mem1
  1375         -    ** and mem2 respectively.
  1376         -    */
  1377         -    offset1 += sqlite3VdbeSerialGet(&aKey1[offset1], serial_type1, &mem1);
  1378         -    offset2 += sqlite3VdbeSerialGet(&aKey2[offset2], serial_type2, &mem2);
  1379         -
  1380         -    rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
  1381         -    if( mem1.flags&MEM_Dyn ){
  1382         -      sqliteFree(mem1.z);
  1383         -    }
  1384         -    if( mem2.flags&MEM_Dyn ){
  1385         -      sqliteFree(mem2.z);
  1386         -    }
  1387         -    if( rc!=0 ){
  1388         -      break;
  1389         -    }
  1390         -    i++;
  1391         -  }
  1392         -
  1393         -  /* One of the keys ran out of fields, but all the fields up to that point
  1394         -  ** were equal. If the incrKey flag is true, then the second key is
  1395         -  ** treated as larger.
  1396         -  */
  1397         -  if( rc==0 ){
  1398         -    if( pKeyInfo->incrKey ){
  1399         -      assert( offset2==nKey2 );
  1400         -      rc = -1;
  1401         -    }else if( offset1<nKey1 ){
  1402         -      rc = 1;
  1403         -    }else if( offset2<nKey2 ){
  1404         -      rc = -1;
  1405         -    }
  1406         -  }
  1407         -
  1408         -  if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
  1409         -    rc = -rc;
  1410         -  }
  1411         -
  1412         -  return rc;
         1332  +  return sqlite3VdbeRowCompare(userData,nKey1,pKey1,nKey2,pKey2);
  1413   1333   }
  1414   1334   
  1415   1335   /*
  1416   1336   ** This function compares the two table row records specified by 
  1417   1337   ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
  1418   1338   ** or positive integer if {nKey1, pKey1} is less than, equal to or 
  1419   1339   ** greater than {nKey2, pKey2}.
................................................................................
  1438   1358     const unsigned char *aKey2 = (const unsigned char *)pKey2;
  1439   1359     
  1440   1360     idx1 = sqlite3GetVarint32(pKey1, &szHdr1);
  1441   1361     d1 = szHdr1;
  1442   1362     idx2 = sqlite3GetVarint32(pKey2, &szHdr2);
  1443   1363     d2 = szHdr2;
  1444   1364     nField = pKeyInfo->nField;
  1445         -  while( idx1<szHdr1 && idx2<szHdr2 && d1<nKey1 && d2<nKey2 && i<nField ){
         1365  +  while( idx1<szHdr1 && idx2<szHdr2 ){
  1446   1366       Mem mem1;
  1447   1367       Mem mem2;
  1448   1368       u32 serial_type1;
  1449   1369       u32 serial_type2;
  1450   1370   
  1451   1371       /* Read the serial types for the next element in each key. */
  1452   1372       idx1 += sqlite3GetVarint32(&aKey1[idx1], &serial_type1);
         1373  +    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
  1453   1374       idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);
         1375  +    if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
  1454   1376   
  1455   1377       /* Assert that there is enough space left in each key for the blob of
  1456   1378       ** data to go with the serial type just read. This assert may fail if
  1457   1379       ** the file is corrupted.  Then read the value from each key into mem1
  1458   1380       ** and mem2 respectively.
  1459   1381       */
  1460   1382       d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
  1461   1383       d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
  1462   1384   
  1463         -    rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
         1385  +    rc = sqlite3MemCompare(&mem1, &mem2, i<nField ? pKeyInfo->aColl[i] : 0);
  1464   1386       if( mem1.flags&MEM_Dyn ){
  1465   1387         sqliteFree(mem1.z);
  1466   1388       }
  1467   1389       if( mem2.flags&MEM_Dyn ){
  1468   1390         sqliteFree(mem2.z);
  1469   1391       }
  1470   1392       if( rc!=0 ){
................................................................................
  1475   1397   
  1476   1398     /* One of the keys ran out of fields, but all the fields up to that point
  1477   1399     ** were equal. If the incrKey flag is true, then the second key is
  1478   1400     ** treated as larger.
  1479   1401     */
  1480   1402     if( rc==0 ){
  1481   1403       if( pKeyInfo->incrKey ){
  1482         -      assert( d2==nKey2 );
  1483   1404         rc = -1;
  1484   1405       }else if( d1<nKey1 ){
  1485   1406         rc = 1;
  1486   1407       }else if( d2<nKey2 ){
  1487   1408         rc = -1;
  1488   1409       }
  1489   1410     }
................................................................................
  1490   1411   
  1491   1412     if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){
  1492   1413       rc = -rc;
  1493   1414     }
  1494   1415   
  1495   1416     return rc;
  1496   1417   }
         1418  +
         1419  +/*
         1420  +** The argument is an index key that contains the ROWID at the end.
         1421  +** Return the length of the rowid.
         1422  +*/
         1423  +int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){
         1424  +  u32 szHdr;        /* Size of the header */
         1425  +  u32 typeRowid;    /* Serial type of the rowid */
         1426  +
         1427  +  sqlite3GetVarint32(aKey, &szHdr);
         1428  +  sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid);
         1429  +  return sqlite3VdbeSerialTypeLen(typeRowid);
         1430  +}
  1497   1431     
  1498   1432   
  1499   1433   /*
  1500   1434   ** pCur points at an index entry. Read the rowid (varint occuring at
  1501   1435   ** the end of the entry and store it in *rowid. Return SQLITE_OK if
  1502   1436   ** everything works, or an error code otherwise.
  1503   1437   */
  1504   1438   int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
  1505         -  i64 sz;
         1439  +  u64 nCellKey;
  1506   1440     int rc;
  1507         -  char buf[10];
  1508         -  int len;
  1509         -  u64 r;
         1441  +  u32 szHdr;        /* Size of the header */
         1442  +  u32 typeRowid;    /* Serial type of the rowid */
         1443  +  u32 lenRowid;     /* Size of the rowid */
         1444  +  Mem m, v;
  1510   1445   
  1511         -  rc = sqlite3BtreeKeySize(pCur, &sz);
  1512         -  if( rc!=SQLITE_OK ){
         1446  +  sqlite3BtreeKeySize(pCur, &nCellKey);
         1447  +  if( nCellKey<=0 ){
         1448  +    return SQLITE_CORRUPT;
         1449  +  }
         1450  +  rc = sqlite3VdbeMemFromBtree(pCur, 0, nCellKey, 1, &m);
         1451  +  if( rc ){
  1513   1452       return rc;
  1514   1453     }
  1515         -  len = ((sz>10)?10:sz);
  1516         -
  1517         -  /* If there are less than 2 bytes in the key, this cannot be
  1518         -  ** a valid index entry. In practice this comes up for a query
  1519         -  ** of the sort "SELECT max(x) FROM t1;" when t1 is an empty table
  1520         -  ** with an index on x. In this case just call the rowid 0.
  1521         -  */
  1522         -  if( len<2 ){
  1523         -    *rowid = 0;
  1524         -    return SQLITE_OK;
         1454  +  sqlite3GetVarint32(m.z, &szHdr);
         1455  +  sqlite3GetVarint32(&m.z[szHdr-1], &typeRowid);
         1456  +  lenRowid = sqlite3VdbeSerialTypeLen(typeRowid);
         1457  +  sqlite3VdbeSerialGet(&m.z[m.n-lenRowid], typeRowid, &v);
         1458  +  *rowid = v.i;
         1459  +  if( m.flags & MEM_Dyn ){
         1460  +    sqliteFree(m.z);
  1525   1461     }
  1526         -
  1527         -  rc = sqlite3BtreeKey(pCur, sz-len, len, buf);
  1528         -  if( rc!=SQLITE_OK ){
  1529         -    return rc;
  1530         -  }
  1531         -
  1532         -  len--;
  1533         -  while( buf[len-1] && --len );
  1534         -
  1535         -  sqlite3GetVarint(&buf[len], &r);
  1536         -  *rowid = r;
  1537   1462     return SQLITE_OK;
  1538   1463   }
  1539   1464   
  1540   1465   /*
  1541   1466   ** Compare the key of the index entry that cursor pC is point to against
  1542   1467   ** the key string in pKey (of length nKey).  Write into *pRes a number
  1543   1468   ** that is negative, zero, or positive if pC is less than, equal to,
  1544   1469   ** or greater than pKey.  Return SQLITE_OK on success.
  1545   1470   **
  1546         -** pKey might contain fewer terms than the cursor.
         1471  +** pKey is either created without a rowid or is truncated so that it
         1472  +** omits the rowid at the end.  The rowid at the end of the index entry
         1473  +** is ignored as well.
  1547   1474   */
  1548   1475   int sqlite3VdbeIdxKeyCompare(
  1549   1476     Cursor *pC,                 /* The cursor to compare against */
  1550   1477     int nKey, const u8 *pKey,   /* The key to compare */
  1551   1478     int *res                    /* Write the comparison result here */
  1552   1479   ){
  1553         -  unsigned char *pCellKey;
  1554   1480     u64 nCellKey;
  1555         -  int freeCellKey = 0;
  1556   1481     int rc;
  1557         -  int len;
  1558   1482     BtCursor *pCur = pC->pCursor;
         1483  +  int lenRowid;
         1484  +  Mem m;
  1559   1485   
  1560   1486     sqlite3BtreeKeySize(pCur, &nCellKey);
  1561   1487     if( nCellKey<=0 ){
  1562   1488       *res = 0;
  1563   1489       return SQLITE_OK;
  1564   1490     }
  1565         -
  1566         -  pCellKey = (unsigned char *)sqlite3BtreeKeyFetch(pCur, nCellKey);
  1567         -  if( !pCellKey ){
  1568         -    pCellKey = (unsigned char *)sqliteMallocRaw(nCellKey);
  1569         -    if( !pCellKey ){
  1570         -      return SQLITE_NOMEM;
  1571         -    }
  1572         -    freeCellKey = 1;
  1573         -    rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
  1574         -    if( rc!=SQLITE_OK ){
  1575         -      sqliteFree(pCellKey);
  1576         -      return rc;
  1577         -    }
         1491  +  rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
         1492  +  if( rc ){
         1493  +    return rc;
  1578   1494     }
  1579         - 
  1580         -  len = nCellKey-2;
  1581         -  while( pCellKey[len] && --len );
  1582         -
  1583         -  *res = sqlite3VdbeKeyCompare(pC->pKeyInfo, len, pCellKey, nKey, pKey);
  1584         -  
  1585         -  if( freeCellKey ){
  1586         -    sqliteFree(pCellKey);
         1495  +  lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z);
         1496  +  *res = sqlite3VdbeKeyCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
         1497  +  if( m.flags & MEM_Dyn ){
         1498  +    sqliteFree(m.z);
  1587   1499     }
  1588   1500     return SQLITE_OK;
  1589   1501   }

Changes to src/vdbemem.c.

   438    438     */
   439    439     rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
   440    440     if( rc==0 ){
   441    441       rc = pMem1->n - pMem2->n;
   442    442     }
   443    443     return rc;
   444    444   }
          445  +
          446  +/*
          447  +** Move data out of a btree key or data field and into a Mem structure.
          448  +** The data or key is taken from the entry that pCur is currently pointing
          449  +** to.  offset and amt determine what portion of the data or key to retrieve.
          450  +** key is true to get the key or false to get data.  The result is written
          451  +** into the pMem element.
          452  +**
          453  +** The pMem structure is assumed to be uninitialized.  Any prior content
          454  +** is overwritten without being freed.
          455  +**
          456  +** If this routine fails for any reason (malloc returns NULL or unable
          457  +** to read from the disk) then the pMem is left in an inconsistent state.
          458  +*/
          459  +int sqlite3VdbeMemFromBtree(
          460  +  BtCursor *pCur,   /* Cursor pointing at record to retrieve. */
          461  +  int offset,       /* Offset from the start of data to return bytes from. */
          462  +  int amt,          /* Number of bytes to return. */
          463  +  int key,          /* If true, retrieve from the btree key, not data. */
          464  +  Mem *pMem         /* OUT: Return data in this Mem structure. */
          465  +){
          466  +  char *zData;
          467  +
          468  +  if( key ){
          469  +    zData = (char *)sqlite3BtreeKeyFetch(pCur, offset+amt);
          470  +  }else{
          471  +    zData = (char *)sqlite3BtreeDataFetch(pCur, offset+amt);
          472  +  }
          473  +
          474  +  pMem->n = amt;
          475  +  if( zData ){
          476  +    pMem->z = &zData[offset];
          477  +    pMem->flags = MEM_Blob|MEM_Ephem;
          478  +  }else{
          479  +    int rc;
          480  +    if( amt>NBFS-2 ){
          481  +      zData = (char *)sqliteMallocRaw(amt+2);
          482  +      if( !zData ){
          483  +        return SQLITE_NOMEM;
          484  +      }
          485  +      pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
          486  +    }else{
          487  +      zData = &(pMem->zShort[0]);
          488  +      pMem->flags = MEM_Blob|MEM_Short|MEM_Term;
          489  +    }
          490  +    pMem->z = zData;
          491  +    pMem->enc = 0;
          492  +    pMem->type = SQLITE3_BLOB;
          493  +
          494  +    if( key ){
          495  +      rc = sqlite3BtreeKey(pCur, offset, amt, zData);
          496  +    }else{
          497  +      rc = sqlite3BtreeData(pCur, offset, amt, zData);
          498  +    }
          499  +    zData[amt] = 0;
          500  +    zData[amt+1] = 0;
          501  +    if( rc!=SQLITE_OK ){
          502  +      if( amt>NBFS ){
          503  +        sqliteFree(zData);
          504  +      }
          505  +      return rc;
          506  +    }
          507  +  }
          508  +
          509  +  return SQLITE_OK;
          510  +}
   445    511   
   446    512   #ifndef NDEBUG
   447    513   /*
   448    514   ** Perform various checks on the memory cell pMem. An assert() will
   449    515   ** fail if pMem is internally inconsistent.
   450    516   */
   451    517   void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
................................................................................
   477    543       assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
   478    544     }
   479    545     /* MEM_Null excludes all other types */
   480    546     assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
   481    547             || (pMem->flags&MEM_Null)==0 );
   482    548   }
   483    549   #endif
   484         -