/ Check-in [321f8c46]
Login

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

Overview
Comment:Remove the encoding argument from sqlite3VdbeSerialGet. Use the 32-bit version of sqlite3GetVarint for schema-level parameters. (CVS 1480)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 321f8c463520e99681de878b743027c570b73e35
User & Date: drh 2004-05-28 01:39:01
Context
2004-05-28
08:21
Tables and indices use the same record format. (CVS 1481) check-in: ebd564d1 user: drh tags: trunk
01:39
Remove the encoding argument from sqlite3VdbeSerialGet. Use the 32-bit version of sqlite3GetVarint for schema-level parameters. (CVS 1480) check-in: 321f8c46 user: drh tags: trunk
2004-05-27
23:56
Add API functions sqlite3_open_varargs(), sqlite3_open16_varargs() and sqlite3_complete16(). (CVS 1479) check-in: 203af2b2 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
....
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983
1984
....
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
....
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
....
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
....
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
....
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
....
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
....
3385
3386
3387
3388
3389
3390
3391
3392

3393
3394
3395
3396
3397
3398
3399
....
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
....
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.341 2004/05/27 19:59:32 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to record-data from stack or pseudo-table. */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  u64 nField;        /* number of fields in the record */
  u32 szHdr;         /* Number of bytes in the record header */
  int len;           /* The length of the serialized data for the column */
  int offset = 0;    /* Offset into the data */
  int idx;           /* Index into the header */
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem sMem;          /* For storing the record being decoded */
................................................................................
  if( zRec ){
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    getBtreeMem(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    zData = sMem.z;
  }
  sqlite3VdbeSerialGet(zData, aType[p2], pTos, p->db->enc);

  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(&sMem);

  /* Release the aType[] memory if we are not dealing with cursor */
  if( !pC ){
................................................................................
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }
................................................................................
    goto no_mem;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }

  /* If zCsr has not been advanced exactly nByte bytes, then one
................................................................................
  ** to store the coerced values serial-type and blob, and add this
  ** quantity to nByte.
  **
  ** TODO: Figure out if the in-place coercion causes a problem for
  ** OP_MakeKey when P2 is 0 (used by DISTINCT).
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    serial_type = sqlite3VdbeSerialType(pRec);
................................................................................
  zKey = (char *)sqliteMallocRaw(nByte);
  if( !zKey ){
    goto no_mem;
  }
  
  /* Build the key in the buffer pointed to by zKey. */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type = sqlite3VdbeSerialType(pRec);
    offset += sqlite3PutVarint(&zKey[offset], serial_type);
    offset += sqlite3VdbeSerialPut(&zKey[offset], pRec);
  }
  if( addRowid ){
    zKey[offset++] = '\0';
    offset += sqlite3PutVarint(&zKey[offset], rowid);
  }
................................................................................
**
** P1 is a cursor opened on an index. Push the first field from the
** current index key onto the stack.
*/
case OP_IdxColumn: {
  char *zData;
  i64 n;
  u64 serial_type;
  int len;
  int freeZData = 0;
  BtCursor *pCsr;

  assert( 0==p->apCsr[pOp->p1]->intKey );
  pCsr = p->apCsr[pOp->p1]->pCursor;
  rc = sqlite3BtreeKeySize(pCsr, &n);
................................................................................
    goto abort_due_to_error;
  }
  if( n>10 ) n = 10;

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, n);
  assert( zData );

  len = sqlite3GetVarint(zData, &serial_type);
  n = sqlite3VdbeSerialTypeLen(serial_type);

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, len+n);
  if( !zData ){
    zData = (char *)sqliteMalloc(n);
    if( !zData ){
      goto no_mem;
................................................................................
      goto abort_due_to_error;
    }
    freeZData = 1;
    len = 0;
  }

  pTos++;
  sqlite3VdbeSerialGet(&zData[len], serial_type, pTos, p->db->enc);

  if( freeZData ){
    sqliteFree(zData);
  }
  break;
}

/* Opcode: FullKey P1 * *
................................................................................
      /* Find the start of the varint by searching backwards for a 0x00
      ** byte. If one does not exists, then intepret the whole 9 bytes as a
      ** varint.
      */
      while( len && buf[len-1] ){
        len--;
      }
      sqlite3GetVarint(&buf[len], &sz);
      pTos->flags = MEM_Int;
      pTos->i = sz;
    }
