/ Check-in [defd5205]
Login

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

Overview
Comment:Reference count the KeyInfo object. Cache a copy of an appropriate KeyInfo for each index in the Index object, and reuse that one copy as much as possible.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-rowid
Files: files | file ages | folders
SHA1: defd5205a7cc3543cdd18f906f568e943b8b3a2c
User & Date: drh 2013-11-06 19:59:23
Context
2013-11-07
14:09
Make sure cached KeyInfo objects are only valid for a single database connection. Clear all cached KeyInfo objects on any collating sequence change. Closed-Leaf check-in: 55eea178 user: drh tags: omit-rowid
2013-11-06
19:59
Reference count the KeyInfo object. Cache a copy of an appropriate KeyInfo for each index in the Index object, and reuse that one copy as much as possible. check-in: defd5205 user: drh tags: omit-rowid
16:28
Have the OP_NoConflict opcode set the VdbeCursor.seekResult variable. This speeds up subsequent OP_Insert and OP_IdxInsert opcodes. check-in: 47455500 user: dan tags: omit-rowid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

   984    984     iIdxCur = iTab++;
   985    985     pParse->nTab = MAX(pParse->nTab, iTab);
   986    986     sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
   987    987     sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
   988    988   
   989    989     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   990    990       int nCol;                     /* Number of columns indexed by pIdx */
   991         -    KeyInfo *pKey;                /* KeyInfo structure for pIdx */
   992    991       int *aGotoChng;               /* Array of jump instruction addresses */
   993    992       int addrRewind;               /* Address of "OP_Rewind iIdxCur" */
   994    993       int addrGotoChng0;            /* Address of "Goto addr_chng_0" */
   995    994       int addrNextRow;              /* Address of "next_row:" */
   996    995       const char *zIdxName;         /* Name of the index */
   997    996   
   998    997       if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
   999    998       if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
  1000    999       VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
  1001   1000       nCol = pIdx->nKeyCol;
  1002   1001       aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
  1003   1002       if( aGotoChng==0 ) continue;
  1004         -    pKey = sqlite3IndexKeyinfo(pParse, pIdx);
  1005   1003   
  1006   1004       /* Populate the register containing the index name. */
  1007   1005       if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
  1008   1006         zIdxName = pTab->zName;
  1009   1007       }else{
  1010   1008         zIdxName = pIdx->zName;
  1011   1009       }
................................................................................
  1048   1046       ** when building a record to insert into the sample column of 
  1049   1047       ** the sqlite_stat4 table.  */
  1050   1048       pParse->nMem = MAX(pParse->nMem, regPrev+nCol);
  1051   1049   
  1052   1050       /* Open a read-only cursor on the index being analyzed. */
  1053   1051       assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
  1054   1052       sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
  1055         -    sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); 
         1053  +    sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  1056   1054       VdbeComment((v, "%s", pIdx->zName));
  1057   1055   
  1058   1056       /* Invoke the stat_init() function. The arguments are:
  1059   1057       ** 
  1060   1058       **    (1) the number of columns in the index including the rowid,
  1061   1059       **    (2) the number of rows in the index,
  1062   1060       **

Changes to src/build.c.

   378    378   /*
   379    379   ** Reclaim the memory used by an index
   380    380   */
   381    381   static void freeIndex(sqlite3 *db, Index *p){
   382    382   #ifndef SQLITE_OMIT_ANALYZE
   383    383     sqlite3DeleteIndexSamples(db, p);
   384    384   #endif
          385  +  if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
   385    386     sqlite3ExprDelete(db, p->pPartIdxWhere);
   386    387     sqlite3DbFree(db, p->zColAff);
   387    388     if( p->isResized ) sqlite3DbFree(db, p->azColl);
   388    389     sqlite3DbFree(db, p);
   389    390   }
   390    391   
   391    392   /*
................................................................................
  2651   2652     v = sqlite3GetVdbe(pParse);
  2652   2653     if( v==0 ) return;
  2653   2654     if( memRootPage>=0 ){
  2654   2655       tnum = memRootPage;
  2655   2656     }else{
  2656   2657       tnum = pIndex->tnum;
  2657   2658     }
  2658         -  pKey = sqlite3IndexKeyinfo(pParse, pIndex);
         2659  +  pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
  2659   2660   
  2660   2661     /* Open the sorter cursor if we are to use one. */
  2661   2662     iSorter = pParse->nTab++;
  2662         -  sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
         2663  +  sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
         2664  +                    sqlite3KeyInfoRef(pKey), P4_KEYINFO);
  2663   2665   
  2664   2666     /* Open the table. Loop through all rows of the table, inserting index
  2665   2667     ** records into the sorter. */
  2666   2668     sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
  2667   2669     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
  2668   2670     regRecord = sqlite3GetTempReg(pParse);
  2669   2671   
