aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/delete.c1
-rw-r--r--src/expr.c35
-rw-r--r--src/select.c2
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/where.c2
5 files changed, 20 insertions, 22 deletions
diff --git a/src/delete.c b/src/delete.c
index 18ed22418..9e99a4d46 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -630,7 +630,6 @@ int sqlite3GenerateIndexKey(
if( doMakeRec ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
- sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1);
}
sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
return regBase;
diff --git a/src/expr.c b/src/expr.c
index e0d13693c..6ba373875 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2019,14 +2019,16 @@ void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){
}
/*
-** Indicate that a register is being overwritten. Purge the register
-** from the column cache.
+** Indicate that registers between iReg..iReg+nReg-1 are being overwritten.
+** Purge the range of registers from the column cache.
*/
-void sqlite3ExprCacheRemove(Parse *pParse, int iReg){
+void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
int i;
+ int iLast = iReg + nReg - 1;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==iReg ){
+ int r = p->iReg;
+ if( r>=iReg && r<=iLast ){
cacheEntryClear(pParse, p);
p->iReg = 0;
}
@@ -2136,16 +2138,7 @@ void sqlite3ExprCacheClear(Parse *pParse){
** registers starting with iStart.
*/
void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){
- int iEnd = iStart + iCount - 1;
- int i;
- struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- int r = p->iReg;
- if( r>=iStart && r<=iEnd ){
- cacheEntryClear(pParse, p);
- p->iReg = 0;
- }
- }
+ sqlite3ExprCacheRemove(pParse, iStart, iCount);
}
/*
@@ -2177,19 +2170,24 @@ void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
}
}
+#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** Return true if any register in the range iFrom..iTo (inclusive)
** is used as part of the column cache.
+**
+** This routine is used within assert() and testcase() macros only
+** and does not appear in a normal build.
*/
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
int i;
struct yColCache *p;
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int r = p->iReg;
- if( r>=iFrom && r<=iTo ) return 1;
+ if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
}
return 0;
}
+#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/*
** If the last instruction coded is an ephemeral copy of any of
@@ -2585,7 +2583,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; i<nFarg; i++){
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
- sqlite3ExprCacheRemove(pParse, target);
+ sqlite3ExprCacheRemove(pParse, target, 1);
sqlite3ExprCachePush(pParse);
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
sqlite3ExprCachePop(pParse, 1);
@@ -2640,7 +2638,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
if( nFarg ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
- sqlite3ExprCacheAffinityChange(pParse, r1, nFarg);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -3720,7 +3717,8 @@ int sqlite3GetTempRange(Parse *pParse, int nReg){
int i, n;
i = pParse->iRangeReg;
n = pParse->nRangeReg;
- if( nReg<=n && !usedAsColumnCache(pParse, i, i+n-1) ){
+ if( nReg<=n ){
+ assert( !usedAsColumnCache(pParse, i, i+n-1) );
pParse->iRangeReg += nReg;
pParse->nRangeReg -= nReg;
}else{
@@ -3730,6 +3728,7 @@ int sqlite3GetTempRange(Parse *pParse, int nReg){
return i;
}
void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
+ sqlite3ExprCacheRemove(pParse, iReg, nReg);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
diff --git a/src/select.c b/src/select.c
index 0ba56a8ae..021c156a5 100644
--- a/src/select.c
+++ b/src/select.c
@@ -3490,8 +3490,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
(void*)pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
- sqlite3ReleaseTempRange(pParse, regAgg, nArg);
sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
+ sqlite3ReleaseTempRange(pParse, regAgg, nArg);
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
sqlite3ExprCacheClear(pParse);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 9ca2a55e5..f9a732cab 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2656,7 +2656,7 @@ void sqlite3ExprCodeCopy(Parse*, int, int, int);
void sqlite3ExprCacheStore(Parse*, int, int, int);
void sqlite3ExprCachePush(Parse*);
void sqlite3ExprCachePop(Parse*, int);
-void sqlite3ExprCacheRemove(Parse*, int);
+void sqlite3ExprCacheRemove(Parse*, int, int);
void sqlite3ExprCacheClear(Parse*);
void sqlite3ExprCacheAffinityChange(Parse*, int, int);
void sqlite3ExprHardCopy(Parse*,int,int);
diff --git a/src/where.c b/src/where.c
index 0f47d18af..a41b66d10 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3160,7 +3160,7 @@ static Bitmask codeOneLoopStart(
nConstraint = nEq;
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
- sqlite3ExprCacheRemove(pParse, regBase+nEq);
+ sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
if( zAff ){