diff options
author | drh <drh@noemail.net> | 2017-07-17 00:40:19 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2017-07-17 00:40:19 +0000 |
commit | ae3ec3f920f39802f81d6ef64283e2925d64ec57 (patch) | |
tree | 7dedb20e1a8bbb316c91802b7913739d20b0abec /src | |
parent | fe8eadc94dc15a77245b7537b1230385caba9161 (diff) | |
download | sqlite-ae3ec3f920f39802f81d6ef64283e2925d64ec57.tar.gz sqlite-ae3ec3f920f39802f81d6ef64283e2925d64ec57.zip |
Add an experimental "pointer type" parameter to sqlite3_bind_pointer(),
sqlite3_result_pointer(), and sqlite3_value_pointer(). The pointer type is
a string that must compare equal using strcmp() or else the pointer comes
through as a NULL.
FossilOrigin-Name: 211cce04e97d2e325a6ea3e99738fc71115d673dc13daeffb03ac3140deb11de
Diffstat (limited to 'src')
-rw-r--r-- | src/sqlite.h.in | 23 | ||||
-rw-r--r-- | src/sqlite3ext.h | 6 | ||||
-rw-r--r-- | src/vdbeInt.h | 2 | ||||
-rw-r--r-- | src/vdbeapi.c | 16 | ||||
-rw-r--r-- | src/vdbemem.c | 11 |
5 files changed, 33 insertions, 25 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9d63a775b..4b3b0bc81 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3883,9 +3883,9 @@ typedef struct sqlite3_context sqlite3_context; ** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** -** ^The sqlite3_bind_pointer(S,I,P) routine causes the I-th parameter in +** ^The sqlite3_bind_pointer(S,I,P,T) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be -** associated with the pointer P. +** associated with the pointer P of type T. ** ^The sqlite3_bind_pointer() routine can be used to pass ** host-language pointers into [application-defined SQL functions]. ** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears @@ -3925,7 +3925,7 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -int sqlite3_bind_pointer(sqlite3_stmt*, int, void*); +int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); @@ -4758,9 +4758,10 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** extract UTF-16 strings as big-endian and little-endian respectively. ** ** ^If [sqlite3_value] object V was initialized -** using [sqlite3_bind_pointer(S,I,P)] or [sqlite3_result_pointer(C,P)], then -** sqlite3_value_pointer(V) will return the pointer P. Otherwise, -** sqlite3_value_pointer(V) returns a NULL. +** using [sqlite3_bind_pointer(S,I,P,X)] or [sqlite3_result_pointer(C,P,X)] +** and if X and Y are strings that compare equal according to strcmp(X,Y), +** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, +** sqlite3_value_pointer(V,Y) returns a NULL. ** ** ^(The sqlite3_value_type(V) interface returns the ** [SQLITE_INTEGER | datatype code] for the initial datatype of the @@ -4794,7 +4795,7 @@ const void *sqlite3_value_blob(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -void *sqlite3_value_pointer(sqlite3_value*); +void *sqlite3_value_pointer(sqlite3_value*, const char*); const unsigned char *sqlite3_value_text(sqlite3_value*); const void *sqlite3_value_text16(sqlite3_value*); const void *sqlite3_value_text16le(sqlite3_value*); @@ -5095,10 +5096,10 @@ typedef void (*sqlite3_destructor_type)(void*); ** [unprotected sqlite3_value] object is required, so either ** kind of [sqlite3_value] object can be used with this interface. ** -** ^The sqlite3_result_pointer(C,P) interface sets the result to an +** ^The sqlite3_result_pointer(C,P,T) interface sets the result to an ** SQL NULL value, just like [sqlite3_result_null(C)], except that it -** also associates the host-language pointer P with that NULL value such -** that the pointer can be retrieved within an +** also associates the host-language pointer P or type T with that +** NULL value such that the pointer can be retrieved within an ** [application-defined SQL function] using [sqlite3_value_pointer()]. ** This mechanism can be used to pass non-SQL values between ** application-defined functions. @@ -5126,7 +5127,7 @@ void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -void sqlite3_result_pointer(sqlite3_context*, void*); +void sqlite3_result_pointer(sqlite3_context*, void*, const char*); void sqlite3_result_zeroblob(sqlite3_context*, int n); int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 8d254b236..c585f17f2 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -289,9 +289,9 @@ struct sqlite3_api_routines { sqlite3_stmt**,const char**); int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, sqlite3_stmt**,const void**); - int (*bind_pointer)(sqlite3_stmt*,int,void*); - void (*result_pointer)(sqlite3_context*,void*); - void *(*value_pointer)(sqlite3_value*); + int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*); + void (*result_pointer)(sqlite3_context*,void*,const char*); + void *(*value_pointer)(sqlite3_value*,const char*); }; /* diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 2d8d3652f..599fe7041 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -476,7 +476,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64); #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif -void sqlite3VdbeMemSetPointer(Mem*, void*); +void sqlite3VdbeMemSetPointer(Mem*, void*, const char*); void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b94facead..9de248633 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -199,9 +199,13 @@ unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } -void *sqlite3_value_pointer(sqlite3_value *pVal){ +void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ Mem *p = (Mem*)pVal; - if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) && p->eSubtype=='p' ){ + if( (p->flags & MEM_TypeMask)==(MEM_Null|MEM_Subtype) + && p->eSubtype=='p' + && zPType!=0 + && strcmp(p->z, zPType)==0 + ){ return p->u.pPtr; }else{ return 0; @@ -385,11 +389,11 @@ void sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } -void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr){ +void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr, const char *zPT){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemSetNull(pOut); - sqlite3VdbeMemSetPointer(pOut, pPtr); + sqlite3VdbeMemSetPointer(pOut, pPtr, zPT); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; @@ -1394,12 +1398,12 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ } return rc; } -int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr){ +int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr,const char *zT){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr); + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zT); sqlite3_mutex_leave(p->db->mutex); } return rc; diff --git a/src/vdbemem.c b/src/vdbemem.c index d73233c0e..64f7c3d63 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -709,11 +709,14 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ ** Set the value stored in *pMem should already be a NULL. ** Also store a pointer to go with it. */ -void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr){ +void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr, const char *zPType){ assert( pMem->flags==MEM_Null ); - pMem->flags = MEM_Null|MEM_Subtype; - pMem->u.pPtr = pPtr; - pMem->eSubtype = 'p'; + if( zPType ){ + pMem->flags = MEM_Null|MEM_Subtype; + pMem->u.pPtr = pPtr; + pMem->eSubtype = 'p'; + pMem->z = (char*)zPType; + } } #ifndef SQLITE_OMIT_FLOATING_POINT |