Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the ability to factor constant functions out of inner loops. But do not factor out non-constant functions, like random(). |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 1b0f779e19a5c0d51eddd2d88db50034 |
User & Date: | drh 2013-11-21 14:33:48 |
Context
2013-11-21
| ||
14:44 | Remove the obsolete TK_CONST_FUNC token type. check-in: 9b4217f0 user: drh tags: trunk | |
14:33 | Add the ability to factor constant functions out of inner loops. But do not factor out non-constant functions, like random(). check-in: 1b0f779e user: drh tags: trunk | |
04:18 | Another improvement to OP_Function and an improvement to OP_Move. check-in: 70b056fb user: drh tags: trunk | |
Changes
Changes to src/expr.c.
1187 1187 if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){ 1188 1188 pWalker->u.i = 0; 1189 1189 return WRC_Abort; 1190 1190 } 1191 1191 1192 1192 switch( pExpr->op ){ 1193 1193 /* Consider functions to be constant if all their arguments are constant 1194 - ** and pWalker->u.i==2 */ 1194 + ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST 1195 + ** flag. */ 1195 1196 case TK_FUNCTION: 1196 - if( pWalker->u.i==2 ) return WRC_Continue; 1197 + if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){ 1198 + return WRC_Continue; 1199 + } 1197 1200 /* Fall through */ 1198 1201 case TK_ID: 1199 1202 case TK_COLUMN: 1200 1203 case TK_AGG_FUNCTION: 1201 1204 case TK_AGG_COLUMN: 1202 1205 testcase( pExpr->op==TK_ID ); 1203 1206 testcase( pExpr->op==TK_COLUMN ); ................................................................................ 2693 2696 u8 exprOp; 2694 2697 assert( nFarg==1 ); 2695 2698 assert( pFarg->a[0].pExpr!=0 ); 2696 2699 exprOp = pFarg->a[0].pExpr->op; 2697 2700 if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ 2698 2701 assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); 2699 2702 assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); 2700 - testcase( (pDef->funcFlags&~SQLITE_FUNC_ENCMASK) 2701 - ==SQLITE_FUNC_LENGTH ); 2702 - pFarg->a[0].pExpr->op2 = pDef->funcFlags&~SQLITE_FUNC_ENCMASK; 2703 + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); 2704 + pFarg->a[0].pExpr->op2 = 2705 + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); 2703 2706 } 2704 2707 } 2705 2708 2706 2709 sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ 2707 2710 sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); 2708 2711 sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ 2709 2712 }else{
Changes to src/func.c.
1660 1660 FUNCTION(coalesce, 1, 0, 0, 0 ), 1661 1661 FUNCTION(coalesce, 0, 0, 0, 0 ), 1662 1662 FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), 1663 1663 FUNCTION(hex, 1, 0, 0, hexFunc ), 1664 1664 FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), 1665 1665 FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), 1666 1666 FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), 1667 - FUNCTION(random, 0, 0, 0, randomFunc ), 1668 - FUNCTION(randomblob, 1, 0, 0, randomBlob ), 1667 + VFUNCTION(random, 0, 0, 0, randomFunc ), 1668 + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), 1669 1669 FUNCTION(nullif, 2, 0, 1, nullifFunc ), 1670 1670 FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), 1671 1671 FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), 1672 1672 FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), 1673 1673 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS 1674 1674 FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), 1675 1675 FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), 1676 1676 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ 1677 1677 FUNCTION(quote, 1, 0, 0, quoteFunc ), 1678 - FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), 1679 - FUNCTION(changes, 0, 0, 0, changes ), 1680 - FUNCTION(total_changes, 0, 0, 0, total_changes ), 1678 + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), 1679 + VFUNCTION(changes, 0, 0, 0, changes ), 1680 + VFUNCTION(total_changes, 0, 0, 0, total_changes ), 1681 1681 FUNCTION(replace, 3, 0, 0, replaceFunc ), 1682 1682 FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), 1683 1683 #ifdef SQLITE_SOUNDEX 1684 1684 FUNCTION(soundex, 1, 0, 0, soundexFunc ), 1685 1685 #endif 1686 1686 #ifndef SQLITE_OMIT_LOAD_EXTENSION 1687 1687 FUNCTION(load_extension, 1, 0, 0, loadExt ),
Changes to src/resolve.c.
721 721 sqlite3ErrorMsg(pParse, "not authorized to use function: %s", 722 722 pDef->zName); 723 723 pNC->nErr++; 724 724 } 725 725 pExpr->op = TK_NULL; 726 726 return WRC_Prune; 727 727 } 728 + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); 728 729 } 729 730 #endif 730 731 if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ 731 732 sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); 732 733 pNC->nErr++; 733 734 is_agg = 0; 734 735 }else if( no_such_func && pParse->db->init.busy==0 ){
Changes to src/sqliteInt.h.
1139 1139 #define SQLITE_FUNC_EPHEM 0x010 /* Ephemeral. Delete with VDBE */ 1140 1140 #define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */ 1141 1141 #define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */ 1142 1142 #define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */ 1143 1143 #define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ 1144 1144 #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ 1145 1145 #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ 1146 +#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ 1146 1147 1147 1148 /* 1148 1149 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are 1149 1150 ** used to create the initializers for the FuncDef structures. 1150 1151 ** 1151 1152 ** FUNCTION(zName, nArg, iArg, bNC, xFunc) 1152 1153 ** Used to create a scalar function definition of a function zName 1153 1154 ** implemented by C function xFunc that accepts nArg arguments. The 1154 1155 ** value passed as iArg is cast to a (void*) and made available 1155 1156 ** as the user-data (sqlite3_user_data()) for the function. If 1156 1157 ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. 1157 1158 ** 1159 +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) 1160 +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. 1161 +** 1158 1162 ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) 1159 1163 ** Used to create an aggregate function definition implemented by 1160 1164 ** the C functions xStep and xFinal. The first four parameters 1161 1165 ** are interpreted in the same way as the first 4 parameters to 1162 1166 ** FUNCTION(). 1163 1167 ** 1164 1168 ** LIKEFUNC(zName, nArg, pArg, flags) ................................................................................ 1166 1170 ** that accepts nArg arguments and is implemented by a call to C 1167 1171 ** function likeFunc. Argument pArg is cast to a (void *) and made 1168 1172 ** available as the function user-data (sqlite3_user_data()). The 1169 1173 ** FuncDef.flags variable is set to the value passed as the flags 1170 1174 ** parameter. 1171 1175 */ 1172 1176 #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ 1177 + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ 1178 + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} 1179 +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ 1173 1180 {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ 1174 1181 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} 1175 1182 #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ 1176 - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ 1183 + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ 1177 1184 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} 1178 1185 #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ 1179 - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ 1186 + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ 1180 1187 pArg, 0, xFunc, 0, 0, #zName, 0, 0} 1181 1188 #define LIKEFUNC(zName, nArg, arg, flags) \ 1182 - {nArg, SQLITE_UTF8|flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} 1189 + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ 1190 + (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} 1183 1191 #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ 1184 1192 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ 1185 1193 SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} 1186 1194 1187 1195 /* 1188 1196 ** All current savepoints are stored in a linked list starting at 1189 1197 ** sqlite3.pSavepoint. The first element in the list is the most recently ................................................................................ 1835 1843 #define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ 1836 1844 #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ 1837 1845 #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ 1838 1846 #define EP_Static 0x008000 /* Held in memory not obtained from malloc() */ 1839 1847 #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ 1840 1848 #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ 1841 1849 #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ 1850 +#define EP_Constant 0x080000 /* Node is a constant */ 1842 1851 1843 1852 /* 1844 1853 ** These macros can be used to test, set, or clear bits in the 1845 1854 ** Expr.flags field. 1846 1855 */ 1847 1856 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0) 1848 1857 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))