diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/func.c | 12 | ||||
-rw-r--r-- | src/loadext.c | 4 | ||||
-rw-r--r-- | src/sqlite.h.in | 6 | ||||
-rw-r--r-- | src/sqlite3ext.h | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 12 | ||||
-rw-r--r-- | src/test1.c | 38 | ||||
-rw-r--r-- | src/test_malloc.c | 21 | ||||
-rw-r--r-- | src/vdbe.c | 2 | ||||
-rw-r--r-- | src/vdbeapi.c | 28 |
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. |