/ Check-in [cc6b959b]
Login

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

Overview
Comment:Adjustments to column cache handling in order to restore 100% branch test coverage.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: cc6b959bc1f968e08eea1afd387201d70a0c1e80
User & Date: drh 2009-12-30 14:12:38
Context
2009-12-30
14:19
Change the version number to 3.6.22. check-in: 96919a46 user: drh tags: trunk
14:12
Adjustments to column cache handling in order to restore 100% branch test coverage. check-in: cc6b959b user: drh tags: trunk
01:13
Remove some code in the column cache that is no longer used. Replace it with an assert(). check-in: 1f890efb user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   626    626         sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
   627    627         sqlite3ColumnDefault(v, pTab, idx, -1);
   628    628       }
   629    629     }
   630    630     if( doMakeRec ){
   631    631       sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
   632    632       sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
   633         -    sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1);
   634    633     }
   635    634     sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
   636    635     return regBase;
   637    636   }

Changes to src/expr.c.

  2015   2015       p->tempReg = 0;
  2016   2016       p->lru = pParse->iCacheCnt++;
  2017   2017       return;
  2018   2018     }
  2019   2019   }
  2020   2020   
  2021   2021   /*
  2022         -** Indicate that a register is being overwritten.  Purge the register
  2023         -** from the column cache.
         2022  +** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
         2023  +** Purge the range of registers from the column cache.
  2024   2024   */
  2025         -void sqlite3ExprCacheRemove(Parse *pParse, int iReg){
         2025  +void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
  2026   2026     int i;
         2027  +  int iLast = iReg + nReg - 1;
  2027   2028     struct yColCache *p;
  2028   2029     for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
  2029         -    if( p->iReg==iReg ){
         2030  +    int r = p->iReg;
         2031  +    if( r>=iReg && r<=iLast ){
  2030   2032         cacheEntryClear(pParse, p);
  2031   2033         p->iReg = 0;
  2032   2034       }
  2033   2035     }
  2034   2036   }
  2035   2037   
  2036   2038   /*
................................................................................
  2132   2134   }
  2133   2135   
  2134   2136   /*
  2135   2137   ** Record the fact that an affinity change has occurred on iCount
  2136   2138   ** registers starting with iStart.
  2137   2139   */
  2138   2140   void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
  2139         -  int iEnd = iStart + iCount - 1;
  2140         -  int i;
  2141         -  struct yColCache *p;
  2142         -  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
  2143         -    int r = p->iReg;
  2144         -    if( r>=iStart && r<=iEnd ){
  2145         -      cacheEntryClear(pParse, p);
  2146         -      p->iReg = 0;
  2147         -    }
  2148         -  }
         2141  +  sqlite3ExprCacheRemove(pParse, iStart, iCount);
  2149   2142   }
  2150   2143   
  2151   2144   /*
  2152   2145   ** Generate code to move content from registers iFrom...iFrom+nReg-1
  2153   2146   ** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
  2154   2147   */
  2155   2148   void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
................................................................................
  2173   2166     int i;
  2174   2167     if( NEVER(iFrom==iTo) ) return;
  2175   2168     for(i=0; i<nReg; i++){
  2176   2169       sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
  2177   2170     }
  2178   2171   }
  2179   2172   
         2173  +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
  2180   2174   /*
  2181   2175   ** Return true if any register in the range iFrom..iTo (inclusive)
  2182   2176   ** is used as part of the column cache.
         2177  +**
         2178  +** This routine is used within assert() and testcase() macros only
         2179  +** and does not appear in a normal build.
  2183   2180   */
  2184   2181   static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
  2185   2182     int i;
  2186   2183     struct yColCache *p;
  2187   2184     for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
  2188   2185       int r = p->iReg;
  2189         -    if( r>=iFrom && r<=iTo ) return 1;
         2186  +    if( r>=iFrom && r<=iTo ) return 1;    /*NO_TEST*/
  2190   2187     }
  2191   2188     return 0;
  2192   2189   }
         2190  +#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
  2193   2191   
  2194   2192   /*
  2195   2193   ** If the last instruction coded is an ephemeral copy of any of
  2196   2194   ** the registers in the nReg registers beginning with iReg, then
  2197   2195   ** convert the last instruction from OP_SCopy to OP_Copy.
  2198   2196   */
  2199   2197   void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
................................................................................
  2581   2579         */
  2582   2580         if( pDef->flags & SQLITE_FUNC_COALESCE ){
  2583   2581           int endCoalesce = sqlite3VdbeMakeLabel(v);
  2584   2582           assert( nFarg>=2 );
  2585   2583           sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
  2586   2584           for(i=1; i<nFarg; i++){
  2587   2585             sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
  2588         -          sqlite3ExprCacheRemove(pParse, target);
         2586  +          sqlite3ExprCacheRemove(pParse, target, 1);
  2589   2587             sqlite3ExprCachePush(pParse);
  2590   2588             sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
  2591   2589             sqlite3ExprCachePop(pParse, 1);
  2592   2590           }
  2593   2591           sqlite3VdbeResolveLabel(v, endCoalesce);
  2594   2592           break;
  2595   2593         }
