/ Check-in [0f250957]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When STAT4 is enabled, allow probes of the STAT4 table using the value of constant functions computed at compile-time.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0f250957cd82be63e44eb99be6cc10760f4fdfc4
User & Date: drh 2015-03-12 21:22:08
References
2015-03-13
08:31
Extra tests for commit [0f250957]. check-in: 5aa522dc user: dan tags: trunk
Context
2015-03-12
23:48
Fix the "now" option for date-time functions for cases when STAT4 is disabled. check-in: 3ac1f6a3 user: drh tags: trunk
21:22
When STAT4 is enabled, allow probes of the STAT4 table using the value of constant functions computed at compile-time. check-in: 0f250957 user: drh tags: trunk
21:02
Always disallow functions as the DEFAULT of a column. Add assert()s and Closed-Leaf check-in: a991bb1a user: drh tags: stat4-function
19:12
Disable multiplexing of master-journal files in the test_multiplex.c module. check-in: b8684df3 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/alter.c.

   686    686     }
   687    687   
   688    688     /* Ensure the default expression is something that sqlite3ValueFromExpr()
   689    689     ** can handle (i.e. not CURRENT_TIME etc.)
   690    690     */
   691    691     if( pDflt ){
   692    692       sqlite3_value *pVal = 0;
   693         -    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
          693  +    int rc;
          694  +    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
          695  +    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
          696  +    if( rc!=SQLITE_OK ){
   694    697         db->mallocFailed = 1;
   695    698         return;
   696    699       }
   697    700       if( !pVal ){
   698    701         sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
   699    702         return;
   700    703       }

Changes to src/func.c.

    18     18   #include <assert.h>
    19     19   #include "vdbeInt.h"
    20     20   
    21     21   /*
    22     22   ** Return the collating function associated with a function.
    23     23   */
    24     24   static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
    25         -  VdbeOp *pOp = &context->pVdbe->aOp[context->iOp-1];
           25  +  VdbeOp *pOp;
           26  +  assert( context->pVdbe!=0 );
           27  +  pOp = &context->pVdbe->aOp[context->iOp-1];
    26     28     assert( pOp->opcode==OP_CollSeq );
    27     29     assert( pOp->p4type==P4_COLLSEQ );
    28     30     return pOp->p4.pColl;
    29     31   }
    30     32   
    31     33   /*
    32     34   ** Indicate that the accumulator load should be skipped on this

Changes to src/vdbeapi.c.

   366    366     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   367    367     sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
   368    368   }
   369    369   void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   370    370     pCtx->isError = errCode;
   371    371     pCtx->fErrorOrAux = 1;
   372    372   #ifdef SQLITE_DEBUG
   373         -  pCtx->pVdbe->rcApp = errCode;
          373  +  if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
   374    374   #endif
   375    375     if( pCtx->pOut->flags & MEM_Null ){
   376    376       sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, 
   377    377                            SQLITE_UTF8, SQLITE_STATIC);
   378    378     }
   379    379   }
   380    380   
................................................................................
   629    629   */
   630    630   sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
   631    631     assert( p && p->pFunc );
   632    632     return p->pOut->db;
   633    633   }
   634    634   
   635    635   /*
   636         -** Return the current time for a statement
          636  +** Return the current time for a statement.  If the current time
          637  +** is requested more than once within the same run of a single prepared
          638  +** statement, the exact same time is returned for each invocation regardless
          639  +** of the amount of time that elapses between invocations.  In other words,
          640  +** the time returned is always the time of the first call.
   637    641   */
   638    642   sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
   639         -  Vdbe *v = p->pVdbe;
   640    643     int rc;
   641         -  if( v->iCurrentTime==0 ){
   642         -    rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, &v->iCurrentTime);
   643         -    if( rc ) v->iCurrentTime = 0;
          644  +  sqlite3_int64 iTime = 0;
          645  +#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
          646  +  sqlite3_int64 *piTime = &iTime;
          647  +  assert( p->pVdbe!=0 );
          648  +#else
          649  +  sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
          650  +  if( *piTime==0 )
          651  +#endif
          652  +  {
          653  +    rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
          654  +    if( rc ) *piTime = 0;
   644    655     }
   645         -  return v->iCurrentTime;
          656  +  return *piTime;
   646    657   }
   647    658   
   648    659   /*
   649    660   ** The following is the implementation of an SQL function that always
   650    661   ** fails with an error message stating that the function is used in the
   651    662   ** wrong context.  The sqlite3_overload_function() API might construct
   652    663   ** SQL function that use this routine so that the functions will exist
................................................................................
   708    719   ** Return the auxiliary data pointer, if any, for the iArg'th argument to
   709    720   ** the user-function defined by pCtx.
   710    721   */
   711    722   void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
   712    723     AuxData *pAuxData;
   713    724   
   714    725     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
          726  +#if SQLITE_ENABLE_STAT3_OR_STAT4
          727  +  if( pCtx->pVdbe==0 ) return 0;
          728  +#else
          729  +  assert( pCtx->pVdbe!=0 );
          730  +#endif
   715    731     for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
   716    732       if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
   717    733     }
   718    734   
   719    735     return (pAuxData ? pAuxData->pAux : 0);
   720    736   }
   721    737   