#endif
  }else{
    pTos->flags = MEM_Null;
  }
................................................................................
  const char *z;

  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  z = pTos->z;
  n = pTos->n;
  for(k=0; k<n && i>0; i--){
    u64 serial_type;
    k += sqlite3GetVarint(&z[k], &serial_type);
    if( serial_type==6 ){   /* Serial type 6 is a NULL */
      pc = pOp->p2-1;
      break;
    }
    k += sqlite3VdbeSerialTypeLen(serial_type);
  }
  Release(pTos);







|







 







|







 







|
>







 







|







 







|







 







|







 







|







 







|







 







|







 







|
>







 







|







 







|
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
....
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
....
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
....
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
....
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
....
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
....
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
....
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
....
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
....
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
....
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.342 2004/05/28 01:39:01 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to record-data from stack or pseudo-table. */
  BtCursor *pCrsr;   /* The BTree cursor */
  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  u32 nField;        /* number of fields in the record */
  u32 szHdr;         /* Number of bytes in the record header */
  int len;           /* The length of the serialized data for the column */
  int offset = 0;    /* Offset into the data */
  int idx;           /* Index into the header */
  int i;             /* Loop counter */
  char *zData;       /* Part of the record being decoded */
  Mem sMem;          /* For storing the record being decoded */
................................................................................
  if( zRec ){
    zData = &zRec[aOffset[p2]];
  }else{
    len = sqlite3VdbeSerialTypeLen(aType[p2]);
    getBtreeMem(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
    zData = sMem.z;
  }
  sqlite3VdbeSerialGet(zData, aType[p2], pTos);
  pTos->enc = db->enc;
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
  Release(&sMem);

  /* Release the aType[] memory if we are not dealing with cursor */
  if( !pC ){
................................................................................
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u32 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nData += sqlite3VdbeSerialTypeLen(serial_type);
    nHdr += sqlite3VarintLen(serial_type);
  }
................................................................................
    goto no_mem;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nHdr);
  for(pRec=pData0; pRec<=pTos; pRec++){
    u32 serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }

  /* If zCsr has not been advanced exactly nByte bytes, then one
................................................................................
  ** to store the coerced values serial-type and blob, and add this
  ** quantity to nByte.
  **
  ** TODO: Figure out if the in-place coercion causes a problem for
  ** OP_MakeKey when P2 is 0 (used by DISTINCT).
  */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u32 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
    }
    if( pRec->flags&MEM_Null ){
      containsNull = 1;
    }
    serial_type = sqlite3VdbeSerialType(pRec);
................................................................................
  zKey = (char *)sqliteMallocRaw(nByte);
  if( !zKey ){
    goto no_mem;
  }
  
  /* Build the key in the buffer pointed to by zKey. */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u32 serial_type = sqlite3VdbeSerialType(pRec);
    offset += sqlite3PutVarint(&zKey[offset], serial_type);
    offset += sqlite3VdbeSerialPut(&zKey[offset], pRec);
  }
  if( addRowid ){
    zKey[offset++] = '\0';
    offset += sqlite3PutVarint(&zKey[offset], rowid);
  }
................................................................................
**
** P1 is a cursor opened on an index. Push the first field from the
** current index key onto the stack.
*/
case OP_IdxColumn: {
  char *zData;
  i64 n;
  u32 serial_type;
  int len;
  int freeZData = 0;
  BtCursor *pCsr;

  assert( 0==p->apCsr[pOp->p1]->intKey );
  pCsr = p->apCsr[pOp->p1]->pCursor;
  rc = sqlite3BtreeKeySize(pCsr, &n);
................................................................................
    goto abort_due_to_error;
  }
  if( n>10 ) n = 10;

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, n);
  assert( zData );

  len = sqlite3GetVarint32(zData, &serial_type);
  n = sqlite3VdbeSerialTypeLen(serial_type);

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, len+n);
  if( !zData ){
    zData = (char *)sqliteMalloc(n);
    if( !zData ){
      goto no_mem;
................................................................................
      goto abort_due_to_error;
    }
    freeZData = 1;
    len = 0;
  }

  pTos++;
  sqlite3VdbeSerialGet(&zData[len], serial_type, pTos);
  pTos->enc = db->enc;
  if( freeZData ){
    sqliteFree(zData);
  }
  break;
}

