/ Check-in [5378a640]
Login

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

Overview
Comment:Commit vdbeaux.c, which should of gone in with the previous commit. (CVS 1369)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5378a6404058f5e9d3e91269ab27afef9874b43a
User & Date: danielk1977 2004-05-13 05:20:26
Context
2004-05-13
11:34
Various minor fixes and updates to make more test cases pass. (CVS 1370) check-in: dbe8385e user: danielk1977 tags: trunk
05:20
Commit vdbeaux.c, which should of gone in with the previous commit. (CVS 1369) check-in: 5378a640 user: danielk1977 tags: trunk
05:16
Manifest types in indices. At the moment indices use manifest typing, but some other parts of the SQL engine do not, which can lead to some strange results. (CVS 1368) check-in: 9f2b6d9d user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

  1126   1126   ** the end. Hence these functions allow the caller to handle the
  1127   1127   ** serial-type and data blob seperately.
  1128   1128   **
  1129   1129   ** The following table describes the various storage classes for data:
  1130   1130   **
  1131   1131   **   serial type        bytes of data      type
  1132   1132   **   --------------     ---------------    ---------------
  1133         -**      0                     0            NULL
         1133  +**      0                     -            Not a type.
  1134   1134   **      1                     1            signed integer
  1135   1135   **      2                     2            signed integer
  1136   1136   **      3                     4            signed integer
  1137   1137   **      4                     8            signed integer
  1138   1138   **      5                     8            IEEE float
  1139         -**     6..12                               reserved for expansion
         1139  +**      6                     0            NULL
         1140  +**     7..11                               reserved for expansion
  1140   1141   **    N>=12 and even       (N-12)/2        BLOB
  1141   1142   **    N>=13 and odd        (N-13)/2        text
  1142   1143   **
  1143   1144   */
  1144   1145   
  1145   1146   /*
  1146   1147   ** Return the serial-type for the value stored in pMem.
  1147   1148   */
  1148   1149   u64 sqlite3VdbeSerialType(const Mem *pMem){
  1149   1150     int flags = pMem->flags;
  1150   1151   
  1151   1152     if( flags&MEM_Null ){
  1152         -    return 0;
         1153  +    return 6;
  1153   1154     }
  1154   1155     if( flags&MEM_Int ){
  1155   1156       /* Figure out whether to use 1, 2, 4 or 8 bytes. */
  1156   1157       i64 i = pMem->i;
  1157   1158       if( i>=-127 && i<=127 ) return 1;
  1158   1159       if( i>=-32767 && i<=32767 ) return 2;
  1159   1160       if( i>=-2147483647 && i<=2147483647 ) return 3;
................................................................................
  1171   1172     return 0;
  1172   1173   }
  1173   1174   
  1174   1175   /*
  1175   1176   ** Return the length of the data corresponding to the supplied serial-type.
  1176   1177   */
  1177   1178   int sqlite3VdbeSerialTypeLen(u64 serial_type){
         1179  +  assert( serial_type!=0 );
  1178   1180     switch(serial_type){
  1179         -    case 0: return 0;                  /* NULL */
         1181  +    case 6: return 0;                  /* NULL */
  1180   1182       case 1: return 1;                  /* 1 byte integer */
  1181   1183       case 2: return 2;                  /* 2 byte integer */
  1182   1184       case 3: return 4;                  /* 4 byte integer */
  1183   1185       case 4: return 8;                  /* 8 byte integer */
  1184   1186       case 5: return 8;                  /* 8 byte float */
  1185   1187     }
  1186   1188     assert( serial_type>=12 );
................................................................................
  1191   1193   ** Write the serialized data blob for the value stored in pMem into 
  1192   1194   ** buf. It is assumed that the caller has allocated sufficient space.
  1193   1195   ** Return the number of bytes written.
  1194   1196   */ 
  1195   1197   int sqlite3VdbeSerialPut(unsigned char *buf, const Mem *pMem){
  1196   1198     u64 serial_type = sqlite3VdbeSerialType(pMem);
  1197   1199     int len;
         1200  +
         1201  +  assert( serial_type!=0 );
  1198   1202    
  1199   1203     /* NULL */
  1200         -  if( serial_type==0 ){
         1204  +  if( serial_type==6 ){
  1201   1205       return 0;
  1202   1206     }
  1203   1207    
  1204   1208     /* Integer */
  1205   1209     if( serial_type<5 ){
  1206   1210       i64 i = pMem->i;
  1207   1211       len = sqlite3VdbeSerialTypeLen(serial_type);
................................................................................
  1229   1233   
  1230   1234   /*
  1231   1235   ** Deserialize the data blob pointed to by buf as serial type serial_type
  1232   1236   ** and store the result in pMem.  Return the number of bytes read.
  1233   1237   */ 
  1234   1238   int sqlite3VdbeSerialGet(const unsigned char *buf, u64 serial_type, Mem *pMem){
  1235   1239     int len;
         1240  +
         1241  +  assert( serial_type!=0 );
  1236   1242   
  1237   1243     /* memset(pMem, 0, sizeof(pMem)); */
  1238   1244     pMem->flags = 0;
  1239   1245     pMem->z = 0;
  1240   1246   
  1241   1247     /* NULL */
  1242         -  if( serial_type==0 ){
         1248  +  if( serial_type==6 ){
  1243   1249       pMem->flags = MEM_Null;
  1244   1250       return 0;
  1245   1251     }
  1246   1252    
  1247   1253     /* Integer */
  1248   1254     if( serial_type<5 ){
  1249   1255       i64 i = 0;
................................................................................
  1368   1374   /*
  1369   1375   ** The following is the comparison function for (non-integer)
  1370   1376   ** keys in the btrees.  This function returns negative, zero, or
  1371   1377   ** positive if the first key is less than, equal to, or greater than
  1372   1378   ** the second.
  1373   1379   **
  1374   1380   ** This function assumes that each key consists of one or more type/blob
  1375         -** pairs, encoded using the sqlite3VdbeSerialXXX() functions above. One
  1376         -** of the keys may have some trailing data appended to it. This is OK
  1377         -** provided that the other key does not have more type/blob pairs than
  1378         -** the key with the trailing data.
         1381  +** pairs, encoded using the sqlite3VdbeSerialXXX() functions above. 
         1382  +**
         1383  +** Following the type/blob pairs, each key may have a single 0x00 byte
         1384  +** followed by a varint. A key may only have this traling 0x00/varint
         1385  +** pair if it has at least as many type/blob pairs as the key it is being
         1386  +** compared to.
  1379   1387   */
  1380   1388   int sqlite3VdbeKeyCompare(
  1381   1389     void *userData,                         /* not used yet */
  1382         -  int nKey1, const unsigned char *aKey1, 
  1383         -  int nKey2, const unsigned char *aKey2
         1390  +  int nKey1, const void *pKey1, 
         1391  +  int nKey2, const void *pKey2
  1384   1392   ){
  1385   1393     int offset1 = 0;
  1386   1394     int offset2 = 0;
  1387         -
         1395  +  const unsigned char *aKey1 = (const unsigned char *)pKey1;
         1396  +  const unsigned char *aKey2 = (const unsigned char *)pKey2;
         1397  +  
  1388   1398     while( offset1<nKey1 && offset2<nKey2 ){
  1389   1399       Mem mem1;
  1390   1400       Mem mem2;
  1391   1401       u64 serial_type1;
  1392   1402       u64 serial_type2;
  1393   1403       int rc;
  1394   1404   
         1405  +    /* Read the serial types for the next element in each key. */
  1395   1406       offset1 += sqlite3GetVarint(&aKey1[offset1], &serial_type1);
  1396   1407       offset2 += sqlite3GetVarint(&aKey2[offset2], &serial_type2);
         1408  +
         1409  +    /* If either of the varints just read in are 0 (not a type), then
         1410  +    ** this is the end of the keys. The remaining data in each key is
         1411  +    ** the varint rowid. Compare these as signed integers and return
         1412  +    ** the result.
         1413  +    */
         1414  +    if( !serial_type1 || !serial_type2 ){
         1415  +      assert( !serial_type1 && !serial_type2 );
         1416  +      sqlite3GetVarint(&aKey1[offset1], &serial_type1);
         1417  +      sqlite3GetVarint(&aKey2[offset2], &serial_type2);
         1418  +      return ( (i64)serial_type1 - (i64)serial_type2 );
         1419  +    }
         1420  +
         1421  +    /* Assert that there is enough space left in each key for the blob of
         1422  +    ** data to go with the serial type just read. This assert may fail if
         1423  +    ** the file is corrupted.  Then read the value from each key into mem1
         1424  +    ** and mem2 respectively.
         1425  +    */
  1397   1426       offset1 += sqlite3VdbeSerialGet(&aKey1[offset1], serial_type1, &mem1);
  1398   1427       offset2 += sqlite3VdbeSerialGet(&aKey2[offset2], serial_type2, &mem2);
  1399   1428   
  1400   1429       rc = compareMemCells(&mem1, &mem2);
  1401   1430       if( mem1.flags&MEM_Dyn ){
  1402   1431         sqliteFree(mem1.z);
  1403   1432       }
................................................................................
  1413   1442       return 1;
  1414   1443     }
  1415   1444     if( offset2<nKey2 ){
  1416   1445       return -1;
  1417   1446     }
  1418   1447     return 0;
  1419   1448   }
         1449  +
         1450  +/*
         1451  +** pCur points at an index entry. Read the rowid (varint occuring at
         1452  +** the end of the entry and store it in *rowid. Return SQLITE_OK if
         1453  +** everything works, or an error code otherwise.
         1454  +*/
         1455  +int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
         1456  +  i64 sz;
         1457  +  int rc;
         1458  +  char buf[9];
         1459  +  int len;
         1460  +  u64 r;
         1461  +
         1462  +  rc = sqlite3BtreeKeySize(pCur, &sz);
         1463  +  if( rc!=SQLITE_OK ){
         1464  +    return rc;
         1465  +  }
         1466  +  len = ((sz>9)?9:sz);
         1467  +  assert( len>=2 );
         1468  +
         1469  +  rc = sqlite3BtreeKey(pCur, sz-len, len, buf);
         1470  +  if( rc!=SQLITE_OK ){
         1471  +    return rc;
         1472  +  }
         1473  +
         1474  +  len = len - 2;
         1475  +  while( buf[len] && --len );
         1476  +
         1477  +  sqlite3GetVarint(buf, &r);
         1478  +  *rowid = r;
         1479  +  return SQLITE_OK;
         1480  +}
         1481  +
         1482  +int sqlite3VdbeIdxKeyCompare(
         1483  +  BtCursor *pCur, 
         1484  +  int nKey, const unsigned char *pKey,
         1485  +  int ignorerowid,
         1486  +  int *res
         1487  +){
         1488  +  unsigned char *pCellKey;
         1489  +  u64 nCellKey;
         1490  +  int freeCellKey = 0;
         1491  +  int rc;
         1492  +  int len;
         1493  +
         1494  +  sqlite3BtreeKeySize(pCur, &nCellKey);
         1495  +  if( nCellKey<=0 ){
         1496  +    *res = 0;
         1497  +    return SQLITE_OK;
         1498  +  }
         1499  +
         1500  +  pCellKey = (unsigned char *)sqlite3BtreeKeyFetch(pCur, nCellKey);
         1501  +  if( !pCellKey ){
         1502  +    pCellKey = (unsigned char *)sqliteMalloc(nCellKey);
         1503  +    if( !pCellKey ){
         1504  +      return SQLITE_NOMEM;
         1505  +    }
         1506  +    freeCellKey = 1;
         1507  +    rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
         1508  +    if( rc!=SQLITE_OK ){
         1509  +      sqliteFree(pCellKey);
         1510  +      return rc;
         1511  +    }
         1512  +  }
         1513  + 
         1514  +  len = nCellKey-2;
         1515  +  while( pCellKey[len] && --len );
         1516  +
         1517  +  if( ignorerowid ){
         1518  +    nKey--;
         1519  +    while( pKey[nKey] && --nKey );
         1520  +  }
         1521  +  *res = sqlite3VdbeKeyCompare(0, len, pCellKey, nKey, pKey);
         1522  +  
         1523  +  if( freeCellKey ){
         1524  +    sqliteFree(pCellKey);
         1525  +  }
         1526  +  return SQLITE_OK;
         1527  +}
         1528  +
         1529  +
         1530  +