Index: third_party/sqlite/src/src/test1.c |
diff --git a/third_party/sqlite/src/src/test1.c b/third_party/sqlite/src/src/test1.c |
index 85a16488ba850f82143dfd67f54a2eb673ac8db2..c5e71582bcd5a5a21f9f0982e83c465b04f21692 100644 |
--- a/third_party/sqlite/src/src/test1.c |
+++ b/third_party/sqlite/src/src/test1.c |
@@ -94,10 +94,7 @@ static int get_sqlite_pointer( |
return TCL_ERROR; |
} |
p = (struct SqliteDb*)cmdInfo.objClientData; |
- sprintf(zBuf, "%p", p->db); |
- if( strncmp(zBuf,"0x",2) ){ |
- sprintf(zBuf, "0x%p", p->db); |
- } |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p->db); |
Tcl_AppendResult(interp, zBuf, 0); |
return TCL_OK; |
} |
@@ -145,7 +142,8 @@ int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ |
&& sqlite3_errcode(db)!=rc ){ |
char zBuf[200]; |
int r2 = sqlite3_errcode(db); |
- sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, |
+ "error code %s (%d) does not match sqlite3_errcode %s (%d)", |
t1ErrorName(rc), rc, t1ErrorName(r2), r2); |
Tcl_ResetResult(interp); |
Tcl_AppendResult(interp, zBuf, 0); |
@@ -261,6 +259,8 @@ static int test_io_trace( |
** |
** Returns true if the program was compiled using clang with the |
** -fsanitize=address switch on the command line. False otherwise. |
+** |
+** Also return true if the OMIT_MISUSE environment variable exists. |
*/ |
static int clang_sanitize_address( |
void *NotUsed, |
@@ -274,6 +274,10 @@ static int clang_sanitize_address( |
res = 1; |
# endif |
#endif |
+#ifdef __SANITIZE_ADDRESS__ |
+ res = 1; |
+#endif |
+ if( res==0 && getenv("OMIT_MISUSE")!=0 ) res = 1; |
Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); |
return TCL_OK; |
} |
@@ -307,7 +311,7 @@ static int test_exec_printf( |
zSql = sqlite3_mprintf(argv[2], argv[3]); |
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); |
sqlite3_free(zSql); |
- sprintf(zBuf, "%d", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); |
Tcl_AppendElement(interp, zBuf); |
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); |
Tcl_DStringFree(&str); |
@@ -334,7 +338,7 @@ static int test_exec_hex( |
int rc, i, j; |
char *zErr = 0; |
char *zHex; |
- char zSql[500]; |
+ char zSql[501]; |
char zBuf[30]; |
if( argc!=3 ){ |
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
@@ -343,7 +347,7 @@ static int test_exec_hex( |
} |
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; |
zHex = argv[2]; |
- for(i=j=0; i<sizeof(zSql) && zHex[j]; i++, j++){ |
+ for(i=j=0; i<(sizeof(zSql)-1) && zHex[j]; i++, j++){ |
if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){ |
zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]); |
j += 2; |
@@ -354,7 +358,7 @@ static int test_exec_hex( |
zSql[i] = 0; |
Tcl_DStringInit(&str); |
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); |
- sprintf(zBuf, "%d", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); |
Tcl_AppendElement(interp, zBuf); |
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); |
Tcl_DStringFree(&str); |
@@ -439,7 +443,7 @@ static int test_exec( |
zSql[j] = 0; |
rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); |
sqlite3_free(zSql); |
- sprintf(zBuf, "%d", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); |
Tcl_AppendElement(interp, zBuf); |
Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); |
Tcl_DStringFree(&str); |
@@ -564,7 +568,7 @@ static int test_get_table_printf( |
Tcl_DString str; |
int rc; |
char *zErr = 0; |
- int nRow, nCol; |
+ int nRow = 0, nCol = 0; |
char **aResult; |
int i; |
char zBuf[30]; |
@@ -588,13 +592,13 @@ static int test_get_table_printf( |
resCount = (nRow+1)*nCol; |
} |
sqlite3_free(zSql); |
- sprintf(zBuf, "%d", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc); |
Tcl_AppendElement(interp, zBuf); |
if( rc==SQLITE_OK ){ |
if( argc==4 ){ |
- sprintf(zBuf, "%d", nRow); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nRow); |
Tcl_AppendElement(interp, zBuf); |
- sprintf(zBuf, "%d", nCol); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nCol); |
Tcl_AppendElement(interp, zBuf); |
} |
for(i=0; i<resCount; i++){ |
@@ -631,7 +635,7 @@ static int test_last_rowid( |
return TCL_ERROR; |
} |
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; |
- sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", sqlite3_last_insert_rowid(db)); |
Tcl_AppendResult(interp, zBuf, 0); |
return SQLITE_OK; |
} |
@@ -771,7 +775,7 @@ static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){ |
char zBuf[200]; |
z = sqlite3_value_text(argv[0]); |
for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){ |
- sprintf(&zBuf[i*2], "%02x", z[i]&0xff); |
+ sqlite3_snprintf(sizeof(zBuf)-i*2, &zBuf[i*2], "%02x", z[i]); |
} |
zBuf[i*2] = 0; |
sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); |
@@ -783,7 +787,7 @@ static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){ |
char zBuf[400]; |
z = sqlite3_value_text16(argv[0]); |
for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){ |
- sprintf(&zBuf[i*4], "%04x", z[i]&0xff); |
+ sqlite3_snprintf(sizeof(zBuf)-i*4, &zBuf[i*4],"%04x", z[i]&0xff); |
} |
zBuf[i*4] = 0; |
sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); |
@@ -1569,7 +1573,6 @@ static int test_libversion_number( |
** Usage: sqlite3_table_column_metadata DB dbname tblname colname |
** |
*/ |
-#ifdef SQLITE_ENABLE_COLUMN_METADATA |
static int test_table_column_metadata( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
@@ -1589,14 +1592,14 @@ static int test_table_column_metadata( |
int primarykey; |
int autoincrement; |
- if( objc!=5 ){ |
+ if( objc!=5 && objc!=4 ){ |
Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname"); |
return TCL_ERROR; |
} |
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
zDb = Tcl_GetString(objv[2]); |
zTbl = Tcl_GetString(objv[3]); |
- zCol = Tcl_GetString(objv[4]); |
+ zCol = objc==5 ? Tcl_GetString(objv[4]) : 0; |
if( strlen(zDb)==0 ) zDb = 0; |
@@ -1618,7 +1621,6 @@ static int test_table_column_metadata( |
return TCL_OK; |
} |
-#endif |
#ifndef SQLITE_OMIT_INCRBLOB |
@@ -1651,154 +1653,6 @@ static int blobHandleFromObj( |
return TCL_OK; |
} |
-/* |
-** sqlite3_blob_bytes CHANNEL |
-*/ |
-static int test_blob_bytes( |
- ClientData clientData, /* Not used */ |
- Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
- int objc, /* Number of arguments */ |
- Tcl_Obj *CONST objv[] /* Command arguments */ |
-){ |
- sqlite3_blob *pBlob; |
- int nByte; |
- |
- if( objc!=2 ){ |
- Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
- return TCL_ERROR; |
- } |
- |
- if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; |
- nByte = sqlite3_blob_bytes(pBlob); |
- Tcl_SetObjResult(interp, Tcl_NewIntObj(nByte)); |
- |
- return TCL_OK; |
-} |
- |
-/* |
-** sqlite3_blob_close CHANNEL |
-*/ |
-static int test_blob_close( |
- ClientData clientData, /* Not used */ |
- Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
- int objc, /* Number of arguments */ |
- Tcl_Obj *CONST objv[] /* Command arguments */ |
-){ |
- sqlite3_blob *pBlob; |
- |
- if( objc!=2 ){ |
- Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
- return TCL_ERROR; |
- } |
- |
- if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; |
- sqlite3_blob_close(pBlob); |
- |
- return TCL_OK; |
-} |
- |
-/* |
-** sqlite3_blob_read CHANNEL OFFSET N |
-** |
-** This command is used to test the sqlite3_blob_read() in ways that |
-** the Tcl channel interface does not. The first argument should |
-** be the name of a valid channel created by the [incrblob] method |
-** of a database handle. This function calls sqlite3_blob_read() |
-** to read N bytes from offset OFFSET from the underlying SQLite |
-** blob handle. |
-** |
-** On success, a byte-array object containing the read data is |
-** returned. On failure, the interpreter result is set to the |
-** text representation of the returned error code (i.e. "SQLITE_NOMEM") |
-** and a Tcl exception is thrown. |
-*/ |
-static int test_blob_read( |
- ClientData clientData, /* Not used */ |
- Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
- int objc, /* Number of arguments */ |
- Tcl_Obj *CONST objv[] /* Command arguments */ |
-){ |
- sqlite3_blob *pBlob; |
- int nByte; |
- int iOffset; |
- unsigned char *zBuf = 0; |
- int rc; |
- |
- if( objc!=4 ){ |
- Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N"); |
- return TCL_ERROR; |
- } |
- |
- if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; |
- if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) |
- || TCL_OK!=Tcl_GetIntFromObj(interp, objv[3], &nByte) |
- ){ |
- return TCL_ERROR; |
- } |
- |
- if( nByte>0 ){ |
- zBuf = (unsigned char *)Tcl_Alloc(nByte); |
- } |
- rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); |
- if( rc==SQLITE_OK ){ |
- Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zBuf, nByte)); |
- }else{ |
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); |
- } |
- Tcl_Free((char *)zBuf); |
- |
- return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
-} |
- |
-/* |
-** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA? |
-** |
-** This command is used to test the sqlite3_blob_write() in ways that |
-** the Tcl channel interface does not. The first argument should |
-** be the name of a valid channel created by the [incrblob] method |
-** of a database handle. This function calls sqlite3_blob_write() |
-** to write the DATA byte-array to the underlying SQLite blob handle. |
-** at offset OFFSET. |
-** |
-** On success, an empty string is returned. On failure, the interpreter |
-** result is set to the text representation of the returned error code |
-** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown. |
-*/ |
-static int test_blob_write( |
- ClientData clientData, /* Not used */ |
- Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
- int objc, /* Number of arguments */ |
- Tcl_Obj *CONST objv[] /* Command arguments */ |
-){ |
- sqlite3_blob *pBlob; |
- int iOffset; |
- int rc; |
- |
- unsigned char *zBuf; |
- int nBuf; |
- |
- if( objc!=4 && objc!=5 ){ |
- Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?"); |
- return TCL_ERROR; |
- } |
- |
- if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR; |
- if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ |
- return TCL_ERROR; |
- } |
- |
- zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); |
- if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ |
- return TCL_ERROR; |
- } |
- rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); |
- if( rc!=SQLITE_OK ){ |
- Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); |
- } |
- |
- return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
-} |
- |
static int test_blob_reopen( |
ClientData clientData, /* Not used */ |
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
@@ -2267,7 +2121,7 @@ static int test_stmt_status( |
Tcl_Obj *CONST objv[] |
){ |
int iValue; |
- int i, op, resetFlag; |
+ int i, op = 0, resetFlag; |
const char *zOpName; |
sqlite3_stmt *pStmt; |
@@ -2301,6 +2155,208 @@ static int test_stmt_status( |
return TCL_OK; |
} |
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
+/* |
+** Usage: sqlite3_stmt_scanstatus STMT IDX |
+*/ |
+static int test_stmt_scanstatus( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ sqlite3_stmt *pStmt; /* First argument */ |
+ int idx; /* Second argument */ |
+ |
+ const char *zName; |
+ const char *zExplain; |
+ sqlite3_int64 nLoop; |
+ sqlite3_int64 nVisit; |
+ double rEst; |
+ int res; |
+ |
+ if( objc!=3 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX"); |
+ return TCL_ERROR; |
+ } |
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; |
+ if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; |
+ |
+ res = sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop); |
+ if( res==0 ){ |
+ Tcl_Obj *pRet = Tcl_NewObj(); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nLoop", -1)); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nLoop)); |
+ sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nVisit", -1)); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nVisit)); |
+ sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EST, (void*)&rEst); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nEst", -1)); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewDoubleObj(rEst)); |
+ sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NAME, (void*)&zName); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zName", -1)); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zName, -1)); |
+ sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zExplain", -1)); |
+ Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zExplain, -1)); |
+ Tcl_SetObjResult(interp, pRet); |
+ }else{ |
+ Tcl_ResetResult(interp); |
+ } |
+ return TCL_OK; |
+} |
+ |
+/* |
+** Usage: sqlite3_stmt_scanstatus_reset STMT |
+*/ |
+static int test_stmt_scanstatus_reset( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ sqlite3_stmt *pStmt; /* First argument */ |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "STMT"); |
+ return TCL_ERROR; |
+ } |
+ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; |
+ sqlite3_stmt_scanstatus_reset(pStmt); |
+ return TCL_OK; |
+} |
+#endif |
+ |
+#ifdef SQLITE_ENABLE_SQLLOG |
+/* |
+** Usage: sqlite3_config_sqllog |
+** |
+** Zero the SQLITE_CONFIG_SQLLOG configuration |
+*/ |
+static int test_config_sqllog( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ if( objc!=1 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, ""); |
+ return TCL_ERROR; |
+ } |
+ sqlite3_config(SQLITE_CONFIG_SQLLOG, 0, 0); |
+ return TCL_OK; |
+} |
+#endif |
+ |
+/* |
+** Usage: vfs_current_time_int64 |
+** |
+** Return the value returned by the default VFS's xCurrentTimeInt64 method. |
+*/ |
+static int vfsCurrentTimeInt64( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ i64 t; |
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(0); |
+ if( objc!=1 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, ""); |
+ return TCL_ERROR; |
+ } |
+ pVfs->xCurrentTimeInt64(pVfs, &t); |
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(t)); |
+ return TCL_OK; |
+} |
+ |
+#ifdef SQLITE_ENABLE_SNAPSHOT |
+/* |
+** Usage: sqlite3_snapshot_get DB DBNAME |
+*/ |
+static int test_snapshot_get( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ int rc; |
+ sqlite3 *db; |
+ char *zName; |
+ sqlite3_snapshot *pSnapshot = 0; |
+ |
+ if( objc!=3 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME"); |
+ return TCL_ERROR; |
+ } |
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
+ zName = Tcl_GetString(objv[2]); |
+ |
+ rc = sqlite3_snapshot_get(db, zName, &pSnapshot); |
+ if( rc!=SQLITE_OK ){ |
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); |
+ return TCL_ERROR; |
+ }else{ |
+ char zBuf[100]; |
+ if( sqlite3TestMakePointerStr(interp, zBuf, pSnapshot) ) return TCL_ERROR; |
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(zBuf, -1)); |
+ } |
+ return TCL_OK; |
+} |
+#endif /* SQLITE_ENABLE_SNAPSHOT */ |
+ |
+#ifdef SQLITE_ENABLE_SNAPSHOT |
+/* |
+** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT |
+*/ |
+static int test_snapshot_open( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ int rc; |
+ sqlite3 *db; |
+ char *zName; |
+ sqlite3_snapshot *pSnapshot; |
+ |
+ if( objc!=4 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT"); |
+ return TCL_ERROR; |
+ } |
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
+ zName = Tcl_GetString(objv[2]); |
+ pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[3])); |
+ |
+ rc = sqlite3_snapshot_open(db, zName, pSnapshot); |
+ if( rc!=SQLITE_OK ){ |
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); |
+ return TCL_ERROR; |
+ } |
+ return TCL_OK; |
+} |
+#endif /* SQLITE_ENABLE_SNAPSHOT */ |
+ |
+#ifdef SQLITE_ENABLE_SNAPSHOT |
+/* |
+** Usage: sqlite3_snapshot_free SNAPSHOT |
+*/ |
+static int test_snapshot_free( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ sqlite3_snapshot *pSnapshot; |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT"); |
+ return TCL_ERROR; |
+ } |
+ pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); |
+ sqlite3_snapshot_free(pSnapshot); |
+ return TCL_OK; |
+} |
+#endif /* SQLITE_ENABLE_SNAPSHOT */ |
+ |
/* |
** Usage: sqlite3_next_stmt DB STMT |
** |
@@ -2573,7 +2629,7 @@ static int test_bind( |
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; |
if( rc ){ |
char zBuf[50]; |
- sprintf(zBuf, "(%d) ", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc); |
Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); |
return TCL_ERROR; |
} |
@@ -3084,6 +3140,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. |
@@ -3174,7 +3267,7 @@ static int test_bind_double( |
){ |
sqlite3_stmt *pStmt; |
int idx; |
- double value; |
+ double value = 0; |
int rc; |
const char *zVal; |
int i; |
@@ -3687,7 +3780,7 @@ static int test_prepare( |
} |
if( rc!=SQLITE_OK ){ |
assert( pStmt==0 ); |
- sprintf(zBuf, "(%d) ", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc); |
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); |
return TCL_ERROR; |
} |
@@ -3715,6 +3808,7 @@ static int test_prepare_v2( |
){ |
sqlite3 *db; |
const char *zSql; |
+ char *zCopy = 0; /* malloc() copy of zSql */ |
int bytes; |
const char *zTail = 0; |
sqlite3_stmt *pStmt = 0; |
@@ -3730,11 +3824,25 @@ static int test_prepare_v2( |
zSql = Tcl_GetString(objv[2]); |
if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; |
- rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0); |
+ /* Instead of using zSql directly, make a copy into a buffer obtained |
+ ** directly from malloc(). The idea is to make it easier for valgrind |
+ ** to spot buffer overreads. */ |
+ if( bytes>=0 ){ |
+ zCopy = malloc(bytes); |
+ memcpy(zCopy, zSql, bytes); |
+ }else{ |
+ int n = (int)strlen(zSql) + 1; |
+ zCopy = malloc(n); |
+ memcpy(zCopy, zSql, n); |
+ } |
+ rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0); |
+ free(zCopy); |
+ zTail = &zSql[(zTail - zCopy)]; |
+ |
assert(rc==SQLITE_OK || pStmt==0); |
Tcl_ResetResult(interp); |
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; |
- if( zTail && objc>=5 ){ |
+ if( rc==SQLITE_OK && zTail && objc>=5 ){ |
if( bytes>=0 ){ |
bytes = bytes - (int)(zTail-zSql); |
} |
@@ -3742,7 +3850,7 @@ static int test_prepare_v2( |
} |
if( rc!=SQLITE_OK ){ |
assert( pStmt==0 ); |
- sprintf(zBuf, "(%d) ", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc); |
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); |
return TCL_ERROR; |
} |
@@ -3783,7 +3891,7 @@ static int test_prepare_tkt3134( |
if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; |
if( rc!=SQLITE_OK ){ |
assert( pStmt==0 ); |
- sprintf(zBuf, "(%d) ", rc); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc); |
Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); |
return TCL_ERROR; |
} |
@@ -4598,7 +4706,7 @@ static int get_autocommit( |
return TCL_ERROR; |
} |
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; |
- sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); |
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3_get_autocommit(db)); |
Tcl_AppendResult(interp, zBuf, 0); |
return TCL_OK; |
} |
@@ -4712,6 +4820,34 @@ static int test_db_release_memory( |
} |
/* |
+** Usage: sqlite3_db_cacheflush DB |
+** |
+** Attempt to flush any dirty pages to disk. |
+*/ |
+static int test_db_cacheflush( |
+ void * clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+ sqlite3 *db; |
+ int rc; |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
+ return TCL_ERROR; |
+ } |
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; |
+ rc = sqlite3_db_cacheflush(db); |
+ if( rc ){ |
+ Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC); |
+ return TCL_ERROR; |
+ } |
+ |
+ Tcl_ResetResult(interp); |
+ return TCL_OK; |
+} |
+ |
+/* |
** Usage: sqlite3_db_filename DB DBNAME |
** |
** Return the name of a file associated with a database. |
@@ -5234,7 +5370,7 @@ static int file_control_lockproxy_test( |
Tcl_AppendResult(interp, "PWD too big", (void*)0); |
return TCL_ERROR; |
} |
- sprintf(proxyPath, "%s/test.proxy", zPwd); |
+ sqlite3_snprintf(sizeof(proxyPath), proxyPath, "%s/test.proxy", zPwd); |
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); |
if( rc ){ |
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); |
@@ -5519,7 +5655,7 @@ static int test_limit( |
{ "SQLITE_LIMIT_TOOSMALL", -1, }, |
{ "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS+1 }, |
}; |
- int i, id; |
+ int i, id = 0; |
int val; |
const char *zId; |
@@ -5752,10 +5888,11 @@ static int test_wal_checkpoint_v2( |
int nCkpt = -555; |
Tcl_Obj *pRet; |
- const char * aMode[] = { "passive", "full", "restart", 0 }; |
+ const char * aMode[] = { "passive", "full", "restart", "truncate", 0 }; |
assert( SQLITE_CHECKPOINT_PASSIVE==0 ); |
assert( SQLITE_CHECKPOINT_FULL==1 ); |
assert( SQLITE_CHECKPOINT_RESTART==2 ); |
+ assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); |
if( objc!=3 && objc!=4 ){ |
Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?"); |
@@ -5765,15 +5902,18 @@ static int test_wal_checkpoint_v2( |
if( objc==4 ){ |
zDb = Tcl_GetString(objv[3]); |
} |
- if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) |
- || Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode) |
- ){ |
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) || ( |
+ TCL_OK!=Tcl_GetIntFromObj(0, objv[2], &eMode) |
+ && TCL_OK!=Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode) |
+ )){ |
return TCL_ERROR; |
} |
rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt); |
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
- Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); |
+ const char *zErrCode = sqlite3ErrName(rc); |
+ Tcl_ResetResult(interp); |
+ Tcl_AppendResult(interp, zErrCode, " - ", (char *)sqlite3_errmsg(db), 0); |
return TCL_ERROR; |
} |
@@ -5787,6 +5927,43 @@ static int test_wal_checkpoint_v2( |
} |
/* |
+** tclcmd: sqlite3_wal_autocheckpoint db VALUE |
+*/ |
+static int test_wal_autocheckpoint( |
+ ClientData clientData, /* Unused */ |
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
+ int objc, /* Number of arguments */ |
+ Tcl_Obj *CONST objv[] /* Command arguments */ |
+){ |
+ sqlite3 *db; |
+ int rc; |
+ int iVal; |
+ |
+ |
+ if( objc!=3 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE"); |
+ return TCL_ERROR; |
+ } |
+ |
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) |
+ || Tcl_GetIntFromObj(0, objv[2], &iVal) |
+ ){ |
+ return TCL_ERROR; |
+ } |
+ |
+ rc = sqlite3_wal_autocheckpoint(db, iVal); |
+ Tcl_ResetResult(interp); |
+ if( rc!=SQLITE_OK ){ |
+ const char *zErrCode = sqlite3ErrName(rc); |
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1)); |
+ return TCL_ERROR; |
+ } |
+ |
+ return TCL_OK; |
+} |
+ |
+ |
+/* |
** tclcmd: test_sqlite3_log ?SCRIPT? |
*/ |
static struct LogCallback { |
@@ -5817,13 +5994,13 @@ static int test_sqlite3_log( |
Tcl_DecrRefCount(logcallback.pObj); |
logcallback.pObj = 0; |
logcallback.pInterp = 0; |
- sqlite3_config(SQLITE_CONFIG_LOG, 0, 0); |
+ sqlite3_config(SQLITE_CONFIG_LOG, (void*)0, (void*)0); |
} |
if( objc>1 ){ |
logcallback.pObj = objv[1]; |
Tcl_IncrRefCount(logcallback.pObj); |
logcallback.pInterp = interp; |
- sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, 0); |
+ sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, (void*)0); |
} |
return TCL_OK; |
} |
@@ -5936,7 +6113,8 @@ static int test_test_control( |
int i; |
} aVerb[] = { |
{ "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, |
- { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, |
+ { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, |
+ { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, |
}; |
int iVerb; |
int iFlag; |
@@ -5977,6 +6155,22 @@ static int test_test_control( |
sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val); |
break; |
} |
+ |
+ case SQLITE_TESTCTRL_IMPOSTER: { |
+ int onOff, tnum; |
+ const char *zDbName; |
+ sqlite3 *db; |
+ if( objc!=6 ){ |
+ Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum"); |
+ return TCL_ERROR; |
+ } |
+ if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; |
+ zDbName = Tcl_GetString(objv[3]); |
+ if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR; |
+ if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR; |
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum); |
+ break; |
+ } |
} |
Tcl_ResetResult(interp); |
@@ -5998,7 +6192,8 @@ static int test_getrusage( |
memset(&r, 0, sizeof(r)); |
getrusage(RUSAGE_SELF, &r); |
- sprintf(buf, "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d", |
+ sqlite3_snprintf(sizeof(buf), buf, |
+ "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d", |
(int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec, |
(int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec, |
(int)r.ru_minflt, (int)r.ru_majflt |
@@ -6293,7 +6488,8 @@ static int optimization_control( |
{ "transitive", SQLITE_Transitive }, |
{ "subquery-coroutine", SQLITE_SubqCoroutine }, |
{ "omit-noop-join", SQLITE_OmitNoopJoin }, |
- { "stat3", SQLITE_Stat3 }, |
+ { "stat3", SQLITE_Stat34 }, |
+ { "stat4", SQLITE_Stat34 }, |
}; |
if( objc!=4 ){ |
@@ -6336,12 +6532,14 @@ static int tclLoadStaticExtensionCmd( |
){ |
extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*); |
+ extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*); |
+ extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*); |
extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*); |
@@ -6351,12 +6549,14 @@ static int tclLoadStaticExtensionCmd( |
} aExtension[] = { |
{ "amatch", sqlite3_amatch_init }, |
{ "closure", sqlite3_closure_init }, |
+ { "eval", sqlite3_eval_init }, |
{ "fileio", sqlite3_fileio_init }, |
{ "fuzzer", sqlite3_fuzzer_init }, |
{ "ieee754", sqlite3_ieee_init }, |
{ "nextchar", sqlite3_nextchar_init }, |
{ "percentile", sqlite3_percentile_init }, |
{ "regexp", sqlite3_regexp_init }, |
+ { "series", sqlite3_series_init }, |
{ "spellfix", sqlite3_spellfix_init }, |
{ "totype", sqlite3_totype_init }, |
{ "wholenumber", sqlite3_wholenumber_init }, |
@@ -6379,7 +6579,11 @@ static int tclLoadStaticExtensionCmd( |
Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0); |
return TCL_ERROR; |
} |
- rc = aExtension[i].pInit(db, &zErrMsg, 0); |
+ if( aExtension[i].pInit ){ |
+ rc = aExtension[i].pInit(db, &zErrMsg, 0); |
+ }else{ |
+ rc = SQLITE_OK; |
+ } |
if( rc!=SQLITE_OK || zErrMsg ){ |
Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg, |
(char*)0); |
@@ -6625,6 +6829,98 @@ static int test_user_delete( |
#endif /* SQLITE_USER_AUTHENTICATION */ |
/* |
+** tclcmd: bad_behavior TYPE |
+** |
+** Do some things that should trigger a valgrind or -fsanitize=undefined |
+** warning. This is used to verify that errors and warnings output by those |
+** tools are detected by the test scripts. |
+** |
+** TYPE BEHAVIOR |
+** 1 Overflow a signed integer |
+** 2 Jump based on an uninitialized variable |
+** 3 Read after free |
+** 4 Panic |
+*/ |
+static int test_bad_behavior( |
+ ClientData clientData, /* Pointer to an integer containing zero */ |
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ |
+ int objc, /* Number of arguments */ |
+ Tcl_Obj *CONST objv[] /* Command arguments */ |
+){ |
+ int iType; |
+ int xyz; |
+ int i = *(int*)clientData; |
+ int j; |
+ int w[10]; |
+ int *a; |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "TYPE"); |
+ return TCL_ERROR; |
+ } |
+ if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR; |
+ switch( iType ){ |
+ case 1: { |
+ xyz = 0x7fffff00 - i; |
+ xyz += 0x100; |
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz)); |
+ break; |
+ } |
+ case 2: { |
+ w[1] = 5; |
+ if( w[i]>0 ) w[1]++; |
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1])); |
+ break; |
+ } |
+ case 3: { |
+ a = malloc( sizeof(int)*10 ); |
+ for(j=0; j<10; j++) a[j] = j; |
+ free(a); |
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i])); |
+ break; |
+ } |
+ case 4: { |
+ Tcl_Panic("Deliberate panic"); |
+ break; |
+ } |
+ } |
+ return TCL_OK; |
+} |
+ |
+/* |
+** tclcmd: register_dbstat_vtab DB |
+** |
+** Cause the dbstat virtual table to be available on the connection DB |
+*/ |
+static int test_register_dbstat_vtab( |
+ void *clientData, |
+ Tcl_Interp *interp, |
+ int objc, |
+ Tcl_Obj *CONST objv[] |
+){ |
+#ifdef SQLITE_OMIT_VIRTUALTABLE |
+ Tcl_AppendResult(interp, "dbstat not available because of " |
+ "SQLITE_OMIT_VIRTUALTABLE", (void*)0); |
+ return TCL_ERROR; |
+#else |
+ struct SqliteDb { sqlite3 *db; }; |
+ char *zDb; |
+ Tcl_CmdInfo cmdInfo; |
+ |
+ if( objc!=2 ){ |
+ Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
+ return TCL_ERROR; |
+ } |
+ |
+ zDb = Tcl_GetString(objv[1]); |
+ if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ |
+ sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db; |
+ sqlite3DbstatRegister(db); |
+ } |
+ return TCL_OK; |
+#endif /* SQLITE_OMIT_VIRTUALTABLE */ |
+} |
+ |
+/* |
** Register commands with the TCL interpreter. |
*/ |
int Sqlitetest1_Init(Tcl_Interp *interp){ |
@@ -6640,6 +6936,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
extern int sqlite3_max_blobsize; |
extern int sqlite3BtreeSharedCacheReport(void*, |
Tcl_Interp*,int,Tcl_Obj*CONST*); |
+ static int iZero = 0; |
static struct { |
char *zName; |
Tcl_CmdProc *xProc; |
@@ -6692,9 +6989,12 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
Tcl_ObjCmdProc *xProc; |
void *clientData; |
} aObjCmd[] = { |
+ { "bad_behavior", test_bad_behavior, (void*)&iZero }, |
+ { "register_dbstat_vtab", test_register_dbstat_vtab }, |
{ "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 }, |
@@ -6735,6 +7035,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
{ "sqlite3_release_memory", test_release_memory, 0}, |
{ "sqlite3_db_release_memory", test_db_release_memory, 0}, |
+ { "sqlite3_db_cacheflush", test_db_cacheflush, 0}, |
{ "sqlite3_db_filename", test_db_filename, 0}, |
{ "sqlite3_db_readonly", test_db_readonly, 0}, |
{ "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, |
@@ -6834,15 +7135,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
{ "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, |
#endif |
{ "sqlite3_libversion_number", test_libversion_number, 0 }, |
-#ifdef SQLITE_ENABLE_COLUMN_METADATA |
{ "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, |
-#endif |
#ifndef SQLITE_OMIT_INCRBLOB |
- { "sqlite3_blob_read", test_blob_read, 0 }, |
- { "sqlite3_blob_write", test_blob_write, 0 }, |
{ "sqlite3_blob_reopen", test_blob_reopen, 0 }, |
- { "sqlite3_blob_bytes", test_blob_bytes, 0 }, |
- { "sqlite3_blob_close", test_blob_close, 0 }, |
#endif |
{ "pcache_stats", test_pcache_stats, 0 }, |
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
@@ -6850,6 +7145,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
#endif |
{ "sqlite3_wal_checkpoint", test_wal_checkpoint, 0 }, |
{ "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0 }, |
+ { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0 }, |
{ "test_sqlite3_log", test_sqlite3_log, 0 }, |
#ifndef SQLITE_OMIT_EXPLAIN |
{ "print_explain_query_plan", test_print_eqp, 0 }, |
@@ -6867,9 +7163,22 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
{ "sqlite3_user_change", test_user_change, 0 }, |
{ "sqlite3_user_delete", test_user_delete, 0 }, |
#endif |
- |
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
+ { "sqlite3_stmt_scanstatus", test_stmt_scanstatus, 0 }, |
+ { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset, 0 }, |
+#endif |
+#ifdef SQLITE_ENABLE_SQLLOG |
+ { "sqlite3_config_sqllog", test_config_sqllog, 0 }, |
+#endif |
+ { "vfs_current_time_int64", vfsCurrentTimeInt64, 0 }, |
+#ifdef SQLITE_ENABLE_SNAPSHOT |
+ { "sqlite3_snapshot_get", test_snapshot_get, 0 }, |
+ { "sqlite3_snapshot_open", test_snapshot_open, 0 }, |
+ { "sqlite3_snapshot_free", test_snapshot_free, 0 }, |
+#endif |
}; |
static int bitmask_size = sizeof(Bitmask)*8; |
+ static int longdouble_size = sizeof(LONGDOUBLE_TYPE); |
int i; |
extern int sqlite3_sync_count, sqlite3_fullsync_count; |
extern int sqlite3_opentemp_count; |
@@ -6970,6 +7279,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ |
(char*)&sqlite3_data_directory, TCL_LINK_STRING); |
Tcl_LinkVar(interp, "bitmask_size", |
(char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); |
+ Tcl_LinkVar(interp, "longdouble_size", |
+ (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); |
Tcl_LinkVar(interp, "sqlite_sync_count", |
(char*)&sqlite3_sync_count, TCL_LINK_INT); |
Tcl_LinkVar(interp, "sqlite_fullsync_count", |