/* Opcode: FullKey P1 * *
................................................................................
      /* Find the start of the varint by searching backwards for a 0x00
      ** byte. If one does not exists, then intepret the whole 9 bytes as a
      ** varint.
      */
      while( len && buf[len-1] ){
        len--;
      }
      sqlite3GetVarint32(&buf[len], &sz);
      pTos->flags = MEM_Int;
      pTos->i = sz;
    }
#endif
  }else{
    pTos->flags = MEM_Null;
  }
................................................................................
  const char *z;

  assert( pTos>=p->aStack );
  assert( pTos->flags & MEM_Blob );
  z = pTos->z;
  n = pTos->n;
  for(k=0; k<n && i>0; i--){
    u32 serial_type;
    k += sqlite3GetVarint32(&z[k], &serial_type);
    if( serial_type==6 ){   /* Serial type 6 is a NULL */
      pc = pOp->p2-1;
      break;
    }
    k += sqlite3VdbeSerialTypeLen(serial_type);
  }
  Release(pTos);

Changes to src/vdbeInt.h.

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
void sqlite3VdbeAggReset(Agg*);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if !defined(NDEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
int sqlite3VdbeSerialTypeLen(u64);
u64 sqlite3VdbeSerialType(Mem *);
int sqlite3VdbeSerialPut(unsigned char *, Mem *);
int sqlite3VdbeSerialGet(const unsigned char *, u64, Mem *, u8 enc);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
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*);







|
|
|
|







335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
void sqlite3VdbeAggReset(Agg*);
void sqlite3VdbeKeylistFree(Keylist*);
void sqliteVdbePopStack(Vdbe*,int);
int sqlite3VdbeCursorMoveto(Cursor*);
#if !defined(NDEBUG) || defined(VDBE_PROFILE)
void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
int sqlite3VdbeSerialTypeLen(u32);
u32 sqlite3VdbeSerialType(Mem*);
int sqlite3VdbeSerialPut(unsigned char*, Mem*);
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);

int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
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*);

Changes to src/vdbeaux.c.

1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
....
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
....
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
....
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
....
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
....
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
....
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
**    N>=13 and odd        (N-13)/2        text
**
*/

