aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2009-05-25 11:46:29 +0000
committerdrh <drh@noemail.net>2009-05-25 11:46:29 +0000
commit5cd792399a1b2435ccae98d1de278ece7cdfb6b2 (patch)
tree665b3c91ad40fe5e6557df9f639fde90e0de36ad /src/expr.c
parentd17fe2a352bcd6783ce8cdcf072bd8826115a55c (diff)
downloadsqlite-5cd792399a1b2435ccae98d1de278ece7cdfb6b2.tar.gz
sqlite-5cd792399a1b2435ccae98d1de278ece7cdfb6b2.zip
When pinning a temp register after it is reused by the column cache, make
sure all instances of that register in the cache are pinned so that the register is never reused for a different purpose. Ticket #3879. (CVS 6676) FossilOrigin-Name: 5f358e63712e8de93bd6fecc5131badeef0292be
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/expr.c b/src/expr.c
index 5e1c7c59f..fdbffc584 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.435 2009/05/21 20:41:32 drh Exp $
+** $Id: expr.c,v 1.436 2009/05/25 11:46:29 drh Exp $
*/
#include "sqliteInt.h"
@@ -1801,6 +1801,22 @@ void sqlite3ExprCachePop(Parse *pParse, int N){
}
/*
+** When a cached column is reused, make sure that its register is
+** no longer available as a temp register. ticket #3879: that same
+** register might be in the cache in multiple places, so be sure to
+** get them all.
+*/
+static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
+ int i;
+ struct yColCache *p;
+ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+ if( p->iReg==iReg ){
+ p->tempReg = 0;
+ }
+ }
+}
+
+/*
** Generate code that will extract the iColumn-th column from
** table pTab and store the column value in a register. An effort
** is made to store the column value in register iReg, but this is
@@ -1835,7 +1851,7 @@ int sqlite3ExprCodeGetColumn(
VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg));
#endif
p->lru = pParse->iCacheCnt++;
- p->tempReg = 0; /* This pins the register, but also leaks it */
+ sqlite3ExprCachePinRegister(pParse, p->iReg);
return p->iReg;
}
}