................................................................................
  2670   2672     sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel);
  2671   2673     sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
  2672   2674     sqlite3VdbeResolveLabel(v, iPartIdxLabel);
  2673   2675     sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
  2674   2676     sqlite3VdbeJumpHere(v, addr1);
  2675   2677     if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
  2676   2678     sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
  2677         -                    (char *)pKey, P4_KEYINFO_HANDOFF);
         2679  +                    (char *)pKey, P4_KEYINFO);
  2678   2680     sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
  2679   2681   
  2680   2682     addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
  2681   2683     assert( pKey!=0 || db->mallocFailed || pParse->nErr );
  2682   2684     if( pIndex->onError!=OE_None && pKey!=0 ){
  2683   2685       int j2 = sqlite3VdbeCurrentAddr(v) + 3;
  2684   2686       sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
................................................................................
  4138   4140       return;
  4139   4141     }
  4140   4142     sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed");
  4141   4143   }
  4142   4144   #endif
  4143   4145   
  4144   4146   /*
  4145         -** Return a dynamicly allocated KeyInfo structure that can be used
  4146         -** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
         4147  +** Return a KeyInfo structure that is appropriate for the given Index.
         4148  +**
         4149  +** The KeyInfo structure for an index is cached in the Index object.
         4150  +** So there might be multiple references to the returned pointer.  The
         4151  +** caller should not try to modify the KeyInfo object.
  4147   4152   **
  4148         -** If successful, a pointer to the new structure is returned. In this case
  4149         -** the caller is responsible for calling sqlite3DbFree(db, ) on the returned 
  4150         -** pointer. If an error occurs (out of memory or missing collation 
  4151         -** sequence), NULL is returned and the state of pParse updated to reflect
  4152         -** the error.
         4153  +** The caller should invoke sqlite3KeyInfoUnref() on the returned object
         4154  +** when it has finished using it.
  4153   4155   */
  4154         -KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
         4156  +KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
  4155   4157     int i;
  4156   4158     int nCol = pIdx->nColumn;
  4157   4159     int nKey = pIdx->nKeyCol;
  4158   4160     KeyInfo *pKey;
  4159   4161   
  4160         -  if( pIdx->uniqNotNull ){
  4161         -    pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
  4162         -  }else{
  4163         -    pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
  4164         -  }
  4165         -  if( pKey ){
  4166         -    for(i=0; i<nCol; i++){
  4167         -      char *zColl = pIdx->azColl[i];
  4168         -      if( zColl==0 ) zColl = "BINARY";
  4169         -      pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
  4170         -      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
         4162  +  if( pParse->nErr ) return 0;
         4163  +  if( pIdx->pKeyInfo==0 ){
         4164  +    if( pIdx->uniqNotNull ){
         4165  +      pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
         4166  +    }else{
         4167  +      pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
         4168  +    }
         4169  +    if( pKey ){
         4170  +      assert( sqlite3KeyInfoIsWriteable(pKey) );
         4171  +      for(i=0; i<nCol; i++){
         4172  +        char *zColl = pIdx->azColl[i];
         4173  +        if( zColl==0 ) zColl = "BINARY";
         4174  +        pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
         4175  +        pKey->aSortOrder[i] = pIdx->aSortOrder[i];
         4176  +      }
         4177  +      if( pParse->nErr ){
         4178  +        sqlite3KeyInfoUnref(pKey);
         4179  +      }else{
         4180  +        pIdx->pKeyInfo = pKey;
         4181  +      }
  4171   4182       }
  4172   4183     }
  4173         -
  4174         -  if( pParse->nErr ){
  4175         -    sqlite3DbFree(pParse->db, pKey);
  4176         -    pKey = 0;
  4177         -  }
  4178         -  return pKey;
         4184  +  return sqlite3KeyInfoRef(pIdx->pKeyInfo);
  4179   4185   }

Changes to src/delete.c.

   378    378       assert( pPk!=0 );
   379    379       nPk = pPk->nKeyCol;
   380    380       iPk = pParse->nMem+1;
   381    381       pParse->nMem += nPk;
   382    382       iKey = ++pParse->nMem;
   383    383       iEph = pParse->nTab++;
   384    384   
   385         -    sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iEph, nPk, 0, 
   386         -                      (char*)sqlite3IndexKeyinfo(pParse, pPk),
   387         -                      P4_KEYINFO_HANDOFF);
          385  +    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
          386  +    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
   388    387       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
   389    388       if( pWInfo==0 ) goto delete_from_cleanup;
   390    389       for(i=0; i<nPk; i++){
   391    390         sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, pPk->aiColumn[i],iPk+i);
   392    391       }
   393    392       sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
   394    393                         sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);

