/ Check-in [aea5990e]
Login

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

Overview
Comment:In the KeyInfo object, refactor the nField and nXField elements into nKeyField and nAllField, which are more useful and run a little faster.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: aea5990eab5e85f92df966aa641db2271c81052010ad2d80982475c4275a1284
User & Date: drh 2017-08-02 22:43:14
Context
2017-08-03
00:29
Optimization to the comparison opcodes in the byte-code engine. check-in: 654935c7 user: drh tags: trunk
2017-08-02
22:43
In the KeyInfo object, refactor the nField and nXField elements into nKeyField and nAllField, which are more useful and run a little faster. check-in: aea5990e user: drh tags: trunk
19:04
Avoid redundant calls to sqlite3ApiExit() in sqlite3_step(). check-in: 527974d4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

  1677   1677   **     (3)  Bypass the creation of the sqlite_master table entry
  1678   1678   **          for the PRIMARY KEY as the primary key index is now
  1679   1679   **          identified by the sqlite_master table entry of the table itself.
  1680   1680   **     (4)  Set the Index.tnum of the PRIMARY KEY Index object in the
  1681   1681   **          schema to the rootpage from the main table.
  1682   1682   **     (5)  Add all table columns to the PRIMARY KEY Index object
  1683   1683   **          so that the PRIMARY KEY is a covering index.  The surplus
  1684         -**          columns are part of KeyInfo.nXField and are not used for
         1684  +**          columns are part of KeyInfo.nAllField and are not used for
  1685   1685   **          sorting or lookup or uniqueness checks.
  1686   1686   **     (6)  Replace the rowid tail on all automatically generated UNIQUE
  1687   1687   **          indices with the PRIMARY KEY columns.
  1688   1688   **
  1689   1689   ** For virtual tables, only (1) is performed.
  1690   1690   */
  1691   1691   static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){

Changes to src/select.c.

   558    558       }
   559    559       VdbeCoverage(v);
   560    560       sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
   561    561       pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
   562    562       if( pParse->db->mallocFailed ) return;
   563    563       pOp->p2 = nKey + nData;
   564    564       pKI = pOp->p4.pKeyInfo;
   565         -    memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
          565  +    memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
   566    566       sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
   567         -    testcase( pKI->nXField>2 );
          567  +    testcase( pKI->nAllField > pKI->nKeyField+2 );
   568    568       pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
   569         -                                           pKI->nXField-1);
          569  +                                           pKI->nAllField-pKI->nKeyField-1);
   570    570       addrJmp = sqlite3VdbeCurrentAddr(v);
   571    571       sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
   572    572       pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
   573    573       pSort->regReturn = ++pParse->nMem;
   574    574       sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
   575    575       sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
   576    576       if( iLimit ){
................................................................................
  1031   1031   ** X extra columns.
  1032   1032   */
  1033   1033   KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
  1034   1034     int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*);
  1035   1035     KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
  1036   1036     if( p ){
  1037   1037       p->aSortOrder = (u8*)&p->aColl[N+X];
  1038         -    p->nField = (u16)N;
  1039         -    p->nXField = (u16)X;
         1038  +    p->nKeyField = (u16)N;
         1039  +    p->nAllField = (u16)(N+X);
  1040   1040       p->enc = ENC(db);
  1041   1041       p->db = db;
  1042   1042       p->nRef = 1;
  1043   1043       memset(&p[1], 0, nExtra);
  1044   1044     }else{
  1045   1045       sqlite3OomFault(db);
  1046   1046     }

