Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Attempt to factor out constant functions from the interior of table scans, since functions can often be expensive to compute. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | factor-constant-funcs |
Files: | files | file ages | folders |
SHA1: |
62e9270a8057d758621da33adb27fad1 |
User & Date: | drh 2017-01-04 01:07:24 |
Context
2017-01-04
| ||
04:10 | Clean up the implementation of constant function factorization. (Closed-Leaf check-in: 2ab997e4 user: drh tags: factor-constant-funcs) | |
01:07 | Attempt to factor out constant functions from the interior of table scans, since functions can often be expensive to compute. (check-in: 62e9270a user: drh tags: factor-constant-funcs) | |
2017-01-03
| ||
21:57 | Use compiler intrinsic functions for signed integer math when overflow detection is needed. (check-in: d3ac32a6 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 | const char *zId; /* The function name */ u32 constMask = 0; /* Mask of function arguments that are constant */ int i; /* Loop counter */ sqlite3 *db = pParse->db; /* The database connection */ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; }else{ pFarg = pExpr->x.pList; } nFarg = pFarg ? pFarg->nExpr : 0; | > > > | 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 | const char *zId; /* The function name */ u32 constMask = 0; /* Mask of function arguments that are constant */ int i; /* Loop counter */ sqlite3 *db = pParse->db; /* The database connection */ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ return sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; }else{ pFarg = pExpr->x.pList; } nFarg = pFarg ? pFarg->nExpr : 0; |
︙ | ︙ | |||
3988 3989 3990 3991 3992 3993 3994 3995 | sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); return inReg; } /* ** Factor out the code of the given expression to initialization time. */ | > > > > > > > > | > > > > > > > > > > > > > | 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 | sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); return inReg; } /* ** 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. */ 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 */ ){ 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; } } } 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->u.iConstExprReg = regDest; pItem->reusable = reusable; } pParse->pConstExpr = p; return regDest; } /* ** Generate code to evaluate an expression and store the results ** into a register. Return the register number where the results ** are stored. ** |
︙ | ︙ | |||
4028 4029 4030 4031 4032 4033 4034 | int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollate(pExpr); if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ | < < < < < < < < < < < | | 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 | int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollate(pExpr); if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ *pReg = 0; r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1, 1); }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); if( r2==r1 ){ *pReg = r1; }else{ sqlite3ReleaseTempReg(pParse, r1); |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3712 3713 3714 3715 3716 3717 3718 | void sqlite3ExprCachePop(Parse*); void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); | | | 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 | void sqlite3ExprCachePop(Parse*); void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); void sqlite3ExprCode(Parse*, Expr*, int); void sqlite3ExprCodeCopy(Parse*, Expr*, int); void sqlite3ExprCodeFactorable(Parse*, Expr*, int); int sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); void sqlite3ExprCodeAndCache(Parse*, Expr*, int); int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); #define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ #define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ #define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */ |
︙ | ︙ |