Changes to src/expr.c.

  1577   1577         int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
  1578   1578   
  1579   1579         for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
  1580   1580           if( (pIdx->aiColumn[0]==iCol)
  1581   1581            && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
  1582   1582            && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
  1583   1583           ){
  1584         -          int iAddr;
  1585         -          char *pKey;
  1586         -  
  1587         -          pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
  1588         -          iAddr = sqlite3CodeOnce(pParse);
  1589         -  
  1590         -          sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
  1591         -                               pKey,P4_KEYINFO_HANDOFF);
         1584  +          int iAddr = sqlite3CodeOnce(pParse);
         1585  +          sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
         1586  +          sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  1592   1587             VdbeComment((v, "%s", pIdx->zName));
  1593   1588             assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
  1594   1589             eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
  1595   1590   
  1596   1591             sqlite3VdbeJumpHere(v, iAddr);
  1597   1592             if( prNotFound && !pTab->aCol[iCol].notNull ){
  1598   1593               *prNotFound = ++pParse->nMem;
................................................................................
  1742   1737           assert( !isRowid );
  1743   1738           sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
  1744   1739           dest.affSdst = (u8)affinity;
  1745   1740           assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
  1746   1741           pExpr->x.pSelect->iLimit = 0;
  1747   1742           testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
  1748   1743           if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
  1749         -          sqlite3DbFree(pParse->db, pKeyInfo);
         1744  +          sqlite3KeyInfoUnref(pKeyInfo);
  1750   1745             return 0;
  1751   1746           }
  1752   1747           pEList = pExpr->x.pSelect->pEList;
  1753   1748           assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
  1754   1749           assert( pEList!=0 );
  1755   1750           assert( pEList->nExpr>0 );
         1751  +        assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  1756   1752           pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
  1757   1753                                                            pEList->a[0].pExpr);
  1758   1754         }else if( ALWAYS(pExpr->x.pList!=0) ){
  1759   1755           /* Case 2:     expr IN (exprlist)
  1760   1756           **
  1761   1757           ** For each expression, build an index key from the evaluation and
  1762   1758           ** store it in the temporary table. If <expr> is a column, then use
................................................................................
  1768   1764           struct ExprList_item *pItem;
  1769   1765           int r1, r2, r3;
  1770   1766   
  1771   1767           if( !affinity ){
  1772   1768             affinity = SQLITE_AFF_NONE;
  1773   1769           }
  1774   1770           if( pKeyInfo ){
         1771  +          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  1775   1772             pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
  1776   1773           }
  1777   1774   
  1778   1775           /* Loop through each expression in <exprlist>. */
  1779   1776           r1 = sqlite3GetTempReg(pParse);
  1780   1777           r2 = sqlite3GetTempReg(pParse);
  1781   1778           sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
................................................................................
  1809   1806               }
  1810   1807             }
  1811   1808           }
  1812   1809           sqlite3ReleaseTempReg(pParse, r1);
  1813   1810           sqlite3ReleaseTempReg(pParse, r2);
  1814   1811         }
  1815   1812         if( pKeyInfo ){
  1816         -        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
         1813  +        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  1817   1814         }
  1818   1815         break;
  1819   1816       }
  1820   1817   
  1821   1818       case TK_EXISTS:
  1822   1819       case TK_SELECT:
  1823   1820       default: {

Changes to src/fkey.c.

   375    375         sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
   376    376         sqlite3VdbeJumpHere(v, iMustBeInt);
   377    377         sqlite3ReleaseTempReg(pParse, regTemp);
   378    378       }else{
   379    379         int nCol = pFKey->nCol;
   380    380         int regTemp = sqlite3GetTempRange(pParse, nCol);
   381    381         int regRec = sqlite3GetTempReg(pParse);
   382         -      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
   383    382     
   384    383         sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
   385         -      sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
          384  +      sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
   386    385         for(i=0; i<nCol; i++){
   387    386           sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
   388    387         }
   389    388     
   390    389         /* If the parent table is the same as the child table, and we are about
   391    390         ** to increment the constraint-counter (i.e. this is an INSERT operation),
   392    391         ** then check if the row being inserted matches itself. If so, do not

Changes to src/insert.c.

    20     20   **   (1) acquire a lock for table pTab then
    21     21   **   (2) open pTab as cursor iCur.
    22     22   **
    23     23   ** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
    24     24   ** for that table that is actually opened.
    25     25   */
    26     26   void sqlite3OpenTable(
    27         -  Parse *p,       /* Generate code into this VDBE */
           27  +  Parse *pParse,  /* Generate code into this VDBE */
    28     28     int iCur,       /* The cursor number of the table */
    29     29     int iDb,        /* The database index in sqlite3.aDb[] */
    30     30     Table *pTab,    /* The table to be opened */
    31     31     int opcode      /* OP_OpenRead or OP_OpenWrite */
    32     32   ){
    33     33     Vdbe *v;
    34     34     assert( !IsVirtual(pTab) );
    35         -  v = sqlite3GetVdbe(p);
           35  +  v = sqlite3GetVdbe(pParse);
    36     36     assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
    37         -  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
           37  +  sqlite3TableLock(pParse, iDb, pTab->tnum, 
           38  +                   (opcode==OP_OpenWrite)?1:0, pTab->zName);
    38     39     if( HasRowid(pTab) ){
    39     40       sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
    40     41       VdbeComment((v, "%s", pTab->zName));
    41     42     }else{
    42     43       Index *pPk = sqlite3PrimaryKeyIndex(pTab);
    43     44       assert( pPk!=0 );
    44     45       assert( pPk->tnum=pTab->tnum );
    45         -    sqlite3VdbeAddOp4(v, opcode, iCur, pPk->tnum, iDb,
    46         -                      (char*)sqlite3IndexKeyinfo(p, pPk), P4_KEYINFO_HANDOFF);
           46  +    sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
           47  +    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
    47     48       VdbeComment((v, "%s", pTab->zName));
    48     49     }
    49     50   }
    50     51   
    51     52   /*
    52     53   ** Return a pointer to the column affinity string associated with index
    53     54   ** pIdx. A column affinity string has one character for each column in 
................................................................................
  1702   1703       *piDataCur = iBase++;
  1703   1704       sqlite3OpenTable(pParse, *piDataCur, iDb, pTab, op);
  1704   1705     }else{
  1705   1706       sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
  1706   1707     }
  1707   1708     *piIdxCur = iBase;
  1708   1709     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
  1709         -    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
  1710   1710       int iIdxCur = iBase++;
  1711   1711       assert( pIdx->pSchema==pTab->pSchema );
  1712   1712       if( pIdx->autoIndex==2 && !HasRowid(pTab) ) *piDataCur = iIdxCur;
  1713         -    sqlite3VdbeAddOp4(v, op, iIdxCur, pIdx->tnum, iDb,
  1714         -                      (char*)pKey, P4_KEYINFO_HANDOFF);
         1713  +    sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
         1714  +    sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  1715   1715       VdbeComment((v, "%s", pIdx->zName));
  1716   1716     }
  1717   1717     if( iBase>pParse->nTab ) pParse->nTab = iBase;
  1718   1718     return i;
  1719   1719   }
  1720   1720   
  1721   1721   
................................................................................
  1824   1824     int i;                           /* Loop counter */
  1825   1825     int iDbSrc;                      /* The database of pSrc */
  1826   1826     int iSrc, iDest;                 /* Cursors from source and destination */
  1827   1827     int addr1, addr2;                /* Loop addresses */
  1828   1828     int emptyDestTest = 0;           /* Address of test for empty pDest */
  1829   1829     int emptySrcTest = 0;            /* Address of test for empty pSrc */
  1830   1830     Vdbe *v;                         /* The VDBE we are building */
  1831         -  KeyInfo *pKey;                   /* Key information for an index */
  1832   1831     int regAutoinc;                  /* Memory register used by AUTOINC */
  1833   1832     int destHasUniqueIdx = 0;        /* True if pDest has a UNIQUE index */
  1834   1833     int regData, regRowid;           /* Registers holding data and rowid */
  1835   1834   
  1836   1835     if( pSelect==0 ){
  1837   1836       return 0;   /* Must be of the form  INSERT INTO ... SELECT ... */
  1838   1837     }
................................................................................
  2024   2023       sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
  2025   2024     }
  2026   2025     for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
  2027   2026       for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
  2028   2027         if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
  2029   2028       }
  2030   2029       assert( pSrcIdx );
  2031         -    pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
  2032         -    sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
  2033         -                      (char*)pKey, P4_KEYINFO_HANDOFF);
         2030  +    sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
         2031  +    sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
  2034   2032       VdbeComment((v, "%s", pSrcIdx->zName));
  2035         -    pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
  2036         -    sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
  2037         -                      (char*)pKey, P4_KEYINFO_HANDOFF);
         2033  +    sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
         2034  +    sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
  2038   2035       sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
  2039   2036       VdbeComment((v, "%s", pDestIdx->zName));
  2040   2037       addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
  2041   2038       sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
  2042   2039       sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
  2043   2040       sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
  2044   2041       sqlite3VdbeJumpHere(v, addr1);

Changes to src/pragma.c.

  1676   1676           pIdx = 0;
  1677   1677           sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
  1678   1678           x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
  1679   1679           if( x==0 ){
  1680   1680             if( pIdx==0 ){
  1681   1681               sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
  1682   1682             }else{
  1683         -            KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
  1684   1683               sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
  1685         -            sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
         1684  +            sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  1686   1685             }
  1687   1686           }else{
  1688   1687             k = 0;
  1689   1688             break;
  1690   1689           }
  1691   1690         }
  1692   1691         assert( pParse->nErr>0 || pFK==0 );