Changes to src/sqliteInt.h.

  2048   2048   ** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
  2049   2049   ** are nField slots for the columns of an index then one extra slot
  2050   2050   ** for the rowid at the end.
  2051   2051   */
  2052   2052   struct KeyInfo {
  2053   2053     u32 nRef;           /* Number of references to this KeyInfo object */
  2054   2054     u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  2055         -  u16 nField;         /* Number of key columns in the index */
  2056         -  u16 nXField;        /* Number of columns beyond the key columns */
         2055  +  u16 nKeyField;      /* Number of key columns in the index */
         2056  +  u16 nAllField;      /* Total columns, including key plus others */
  2057   2057     sqlite3 *db;        /* The database connection */
  2058   2058     u8 *aSortOrder;     /* Sort order for each column. */
  2059   2059     CollSeq *aColl[1];  /* Collating sequence for each term of the key */
  2060   2060   };
  2061   2061   
  2062   2062   /*
  2063   2063   ** This object holds a record which has been parsed out into individual

Changes to src/vdbe.c.

  2100   2100   #endif /* SQLITE_DEBUG */
  2101   2101     for(i=0; i<n; i++){
  2102   2102       idx = aPermute ? aPermute[i] : i;
  2103   2103       assert( memIsValid(&aMem[p1+idx]) );
  2104   2104       assert( memIsValid(&aMem[p2+idx]) );
  2105   2105       REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
  2106   2106       REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
  2107         -    assert( i<pKeyInfo->nField );
         2107  +    assert( i<pKeyInfo->nKeyField );
  2108   2108       pColl = pKeyInfo->aColl[i];
  2109   2109       bRev = pKeyInfo->aSortOrder[i];
  2110   2110       iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
  2111   2111       if( iCompare ){
  2112   2112         if( bRev ) iCompare = -iCompare;
  2113   2113         break;
  2114   2114       }
................................................................................
  3394   3394       ** before reaching this instruction. */
  3395   3395       assert( p2>=2 );
  3396   3396     }
  3397   3397     if( pOp->p4type==P4_KEYINFO ){
  3398   3398       pKeyInfo = pOp->p4.pKeyInfo;
  3399   3399       assert( pKeyInfo->enc==ENC(db) );
  3400   3400       assert( pKeyInfo->db==db );
  3401         -    nField = pKeyInfo->nField+pKeyInfo->nXField;
         3401  +    nField = pKeyInfo->nAllField;
  3402   3402     }else if( pOp->p4type==P4_INT32 ){
  3403   3403       nField = pOp->p4.i;
  3404   3404     }
  3405   3405     assert( pOp->p1>=0 );
  3406   3406     assert( nField>=0 );
  3407   3407     testcase( nField==0 );  /* Table with INTEGER PRIMARY KEY and nothing else */
  3408   3408     pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);

