/ Check-in [1b0f779e]
Login

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: 1b0f779e19a5c0d51eddd2d88db50034d77d132c
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
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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))