Changes to src/select.c.

   801    801       sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
   802    802     }
   803    803   }
   804    804   
   805    805   /*
   806    806   ** Allocate a KeyInfo object sufficient for an index of N key columns and
   807    807   ** X extra columns.
   808         -**
   809         -** Actually, always allocate one extra column for the rowid at the end
   810         -** of the index.  So the KeyInfo returned will have space sufficient for
   811         -** N+1 columns.
   812    808   */
   813    809   KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
   814         -  KeyInfo *p = sqlite3DbMallocZero(db, 
          810  +  KeyInfo *p = sqlite3DbMallocZero(0, 
   815    811                      sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
   816    812     if( p ){
   817    813       p->aSortOrder = (u8*)&p->aColl[N+X];
   818    814       p->nField = (u16)N;
   819    815       p->nXField = (u16)X;
   820    816       p->enc = ENC(db);
   821    817       p->db = db;
          818  +    p->nRef = 1;
          819  +  }else{
          820  +    db->mallocFailed = 1;
          821  +  }
          822  +  return p;
          823  +}
          824  +
          825  +/*
          826  +** Deallocate a KeyInfo object
          827  +*/
          828  +void sqlite3KeyInfoUnref(KeyInfo *p){
          829  +  if( p ){
          830  +    assert( p->nRef>0 );
          831  +    assert( p->db==0 || p->db->pnBytesFreed==0 );
          832  +    p->nRef--;
          833  +    if( p->nRef==0 ) sqlite3DbFree(p->db, p);
          834  +  }
          835  +}
          836  +
          837  +/*
          838  +** Make a new pointer to a KeyInfo object
          839  +*/
          840  +KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){
          841  +  if( p ){
          842  +    assert( p->nRef>0 );
          843  +    p->nRef++;
   822    844     }
   823    845     return p;
   824    846   }
   825    847   
          848  +#ifdef SQLITE_DEBUG
          849  +/*
          850  +** Return TRUE if a KeyInfo object can be change.  The KeyInfo object
          851  +** can only be changed if this is just a single reference to the object.
          852  +**
          853  +** This routine is used only inside of assert() statements.
          854  +*/
          855  +int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
          856  +#endif /* SQLITE_DEBUG */
          857  +
   826    858   /*
   827    859   ** Given an expression list, generate a KeyInfo structure that records
   828    860   ** the collating sequence for each expression in that expression list.
   829    861   **
   830    862   ** If the ExprList is an ORDER BY or GROUP BY clause then the resulting
   831    863   ** KeyInfo structure is appropriate for initializing a virtual index to
   832    864   ** implement that clause.  If the ExprList is the result set of a SELECT
   833    865   ** then the KeyInfo structure is appropriate for initializing a virtual
   834    866   ** index to implement a DISTINCT test.
   835    867   **
   836    868   ** Space to hold the KeyInfo structure is obtain from malloc.  The calling
   837    869   ** function is responsible for seeing that this structure is eventually
   838         -** freed.  Add the KeyInfo structure to the P4 field of an opcode using
   839         -** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
          870  +** freed.
   840    871   */
   841    872   static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
   842    873     int nExpr;
   843    874     KeyInfo *pInfo;
   844    875     struct ExprList_item *pItem;
   845    876     sqlite3 *db = pParse->db;
   846    877     int i;
   847    878   
   848    879     nExpr = pList->nExpr;
   849    880     pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1);
   850    881     if( pInfo ){
          882  +    assert( sqlite3KeyInfoIsWriteable(pInfo) );
   851    883       for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
   852    884         CollSeq *pColl;
   853    885         pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
   854    886         if( !pColl ) pColl = db->pDfltColl;
   855    887         pInfo->aColl[i] = pColl;
   856    888         pInfo->aSortOrder[i] = pItem->sortOrder;
   857    889       }
................................................................................
  2008   2040           if( addr<0 ){
  2009   2041             /* If [0] is unused then [1] is also unused.  So we can
  2010   2042             ** always safely abort as soon as the first unused slot is found */
  2011   2043             assert( pLoop->addrOpenEphm[1]<0 );
  2012   2044             break;
  2013   2045           }
  2014   2046           sqlite3VdbeChangeP2(v, addr, nCol);
  2015         -        sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
         2047  +        sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
         2048  +                            P4_KEYINFO);
  2016   2049           pLoop->addrOpenEphm[i] = -1;
  2017   2050         }
  2018   2051       }
  2019         -    sqlite3DbFree(db, pKeyInfo);
         2052  +    sqlite3KeyInfoUnref(pKeyInfo);
  2020   2053     }
  2021   2054   
  2022   2055   multi_select_end:
  2023   2056     pDest->iSdst = dest.iSdst;
  2024   2057     pDest->nSdst = dest.nSdst;
  2025   2058     sqlite3SelectDelete(db, pDelete);
  2026   2059     return rc;
................................................................................
  2051   2084     Parse *pParse,          /* Parsing context */
  2052   2085     Select *p,              /* The SELECT statement */
  2053   2086     SelectDest *pIn,        /* Coroutine supplying data */
  2054   2087     SelectDest *pDest,      /* Where to send the data */
  2055   2088     int regReturn,          /* The return address register */
  2056   2089     int regPrev,            /* Previous result register.  No uniqueness if 0 */
  2057   2090     KeyInfo *pKeyInfo,      /* For comparing with previous entry */
  2058         -  int p4type,             /* The p4 type for pKeyInfo */
  2059   2091     int iBreak              /* Jump here if we hit the LIMIT */
  2060   2092   ){
  2061   2093     Vdbe *v = pParse->pVdbe;
  2062   2094     int iContinue;
  2063   2095     int addr;
  2064   2096   
  2065   2097     addr = sqlite3VdbeCurrentAddr(v);
................................................................................
  2067   2099   
  2068   2100     /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  2069   2101     */
  2070   2102     if( regPrev ){
  2071   2103       int j1, j2;
  2072   2104       j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
  2073   2105       j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
  2074         -                              (char*)pKeyInfo, p4type);
         2106  +                              (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
  2075   2107       sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
  2076   2108       sqlite3VdbeJumpHere(v, j1);
  2077   2109       sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
  2078   2110       sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  2079   2111     }
  2080   2112     if( pParse->db->mallocFailed ) return 0;
  2081   2113   
................................................................................
  2378   2410             pColl = sqlite3ExprCollSeq(pParse, pTerm);
  2379   2411           }else{
  2380   2412             pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
  2381   2413             if( pColl==0 ) pColl = db->pDfltColl;
  2382   2414             pOrderBy->a[i].pExpr =
  2383   2415                sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
  2384   2416           }
         2417  +        assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
  2385   2418           pKeyMerge->aColl[i] = pColl;
  2386   2419           pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
  2387   2420         }
  2388   2421       }
  2389   2422     }else{
  2390   2423       pKeyMerge = 0;
  2391   2424     }