................................................................................
  2636   2634         }
  2637   2635         sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
  2638   2636                           (char*)pDef, P4_FUNCDEF);
  2639   2637         sqlite3VdbeChangeP5(v, (u8)nFarg);
  2640   2638         if( nFarg ){
  2641   2639           sqlite3ReleaseTempRange(pParse, r1, nFarg);
  2642   2640         }
  2643         -      sqlite3ExprCacheAffinityChange(pParse, r1, nFarg);
  2644   2641         break;
  2645   2642       }
  2646   2643   #ifndef SQLITE_OMIT_SUBQUERY
  2647   2644       case TK_EXISTS:
  2648   2645       case TK_SELECT: {
  2649   2646         testcase( op==TK_EXISTS );
  2650   2647         testcase( op==TK_SELECT );
................................................................................
  3716   3713   /*
  3717   3714   ** Allocate or deallocate a block of nReg consecutive registers
  3718   3715   */
  3719   3716   int sqlite3GetTempRange(Parse *pParse, int nReg){
  3720   3717     int i, n;
  3721   3718     i = pParse->iRangeReg;
  3722   3719     n = pParse->nRangeReg;
  3723         -  if( nReg<=n && !usedAsColumnCache(pParse, i, i+n-1) ){
         3720  +  if( nReg<=n ){
         3721  +    assert( !usedAsColumnCache(pParse, i, i+n-1) );
  3724   3722       pParse->iRangeReg += nReg;
  3725   3723       pParse->nRangeReg -= nReg;
  3726   3724     }else{
  3727   3725       i = pParse->nMem+1;
  3728   3726       pParse->nMem += nReg;
  3729   3727     }
  3730   3728     return i;
  3731   3729   }
  3732   3730   void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
         3731  +  sqlite3ExprCacheRemove(pParse, iReg, nReg);
  3733   3732     if( nReg>pParse->nRangeReg ){
  3734   3733       pParse->nRangeReg = nReg;
  3735   3734       pParse->iRangeReg = iReg;
  3736   3735     }
  3737   3736   }

Changes to src/select.c.

  3486   3486           pColl = pParse->db->pDfltColl;
  3487   3487         }
  3488   3488         sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
  3489   3489       }
  3490   3490       sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
  3491   3491                         (void*)pF->pFunc, P4_FUNCDEF);
  3492   3492       sqlite3VdbeChangeP5(v, (u8)nArg);
  3493         -    sqlite3ReleaseTempRange(pParse, regAgg, nArg);
  3494   3493       sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
         3494  +    sqlite3ReleaseTempRange(pParse, regAgg, nArg);
  3495   3495       if( addrNext ){
  3496   3496         sqlite3VdbeResolveLabel(v, addrNext);
  3497   3497         sqlite3ExprCacheClear(pParse);
  3498   3498       }
  3499   3499     }
  3500   3500     for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
  3501   3501       sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);

Changes to src/sqliteInt.h.

  2652   2652   void sqlite3WhereEnd(WhereInfo*);
  2653   2653   int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int);
  2654   2654   void sqlite3ExprCodeMove(Parse*, int, int, int);
  2655   2655   void sqlite3ExprCodeCopy(Parse*, int, int, int);
  2656   2656   void sqlite3ExprCacheStore(Parse*, int, int, int);
  2657   2657   void sqlite3ExprCachePush(Parse*);
  2658   2658   void sqlite3ExprCachePop(Parse*, int);
  2659         -void sqlite3ExprCacheRemove(Parse*, int);
         2659  +void sqlite3ExprCacheRemove(Parse*, int, int);
  2660   2660   void sqlite3ExprCacheClear(Parse*);
  2661   2661   void sqlite3ExprCacheAffinityChange(Parse*, int, int);
  2662   2662   void sqlite3ExprHardCopy(Parse*,int,int);
  2663   2663   int sqlite3ExprCode(Parse*, Expr*, int);
  2664   2664   int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
  2665   2665   int sqlite3ExprCodeTarget(Parse*, Expr*, int);
  2666   2666   int sqlite3ExprCodeAndCache(Parse*, Expr*, int);

Changes to src/where.c.

  3156   3156   
  3157   3157       /* Load the value for the inequality constraint at the end of the
  3158   3158       ** range (if any).
  3159   3159       */
  3160   3160       nConstraint = nEq;
  3161   3161       if( pRangeEnd ){
  3162   3162         Expr *pRight = pRangeEnd->pExpr->pRight;
  3163         -      sqlite3ExprCacheRemove(pParse, regBase+nEq);
         3163  +      sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
  3164   3164         sqlite3ExprCode(pParse, pRight, regBase+nEq);
  3165   3165         sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
  3166   3166         if( zAff ){
  3167   3167           if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){
  3168   3168             /* Since the comparison is to be performed with no conversions
  3169   3169             ** applied to the operands, set the affinity to apply to pRight to 
  3170   3170             ** SQLITE_AFF_NONE.  */