aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/func.c12
-rw-r--r--src/loadext.c4
-rw-r--r--src/sqlite.h.in6
-rw-r--r--src/sqlite3ext.h4
-rw-r--r--src/sqliteInt.h12
-rw-r--r--src/test1.c38
-rw-r--r--src/test_malloc.c21
-rw-r--r--src/vdbe.c2
-rw-r--r--src/vdbeapi.c28
9 files changed, 102 insertions, 25 deletions
diff --git a/src/func.c b/src/func.c
index d0565357d..6ecd74396 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1122,16 +1122,14 @@ static void zeroblobFunc(
sqlite3_value **argv
){
i64 n;
- sqlite3 *db = sqlite3_context_db_handle(context);
+ int rc;
assert( argc==1 );
UNUSED_PARAMETER(argc);
n = sqlite3_value_int64(argv[0]);
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH] );
- testcase( n==db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
- if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
- sqlite3_result_error_toobig(context);
- }else{
- sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
+ if( n<0 ) n = 0;
+ rc = sqlite3_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
+ if( rc ){
+ sqlite3_result_error_code(context, rc);
}
}
diff --git a/src/loadext.c b/src/loadext.c
index dcdbb2812..1d398c54c 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -405,7 +405,9 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_strglob,
/* Version 3.8.11 and later */
(sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
- sqlite3_value_free
+ sqlite3_value_free,
+ sqlite3_result_zeroblob64,
+ sqlite3_bind_zeroblob64
};
/*
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 3ddd8ece5..85fe1abaf 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -3562,6 +3562,7 @@ 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_zeroblob(sqlite3_stmt*, int, int n);
+int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
@@ -4534,8 +4535,8 @@ typedef void (*sqlite3_destructor_type)(void*);
** to by the second parameter and which is N bytes long where N is the
** third parameter.
**
-** ^The sqlite3_result_zeroblob() interfaces set the result of
-** the application-defined function to be a BLOB containing all zero
+** ^The sqlite3_result_zeroblob() and zeroblob64() interfaces set the result
+** of the application-defined function to be a BLOB containing all zero
** bytes and N bytes in size, where N is the value of the 2nd parameter.
**
** ^The sqlite3_result_double() interface sets the result from
@@ -4651,6 +4652,7 @@ 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_zeroblob(sqlite3_context*, int n);
+int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
/*
** CAPI3REF: Define New Collating Sequences
diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h
index b56cc4e54..48a5bf744 100644
--- a/src/sqlite3ext.h
+++ b/src/sqlite3ext.h
@@ -270,6 +270,8 @@ struct sqlite3_api_routines {
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
+ int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
+ int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
};
/*
@@ -503,6 +505,8 @@ struct sqlite3_api_routines {
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
+#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
+#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
#endif /* SQLITE_CORE */
#ifndef SQLITE_CORE
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7d99d772f..aa6b63bff 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -189,10 +189,14 @@
** Make sure that the compiler intrinsics we desire are enabled when
** compiling with an appropriate version of MSVC.
*/
-#if defined(_MSC_VER) && _MSC_VER>=1300 && !defined(_WIN32_WCE)
-# include <intrin.h>
-# pragma intrinsic(_byteswap_ushort)
-# pragma intrinsic(_byteswap_ulong)
+#if defined(_MSC_VER) && _MSC_VER>=1300
+# if !defined(_WIN32_WCE)
+# include <intrin.h>
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# else
+# include <cmnintrin.h>
+# endif
#endif
/*
diff --git a/src/test1.c b/src/test1.c
index 15fd8c7f7..ceccf10db 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -3009,6 +3009,43 @@ static int test_bind_zeroblob(
}
/*
+** Usage: sqlite3_bind_zeroblob64 STMT IDX N
+**
+** Test the sqlite3_bind_zeroblob64 interface. STMT is a prepared statement.
+** IDX is the index of a wildcard in the prepared statement. This command
+** binds a N-byte zero-filled BLOB to the wildcard.
+*/
+static int test_bind_zeroblob64(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3_stmt *pStmt;
+ int idx;
+ i64 n;
+ int rc;
+
+ if( objc!=4 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
+ return TCL_ERROR;
+ }
+
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
+ if( Tcl_GetWideIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;
+
+ rc = sqlite3_bind_zeroblob64(pStmt, idx, n);
+ if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
+ if( rc!=SQLITE_OK ){
+ Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
+ return TCL_ERROR;
+ }
+
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_bind_int STMT N VALUE
**
** Test the sqlite3_bind_int interface. STMT is a prepared statement.
@@ -6796,6 +6833,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_connection_pointer", get_sqlite_pointer, 0 },
{ "sqlite3_bind_int", test_bind_int, 0 },
{ "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 },
+ { "sqlite3_bind_zeroblob64", test_bind_zeroblob64, 0 },
{ "sqlite3_bind_int64", test_bind_int64, 0 },
{ "sqlite3_bind_double", test_bind_double, 0 },
{ "sqlite3_bind_null", test_bind_null ,0 },
diff --git a/src/test_malloc.c b/src/test_malloc.c
index 94a228292..3ab177dcb 100644
--- a/src/test_malloc.c
+++ b/src/test_malloc.c
@@ -938,8 +938,8 @@ static int test_config_pagecache(
int objc,
Tcl_Obj *CONST objv[]
){
- int sz, N, rc;
- Tcl_Obj *pResult;
+ int sz, N;
+ Tcl_Obj *pRes;
static char *buf = 0;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "SIZE N");
@@ -948,17 +948,20 @@ static int test_config_pagecache(
if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR;
free(buf);
+ buf = 0;
+
+ /* Set the return value */
+ pRes = Tcl_NewObj();
+ Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(sqlite3GlobalConfig.szPage));
+ Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(sqlite3GlobalConfig.nPage));
+ Tcl_SetObjResult(interp, pRes);
+
if( sz<0 ){
- buf = 0;
- rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0);
+ sqlite3_config(SQLITE_CONFIG_PAGECACHE, 0, 0, 0);
}else{
buf = malloc( sz*N );
- rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
+ sqlite3_config(SQLITE_CONFIG_PAGECACHE, buf, sz, N);
}
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N));
- Tcl_SetObjResult(interp, pResult);
return TCL_OK;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index 0fbe96e42..3a960ccf5 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2712,7 +2712,7 @@ case OP_MakeRecord: {
len = sqlite3VdbeSerialTypeLen(serial_type);
if( pRec->flags & MEM_Zero ){
if( nData ){
- sqlite3VdbeMemExpandBlob(pRec);
+ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
}else{
nZero += pRec->u.nZero;
len -= pRec->u.nZero;
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index a35225732..2c75bbf2a 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -162,7 +162,10 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
- sqlite3VdbeMemExpandBlob(p);
+ if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){
+ assert( p->flags==MEM_Null && p->z==0 );
+ return 0;
+ }
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
@@ -424,6 +427,15 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
+int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
+ Mem *pOut = pCtx->pOut;
+ assert( sqlite3_mutex_held(pOut->db->mutex) );
+ if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ return SQLITE_TOOBIG;
+ }
+ sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
+ return SQLITE_OK;
+}
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
@@ -1403,6 +1415,20 @@ int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
}
return rc;
}
+int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ sqlite3_mutex_enter(p->db->mutex);
+ if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ rc = SQLITE_TOOBIG;
+ }else{
+ assert( (n & 0x7FFFFFFF)==n );
+ rc = sqlite3_bind_zeroblob(pStmt, i, n);
+ }
+ rc = sqlite3ApiExit(p->db, rc);
+ sqlite3_mutex_leave(p->db->mutex);
+ return rc;
+}
/*
** Return the number of wildcards that can be potentially bound to.