................................................................................
  2405   2438       int nExpr = p->pEList->nExpr;
  2406   2439       assert( nOrderBy>=nExpr || db->mallocFailed );
  2407   2440       regPrev = pParse->nMem+1;
  2408   2441       pParse->nMem += nExpr+1;
  2409   2442       sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
  2410   2443       pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
  2411   2444       if( pKeyDup ){
         2445  +      assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
  2412   2446         for(i=0; i<nExpr; i++){
  2413   2447           pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
  2414   2448           pKeyDup->aSortOrder[i] = 0;
  2415   2449         }
  2416   2450       }
  2417   2451     }
  2418   2452    
................................................................................
  2486   2520   
  2487   2521     /* Generate a subroutine that outputs the current row of the A
  2488   2522     ** select as the next output row of the compound select.
  2489   2523     */
  2490   2524     VdbeNoopComment((v, "Output routine for A"));
  2491   2525     addrOutA = generateOutputSubroutine(pParse,
  2492   2526                    p, &destA, pDest, regOutA,
  2493         -                 regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
         2527  +                 regPrev, pKeyDup, labelEnd);
  2494   2528     
  2495   2529     /* Generate a subroutine that outputs the current row of the B
  2496   2530     ** select as the next output row of the compound select.
  2497   2531     */
  2498   2532     if( op==TK_ALL || op==TK_UNION ){
  2499   2533       VdbeNoopComment((v, "Output routine for B"));
  2500   2534       addrOutB = generateOutputSubroutine(pParse,
  2501   2535                    p, &destB, pDest, regOutB,
  2502         -                 regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
         2536  +                 regPrev, pKeyDup, labelEnd);
  2503   2537     }
         2538  +  sqlite3KeyInfoUnref(pKeyDup);
  2504   2539   
  2505   2540     /* Generate a subroutine to run when the results from select A
  2506   2541     ** are exhausted and only data in select B remains.
  2507   2542     */
  2508   2543     VdbeNoopComment((v, "eof-A subroutine"));
  2509   2544     if( op==TK_EXCEPT || op==TK_INTERSECT ){
  2510   2545       addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
................................................................................
  2575   2610     sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
  2576   2611   
  2577   2612     /* Implement the main merge loop
  2578   2613     */
  2579   2614     sqlite3VdbeResolveLabel(v, labelCmpr);
  2580   2615     sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
  2581   2616     sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
  2582         -                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
         2617  +                         (char*)pKeyMerge, P4_KEYINFO);
  2583   2618     sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
  2584   2619     sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
  2585   2620   
  2586   2621     /* Jump to the this point in order to terminate the query.
  2587   2622     */
  2588   2623     sqlite3VdbeResolveLabel(v, labelEnd);
  2589   2624   
................................................................................
  3801   3836         if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
  3802   3837           sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
  3803   3838              "argument");
  3804   3839           pFunc->iDistinct = -1;
  3805   3840         }else{
  3806   3841           KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
  3807   3842           sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
  3808         -                          (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
         3843  +                          (char*)pKeyInfo, P4_KEYINFO);
  3809   3844         }
  3810   3845       }
  3811   3846     }
  3812   3847   }
  3813   3848   
  3814   3849   /*
  3815   3850   ** Invoke the OP_AggFinalize opcode for every aggregate function
................................................................................
  4256   4291     if( pOrderBy ){
  4257   4292       KeyInfo *pKeyInfo;
  4258   4293       pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
  4259   4294       pOrderBy->iECursor = pParse->nTab++;
  4260   4295       p->addrOpenEphm[2] = addrSortIndex =
  4261   4296         sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
  4262   4297                              pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
  4263         -                           (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
         4298  +                           (char*)pKeyInfo, P4_KEYINFO);
  4264   4299     }else{
  4265   4300       addrSortIndex = -1;
  4266   4301     }
  4267   4302   
  4268   4303     /* If the output is destined for a temporary table, open that table.
  4269   4304     */
  4270   4305     if( pDest->eDest==SRT_EphemTab ){
................................................................................
  4284   4319     /* Open a virtual index to use for the distinct set.
  4285   4320     */
  4286   4321     if( p->selFlags & SF_Distinct ){
  4287   4322       sDistinct.tabTnct = pParse->nTab++;
  4288   4323       sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
  4289   4324                                   sDistinct.tabTnct, 0, 0,
  4290   4325                                   (char*)keyInfoFromExprList(pParse, p->pEList),
  4291         -                                P4_KEYINFO_HANDOFF);
         4326  +                                P4_KEYINFO);
  4292   4327       sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
  4293   4328       sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
  4294   4329     }else{
  4295   4330       sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
  4296   4331     }
  4297   4332   
  4298   4333     if( !isAgg && pGroupBy==0 ){
................................................................................
  4408   4443         ** that we do not need it after all, the OP_SorterOpen instruction
  4409   4444         ** will be converted into a Noop.  
  4410   4445         */
  4411   4446         sAggInfo.sortingIdx = pParse->nTab++;
  4412   4447         pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
  4413   4448         addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
  4414   4449             sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
  4415         -          0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
         4450  +          0, (char*)pKeyInfo, P4_KEYINFO);
  4416   4451   
  4417   4452         /* Initialize memory locations used by GROUP BY aggregate processing
  4418   4453         */
  4419   4454         iUseFlag = ++pParse->nMem;
  4420   4455         iAbortFlag = ++pParse->nMem;
  4421   4456         regOutputRow = ++pParse->nMem;
  4422   4457         addrOutputRow = sqlite3VdbeMakeLabel(v);