................................................................................
   731    747     void (*xDelete)(void*)
   732    748   ){
   733    749     AuxData *pAuxData;
   734    750     Vdbe *pVdbe = pCtx->pVdbe;
   735    751   
   736    752     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   737    753     if( iArg<0 ) goto failed;
          754  +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          755  +  if( pVdbe==0 ) goto failed;
          756  +#else
          757  +  assert( pVdbe!=0 );
          758  +#endif
   738    759   
   739    760     for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
   740    761       if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
   741    762     }
   742    763     if( pAuxData==0 ){
   743    764       pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
   744    765       if( !pAuxData ) goto failed;

Changes to src/vdbemem.c.

  1086   1086   ** Allocate and return a pointer to a new sqlite3_value object. If
  1087   1087   ** the second argument to this function is NULL, the object is allocated
  1088   1088   ** by calling sqlite3ValueNew().
  1089   1089   **
  1090   1090   ** Otherwise, if the second argument is non-zero, then this function is 
  1091   1091   ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
  1092   1092   ** already been allocated, allocate the UnpackedRecord structure that 
  1093         -** that function will return to its caller here. Then return a pointer 
         1093  +** that function will return to its caller here. Then return a pointer to
  1094   1094   ** an sqlite3_value within the UnpackedRecord.a[] array.
  1095   1095   */
  1096   1096   static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
  1097   1097   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1098   1098     if( p ){
  1099   1099       UnpackedRecord *pRec = p->ppRec[0];
  1100   1100   
................................................................................
  1130   1130     }
  1131   1131   #else
  1132   1132     UNUSED_PARAMETER(p);
  1133   1133   #endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
  1134   1134     return sqlite3ValueNew(db);
  1135   1135   }
  1136   1136   
         1137  +/*
         1138  +** The expression object indicated by the second argument is guaranteed
         1139  +** to be a scalar SQL function. If
         1140  +**
         1141  +**   * all function arguments are SQL literals,
         1142  +**   * the SQLITE_FUNC_CONSTANT function flag is set, and
         1143  +**   * the SQLITE_FUNC_NEEDCOLL function flag is not set,
         1144  +**
         1145  +** then this routine attempts to invoke the SQL function. Assuming no
         1146  +** error occurs, output parameter (*ppVal) is set to point to a value 
         1147  +** object containing the result before returning SQLITE_OK.
         1148  +**
         1149  +** Affinity aff is applied to the result of the function before returning.
         1150  +** If the result is a text value, the sqlite3_value object uses encoding 
         1151  +** enc.
         1152  +**
         1153  +** If the conditions above are not met, this function returns SQLITE_OK
         1154  +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
         1155  +** NULL and an SQLite error code returned.
         1156  +*/
         1157  +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1158  +static int valueFromFunction(
         1159  +  sqlite3 *db,                    /* The database connection */
         1160  +  Expr *p,                        /* The expression to evaluate */
         1161  +  u8 enc,                         /* Encoding to use */
         1162  +  u8 aff,                         /* Affinity to use */
         1163  +  sqlite3_value **ppVal,          /* Write the new value here */
         1164  +  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
         1165  +){
         1166  +  sqlite3_context ctx;            /* Context object for function invocation */
         1167  +  sqlite3_value **apVal = 0;      /* Function arguments */
         1168  +  int nVal = 0;                   /* Size of apVal[] array */
         1169  +  FuncDef *pFunc = 0;             /* Function definition */
         1170  +  sqlite3_value *pVal = 0;        /* New value */
         1171  +  int rc = SQLITE_OK;             /* Return code */
         1172  +  int nName;                      /* Size of function name in bytes */
         1173  +  ExprList *pList = 0;            /* Function arguments */
         1174  +  int i;                          /* Iterator variable */
         1175  +
         1176  +  assert( pCtx!=0 );
         1177  +  assert( (p->flags & EP_TokenOnly)==0 );
         1178  +  pList = p->x.pList;
         1179  +  if( pList ) nVal = pList->nExpr;
         1180  +  nName = sqlite3Strlen30(p->u.zToken);
         1181  +  pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
         1182  +  assert( pFunc );
         1183  +  if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 
         1184  +   || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
         1185  +  ){
         1186  +    return SQLITE_OK;
         1187  +  }
         1188  +
         1189  +  if( pList ){
         1190  +    apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
         1191  +    if( apVal==0 ){
         1192  +      rc = SQLITE_NOMEM;
         1193  +      goto value_from_function_out;
         1194  +    }
         1195  +    for(i=0; i<nVal; i++){
         1196  +      rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
         1197  +      if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
         1198  +    }
         1199  +  }
         1200  +
         1201  +  pVal = valueNew(db, pCtx);
         1202  +  if( pVal==0 ){
         1203  +    rc = SQLITE_NOMEM;
         1204  +    goto value_from_function_out;
         1205  +  }
         1206  +
         1207  +  memset(&ctx, 0, sizeof(ctx));
         1208  +  ctx.pOut = pVal;
         1209  +  ctx.pFunc = pFunc;
         1210  +  pFunc->xFunc(&ctx, nVal, apVal);
         1211  +  if( ctx.isError ){
         1212  +    rc = ctx.isError;
         1213  +    sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
         1214  +    pCtx->pParse->rc = rc;
         1215  +  }else{
         1216  +    sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
         1217  +    assert( rc==SQLITE_OK );
         1218  +    rc = sqlite3VdbeChangeEncoding(pVal, enc);
         1219  +    if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
         1220  +      rc = SQLITE_TOOBIG;
         1221  +    }
         1222  +  }
         1223  +
         1224  + value_from_function_out:
         1225  +  if( rc!=SQLITE_OK ){
         1226  +    pVal = 0;
         1227  +  }
         1228  +  if( apVal ){
         1229  +    for(i=0; i<nVal; i++){
         1230  +      sqlite3ValueFree(apVal[i]);
         1231  +    }
         1232  +    sqlite3DbFree(db, apVal);
         1233  +  }
         1234  +
         1235  +  *ppVal = pVal;
         1236  +  return rc;
         1237  +}
         1238  +#else
         1239  +# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
         1240  +#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
         1241  +
  1137   1242   /*
  1138   1243   ** Extract a value from the supplied expression in the manner described
  1139   1244   ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
  1140   1245   ** using valueNew().
  1141   1246   **
  1142   1247   ** If pCtx is NULL and an error occurs after the sqlite3_value object
  1143   1248   ** has been allocated, it is freed before returning. Or, if pCtx is not
................................................................................
  1161   1266   
  1162   1267     if( !pExpr ){
  1163   1268       *ppVal = 0;
  1164   1269       return SQLITE_OK;
  1165   1270     }
  1166   1271     while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
  1167   1272     if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
         1273  +
         1274  +  /* Compressed expressions only appear when parsing the DEFAULT clause
         1275  +  ** on a table column definition, and hence only when pCtx==0.  This
         1276  +  ** check ensures that an EP_TokenOnly expression is never passed down
         1277  +  ** into valueFromFunction(). */
         1278  +  assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
  1168   1279   
  1169   1280     if( op==TK_CAST ){
  1170   1281       u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
  1171   1282       rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
  1172   1283       testcase( rc!=SQLITE_OK );
  1173   1284       if( *ppVal ){
  1174   1285         sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
................................................................................
  1237   1348       zVal = &pExpr->u.zToken[2];
  1238   1349       nVal = sqlite3Strlen30(zVal)-1;
  1239   1350       assert( zVal[nVal]=='\'' );
  1240   1351       sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
  1241   1352                            0, SQLITE_DYNAMIC);
  1242   1353     }
  1243   1354   #endif
         1355  +
         1356  +  else if( op==TK_FUNCTION && pCtx!=0 ){
         1357  +    rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
         1358  +  }
  1244   1359   
  1245   1360     *ppVal = pVal;
  1246   1361     return rc;
  1247   1362   
  1248   1363   no_mem:
  1249   1364     db->mallocFailed = 1;
  1250   1365     sqlite3DbFree(db, zVal);

