/ Check-in [98da62df]
Login

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

Overview
Comment:Initial implementation of the sqlite3_value_frombind() interface.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | value_frombind
Files: files | file ages | folders
SHA3-256: 98da62dfdacc6b3c490c387d1f8a74cc5daa978776967e264ad4800c380b0ddf
User & Date: drh 2019-03-29 11:13:37
Context
2019-03-29
11:39
The two-argument version of fts3_tokenizer() works regardless of the value of SQLITE_DBCONFIG_ENABLE_FT3_TOKENIZER as long as the second argument is a bind parameter. check-in: ab76e3a9 user: drh tags: value_frombind
11:13
Initial implementation of the sqlite3_value_frombind() interface. check-in: 98da62df user: drh tags: value_frombind
01:15
Recover a some of the performance lost by window function alias fix two check-ins back. check-in: 965cbcea user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqlite.h.in.

  4975   4975   ** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
  4976   4976   ** datatype of the value
  4977   4977   ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
  4978   4978   ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
  4979   4979   ** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
  4980   4980   ** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
  4981   4981   ** against a virtual table.
         4982  +** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
         4983  +** <td>&rarr;&nbsp;&nbsp;<td>True if value originated a bound parameter
  4982   4984   ** </table></blockquote>
  4983   4985   **
  4984   4986   ** <b>Details:</b>
  4985   4987   **
  4986   4988   ** These routines extract type, size, and content information from
  4987   4989   ** [protected sqlite3_value] objects.  Protected sqlite3_value objects
  4988   4990   ** are used to pass parameter information into implementation of
................................................................................
  5035   5037   ** the value for that column returned without setting a result (probably
  5036   5038   ** because it queried [sqlite3_vtab_nochange()] and found that the column
  5037   5039   ** was unchanging).  ^Within an [xUpdate] method, any value for which
  5038   5040   ** sqlite3_value_nochange(X) is true will in all other respects appear
  5039   5041   ** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
  5040   5042   ** than within an [xUpdate] method call for an UPDATE statement, then
  5041   5043   ** the return value is arbitrary and meaningless.
         5044  +**
         5045  +** ^The sqlite3_value_frombind(X) interface returns non-zero if the
         5046  +** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
         5047  +** interfaces.  ^If X comes from an SQL literal value, or a table column,
         5048  +** and expression, then sqlite3_value_frombind(X) returns zero.
  5042   5049   **
  5043   5050   ** Please pay particular attention to the fact that the pointer returned
  5044   5051   ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
  5045   5052   ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
  5046   5053   ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
  5047   5054   ** or [sqlite3_value_text16()].
  5048   5055   **
................................................................................
  5081   5088   const void *sqlite3_value_text16le(sqlite3_value*);
  5082   5089   const void *sqlite3_value_text16be(sqlite3_value*);
  5083   5090   int sqlite3_value_bytes(sqlite3_value*);
  5084   5091   int sqlite3_value_bytes16(sqlite3_value*);
  5085   5092   int sqlite3_value_type(sqlite3_value*);
  5086   5093   int sqlite3_value_numeric_type(sqlite3_value*);
  5087   5094   int sqlite3_value_nochange(sqlite3_value*);
         5095  +int sqlite3_value_frombind(sqlite3_value*);
  5088   5096   
  5089   5097   /*
  5090   5098   ** CAPI3REF: Finding The Subtype Of SQL Values
  5091   5099   ** METHOD: sqlite3_value
  5092   5100   **
  5093   5101   ** The sqlite3_value_subtype(V) function returns the subtype for
  5094   5102   ** an [application-defined SQL function] argument V.  The subtype

Changes to src/test_func.c.

   625    625   static void test_getsubtype(
   626    626     sqlite3_context *context,
   627    627     int argc,
   628    628     sqlite3_value **argv
   629    629   ){
   630    630     sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
   631    631   }
          632  +
          633  +/*         test_frombind(A,B,C,...)
          634  +**
          635  +** Return an integer bitmask that has a bit set for every argument
          636  +** (up to the first 63 arguments) that originates from a bind a parameter.
          637  +*/
          638  +static void test_frombind(
          639  +  sqlite3_context *context,
          640  +  int argc,
          641  +  sqlite3_value **argv
          642  +){
          643  +  sqlite3_uint64 m = 0;
          644  +  int i;
          645  +  for(i=0; i<argc && i<63; i++){
          646  +    if( sqlite3_value_frombind(argv[i]) ) m |= ((sqlite3_uint64)1)<<i;
          647  +  }
          648  +  sqlite3_result_int64(context, (sqlite3_int64)m);
          649  +}
   632    650   
   633    651   /*         test_setsubtype(V, T)
   634    652   **
   635    653   ** Return the value V with its subtype changed to T
   636    654   */
   637    655   static void test_setsubtype(
   638    656     sqlite3_context *context,
................................................................................
   671    689       { "test_counter",          1, SQLITE_UTF8, counterFunc},
   672    690       { "real2hex",              1, SQLITE_UTF8, real2hex},
   673    691       { "test_decode",           1, SQLITE_UTF8, test_decode},
   674    692       { "test_extract",          2, SQLITE_UTF8, test_extract},
   675    693       { "test_zeroblob",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
   676    694       { "test_getsubtype",       1, SQLITE_UTF8, test_getsubtype},
   677    695       { "test_setsubtype",       2, SQLITE_UTF8, test_setsubtype},
          696  +    { "test_frombind",        -1, SQLITE_UTF8, test_frombind},
   678    697     };
   679    698     int i;
   680    699   
   681    700     for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
   682    701       sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
   683    702           aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0);
   684    703     }