................................................................................
  4522   4557             if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
  4523   4558           }else{
  4524   4559             sAggInfo.directMode = 1;
  4525   4560             sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
  4526   4561           }
  4527   4562         }
  4528   4563         sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
  4529         -                          (char*)pKeyInfo, P4_KEYINFO);
         4564  +                          (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
  4530   4565         j1 = sqlite3VdbeCurrentAddr(v);
  4531   4566         sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
  4532   4567   
  4533   4568         /* Generate code that runs whenever the GROUP BY changes.
  4534   4569         ** Changes in the GROUP BY are detected by the previous code
  4535   4570         ** block.  If there were no changes, this block is skipped.
  4536   4571         **
................................................................................
  4648   4683              && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
  4649   4684             ){
  4650   4685               pBest = pIdx;
  4651   4686             }
  4652   4687           }
  4653   4688           if( pBest ){
  4654   4689             iRoot = pBest->tnum;
  4655         -          pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
         4690  +          pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
  4656   4691           }
  4657   4692   
  4658   4693           /* Open a read-only cursor, execute the OP_Count, close the cursor. */
  4659   4694           sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
  4660   4695           if( pKeyInfo ){
  4661         -          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
         4696  +          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
  4662   4697           }
  4663   4698           sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
  4664   4699           sqlite3VdbeAddOp1(v, OP_Close, iCsr);
  4665   4700           explainSimpleCount(pParse, pTab, pBest);
  4666   4701         }else
  4667   4702   #endif /* SQLITE_OMIT_BTREECOUNT */
  4668   4703         {

Changes to src/sqliteInt.h.

  1528   1528   ** comparison of the two index keys.
  1529   1529   **
  1530   1530   ** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
  1531   1531   ** are nField slots for the columns of an index then one extra slot
  1532   1532   ** for the rowid at the end.
  1533   1533   */
  1534   1534   struct KeyInfo {
  1535         -  sqlite3 *db;        /* The database connection */
         1535  +  u32 nRef;           /* Number of references to this KeyInfo object */
  1536   1536     u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  1537   1537     u16 nField;         /* Number of key columns in the index */
  1538   1538     u16 nXField;        /* Number of columns beyond the key columns */
         1539  +  sqlite3 *db;        /* The database connection */
  1539   1540     u8 *aSortOrder;     /* Sort order for each column. */
  1540   1541     CollSeq *aColl[1];  /* Collating sequence for each term of the key */
  1541   1542   };
  1542   1543   
  1543   1544   /*
  1544   1545   ** An instance of the following structure holds information about a
  1545   1546   ** single index record that has already been parsed out into individual
................................................................................
  1600   1601     Table *pTable;           /* The SQL table being indexed */
  1601   1602     char *zColAff;           /* String defining the affinity of each column */
  1602   1603     Index *pNext;            /* The next index associated with the same table */
  1603   1604     Schema *pSchema;         /* Schema containing this index */
  1604   1605     u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
  1605   1606     char **azColl;           /* Array of collation sequence names for index */
  1606   1607     Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
         1608  +  KeyInfo *pKeyInfo;       /* A KeyInfo object suitable for this index */
  1607   1609     int tnum;                /* DB Page containing root of this index */
  1608   1610     LogEst szIdxRow;         /* Estimated average row size in bytes */
  1609   1611     u16 nKeyCol;             /* Number of columns forming the key */
  1610   1612     u16 nColumn;             /* Number of columns stored in the index */
  1611   1613     u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
  1612   1614     unsigned autoIndex:2;    /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
  1613   1615     unsigned bUnordered:1;   /* Use this index for == or IN queries only */
................................................................................
  3155   3157   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  3156   3158   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  3157   3159   void sqlite3MinimumFileFormat(Parse*, int, int);
  3158   3160   void sqlite3SchemaClear(void *);
  3159   3161   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  3160   3162   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  3161   3163   KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
  3162         -KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
         3164  +void sqlite3KeyInfoUnref(KeyInfo*);
         3165  +KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
         3166  +KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
         3167  +#ifdef SQLITE_DEBUG
         3168  +int sqlite3KeyInfoIsWriteable(KeyInfo*);
         3169  +#endif
  3163   3170   int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  3164   3171     void (*)(sqlite3_context*,int,sqlite3_value **),
  3165   3172     void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
  3166   3173     FuncDestructor *pDestructor
  3167   3174   );
  3168   3175   int sqlite3ApiExit(sqlite3 *db, int);
  3169   3176   int sqlite3OpenTempDatabase(Parse *);

Changes to src/update.c.

   356    356   
   357    357       assert( pPk!=0 );
   358    358       nPk = pPk->nKeyCol;
   359    359       iPk = pParse->nMem+1;
   360    360       pParse->nMem += nPk;
   361    361       regKey = ++pParse->nMem;
   362    362       iEph = pParse->nTab++;
   363         -    sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iEph, nPk, 0, 
   364         -                      (char*)sqlite3IndexKeyinfo(pParse, pPk),
   365         -                      P4_KEYINFO_HANDOFF);
          363  +    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
          364  +    sqlite3VdbeSetP4KeyInfo(pParse, pPk);
   366    365       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0);
   367    366       if( pWInfo==0 ) goto update_cleanup;
   368    367       for(i=0; i<nPk; i++){
   369    368         sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
   370    369                                         iPk+i);
   371    370       }
   372    371       sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
................................................................................
   404    403             break;
   405    404           }
   406    405         }
   407    406       }
   408    407       for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
   409    408         assert( aRegIdx );
   410    409         if( openAll || aRegIdx[i]>0 ){
   411         -        KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
   412         -        sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdxCur+i, pIdx->tnum, iDb,
   413         -                       (char*)pKey, P4_KEYINFO_HANDOFF);
          410  +        sqlite3VdbeAddOp3(v, OP_OpenWrite, iIdxCur+i, pIdx->tnum, iDb);
          411  +        sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
   414    412           assert( pParse->nTab>iIdxCur+i );
   415    413           VdbeComment((v, "%s", pIdx->zName));
   416    414         }
   417    415       }
   418    416     }
   419    417   
   420    418     /* Top of the update loop */

