aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2017-07-17 00:40:19 +0000
committerdrh <drh@noemail.net>2017-07-17 00:40:19 +0000
commitae3ec3f920f39802f81d6ef64283e2925d64ec57 (patch)
tree7dedb20e1a8bbb316c91802b7913739d20b0abec /src
parentfe8eadc94dc15a77245b7537b1230385caba9161 (diff)
downloadsqlite-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.in23
-rw-r--r--src/sqlite3ext.h6
-rw-r--r--src/vdbeInt.h2
-rw-r--r--src/vdbeapi.c16
-rw-r--r--src/vdbemem.c11
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