Add the sqlite3_value_frombind() interface. Use that interface to

improve fts3_tokenizer().

FossilOrigin-Name: b3f2c3205a28dc21ea7080e5e1ba246ce9c9b90c1309262ca11d8e40943ed677
This commit is contained in:
drh
2019-04-02 00:28:54 +00:00
11 changed files with 120 additions and 20 deletions
+8
View File
@@ -4979,6 +4979,8 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
** against a virtual table.
** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if value originated a bound parameter
** </table></blockquote>
**
** <b>Details:</b>
@@ -5040,6 +5042,11 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
**
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces. ^If X comes from an SQL literal value, or a table column,
** and expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -5085,6 +5092,7 @@ int sqlite3_value_bytes16(sqlite3_value*);
int sqlite3_value_type(sqlite3_value*);
int sqlite3_value_numeric_type(sqlite3_value*);
int sqlite3_value_nochange(sqlite3_value*);
int sqlite3_value_frombind(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
+19
View File
@@ -630,6 +630,24 @@ static void test_getsubtype(
sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
}
/* test_frombind(A,B,C,...)
**
** Return an integer bitmask that has a bit set for every argument
** (up to the first 63 arguments) that originates from a bind a parameter.
*/
static void test_frombind(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_uint64 m = 0;
int i;
for(i=0; i<argc && i<63; i++){
if( sqlite3_value_frombind(argv[i]) ) m |= ((sqlite3_uint64)1)<<i;
}
sqlite3_result_int64(context, (sqlite3_int64)m);
}
/* test_setsubtype(V, T)
**
** Return the value V with its subtype changed to T
@@ -675,6 +693,7 @@ static int registerTestFunctions(
{ "test_zeroblob", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
{ "test_getsubtype", 1, SQLITE_UTF8, test_getsubtype},
{ "test_setsubtype", 2, SQLITE_UTF8, test_setsubtype},
{ "test_frombind", -1, SQLITE_UTF8, test_frombind},
};
int i;
+4 -1
View File
@@ -1256,7 +1256,10 @@ case OP_Variable: { /* out2 */
goto too_big;
}
pOut = &aMem[pOp->p2];
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
memcpy(pOut, pVar, MEMCELLSIZE);
pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
pOut->flags |= MEM_Static|MEM_FromBind;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
+1 -1
View File
@@ -246,7 +246,7 @@ struct sqlite3_value {
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
#define MEM_AffMask 0x001f /* Mask of affinity bits */
/* Available 0x0020 */
#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */
/* Available 0x0040 */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
+5
View File
@@ -275,6 +275,11 @@ int sqlite3_value_nochange(sqlite3_value *pVal){
return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
}
/* Return true if a parameter value originated from an sqlite3_bind() */
int sqlite3_value_frombind(sqlite3_value *pVal){
return (pVal->flags&MEM_FromBind)!=0;
}
/* Make a copy of an sqlite3_value object
*/
sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
+1 -1
View File
@@ -57,7 +57,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
/* No other bits set */
assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
|MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
}else{
/* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,