Added test/analyzeF.test.

            1  +# 2015-03-12
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# Test that deterministic scalar functions passed constant arguments
           12  +# are used with stat4 data.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set ::testprefix analyzeF
           18  +
           19  +ifcapable {!stat4} {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +proc isqrt {i} { expr { int(sqrt($i)) } }
           25  +db func isqrt isqrt
           26  +
           27  +do_execsql_test 1.0 {
           28  +  CREATE TABLE t1(x INTEGER, y INTEGER);
           29  +  WITH data(i) AS (
           30  +    SELECT 1 UNION ALL SELECT i+1 FROM data
           31  +  )
           32  +  INSERT INTO t1 SELECT isqrt(i), isqrt(i) FROM data LIMIT 400;
           33  +  CREATE INDEX t1x ON t1(x);
           34  +  CREATE INDEX t1y ON t1(y);
           35  +  ANALYZE;
           36  +}
           37  +
           38  +proc str {a} { return $a }
           39  +db func str str
           40  +
           41  +# Note: tests 7 to 12 might be unstable - as they assume SQLite will
           42  +# prefer the expression to the right of the AND clause. Which of
           43  +# course could change.
           44  +#
           45  +# Note 2: tests 9 and 10 depend on the tcl interface creating functions
           46  +# without the SQLITE_DETERMINISTIC flag set.
           47  +#
           48  +foreach {tn where idx} {
           49  +  1 "x = 4 AND y = 19"     {t1x (x=?)}
           50  +  2 "x = 19 AND y = 4"     {t1y (y=?)}
           51  +  3 "x = '4' AND y = '19'" {t1x (x=?)}
           52  +  4 "x = '19' AND y = '4'" {t1y (y=?)}
           53  +  5 "x = substr('5195', 2, 2) AND y = substr('145', 2, 1)" {t1y (y=?)}
           54  +  6 "x = substr('145', 2, 1) AND y = substr('5195', 2, 2)" {t1x (x=?)}
           55  +
           56  +  7  "x = substr('5195', 2, 2+0) AND y = substr('145', 2, 1+0)" {t1y (y=?)}
           57  +  8  "x = substr('145', 2, 1+0) AND y = substr('5195', 2, 2+0)" {t1y (y=?)}
           58  +
           59  +  9  "x = str('19') AND y = str('4')" {t1y (y=?)}
           60  +  10 "x = str('4') AND y = str('19')" {t1y (y=?)}
           61  +
           62  +  11 "x = nullif('19', 0) AND y = nullif('4', 0)" {t1y (y=?)}
           63  +  12 "x = nullif('4', 0) AND y = nullif('19', 0)" {t1y (y=?)}
           64  +} {
           65  +  set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
           66  +  do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res
           67  +}
           68  +
           69  +do_catchsql_test 2.1 {
           70  +  SELECT * FROM t1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
           71  +} {1 {no such function: func}}
           72  +do_catchsql_test 2.2 {
           73  +  UPDATE t1 SET y=y+1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
           74  +} {1 {no such function: func}}
           75  +
           76  +
           77  +finish_test
           78  +