mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Clean up the implementation of constant function factorization.
FossilOrigin-Name: 2ab997e47998d261bd6190bbce5c09f3fbd4cfd3
This commit is contained in:
43
src/expr.c
43
src/expr.c
@@ -3613,7 +3613,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
CollSeq *pColl = 0; /* A collating sequence */
|
||||
|
||||
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
|
||||
return sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1);
|
||||
/* SQL function can be expensive. So try to move constant functions
|
||||
** out of the inner loop, even if that means an extra OP_Copy. */
|
||||
return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
|
||||
}
|
||||
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
|
||||
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
|
||||
@@ -3996,41 +3998,36 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
||||
/*
|
||||
** Factor out the code of the given expression to initialization time.
|
||||
**
|
||||
** If regDest>=0 then the result is always stored in that register.
|
||||
** If regDest<0 then this routine is free to store the value whereever
|
||||
** it wants. The register where the expression is stored is returned.
|
||||
**
|
||||
** If regDest<0 and an equivalent expression already exists elsewhere
|
||||
** in the initialization expressions, then routine just returns the
|
||||
** register of the prior occurrance.
|
||||
** If regDest>=0 then the result is always stored in that register and the
|
||||
** result is not reusable. If regDest<0 then this routine is free to
|
||||
** store the value whereever it wants. The register where the expression
|
||||
** is stored is returned. When regDest<0, two identical expressions will
|
||||
** code to the same register.
|
||||
*/
|
||||
int sqlite3ExprCodeAtInit(
|
||||
Parse *pParse, /* Parsing context */
|
||||
Expr *pExpr, /* The expression to code when the VDBE initializes */
|
||||
int regDest, /* Store the value in this register */
|
||||
u8 reusable /* True if this expression is reusable */
|
||||
int regDest /* Store the value in this register */
|
||||
){
|
||||
ExprList *p;
|
||||
assert( ConstFactorOk(pParse) );
|
||||
p = pParse->pConstExpr;
|
||||
if( regDest<0 ){
|
||||
if( p && reusable ){
|
||||
struct ExprList_item *pItem;
|
||||
int i;
|
||||
for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
|
||||
if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
|
||||
return pItem->u.iConstExprReg;
|
||||
}
|
||||
if( regDest<0 && p ){
|
||||
struct ExprList_item *pItem;
|
||||
int i;
|
||||
for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
|
||||
if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
|
||||
return pItem->u.iConstExprReg;
|
||||
}
|
||||
}
|
||||
regDest = ++pParse->nMem;
|
||||
}
|
||||
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
|
||||
p = sqlite3ExprListAppend(pParse, p, pExpr);
|
||||
if( p ){
|
||||
struct ExprList_item *pItem = &p->a[p->nExpr-1];
|
||||
pItem->reusable = regDest<0;
|
||||
if( regDest<0 ) regDest = ++pParse->nMem;
|
||||
pItem->u.iConstExprReg = regDest;
|
||||
pItem->reusable = reusable;
|
||||
}
|
||||
pParse->pConstExpr = p;
|
||||
return regDest;
|
||||
@@ -4057,7 +4054,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
|
||||
&& sqlite3ExprIsConstantNotJoin(pExpr)
|
||||
){
|
||||
*pReg = 0;
|
||||
r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1);
|
||||
r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
|
||||
}else{
|
||||
int r1 = sqlite3GetTempReg(pParse);
|
||||
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
|
||||
@@ -4111,7 +4108,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
|
||||
*/
|
||||
void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
|
||||
if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target);
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pExpr, target);
|
||||
}
|
||||
@@ -4183,7 +4180,7 @@ int sqlite3ExprCodeExprList(
|
||||
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
|
||||
}
|
||||
}else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
|
||||
sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
|
||||
}else{
|
||||
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
|
||||
if( inReg!=target+i ){
|
||||
|
||||
Reference in New Issue
Block a user