Changes to src/vdbe.h.

   113    113   #define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
   114    114   #define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
   115    115   #define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
   116    116   #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
   117    117   #define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */
   118    118   #define P4_ADVANCE  (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
   119    119   
   120         -/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
   121         -** is made.  That copy is freed when the Vdbe is finalized.  But if the
   122         -** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used.  It still
   123         -** gets freed when the Vdbe is finalized so it still should be obtained
   124         -** from a single sqliteMalloc().  But no copy is made and the calling
   125         -** function should *not* try to free the KeyInfo.
   126         -*/
   127         -#define P4_KEYINFO_HANDOFF (-16)
   128         -#define P4_KEYINFO_STATIC  (-17)
   129         -
   130    120   /* Error message codes for OP_Halt */
   131    121   #define P5_ConstraintNotNull 1
   132    122   #define P5_ConstraintUnique  2
   133    123   #define P5_ConstraintCheck   3
   134    124   #define P5_ConstraintFK      4
   135    125   
   136    126   /*
................................................................................
   182    172   void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
   183    173   void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
   184    174   void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
   185    175   void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
   186    176   void sqlite3VdbeJumpHere(Vdbe*, int addr);
   187    177   void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
   188    178   void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
          179  +void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
   189    180   void sqlite3VdbeUsesBtree(Vdbe*, int);
   190    181   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
   191    182   int sqlite3VdbeMakeLabel(Vdbe*);
   192    183   void sqlite3VdbeRunOnlyOnce(Vdbe*);
   193    184   void sqlite3VdbeDelete(Vdbe*);
   194    185   void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
   195    186   void sqlite3VdbeMakeReady(Vdbe*,Parse*);

Changes to src/vdbeaux.c.

   633    633   static void freeP4(sqlite3 *db, int p4type, void *p4){
   634    634     if( p4 ){
   635    635       assert( db );
   636    636       switch( p4type ){
   637    637         case P4_REAL:
   638    638         case P4_INT64:
   639    639         case P4_DYNAMIC:
   640         -      case P4_KEYINFO:
   641         -      case P4_INTARRAY:
   642         -      case P4_KEYINFO_HANDOFF: {
          640  +      case P4_INTARRAY: {
   643    641           sqlite3DbFree(db, p4);
   644    642           break;
          643  +      }
          644  +      case P4_KEYINFO: {
          645  +        if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
          646  +        break;
   645    647         }
   646    648         case P4_MPRINTF: {
   647    649           if( db->pnBytesFreed==0 ) sqlite3_free(p4);
   648    650           break;
   649    651         }
   650    652         case P4_FUNCDEF: {
   651    653           freeEphemeralFunction(db, (FuncDef*)p4);
................................................................................
   717    719   ** static array using sqlite3VdbeAddOpList but we want to make a
   718    720   ** few minor changes to the program.
   719    721   **
   720    722   ** If n>=0 then the P4 operand is dynamic, meaning that a copy of
   721    723   ** the string is made into memory obtained from sqlite3_malloc().
   722    724   ** A value of n==0 means copy bytes of zP4 up to and including the
   723    725   ** first null byte.  If n>0 then copy n+1 bytes of zP4.
   724         -**
   725         -** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
   726         -** A copy is made of the KeyInfo structure into memory obtained from
   727         -** sqlite3_malloc, to be freed when the Vdbe is finalized.
   728         -** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
   729         -** stored in memory that the caller has obtained from sqlite3_malloc. The 
   730         -** caller should not free the allocation, it will be freed when the Vdbe is
   731         -** finalized.
   732    726   ** 
   733    727   ** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
   734    728   ** to a string or structure that is guaranteed to exist for the lifetime of
   735    729   ** the Vdbe. In these cases we can just copy the pointer.
   736    730   **
   737    731   ** If addr<0 then change P4 on the most recently inserted instruction.
   738    732   */