Changes to src/vdbe.c.

  1233   1233     assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
  1234   1234     pVar = &p->aVar[pOp->p1 - 1];
  1235   1235     if( sqlite3VdbeMemTooBig(pVar) ){
  1236   1236       goto too_big;
  1237   1237     }
  1238   1238     pOut = &aMem[pOp->p2];
  1239   1239     sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
         1240  +  pOut->flags |= MEM_FromBind;
  1240   1241     UPDATE_MAX_BLOBSIZE(pOut);
  1241   1242     break;
  1242   1243   }
  1243   1244   
  1244   1245   /* Opcode: Move P1 P2 P3 * *
  1245   1246   ** Synopsis: r[P2@P3]=r[P1@P3]
  1246   1247   **

Changes to src/vdbeInt.h.

   242    242   */
   243    243   #define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
   244    244   #define MEM_Str       0x0002   /* Value is a string */
   245    245   #define MEM_Int       0x0004   /* Value is an integer */
   246    246   #define MEM_Real      0x0008   /* Value is a real number */
   247    247   #define MEM_Blob      0x0010   /* Value is a BLOB */
   248    248   #define MEM_AffMask   0x001f   /* Mask of affinity bits */
   249         -/* Available          0x0020   */
          249  +#define MEM_FromBind  0x0020   /* Value originates from sqlite3_bind() */
   250    250   /* Available          0x0040   */
   251    251   #define MEM_Undefined 0x0080   /* Value is undefined */
   252    252   #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
   253    253   #define MEM_TypeMask  0xc1ff   /* Mask of type bits */
   254    254   
   255    255   
   256    256   /* Whenever Mem contains a valid string or blob representation, one of

Changes to src/vdbeapi.c.

   270    270     return aType[pVal->flags&MEM_AffMask];
   271    271   }
   272    272   
   273    273   /* Return true if a parameter to xUpdate represents an unchanged column */
   274    274   int sqlite3_value_nochange(sqlite3_value *pVal){
   275    275     return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
   276    276   }
          277  +
          278  +/* Return true if a parameter value originated from an sqlite3_bind() */
          279  +int sqlite3_value_frombind(sqlite3_value *pVal){
          280  +  return (pVal->flags&MEM_FromBind)!=0;
          281  +}
   277    282   
   278    283   /* Make a copy of an sqlite3_value object
   279    284   */
   280    285   sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
   281    286     sqlite3_value *pNew;
   282    287     if( pOrig==0 ) return 0;
   283    288     pNew = sqlite3_malloc( sizeof(*pNew) );

Changes to test/func.test.

  1387   1387   }
  1388   1388   
  1389   1389   # Test char().
  1390   1390   #
  1391   1391   do_execsql_test func-31.1 { 
  1392   1392     SELECT char(), length(char()), typeof(char()) 
  1393   1393   } {{} 0 text}
         1394  +
         1395  +# sqlite3_value_frombind()
         1396  +#
         1397  +do_execsql_test func-32.100 {
         1398  +  SELECT test_frombind(1,2,3,4);
         1399  +} {0}
         1400  +do_execsql_test func-32.110 {
         1401  +  SELECT test_frombind(1,2,?,4);
         1402  +} {4}
         1403  +do_execsql_test func-32.120 {
         1404  +  SELECT test_frombind(1,(?),4,?+7);
         1405  +} {2}
         1406  +do_execsql_test func-32.130 {
         1407  +  DROP TABLE IF EXISTS t1;
         1408  +  CREATE TABLE t1(a,b,c,e,f);
         1409  +  INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null);
         1410  +  SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1;
         1411  +} {32}
         1412  +do_execsql_test func-32.140 {
         1413  +  SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
         1414  +} {0}
         1415  +do_execsql_test func-32.150 {
         1416  +  SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
         1417  +} {8}
         1418  +
         1419  +
         1420  +
         1421  +
  1394   1422   finish_test