/ Check-in [e41376cf]
Login

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

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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeaux.c.

  3756   3756     int serial_type = ((const u8*)pKey1)[1];
  3757   3757     int res;
  3758   3758     u32 y;
  3759   3759     u64 x;
  3760   3760     i64 v = pPKey2->aMem[0].u.i;
  3761   3761     i64 lhs;
  3762   3762   
  3763         -  assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
         3763  +  if( ((const u8*)pKey1)[0]>=64 ){
         3764  +    return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
         3765  +  }
  3764   3766     switch( serial_type ){
  3765   3767       case 1: { /* 1-byte signed integer */
  3766   3768         lhs = ONE_BYTE_INT(aKey);
  3767   3769         testcase( lhs<0 );
  3768   3770         break;
  3769   3771       }
  3770   3772       case 2: { /* 2-byte signed integer */
................................................................................
  3843   3845     int nKey1, const void *pKey1, /* Left key */
  3844   3846     UnpackedRecord *pPKey2        /* Right key */
  3845   3847   ){
  3846   3848     const u8 *aKey1 = (const u8*)pKey1;
  3847   3849     int serial_type;
  3848   3850     int res;
  3849   3851   
         3852  +  if( aKey1[0]>=64 ){
         3853  +    return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
         3854  +  }
  3850   3855     getVarint32(&aKey1[1], serial_type);
  3851   3856     if( serial_type<12 ){
  3852   3857       res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
  3853   3858     }else if( !(serial_type & 0x01) ){ 
  3854   3859       res = pPKey2->r2;      /* (pKey1/nKey1) is a blob */
  3855   3860     }else{
  3856   3861       int nCmp;
................................................................................
  3894   3899   
  3895   3900   /*
  3896   3901   ** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
  3897   3902   ** suitable for comparing serialized records to the unpacked record passed
  3898   3903   ** as the only argument.
  3899   3904   */
  3900   3905   RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
  3901         -  /* varintRecordCompareInt() and varintRecordCompareString() both assume
  3902         -  ** that the size-of-header varint that occurs at the start of each record
  3903         -  ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt()
  3904         -  ** also assumes that it is safe to overread a buffer by at least the 
  3905         -  ** maximum possible legal header size plus 8 bytes. Because there is
  3906         -  ** guaranteed to be at least 74 (but not 136) bytes of padding following each
  3907         -  ** buffer passed to varintRecordCompareInt() this makes it convenient to
  3908         -  ** limit the size of the header to 64 bytes in cases where the first field
  3909         -  ** is an integer.
  3910         -  **
  3911         -  ** The easiest way to enforce this limit is to consider only records with
  3912         -  ** 13 fields or less. If the first field is an integer, the maximum legal
  3913         -  ** header size is (12*5 + 1 + 1) bytes.  */
  3914         -  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
  3915         -    int flags = p->aMem[0].flags;
  3916         -    if( p->pKeyInfo->aSortOrder[0] ){
  3917         -      p->r1 = 1;
  3918         -      p->r2 = -1;
  3919         -    }else{
  3920         -      p->r1 = -1;
  3921         -      p->r2 = 1;
  3922         -    }
  3923         -    if( (flags & MEM_Int) ){
  3924         -      return vdbeRecordCompareInt;
  3925         -    }
  3926         -    testcase( flags & MEM_Real );
  3927         -    testcase( flags & MEM_Null );
  3928         -    testcase( flags & MEM_Blob );
  3929         -    if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
  3930         -      assert( flags & MEM_Str );
  3931         -      return vdbeRecordCompareString;
  3932         -    }
         3906  +  int flags = p->aMem[0].flags;
         3907  +  if( p->pKeyInfo->aSortOrder[0] ){
         3908  +    p->r1 = 1;
         3909  +    p->r2 = -1;
         3910  +  }else{
         3911  +    p->r1 = -1;
         3912  +    p->r2 = 1;
         3913  +  }
         3914  +  if( (flags & MEM_Int) ){
         3915  +    return vdbeRecordCompareInt;
  3933   3916     }
  3934         -
         3917  +  testcase( flags & MEM_Real );
         3918  +  testcase( flags & MEM_Null );
         3919  +  testcase( flags & MEM_Blob );
         3920  +  if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
         3921  +    assert( flags & MEM_Str );
         3922  +    return vdbeRecordCompareString;
         3923  +  }
  3935   3924     return sqlite3VdbeRecordCompare;
  3936   3925   }
  3937   3926   
  3938   3927   /*
  3939   3928   ** pCur points at an index entry created using the OP_MakeRecord opcode.
  3940   3929   ** Read the rowid (the last field in the record) and store it in *rowid.
  3941   3930   ** Return SQLITE_OK if everything works, or an error code otherwise.