/*
** Return the serial-type for the value stored in pMem.
*/
u64 sqlite3VdbeSerialType(Mem *pMem){
  int flags = pMem->flags;

  if( flags&MEM_Null ){
    return 6;
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4 or 8 bytes. */
................................................................................
  }
  return 0;
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
int sqlite3VdbeSerialTypeLen(u64 serial_type){
  assert( serial_type!=0 );
  switch(serial_type){
    case 6: return 0;                  /* NULL */
    case 1: return 1;                  /* 1 byte integer */
    case 2: return 2;                  /* 2 byte integer */
    case 3: return 4;                  /* 4 byte integer */
    case 4: return 8;                  /* 8 byte integer */
................................................................................

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
  u64 serial_type = sqlite3VdbeSerialType(pMem);
  int len;

  assert( serial_type!=0 );
 
  /* NULL */
  if( serial_type==6 ){
    return 0;
................................................................................

/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u64 serial_type,              /* Serial type to deserialize */
  Mem *pMem,                    /* Memory cell to write value into */
  u8 enc      /* Text encoding. Used to determine nul term. character */
){
  int len;

  assert( serial_type!=0 );

  /* memset(pMem, 0, sizeof(pMem)); */
  pMem->flags = 0;
................................................................................
  /* String or blob */
  assert( serial_type>=12 );
  len = sqlite3VdbeSerialTypeLen(serial_type);
  pMem->z = (char *)buf;
  pMem->n = len;
  if( serial_type&0x01 ){
    pMem->flags = MEM_Str | MEM_Ephem;
    pMem->enc = enc;
  }else{
    pMem->flags = MEM_Blob | MEM_Ephem;
  }
  sqlite3VdbeMemMakeWriteable(pMem);
  return len;
}

................................................................................
  int nKey2, const void *pKey2
){
  KeyInfo *pKeyInfo = (KeyInfo*)userData;
  int offset1 = 0;
  int offset2 = 0;
  int i = 0;
  int rc = 0;
  u8 enc = pKeyInfo->enc;
  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;
    u64 serial_type1;
    u64 serial_type2;

    /* Read the serial types for the next element in each key. */
    offset1 += sqlite3GetVarint(&aKey1[offset1], &serial_type1);
    offset2 += sqlite3GetVarint(&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 );
      sqlite3GetVarint(&aKey1[offset1], &serial_type1);
      sqlite3GetVarint(&aKey2[offset2], &serial_type2);
      if( serial_type1 < serial_type2 ){
        rc = -1;
      }else if( serial_type1 > serial_type2 ){
        rc = +1;
      }else{
        rc = 0;
      }
................................................................................
    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, enc);
    offset2 += sqlite3VdbeSerialGet(&aKey2[offset2], serial_type2, &mem2, enc);

    rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
    if( mem1.flags&MEM_Dyn ){
      sqliteFree(mem1.z);
    }
    if( mem2.flags&MEM_Dyn ){
      sqliteFree(mem2.z);
................................................................................
    idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);

    /* 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.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1, 0);
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2, 0);

    rc = sqlite3MemCompare(&mem1, &mem2, pKeyInfo->aColl[i]);
    if( mem1.flags&MEM_Dyn ){
      sqliteFree(mem1.z);
    }
    if( mem2.flags&MEM_Dyn ){
      sqliteFree(mem2.z);







|







 







|







 







|







 







|
|
<







 







<







 







<







|
|


|
|








|
|







 







|
|







 







|
|







1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
....
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
....
1250
1251
1252
1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
....
1299
1300
1301
1302
1303
1304
1305

1306
1307
1308
1309
1310
1311
1312
....
1330
1331
1332
1333
1334
1335
1336

1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
....
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
....
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
**    N>=13 and odd        (N-13)/2        text
**
*/

/*
** Return the serial-type for the value stored in pMem.
*/
u32 sqlite3VdbeSerialType(Mem *pMem){
  int flags = pMem->flags;

  if( flags&MEM_Null ){
    return 6;
  }
  if( flags&MEM_Int ){
    /* Figure out whether to use 1, 2, 4 or 8 bytes. */
................................................................................
  }
  return 0;
}

/*
** Return the length of the data corresponding to the supplied serial-type.
*/
int sqlite3VdbeSerialTypeLen(u32 serial_type){
  assert( serial_type!=0 );
  switch(serial_type){
    case 6: return 0;                  /* NULL */
    case 1: return 1;                  /* 1 byte integer */
    case 2: return 2;                  /* 2 byte integer */
    case 3: return 4;                  /* 4 byte integer */
    case 4: return 8;                  /* 8 byte integer */
................................................................................

/*
** Write the serialized data blob for the value stored in pMem into 
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
*/ 
int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
  u32 serial_type = sqlite3VdbeSerialType(pMem);
  int len;

  assert( serial_type!=0 );
 
  /* NULL */
  if( serial_type==6 ){
    return 0;
................................................................................

/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem.  Return the number of bytes read.
*/ 
int sqlite3VdbeSerialGet(
  const unsigned char *buf,     /* Buffer to deserialize from */
  u32 serial_type,              /* Serial type to deserialize */
  Mem *pMem                     /* Memory cell to write value into */

){
  int len;

  assert( serial_type!=0 );

  /* memset(pMem, 0, sizeof(pMem)); */
  pMem->flags = 0;
................................................................................
  /* String or blob */
  assert( serial_type>=12 );
  len = sqlite3VdbeSerialTypeLen(serial_type);
  pMem->z = (char *)buf;
  pMem->n = len;
  if( serial_type&0x01 ){
    pMem->flags = MEM_Str | MEM_Ephem;

  }else{
    pMem->flags = MEM_Blob | MEM_Ephem;
  }
  sqlite3VdbeMemMakeWriteable(pMem);
  return len;
}

................................................................................
  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;
      }
................................................................................
    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);
................................................................................
    idx2 += sqlite3GetVarint32(&aKey2[idx2], &serial_type2);

    /* 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.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
    d2 += sqlite3VdbeSerialGet(&aKey2[d2], 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);