Changes to src/vdbeapi.c.

  1716   1716     int nKey, 
  1717   1717     const void *pKey
  1718   1718   ){
  1719   1719     UnpackedRecord *pRet;           /* Return value */
  1720   1720   
  1721   1721     pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
  1722   1722     if( pRet ){
  1723         -    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
         1723  +    memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
  1724   1724       sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
  1725   1725     }
  1726   1726     return pRet;
  1727   1727   }
  1728   1728   
  1729   1729   /*
  1730   1730   ** This function is called from within a pre-update callback to retrieve
................................................................................
  1789   1789   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  1790   1790   /*
  1791   1791   ** This function is called from within a pre-update callback to retrieve
  1792   1792   ** the number of columns in the row being updated, deleted or inserted.
  1793   1793   */
  1794   1794   int sqlite3_preupdate_count(sqlite3 *db){
  1795   1795     PreUpdate *p = db->pPreUpdate;
  1796         -  return (p ? p->keyinfo.nField : 0);
         1796  +  return (p ? p->keyinfo.nKeyField : 0);
  1797   1797   }
  1798   1798   #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
  1799   1799   
  1800   1800   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  1801   1801   /*
  1802   1802   ** This function is designed to be called from within a pre-update callback
  1803   1803   ** only. It returns zero if the change that caused the callback was made

Changes to src/vdbeaux.c.

  1316   1316     assert( nTemp>=20 );
  1317   1317     sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
  1318   1318     switch( pOp->p4type ){
  1319   1319       case P4_KEYINFO: {
  1320   1320         int j;
  1321   1321         KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  1322   1322         assert( pKeyInfo->aSortOrder!=0 );
  1323         -      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
  1324         -      for(j=0; j<pKeyInfo->nField; j++){
         1323  +      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
         1324  +      for(j=0; j<pKeyInfo->nKeyField; j++){
  1325   1325           CollSeq *pColl = pKeyInfo->aColl[j];
  1326   1326           const char *zColl = pColl ? pColl->zName : "";
  1327   1327           if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
  1328   1328           sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
  1329   1329         }
  1330   1330         sqlite3StrAccumAppend(&x, ")", 1);
  1331   1331         break;
................................................................................
  3543   3543   ** If an OOM error occurs, NULL is returned.
  3544   3544   */
  3545   3545   UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
  3546   3546     KeyInfo *pKeyInfo               /* Description of the record */
  3547   3547   ){
  3548   3548     UnpackedRecord *p;              /* Unpacked record to return */
  3549   3549     int nByte;                      /* Number of bytes required for *p */
  3550         -  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
         3550  +  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
  3551   3551     p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
  3552   3552     if( !p ) return 0;
  3553   3553     p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
  3554   3554     assert( pKeyInfo->aSortOrder!=0 );
  3555   3555     p->pKeyInfo = pKeyInfo;
  3556         -  p->nField = pKeyInfo->nField + 1;
         3556  +  p->nField = pKeyInfo->nKeyField + 1;
  3557   3557     return p;
  3558   3558   }
  3559   3559   
  3560   3560   /*
  3561   3561   ** Given the nKey-byte encoding of a record in pKey[], populate the 
  3562   3562   ** UnpackedRecord structure indicated by the fourth argument with the
  3563   3563   ** contents of the decoded record.
................................................................................
  3589   3589       /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
  3590   3590       pMem->szMalloc = 0;
  3591   3591       pMem->z = 0;
  3592   3592       d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
  3593   3593       pMem++;
  3594   3594       if( (++u)>=p->nField ) break;
  3595   3595     }
  3596         -  assert( u<=pKeyInfo->nField + 1 );
         3596  +  assert( u<=pKeyInfo->nKeyField + 1 );
  3597   3597     p->nField = u;
  3598   3598   }
  3599   3599   
  3600   3600   #ifdef SQLITE_DEBUG
  3601   3601   /*
  3602   3602   ** This function compares two index or table record keys in the same way
  3603   3603   ** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
................................................................................
  3638   3638     ** to ignore the compiler warnings and leave this variable uninitialized.
  3639   3639     */
  3640   3640     /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  3641   3641     
  3642   3642     idx1 = getVarint32(aKey1, szHdr1);
  3643   3643     if( szHdr1>98307 ) return SQLITE_CORRUPT;
  3644   3644     d1 = szHdr1;
  3645         -  assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
         3645  +  assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
  3646   3646     assert( pKeyInfo->aSortOrder!=0 );
  3647         -  assert( pKeyInfo->nField>0 );
         3647  +  assert( pKeyInfo->nKeyField>0 );
  3648   3648     assert( idx1<=szHdr1 || CORRUPT_DB );
  3649   3649     do{
  3650   3650       u32 serial_type1;
  3651   3651   
  3652   3652       /* Read the serial types for the next element in each key. */
  3653   3653       idx1 += getVarint32( aKey1+idx1, serial_type1 );
  3654   3654   
................................................................................
  3702   3702   }
  3703   3703   #endif
  3704   3704   
  3705   3705   #ifdef SQLITE_DEBUG
  3706   3706   /*
  3707   3707   ** Count the number of fields (a.k.a. columns) in the record given by
  3708   3708   ** pKey,nKey.  The verify that this count is less than or equal to the
  3709         -** limit given by pKeyInfo->nField + pKeyInfo->nXField.
         3709  +** limit given by pKeyInfo->nAllField.
  3710   3710   **
  3711   3711   ** If this constraint is not satisfied, it means that the high-speed
  3712   3712   ** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
  3713   3713   ** not work correctly.  If this assert() ever fires, it probably means
  3714         -** that the KeyInfo.nField or KeyInfo.nXField values were computed
         3714  +** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed
  3715   3715   ** incorrectly.
  3716   3716   */
  3717   3717   static void vdbeAssertFieldCountWithinLimits(
  3718   3718     int nKey, const void *pKey,   /* The record to verify */ 
  3719   3719     const KeyInfo *pKeyInfo       /* Compare size with this KeyInfo */
  3720   3720   ){
  3721   3721     int nField = 0;
................................................................................
  3728   3728     idx = getVarint32(aKey, szHdr);
  3729   3729     assert( nKey>=0 );
  3730   3730     assert( szHdr<=(u32)nKey );
  3731   3731     while( idx<szHdr ){
  3732   3732       idx += getVarint32(aKey+idx, notUsed);
  3733   3733       nField++;
  3734   3734     }
  3735         -  assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
         3735  +  assert( nField <= pKeyInfo->nAllField );
  3736   3736   }
  3737   3737   #else
  3738   3738   # define vdbeAssertFieldCountWithinLimits(A,B,C)
  3739   3739   #endif
  3740   3740   
  3741   3741   /*
  3742   3742   ** Both *pMem1 and *pMem2 contain string values. Compare the two values
................................................................................
  4033   4033         pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
  4034   4034         return 0;  /* Corruption */
  4035   4035       }
  4036   4036       i = 0;
  4037   4037     }
  4038   4038   
  4039   4039     VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
  4040         -  assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField 
         4040  +  assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField 
  4041   4041          || CORRUPT_DB );
  4042   4042     assert( pPKey2->pKeyInfo->aSortOrder!=0 );
  4043         -  assert( pPKey2->pKeyInfo->nField>0 );
         4043  +  assert( pPKey2->pKeyInfo->nKeyField>0 );
  4044   4044     assert( idx1<=szHdr1 || CORRUPT_DB );
  4045   4045     do{
  4046   4046       u32 serial_type;
  4047   4047   
  4048   4048       /* RHS is an integer */
  4049   4049       if( pRhs->flags & MEM_Int ){
  4050   4050         serial_type = aKey1[idx1];
................................................................................
  4369   4369     ** buffer passed to varintRecordCompareInt() this makes it convenient to
  4370   4370     ** limit the size of the header to 64 bytes in cases where the first field
  4371   4371     ** is an integer.
  4372   4372     **
  4373   4373     ** The easiest way to enforce this limit is to consider only records with
  4374   4374     ** 13 fields or less. If the first field is an integer, the maximum legal
  4375   4375     ** header size is (12*5 + 1 + 1) bytes.  */
  4376         -  if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
         4376  +  if( p->pKeyInfo->nAllField<=13 ){
  4377   4377       int flags = p->aMem[0].flags;
  4378   4378       if( p->pKeyInfo->aSortOrder[0] ){
  4379   4379         p->r1 = 1;
  4380   4380         p->r2 = -1;
  4381   4381       }else{
  4382   4382         p->r1 = -1;
  4383   4383         p->r2 = 1;
................................................................................
  4704   4704   
  4705   4705     preupdate.v = v;
  4706   4706     preupdate.pCsr = pCsr;
  4707   4707     preupdate.op = op;
  4708   4708     preupdate.iNewReg = iReg;
  4709   4709     preupdate.keyinfo.db = db;
  4710   4710     preupdate.keyinfo.enc = ENC(db);
  4711         -  preupdate.keyinfo.nField = pTab->nCol;
         4711  +  preupdate.keyinfo.nKeyField = pTab->nCol;
  4712   4712     preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
  4713   4713     preupdate.iKey1 = iKey1;
  4714   4714     preupdate.iKey2 = iKey2;
  4715   4715     preupdate.pTab = pTab;
  4716   4716   
  4717   4717     db->pPreUpdate = &preupdate;
  4718   4718     db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
  4719   4719     db->pPreUpdate = 0;
  4720   4720     sqlite3DbFree(db, preupdate.aRecord);
  4721         -  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
  4722         -  vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
         4721  +  vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked);
         4722  +  vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked);
  4723   4723     if( preupdate.aNew ){
  4724   4724       int i;
  4725   4725       for(i=0; i<pCsr->nField; i++){
  4726   4726         sqlite3VdbeMemRelease(&preupdate.aNew[i]);
  4727   4727       }
  4728   4728       sqlite3DbFreeNN(db, preupdate.aNew);
  4729   4729     }
  4730   4730   }
  4731   4731   #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */

Changes to src/vdbemem.c.

  1159   1159         int nCol = pIdx->nColumn;   /* Number of index columns including rowid */
  1160   1160     
  1161   1161         nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord));
  1162   1162         pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
  1163   1163         if( pRec ){
  1164   1164           pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
  1165   1165           if( pRec->pKeyInfo ){
  1166         -          assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
         1166  +          assert( pRec->pKeyInfo->nAllField==nCol );
  1167   1167             assert( pRec->pKeyInfo->enc==ENC(db) );
  1168   1168             pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
  1169   1169             for(i=0; i<nCol; i++){
  1170   1170               pRec->aMem[i].flags = MEM_Null;
  1171   1171               pRec->aMem[i].db = db;
  1172   1172             }
  1173   1173           }else{
................................................................................
  1695   1695   ** Unless it is NULL, the argument must be an UnpackedRecord object returned
  1696   1696   ** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
  1697   1697   ** the object.
  1698   1698   */
  1699   1699   void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
  1700   1700     if( pRec ){
  1701   1701       int i;
  1702         -    int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
         1702  +    int nCol = pRec->pKeyInfo->nAllField;
  1703   1703       Mem *aMem = pRec->aMem;
  1704   1704       sqlite3 *db = aMem[0].db;
  1705   1705       for(i=0; i<nCol; i++){
  1706   1706         sqlite3VdbeMemRelease(&aMem[i]);
  1707   1707       }
  1708   1708       sqlite3KeyInfoUnref(pRec->pKeyInfo);
  1709   1709       sqlite3DbFreeNN(db, pRec);

Changes to src/vdbesort.c.

   819    819     getVarint32(&p2[1], n2);
   820    820     res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
   821    821     if( res==0 ){
   822    822       res = n1 - n2;
   823    823     }
   824    824   
   825    825     if( res==0 ){
   826         -    if( pTask->pSorter->pKeyInfo->nField>1 ){
          826  +    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
   827    827         res = vdbeSorterCompareTail(
   828    828             pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
   829    829         );
   830    830       }
   831    831     }else{
   832    832       if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
   833    833         res = res * -1;
................................................................................
   888    888         if( *v1 & 0x80 ) res = -1;
   889    889       }else{
   890    890         if( *v2 & 0x80 ) res = +1;
   891    891       }
   892    892     }
   893    893   
   894    894     if( res==0 ){
   895         -    if( pTask->pSorter->pKeyInfo->nField>1 ){
          895  +    if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
   896    896         res = vdbeSorterCompareTail(
   897    897             pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
   898    898         );
   899    899       }
   900    900     }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
   901    901       res = res * -1;
   902    902     }
................................................................................
   903    903   
   904    904     return res;
   905    905   }
   906    906   
   907    907   /*
   908    908   ** Initialize the temporary index cursor just opened as a sorter cursor.
   909    909   **
   910         -** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
          910  +** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
   911    911   ** to determine the number of fields that should be compared from the
   912    912   ** records being sorted. However, if the value passed as argument nField
   913    913   ** is non-zero and the sorter is able to guarantee a stable sort, nField
   914    914   ** is used instead. This is used when sorting records for a CREATE INDEX
   915    915   ** statement. In this case, keys are always delivered to the sorter in
   916    916   ** order of the primary key, which happens to be make up the final part 
   917    917   ** of the records being sorted. So if the sort is stable, there is never
................................................................................
   956    956     if( nWorker>=SORTER_MAX_MERGE_COUNT ){
   957    957       nWorker = SORTER_MAX_MERGE_COUNT-1;
   958    958     }
   959    959   #endif
   960    960   
   961    961     assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
   962    962     assert( pCsr->eCurType==CURTYPE_SORTER );
   963         -  szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
          963  +  szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
   964    964     sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
   965    965   
   966    966     pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
   967    967     pCsr->uc.pSorter = pSorter;
   968    968     if( pSorter==0 ){
   969    969       rc = SQLITE_NOMEM_BKPT;
   970    970     }else{
   971    971       pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
   972    972       memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
   973    973       pKeyInfo->db = 0;
   974    974       if( nField && nWorker==0 ){
   975         -      pKeyInfo->nXField += (pKeyInfo->nField - nField);
   976         -      pKeyInfo->nField = nField;
          975  +      pKeyInfo->nKeyField = nField;
   977    976       }
   978    977       pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
   979    978       pSorter->nTask = nWorker + 1;
   980    979       pSorter->iPrev = (u8)(nWorker - 1);
   981    980       pSorter->bUseThreads = (pSorter->nTask>1);
   982    981       pSorter->db = db;
   983    982       for(i=0; i<pSorter->nTask; i++){
................................................................................
  1009   1008           assert( pSorter->iMemory==0 );
  1010   1009           pSorter->nMemory = pgsz;
  1011   1010           pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
  1012   1011           if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
  1013   1012         }
  1014   1013       }
  1015   1014   
  1016         -    if( (pKeyInfo->nField+pKeyInfo->nXField)<13 
         1015  +    if( pKeyInfo->nAllField<13 
  1017   1016        && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
  1018   1017       ){
  1019   1018         pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
  1020   1019       }
  1021   1020     }
  1022   1021   
  1023   1022     return rc;
................................................................................
  1324   1323   ** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or 
  1325   1324   ** if no allocation was required), or SQLITE_NOMEM otherwise.
  1326   1325   */
  1327   1326   static int vdbeSortAllocUnpacked(SortSubtask *pTask){
  1328   1327     if( pTask->pUnpacked==0 ){
  1329   1328       pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
  1330   1329       if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
  1331         -    pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
         1330  +    pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField;
  1332   1331       pTask->pUnpacked->errCode = 0;
  1333   1332     }
  1334   1333     return SQLITE_OK;
  1335   1334   }
  1336   1335   
  1337   1336   
  1338   1337   /*