SQLite4
Check-in [2054b8483b2bce05a105c81d7fe60b3b26cf0ed9]
Not logged in

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

Overview
SHA1 Hash:2054b8483b2bce05a105c81d7fe60b3b26cf0ed9
Date: 2013-07-30 14:34:06
User: drh
Comment:Enhanced comments and logic clarification in the OP_MakeIdxKey implementation.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c

2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
....
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205


2206
2207
2208
2209
2210
2211
2212
....
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225


2226
2227
2228
2229
2230
2231
2232
  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** P1 is an open cursor. P2 is the first register in a contiguous array
** of N registers containing values to encode into a database key. Normally,
** N is equal to the number of columns indexed by P1, plus the number of 
** trailing primary key columns (if any). 
**
** Or, if P4 is a non-zero integer, then it contains the value for N.
**
** This instruction encodes the N values into a database key and writes
** the result to register P3. No affinity transformations are applied to 
** the input values before they are encoded. 
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursors table.
**
** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
** for N is not the true number of values in the key, only the number that
** need to be encoded for this operation.  This effects the encoding of
** final BLOBs.
*/
case OP_MakeIdxKey: {
................................................................................
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  /* If pOp->p5 is non-zero, encode the sequence number blob to append to
  ** the end of the key. Variable nSeq is set to the number of bytes in
  ** the encoded key.


  */
  nSeq = 0;
  if( pOp->p5 & OPFLAG_SEQCOUNT ){
    iSeq = pC->seqCount++;
    do {
      nSeq++;
      aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
................................................................................
      iSeq = iSeq >> 7;
    }while( iSeq );
    aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  }

  memAboutToChange(p, pOut);

  nField = pOp->p4.i;
  if( nField==0 ) nField = pKeyInfo->nField;

  if( pOp->p4type==P4_INT32 && pOp->p4.i ){
    nField = pOp->p4.i;
    assert( nField<=pKeyInfo->nField );


  }
  rc = sqlite4VdbeEncodeKey(
    db, pData0, nField, pKeyInfo->nField,
    pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
  );

  if( rc ){







|
|
<
<







|







 







|
|
|
>
>







 







<
<
<
|


>
>







2161
2162
2163
2164
2165
2166
2167
2168
2169


2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
....
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
....
2213
2214
2215
2216
2217
2218
2219



2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** P1 is an open cursor. P2 is the first register in a contiguous array
** of N registers containing values to encode into a database key. Normally,
** N is taken from the KeyInfo object of P1.  However, of P4 is a positive
** integer, P4 is used for N instead.


**
** This instruction encodes the N values into a database key and writes
** the result to register P3. No affinity transformations are applied to 
** the input values before they are encoded. 
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursor table.
**
** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
** for N is not the true number of values in the key, only the number that
** need to be encoded for this operation.  This effects the encoding of
** final BLOBs.
*/
case OP_MakeIdxKey: {
................................................................................
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  /* If P4 contains OPFLAG_SEQCOUNT, encode the sequence number blob to be
  ** appended to the end of the key.  Variable nSeq is set to the number
  ** of bytes in the encoded key.  A non-standard encoding is used (not
  ** the usual varint encoding) so that the OP_GrpCompare opcode can easily
  ** back up over the sequence count to find the true end of the key.
  */
  nSeq = 0;
  if( pOp->p5 & OPFLAG_SEQCOUNT ){
    iSeq = pC->seqCount++;
    do {
      nSeq++;
      aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
................................................................................
      iSeq = iSeq >> 7;
    }while( iSeq );
    aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  }

  memAboutToChange(p, pOut);




  if( pOp->p4type==P4_INT32 && pOp->p4.i>0 ){
    nField = pOp->p4.i;
    assert( nField<=pKeyInfo->nField );
  }else{
    nField = pKeyInfo->nField;
  }
  rc = sqlite4VdbeEncodeKey(
    db, pData0, nField, pKeyInfo->nField,
    pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
  );

  if( rc ){