"Usage: %s [--options] DATABASE\n"
"Options:\n"
" --autovacuum Enable AUTOVACUUM mode\n"
+ " --big-transactions Add BEGIN/END around large tests which normally don't\n"
" --cachesize N Set the cache size to N\n"
" --checkpoint Run PRAGMA wal_checkpoint after each test case\n"
" --exclusive Enable locking_mode=EXCLUSIVE\n"
" --mmap SZ MMAP the first SZ bytes of the database file\n"
" --multithread Set multithreaded mode\n"
" --nomemstat Disable memory statistics\n"
+ " --nomutex Open db with SQLITE_OPEN_NOMUTEX\n"
" --nosync Set PRAGMA synchronous=OFF\n"
" --notnull Add NOT NULL constraints to table columns\n"
" --output FILE Store SQL output in FILE\n"
" --threads N Use up to N threads for sorting\n"
" --utf16be Set text encoding to UTF-16BE\n"
" --utf16le Set text encoding to UTF-16LE\n"
- " --verify Run additional verification steps.\n"
- " --vfs NAME Specify the VFS to use.\n"
+ " --verify Run additional verification steps\n"
+ " --vfs NAME Use the given (preinstalled) VFS\n"
" --without-rowid Use WITHOUT ROWID where appropriate\n"
;
int nRepeat; /* Repeat selects this many times */
int doCheckpoint; /* Run PRAGMA wal_checkpoint after each trans */
int nReserve; /* Reserve bytes */
+ int doBigTransactions; /* Enable transactions on tests 410 and 510 */
const char *zWR; /* Might be WITHOUT ROWID */
const char *zNN; /* Might be NOT NULL */
const char *zPK; /* Might be UNIQUE or PRIMARY KEY */
#define NAMEWIDTH 60
static const char zDots[] =
".......................................................................";
+static int iTestNumber = 0; /* Current test # for begin/end_test(). */
void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){
int n = (int)strlen(zTestName);
char *zName;
va_list ap;
+ iTestNumber = iTestNum;
va_start(ap, zTestName);
zName = sqlite3_vmprintf(zTestName, ap);
va_end(ap);
zName[NAMEWIDTH] = 0;
n = NAMEWIDTH;
}
+ if( g.pScript ){
+ fprintf(g.pScript,"-- begin test %d %.*s\n", iTestNumber, n, zName)
+ /* maintenance reminder: ^^^ code in ext/wasm expects %d to be
+ ** field #4 (as in: cut -d' ' -f4). */;
+ }
if( g.bSqlOnly ){
printf("/* %4d - %s%.*s */\n", iTestNum, zName, NAMEWIDTH-n, zDots);
}else{
void speedtest1_end_test(void){
sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart;
if( g.doCheckpoint ) speedtest1_exec("PRAGMA wal_checkpoint;");
+ assert( iTestNumber > 0 );
+ if( g.pScript ){
+ fprintf(g.pScript,"-- end test %d\n", iTestNumber);
+ }
if( !g.bSqlOnly ){
g.iTotal += iElapseTime;
printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000));
sqlite3_finalize(g.pStmt);
g.pStmt = 0;
}
+ iTestNumber = 0;
}
/* Report end of testing */
speedtest1_exec("COMMIT");
speedtest1_end_test();
speedtest1_begin_test(410, "%d SELECTS on an IPK", n);
+ if( g.doBigTransactions ){
+ /* Historical note: tests 410 and 510 have historically not used
+ ** explicit transactions. The --big-transactions flag was added
+ ** 2022-09-08 to support the WASM/OPFS build, as the run-times
+ ** approach 1 minute for each of these tests if they're not in an
+ ** explicit transaction. The run-time effect of --big-transaciions
+ ** on native builds is negligible. */
+ speedtest1_exec("BEGIN");
+ }
speedtest1_prepare("SELECT b FROM t5 WHERE a=?1; -- %d times",n);
for(i=1; i<=n; i++){
x1 = swizzle(i,maxb);
sqlite3_bind_int(g.pStmt, 1, (sqlite3_int64)x1);
speedtest1_run();
}
+ if( g.doBigTransactions ){
+ speedtest1_exec("COMMIT");
+ }
speedtest1_end_test();
sz = n = g.szTest*700;
speedtest1_exec("COMMIT");
speedtest1_end_test();
speedtest1_begin_test(510, "%d SELECTS on a TEXT PK", n);
+ if( g.doBigTransactions ){
+ /* See notes for test 410. */
+ speedtest1_exec("BEGIN");
+ }
speedtest1_prepare("SELECT b FROM t6 WHERE a=?1; -- %d times",n);
for(i=1; i<=n; i++){
x1 = swizzle(i,maxb);
sqlite3_bind_text(g.pStmt, 1, zNum, -1, SQLITE_STATIC);
speedtest1_run();
}
+ if( g.doBigTransactions ){
+ speedtest1_exec("COMMIT");
+ }
speedtest1_end_test();
speedtest1_begin_test(520, "%d SELECT DISTINCT", n);
speedtest1_exec("SELECT DISTINCT b FROM t5;");
printf("-- Compile option: %s\n", azVal[0]);
return SQLITE_OK;
}
-
int main(int argc, char **argv){
int doAutovac = 0; /* True for --autovacuum */
int cacheSize = 0; /* Desired cache size. 0 means default */
int nThread = 0; /* --threads value */
int mmapSize = 0; /* How big of a memory map to use */
int memDb = 0; /* --memdb. Use an in-memory database */
+ int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
+ ; /* SQLITE_OPEN_xxx flags. */
char *zTSet = "main"; /* Which --testset torun */
+ const char * zVfs = 0; /* --vfs NAME */
int doTrace = 0; /* True for --trace */
const char *zEncoding = 0; /* --utf16be or --utf16le */
const char *zDbName = 0; /* Name of the test database */
- const char *zVfs = 0; /* VFS to use. NULL means use the default */
void *pHeap = 0; /* Allocated heap space */
void *pLook = 0; /* Allocated lookaside space */
int i; /* Loop counter */
int rc; /* API return code */
+#ifdef SQLITE_SPEEDTEST1_WASM
+ /* Resetting all state is important for the WASM build, which may
+ ** call main() multiple times. */
+ memset(&g, 0, sizeof(g));
+ iTestNumber = 0;
+#endif
#ifdef SQLITE_CKSUMVFS_STATIC
sqlite3_register_cksumvfs(0);
#endif
-
+ /*
+ ** Confirms that argc has at least N arguments following argv[i]. */
+#define ARGC_VALUE_CHECK(N) \
+ if( i>=argc-(N) ) fatal_error("missing argument on %s\n", argv[i])
/* Display the version of SQLite being tested */
printf("-- Speedtest1 for SQLite %s %.48s\n",
sqlite3_libversion(), sqlite3_sourceid());
do{ z++; }while( z[0]=='-' );
if( strcmp(z,"autovacuum")==0 ){
doAutovac = 1;
+ }else if( strcmp(z,"big-transactions")==0 ){
+ g.doBigTransactions = 1;
}else if( strcmp(z,"cachesize")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
- i++;
- cacheSize = integerValue(argv[i]);
+ ARGC_VALUE_CHECK(1);
+ cacheSize = integerValue(argv[++i]);
}else if( strcmp(z,"exclusive")==0 ){
doExclusive = 1;
}else if( strcmp(z,"checkpoint")==0 ){
g.bSqlOnly = 1;
g.bExplain = 1;
}else if( strcmp(z,"heap")==0 ){
- if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(2);
nHeap = integerValue(argv[i+1]);
mnHeap = integerValue(argv[i+2]);
i += 2;
}else if( strcmp(z,"incrvacuum")==0 ){
doIncrvac = 1;
}else if( strcmp(z,"journal")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
zJMode = argv[++i];
}else if( strcmp(z,"key")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
zKey = argv[++i];
}else if( strcmp(z,"lookaside")==0 ){
- if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(2);
nLook = integerValue(argv[i+1]);
szLook = integerValue(argv[i+2]);
i += 2;
#endif
#if SQLITE_VERSION_NUMBER>=3007017
}else if( strcmp(z, "mmap")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
mmapSize = integerValue(argv[++i]);
#endif
+ }else if( strcmp(z,"nomutex")==0 ){
+ openFlags |= SQLITE_OPEN_NOMUTEX;
}else if( strcmp(z,"nosync")==0 ){
noSync = 1;
}else if( strcmp(z,"notnull")==0 ){
fatal_error("The --output option is not supported with"
" -DSPEEDTEST_OMIT_HASH\n");
#else
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
i++;
if( strcmp(argv[i],"-")==0 ){
g.hashFile = stdout;
}
#endif
}else if( strcmp(z,"pagesize")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
pageSize = integerValue(argv[++i]);
}else if( strcmp(z,"pcache")==0 ){
- if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(2);
nPCache = integerValue(argv[i+1]);
szPCache = integerValue(argv[i+2]);
doPCache = 1;
}else if( strcmp(z,"primarykey")==0 ){
g.zPK = "PRIMARY KEY";
}else if( strcmp(z,"repeat")==0 ){
- if( i>=argc-1 ) fatal_error("missing arguments on %s\n", argv[i]);
- g.nRepeat = integerValue(argv[i+1]);
- i += 1;
+ ARGC_VALUE_CHECK(1);
+ g.nRepeat = integerValue(argv[++i]);
}else if( strcmp(z,"reprepare")==0 ){
g.bReprepare = 1;
#if SQLITE_VERSION_NUMBER>=3006000
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
#endif
}else if( strcmp(z,"script")==0 ){
- if( i>=argc-1 ) fatal_error("missing arguments on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
if( g.pScript ) fclose(g.pScript);
g.pScript = fopen(argv[++i], "wb");
if( g.pScript==0 ){
}else if( strcmp(z,"shrink-memory")==0 ){
g.bMemShrink = 1;
}else if( strcmp(z,"size")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
g.szTest = integerValue(argv[++i]);
}else if( strcmp(z,"stats")==0 ){
showStats = 1;
}else if( strcmp(z,"temp")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
i++;
if( argv[i][0]<'0' || argv[i][0]>'9' || argv[i][1]!=0 ){
fatal_error("argument to --temp should be integer between 0 and 9");
}
g.eTemp = argv[i][0] - '0';
}else if( strcmp(z,"testset")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
zTSet = argv[++i];
}else if( strcmp(z,"trace")==0 ){
doTrace = 1;
}else if( strcmp(z,"threads")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
nThread = integerValue(argv[++i]);
}else if( strcmp(z,"utf16le")==0 ){
zEncoding = "utf16le";
#ifndef SPEEDTEST_OMIT_HASH
HashInit();
#endif
+ }else if( strcmp(z,"vfs")==0 ){
+ ARGC_VALUE_CHECK(1);
+ zVfs = argv[++i];
}else if( strcmp(z,"reserve")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
+ ARGC_VALUE_CHECK(1);
g.nReserve = atoi(argv[++i]);
}else if( strcmp(z,"without-rowid")==0 ){
if( strstr(g.zWR,"WITHOUT")!=0 ){
}else{
g.zWR = "STRICT";
}
- }else if( strcmp(z,"vfs")==0 ){
- if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
- zVfs = argv[++i];
}else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){
printf(zHelp, argv[0]);
exit(0);
argv[i], argv[0]);
}
}
+#undef ARGC_VALUE_CHECK
if( zDbName!=0 ) unlink(zDbName);
#if SQLITE_VERSION_NUMBER>=3006001
if( nHeap>0 ){
/* Open the database and the input file */
if( sqlite3_open_v2(memDb ? ":memory:" : zDbName, &g.db,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, zVfs) ){
+ openFlags, zVfs) ){
fatal_error("Cannot open database file: %s\n", zDbName);
}
#if SQLITE_VERSION_NUMBER>=3006001
free( pHeap );
return 0;
}
+
+#ifdef SQLITE_SPEEDTEST1_WASM
+/*
+** A workaround for some inconsistent behaviour with how
+** main() does (or does not) get exported to WASM.
+*/
+int wasm_main(int argc, char **argv){
+ return main(argc, argv);
+}
+#endif