................................................................................
   739    733   void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){
   740    734     Op *pOp;
   741    735     sqlite3 *db;
   742    736     assert( p!=0 );
   743    737     db = p->db;
   744    738     assert( p->magic==VDBE_MAGIC_INIT );
   745    739     if( p->aOp==0 || db->mallocFailed ){
   746         -    if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
          740  +    if( n!=P4_VTAB ){
   747    741         freeP4(db, n, (void*)*(char**)&zP4);
   748    742       }
   749    743       return;
   750    744     }
   751    745     assert( p->nOp>0 );
   752    746     assert( addr<p->nOp );
   753    747     if( addr<0 ){
................................................................................
   762    756       ** that was cast to a (const char *). */
   763    757       pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
   764    758       pOp->p4type = P4_INT32;
   765    759     }else if( zP4==0 ){
   766    760       pOp->p4.p = 0;
   767    761       pOp->p4type = P4_NOTUSED;
   768    762     }else if( n==P4_KEYINFO ){
   769         -    KeyInfo *pOrig, *pNew;
   770         -
   771         -    pOrig = (KeyInfo*)zP4;
   772         -    pNew = sqlite3KeyInfoAlloc(db, pOrig->nField, pOrig->nXField);
   773         -    pOp->p4.pKeyInfo = pNew;
   774         -    if( pNew ){
   775         -      int n = pOrig->nField+pOrig->nXField;
   776         -      memcpy(pNew->aColl, pOrig->aColl, n*sizeof(pNew->aColl[0]));
   777         -      memcpy(pNew->aSortOrder, pOrig->aSortOrder, n);
   778         -      pOp->p4type = P4_KEYINFO;
   779         -    }else{
   780         -      p->db->mallocFailed = 1;
   781         -      pOp->p4type = P4_NOTUSED;
   782         -    }
   783         -  }else if( n==P4_KEYINFO_HANDOFF ){
   784    763       pOp->p4.p = (void*)zP4;
   785    764       pOp->p4type = P4_KEYINFO;
   786    765     }else if( n==P4_VTAB ){
   787    766       pOp->p4.p = (void*)zP4;
   788    767       pOp->p4type = P4_VTAB;
   789    768       sqlite3VtabLock((VTable *)zP4);
   790    769       assert( ((VTable *)zP4)->db==p->db );
................................................................................
   793    772       pOp->p4type = (signed char)n;
   794    773     }else{
   795    774       if( n==0 ) n = sqlite3Strlen30(zP4);
   796    775       pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n);
   797    776       pOp->p4type = P4_DYNAMIC;
   798    777     }
   799    778   }
          779  +
          780  +/*
          781  +** Set the P4 on the most recently added opcode to the KeyInfo for the
          782  +** index given.
          783  +*/
          784  +void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
          785  +  Vdbe *v = pParse->pVdbe;
          786  +  assert( v!=0 );
          787  +  assert( pIdx!=0 );
          788  +  sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
          789  +                      P4_KEYINFO);
          790  +}
   800    791   
   801    792   #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
   802    793   /*
   803    794   ** Change the comment on the most recently coded instruction.  Or
   804    795   ** insert a No-op and add the comment to that new instruction.  This
   805    796   ** makes the code easier to read during debugging.  None of this happens
   806    797   ** in a production build.
................................................................................
   954    945   ** Compute a string that describes the P4 parameter for an opcode.
   955    946   ** Use zTemp for any required temporary buffer space.
   956    947   */
   957    948   static char *displayP4(Op *pOp, char *zTemp, int nTemp){
   958    949     char *zP4 = zTemp;
   959    950     assert( nTemp>=20 );
   960    951     switch( pOp->p4type ){
   961         -    case P4_KEYINFO_STATIC:
   962    952       case P4_KEYINFO: {
   963    953         int i, j;
   964    954         KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
   965    955         assert( pKeyInfo->aSortOrder!=0 );
   966    956         sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
   967    957         i = sqlite3Strlen30(zTemp);
   968    958         for(j=0; j<pKeyInfo->nField; j++){

Changes to src/vdbemem.c.

  1032   1032         int nByte;                  /* Bytes of space to allocate */
  1033   1033         int i;                      /* Counter variable */
  1034   1034         int nCol = pIdx->nColumn;   /* Number of index columns including rowid */
  1035   1035     
  1036   1036         nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord);
  1037   1037         pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
  1038   1038         if( pRec ){
  1039         -        pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx);
         1039  +        pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
  1040   1040           if( pRec->pKeyInfo ){
  1041   1041             assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
  1042         -          pRec->pKeyInfo->enc = ENC(db);
         1042  +          assert( pRec->pKeyInfo->enc==ENC(db) );
  1043   1043             pRec->flags = UNPACKED_PREFIX_MATCH;
  1044   1044             pRec->aMem = (Mem *)&pRec[1];
  1045   1045             for(i=0; i<nCol; i++){
  1046   1046               pRec->aMem[i].flags = MEM_Null;
  1047   1047               pRec->aMem[i].type = SQLITE_NULL;
  1048   1048               pRec->aMem[i].db = db;
  1049   1049             }
................................................................................
  1364   1364       int i;
  1365   1365       int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
  1366   1366       Mem *aMem = pRec->aMem;
  1367   1367       sqlite3 *db = aMem[0].db;
  1368   1368       for(i=0; i<nCol; i++){
  1369   1369         sqlite3DbFree(db, aMem[i].zMalloc);
  1370   1370       }
  1371         -    sqlite3DbFree(db, pRec->pKeyInfo);
         1371  +    sqlite3KeyInfoUnref(pRec->pKeyInfo);
  1372   1372       sqlite3DbFree(db, pRec);
  1373   1373     }
  1374   1374   }
  1375   1375   #endif /* ifdef SQLITE_ENABLE_STAT4 */
  1376   1376   
  1377   1377   /*
  1378   1378   ** Change the string value of an sqlite3_value object

Changes to src/where.c.

  2011   2011     int nKeyCol;                /* Number of columns in the constructed index */
  2012   2012     WhereTerm *pTerm;           /* A single term of the WHERE clause */
  2013   2013     WhereTerm *pWCEnd;          /* End of pWC->a[] */
  2014   2014     Index *pIdx;                /* Object describing the transient index */
  2015   2015     Vdbe *v;                    /* Prepared statement under construction */
  2016   2016     int addrInit;               /* Address of the initialization bypass jump */
  2017   2017     Table *pTable;              /* The table being indexed */
  2018         -  KeyInfo *pKeyinfo;          /* Key information for the index */   
  2019   2018     int addrTop;                /* Top of the index fill loop */
  2020   2019     int regRecord;              /* Register holding an index record */
  2021   2020     int n;                      /* Column counter */
  2022   2021     int i;                      /* Loop counter */
  2023   2022     int mxBitCol;               /* Maximum column in pSrc->colUsed */
  2024   2023     CollSeq *pColl;             /* Collating sequence to on a column */
  2025   2024     WhereLoop *pLoop;           /* The Loop object */
................................................................................
  2128   2127       }
  2129   2128     }
  2130   2129     assert( n==nKeyCol );
  2131   2130     pIdx->aiColumn[n] = -1;
  2132   2131     pIdx->azColl[n] = "BINARY";
  2133   2132   
  2134   2133     /* Create the automatic index */
  2135         -  pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
  2136   2134     assert( pLevel->iIdxCur>=0 );
  2137   2135     pLevel->iIdxCur = pParse->nTab++;
  2138         -  sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1, 0,
  2139         -                    (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
         2136  +  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
         2137  +  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  2140   2138     VdbeComment((v, "for %s", pTable->zName));
  2141   2139   
  2142   2140     /* Fill the automatic index with content */
  2143   2141     addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
  2144   2142     regRecord = sqlite3GetTempReg(pParse);
  2145   2143     sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0);
  2146   2144     sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
................................................................................
  3992   3990     if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
  3993   3991       if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
  3994   3992         sqlite3_free(p->u.vtab.idxStr);
  3995   3993         p->u.vtab.needFree = 0;
  3996   3994         p->u.vtab.idxStr = 0;
  3997   3995       }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
  3998   3996         sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
         3997  +      sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
  3999   3998         sqlite3DbFree(db, p->u.btree.pIndex);
  4000   3999         p->u.btree.pIndex = 0;
  4001   4000       }
  4002   4001     }
  4003   4002   }
  4004   4003   
  4005   4004   /*
................................................................................
  6034   6033           assert( n<=pTab->nCol );
  6035   6034         }
  6036   6035       }else{
  6037   6036         sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  6038   6037       }
  6039   6038       if( pLoop->wsFlags & WHERE_INDEXED ){
  6040   6039         Index *pIx = pLoop->u.btree.pIndex;
  6041         -      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
  6042   6040         /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
  6043   6041         int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
  6044   6042         assert( pIx->pSchema==pTab->pSchema );
  6045   6043         assert( iIndexCur>=0 );
  6046         -      sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
  6047         -                        (char*)pKey, P4_KEYINFO_HANDOFF);
         6044  +      sqlite3VdbeAddOp3(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb);
         6045  +      sqlite3VdbeSetP4KeyInfo(pParse, pIx);
  6048   6046         VdbeComment((v, "%s", pIx->zName));
  6049   6047       }
  6050   6048       sqlite3CodeVerifySchema(pParse, iDb);
  6051   6049       notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
  6052   6050     }
  6053   6051     pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
  6054   6052     if( db->mallocFailed ) goto whereBeginError;