aboutsummaryrefslogtreecommitdiff
path: root/src/expr.c
diff options
context:
space:
mode:
authordrh <>2023-03-26 16:36:27 +0000
committerdrh <>2023-03-26 16:36:27 +0000
commitaa9192e6aa4da7d6c685bfbbefe0b4f6e55c5b2d (patch)
tree90bbff9e2c125a8c043ba6b6fa046da50f5af284 /src/expr.c
parent418f947b9818542e8c2ab0a9e5c269adfbdc21f4 (diff)
downloadsqlite-aa9192e6aa4da7d6c685bfbbefe0b4f6e55c5b2d.tar.gz
sqlite-aa9192e6aa4da7d6c685bfbbefe0b4f6e55c5b2d.zip
Improvements to register allocation, especially in the ANALYZE command.
New assert() statements added to help verify that memory allocation is correct, and to help fuzzer find lingering errors. FossilOrigin-Name: 6f8b97f31a4c8552312b4c98432ea356ae54c06d9cc929969f50c3c88360cd7b
Diffstat (limited to 'src/expr.c')
-rw-r--r--src/expr.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/expr.c b/src/expr.c
index cd09c0d71..564dfc7fb 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -6636,6 +6636,35 @@ void sqlite3ClearTempRegCache(Parse *pParse){
}
/*
+** Make sure sufficient registers have been allocated so that
+** iReg is a valid register number.
+*/
+void sqlite3TouchRegister(Parse *pParse, int iReg){
+ if( pParse->nMem<iReg ) pParse->nMem = iReg;
+}
+
+/*
+** Return the latest reusable register in the set of all registers.
+** The value returned is no less than iMin. If any register iMin or
+** greater is in permanent use, then return one more than that last
+** permanent register.
+*/
+int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){
+ const ExprList *pList = pParse->pConstExpr;
+ if( pList ){
+ int i;
+ for(i=0; i<pList->nExpr; i++){
+ if( pList->a[i].u.iConstExprReg>=iMin ){
+ iMin = pList->a[i].u.iConstExprReg + 1;
+ }
+ }
+ }
+ pParse->nTempReg = 0;
+ pParse->nRangeReg = 0;
+ return iMin;
+}
+
+/*
** Validate that no temporary register falls within the range of
** iFirst..iLast, inclusive. This routine is only call from within assert()
** statements.
@@ -6654,6 +6683,14 @@ int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
return 0;
}
}
+ if( pParse->pConstExpr ){
+ ExprList *pList = pParse->pConstExpr;
+ for(i=0; i<pList->nExpr; i++){
+ int iReg = pList->a[i].u.iConstExprReg;
+ if( iReg==0 ) continue;
+ if( iReg>=iFirst && iReg<=iLast ) return 0;
+ }
+ }
return 1;
}
#endif /* SQLITE_DEBUG */