/ Check-in [e41376cf]
Login
Overview
Comment:An alternative way of fixing the key comparison bug of ticket [f97c4637102a3ae72b].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | alt1-tkt-f97c4637
Files: files | file ages | folders
SHA1:e41376cf0804a0ca1b9033661ef6e94e37ad865e
User & Date: drh 2015-01-19 19:21:36
Context
2015-01-19
19:21
An alternative way of fixing the key comparison bug of ticket [f97c4637102a3ae72b]. Closed-Leaf check-in: e41376cf user: drh tags: alt1-tkt-f97c4637
15:05
Enhance the command-line shell with the ability to set the SQLITE_TESTCTRL_NEVER_CORRUPT flag using: ".testctrl never_corrupt 1". check-in: 824328f9 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

3756
3757
3758
3759
3760
3761
3762
3763


3764
3765
3766
3767
3768
3769
3770
....
3843
3844
3845
3846
3847
3848
3849



3850
3851
3852
3853
3854
3855
3856
....
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
  int serial_type = ((const u8*)pKey1)[1];
  int res;
  u32 y;
  u64 x;
  i64 v = pPKey2->aMem[0].u.i;
  i64 lhs;

  assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );


  switch( serial_type ){
    case 1: { /* 1-byte signed integer */
      lhs = ONE_BYTE_INT(aKey);
      testcase( lhs<0 );
      break;
    }
    case 2: { /* 2-byte signed integer */
................................................................................
  int nKey1, const void *pKey1, /* Left key */
  UnpackedRecord *pPKey2        /* Right key */
){
  const u8 *aKey1 = (const u8*)pKey1;
  int serial_type;
  int res;




  getVarint32(&aKey1[1], serial_type);
  if( serial_type<12 ){
    res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
  }else if( !(serial_type & 0x01) ){ 
    res = pPKey2->r2;      /* (pKey1/nKey1) is a blob */
  }else{
    int nCmp;
................................................................................

/*
** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
** suitable for comparing serialized records to the unpacked record passed
** as the only argument.
*/
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
  /* varintRecordCompareInt() and varintRecordCompareString() both assume
  ** that the size-of-header varint that occurs at the start of each record
  ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt()
  ** also assumes that it is safe to overread a buffer by at least the 
  ** maximum possible legal header size plus 8 bytes. Because there is
  ** guaranteed to be at least 74 (but not 136) bytes of padding following each
  ** buffer passed to varintRecordCompareInt() this makes it convenient to
  ** limit the size of the header to 64 bytes in cases where the first field
  ** is an integer.
  **
  ** The easiest way to enforce this limit is to consider only records with
  ** 13 fields or less. If the first field is an integer, the maximum legal
  ** header size is (12*5 + 1 + 1) bytes.  */
  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
    int flags = p->aMem[0].flags;
    if( p->pKeyInfo->aSortOrder[0] ){
      p->r1 = 1;
      p->r2 = -1;
    }else{
      p->r1 = -1;
      p->r2 = 1;
    }
    if( (flags & MEM_Int) ){
      return vdbeRecordCompareInt;
    }
    testcase( flags & MEM_Real );
    testcase( flags & MEM_Null );
    testcase( flags & MEM_Blob );
    if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
      assert( flags & MEM_Str );
      return vdbeRecordCompareString;
    }
  }

  return sqlite3VdbeRecordCompare;
}

/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
** Read the rowid (the last field in the record) and store it in *rowid.
** Return SQLITE_OK if everything works, or an error code otherwise.







|
>
>







 







>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<







3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
....
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
....
3899
3900
3901
3902
3903
3904
3905














3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923


3924
3925
3926
3927
3928
3929
3930
  int serial_type = ((const u8*)pKey1)[1];
  int res;
  u32 y;
  u64 x;
  i64 v = pPKey2->aMem[0].u.i;
  i64 lhs;

  if( ((const u8*)pKey1)[0]>=64 ){
    return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
  }
  switch( serial_type ){
    case 1: { /* 1-byte signed integer */
      lhs = ONE_BYTE_INT(aKey);
      testcase( lhs<0 );
      break;
    }
    case 2: { /* 2-byte signed integer */
................................................................................
  int nKey1, const void *pKey1, /* Left key */
  UnpackedRecord *pPKey2        /* Right key */
){
  const u8 *aKey1 = (const u8*)pKey1;
  int serial_type;
  int res;

  if( aKey1[0]>=64 ){
    return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
  }
  getVarint32(&aKey1[1], serial_type);
  if( serial_type<12 ){
    res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
  }else if( !(serial_type & 0x01) ){ 
    res = pPKey2->r2;      /* (pKey1/nKey1) is a blob */
  }else{
    int nCmp;
................................................................................

/*
** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
** suitable for comparing serialized records to the unpacked record passed
** as the only argument.
*/
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){














  int flags = p->aMem[0].flags;
  if( p->pKeyInfo->aSortOrder[0] ){
    p->r1 = 1;
    p->r2 = -1;
  }else{
    p->r1 = -1;
    p->r2 = 1;
  }
  if( (flags & MEM_Int) ){
    return vdbeRecordCompareInt;
  }
  testcase( flags & MEM_Real );
  testcase( flags & MEM_Null );
  testcase( flags & MEM_Blob );
  if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
    assert( flags & MEM_Str );
    return vdbeRecordCompareString;
  }


  return sqlite3VdbeRecordCompare;
}

/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
** Read the rowid (the last field in the record) and store it in *rowid.
** Return SQLITE_OK if everything works, or an error code otherwise.