blob: d7f2af47b8ad46ae2a728f8d747a62664bc2251b [file] [log] [blame]
drhad1ca9a2013-11-23 04:16:58 +00001/*
2** A program for performance testing.
3**
4** The available command-line options are described below:
5*/
6static const char zHelp[] =
7 "Usage: %s [--options] DATABASE\n"
8 "Options:\n"
9 " --autovacuum Enable AUTOVACUUM mode\n"
10 " --cachesize N Set the cache size to N\n"
11 " --exclusive Enable locking_mode=EXCLUSIVE\n"
drh849a9d92013-12-21 15:46:06 +000012 " --explain Like --sqlonly but with added EXPLAIN keywords\n"
drh93307e92013-11-24 01:14:14 +000013 " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
drhad1ca9a2013-11-23 04:16:58 +000014 " --incrvacuum Enable incremenatal vacuum mode\n"
drh1dae26b2015-02-03 19:20:03 +000015 " --journal M Set the journal_mode to M\n"
drhad1ca9a2013-11-23 04:16:58 +000016 " --key KEY Set the encryption key to KEY\n"
17 " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n"
drh2e43e962015-07-03 14:34:25 +000018 " --multithread Set multithreaded mode\n"
19 " --nomemstat Disable memory statistics\n"
drhad1ca9a2013-11-23 04:16:58 +000020 " --nosync Set PRAGMA synchronous=OFF\n"
21 " --notnull Add NOT NULL constraints to table columns\n"
22 " --pagesize N Set the page size to N\n"
23 " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
24 " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n"
25 " --reprepare Reprepare each statement upon every invocation\n"
drh93307e92013-11-24 01:14:14 +000026 " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n"
drh2e43e962015-07-03 14:34:25 +000027 " --serialized Set serialized threading mode\n"
28 " --singlethread Set single-threaded mode - disables all mutexing\n"
drhad1ca9a2013-11-23 04:16:58 +000029 " --sqlonly No-op. Only show the SQL that would have been run.\n"
drh0d847182015-07-02 01:38:39 +000030 " --shrink-memory Invoke sqlite3_db_release_memory() frequently.\n"
drhad1ca9a2013-11-23 04:16:58 +000031 " --size N Relative test size. Default=100\n"
32 " --stats Show statistics at the end\n"
33 " --testset T Run test-set T\n"
34 " --trace Turn on SQL tracing\n"
drh46a06bb2014-04-18 13:57:39 +000035 " --threads N Use up to N threads for sorting\n"
drhad1ca9a2013-11-23 04:16:58 +000036 " --utf16be Set text encoding to UTF-16BE\n"
37 " --utf16le Set text encoding to UTF-16LE\n"
drh65e6b0d2014-04-28 17:56:19 +000038 " --verify Run additional verification steps.\n"
drhad1ca9a2013-11-23 04:16:58 +000039 " --without-rowid Use WITHOUT ROWID where appropriate\n"
40;
41
42
43#include "sqlite3.h"
44#include <assert.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <stdarg.h>
48#include <string.h>
49#include <ctype.h>
drhc56fac72015-10-29 13:48:15 +000050#define ISSPACE(X) isspace((unsigned char)(X))
51#define ISDIGIT(X) isdigit((unsigned char)(X))
drhad1ca9a2013-11-23 04:16:58 +000052
drh43076902015-06-18 15:26:09 +000053#if SQLITE_VERSION_NUMBER<3005000
54# define sqlite3_int64 sqlite_int64
55#endif
drhcfb8f8d2015-07-23 20:44:49 +000056#ifdef SQLITE_ENABLE_RBU
57# include "sqlite3rbu.h"
dan54fc2142015-03-05 16:21:20 +000058#endif
59
drhad1ca9a2013-11-23 04:16:58 +000060/* All global state is held in this structure */
61static struct Global {
62 sqlite3 *db; /* The open database connection */
63 sqlite3_stmt *pStmt; /* Current SQL statement */
64 sqlite3_int64 iStart; /* Start-time for the current test */
65 sqlite3_int64 iTotal; /* Total time */
66 int bWithoutRowid; /* True for --without-rowid */
67 int bReprepare; /* True to reprepare the SQL on each rerun */
68 int bSqlOnly; /* True to print the SQL once only */
drh849a9d92013-12-21 15:46:06 +000069 int bExplain; /* Print SQL with EXPLAIN prefix */
drh65e6b0d2014-04-28 17:56:19 +000070 int bVerify; /* Try to verify that results are correct */
drh0d847182015-07-02 01:38:39 +000071 int bMemShrink; /* Call sqlite3_db_release_memory() often */
drhad1ca9a2013-11-23 04:16:58 +000072 int szTest; /* Scale factor for test iterations */
73 const char *zWR; /* Might be WITHOUT ROWID */
74 const char *zNN; /* Might be NOT NULL */
75 const char *zPK; /* Might be UNIQUE or PRIMARY KEY */
76 unsigned int x, y; /* Pseudo-random number generator state */
77 int nResult; /* Size of the current result */
78 char zResult[3000]; /* Text of the current result */
79} g;
80
drhad1ca9a2013-11-23 04:16:58 +000081
drh93307e92013-11-24 01:14:14 +000082/* Print an error message and exit */
83static void fatal_error(const char *zMsg, ...){
84 va_list ap;
85 va_start(ap, zMsg);
86 vfprintf(stderr, zMsg, ap);
87 va_end(ap);
88 exit(1);
drhad1ca9a2013-11-23 04:16:58 +000089}
90
91/*
92** Return the value of a hexadecimal digit. Return -1 if the input
93** is not a hex digit.
94*/
95static int hexDigitValue(char c){
96 if( c>='0' && c<='9' ) return c - '0';
97 if( c>='a' && c<='f' ) return c - 'a' + 10;
98 if( c>='A' && c<='F' ) return c - 'A' + 10;
99 return -1;
100}
101
drh290ea402013-12-01 18:10:01 +0000102/* Provide an alternative to sqlite3_stricmp() in older versions of
103** SQLite */
104#if SQLITE_VERSION_NUMBER<3007011
105# define sqlite3_stricmp strcmp
106#endif
107
drhad1ca9a2013-11-23 04:16:58 +0000108/*
109** Interpret zArg as an integer value, possibly with suffixes.
110*/
drh93307e92013-11-24 01:14:14 +0000111static int integerValue(const char *zArg){
drhad1ca9a2013-11-23 04:16:58 +0000112 sqlite3_int64 v = 0;
113 static const struct { char *zSuffix; int iMult; } aMult[] = {
114 { "KiB", 1024 },
115 { "MiB", 1024*1024 },
116 { "GiB", 1024*1024*1024 },
117 { "KB", 1000 },
118 { "MB", 1000000 },
119 { "GB", 1000000000 },
120 { "K", 1000 },
121 { "M", 1000000 },
122 { "G", 1000000000 },
123 };
124 int i;
125 int isNeg = 0;
126 if( zArg[0]=='-' ){
127 isNeg = 1;
128 zArg++;
129 }else if( zArg[0]=='+' ){
130 zArg++;
131 }
132 if( zArg[0]=='0' && zArg[1]=='x' ){
133 int x;
134 zArg += 2;
135 while( (x = hexDigitValue(zArg[0]))>=0 ){
136 v = (v<<4) + x;
137 zArg++;
138 }
139 }else{
140 while( isdigit(zArg[0]) ){
141 v = v*10 + zArg[0] - '0';
142 zArg++;
143 }
144 }
145 for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
146 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
147 v *= aMult[i].iMult;
148 break;
149 }
150 }
mistachkinb87875a2013-11-27 18:00:20 +0000151 if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
drhdcb5fa02013-11-27 14:50:51 +0000152 return (int)(isNeg? -v : v);
drhad1ca9a2013-11-23 04:16:58 +0000153}
154
155/* Return the current wall-clock time, in milliseconds */
156sqlite3_int64 speedtest1_timestamp(void){
drh43076902015-06-18 15:26:09 +0000157#if SQLITE_VERSION_NUMBER<3005000
158 return 0;
159#else
drhad1ca9a2013-11-23 04:16:58 +0000160 static sqlite3_vfs *clockVfs = 0;
161 sqlite3_int64 t;
162 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
drhd79e9c52013-12-02 01:24:05 +0000163#if SQLITE_VERSION_NUMBER>=3007000
drh290ea402013-12-01 18:10:01 +0000164 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drhad1ca9a2013-11-23 04:16:58 +0000165 clockVfs->xCurrentTimeInt64(clockVfs, &t);
drhd79e9c52013-12-02 01:24:05 +0000166 }else
167#endif
168 {
drhad1ca9a2013-11-23 04:16:58 +0000169 double r;
170 clockVfs->xCurrentTime(clockVfs, &r);
171 t = (sqlite3_int64)(r*86400000.0);
172 }
173 return t;
drh43076902015-06-18 15:26:09 +0000174#endif
drhad1ca9a2013-11-23 04:16:58 +0000175}
176
177/* Return a pseudo-random unsigned integer */
178unsigned int speedtest1_random(void){
179 g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001);
180 g.y = g.y*1103515245 + 12345;
181 return g.x ^ g.y;
182}
183
184/* Map the value in within the range of 1...limit into another
185** number in a way that is chatic and invertable.
186*/
187unsigned swizzle(unsigned in, unsigned limit){
188 unsigned out = 0;
189 while( limit ){
190 out = (out<<1) | (in&1);
191 in >>= 1;
192 limit >>= 1;
193 }
194 return out;
195}
196
197/* Round up a number so that it is a power of two minus one
198*/
199unsigned roundup_allones(unsigned limit){
200 unsigned m = 1;
201 while( m<limit ) m = (m<<1)+1;
202 return m;
203}
204
205/* The speedtest1_numbername procedure below converts its argment (an integer)
206** into a string which is the English-language name for that number.
207** The returned string should be freed with sqlite3_free().
208**
209** Example:
210**
211** speedtest1_numbername(123) -> "one hundred twenty three"
212*/
213int speedtest1_numbername(unsigned int n, char *zOut, int nOut){
214 static const char *ones[] = { "zero", "one", "two", "three", "four", "five",
215 "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
216 "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
217 "eighteen", "nineteen" };
218 static const char *tens[] = { "", "ten", "twenty", "thirty", "forty",
219 "fifty", "sixty", "seventy", "eighty", "ninety" };
220 int i = 0;
221
222 if( n>=1000000000 ){
223 i += speedtest1_numbername(n/1000000000, zOut+i, nOut-i);
224 sqlite3_snprintf(nOut-i, zOut+i, " billion");
225 i += (int)strlen(zOut+i);
226 n = n % 1000000000;
227 }
228 if( n>=1000000 ){
229 if( i && i<nOut-1 ) zOut[i++] = ' ';
230 i += speedtest1_numbername(n/1000000, zOut+i, nOut-i);
231 sqlite3_snprintf(nOut-i, zOut+i, " million");
232 i += (int)strlen(zOut+i);
233 n = n % 1000000;
234 }
235 if( n>=1000 ){
236 if( i && i<nOut-1 ) zOut[i++] = ' ';
237 i += speedtest1_numbername(n/1000, zOut+i, nOut-i);
238 sqlite3_snprintf(nOut-i, zOut+i, " thousand");
239 i += (int)strlen(zOut+i);
240 n = n % 1000;
241 }
242 if( n>=100 ){
243 if( i && i<nOut-1 ) zOut[i++] = ' ';
244 sqlite3_snprintf(nOut-i, zOut+i, "%s hundred", ones[n/100]);
245 i += (int)strlen(zOut+i);
246 n = n % 100;
247 }
248 if( n>=20 ){
249 if( i && i<nOut-1 ) zOut[i++] = ' ';
250 sqlite3_snprintf(nOut-i, zOut+i, "%s", tens[n/10]);
251 i += (int)strlen(zOut+i);
252 n = n % 10;
253 }
254 if( n>0 ){
255 if( i && i<nOut-1 ) zOut[i++] = ' ';
256 sqlite3_snprintf(nOut-i, zOut+i, "%s", ones[n]);
257 i += (int)strlen(zOut+i);
258 }
259 if( i==0 ){
260 sqlite3_snprintf(nOut-i, zOut+i, "zero");
261 i += (int)strlen(zOut+i);
262 }
263 return i;
264}
265
266
267/* Start a new test case */
268#define NAMEWIDTH 60
269static const char zDots[] =
270 ".......................................................................";
271void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){
272 int n = (int)strlen(zTestName);
273 char *zName;
274 va_list ap;
275 va_start(ap, zTestName);
276 zName = sqlite3_vmprintf(zTestName, ap);
277 va_end(ap);
278 n = (int)strlen(zName);
279 if( n>NAMEWIDTH ){
280 zName[NAMEWIDTH] = 0;
281 n = NAMEWIDTH;
282 }
283 if( g.bSqlOnly ){
284 printf("/* %4d - %s%.*s */\n", iTestNum, zName, NAMEWIDTH-n, zDots);
285 }else{
286 printf("%4d - %s%.*s ", iTestNum, zName, NAMEWIDTH-n, zDots);
287 fflush(stdout);
288 }
289 sqlite3_free(zName);
290 g.nResult = 0;
291 g.iStart = speedtest1_timestamp();
drhdcb5fa02013-11-27 14:50:51 +0000292 g.x = 0xad131d0b;
293 g.y = 0x44f9eac8;
drhad1ca9a2013-11-23 04:16:58 +0000294}
295
296/* Complete a test case */
297void speedtest1_end_test(void){
298 sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart;
299 if( !g.bSqlOnly ){
300 g.iTotal += iElapseTime;
301 printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000));
302 }
303 if( g.pStmt ){
304 sqlite3_finalize(g.pStmt);
305 g.pStmt = 0;
306 }
307}
308
309/* Report end of testing */
310void speedtest1_final(void){
311 if( !g.bSqlOnly ){
312 printf(" TOTAL%.*s %4d.%03ds\n", NAMEWIDTH-5, zDots,
313 (int)(g.iTotal/1000), (int)(g.iTotal%1000));
314 }
315}
316
drh849a9d92013-12-21 15:46:06 +0000317/* Print an SQL statement to standard output */
318static void printSql(const char *zSql){
319 int n = (int)strlen(zSql);
drhc56fac72015-10-29 13:48:15 +0000320 while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ){ n--; }
drh849a9d92013-12-21 15:46:06 +0000321 if( g.bExplain ) printf("EXPLAIN ");
322 printf("%.*s;\n", n, zSql);
323 if( g.bExplain
drh5995e292015-06-18 12:37:32 +0000324#if SQLITE_VERSION_NUMBER>=3007017
drh25555502013-12-21 17:14:58 +0000325 && ( sqlite3_strglob("CREATE *", zSql)==0
326 || sqlite3_strglob("DROP *", zSql)==0
327 || sqlite3_strglob("ALTER *", zSql)==0
drh849a9d92013-12-21 15:46:06 +0000328 )
drh25555502013-12-21 17:14:58 +0000329#endif
drh849a9d92013-12-21 15:46:06 +0000330 ){
331 printf("%.*s;\n", n, zSql);
332 }
333}
334
drh0d847182015-07-02 01:38:39 +0000335/* Shrink memory used, if appropriate and if the SQLite version is capable
336** of doing so.
337*/
338void speedtest1_shrink_memory(void){
339#if SQLITE_VERSION_NUMBER>=3007010
340 if( g.bMemShrink ) sqlite3_db_release_memory(g.db);
341#endif
342}
343
drhad1ca9a2013-11-23 04:16:58 +0000344/* Run SQL */
345void speedtest1_exec(const char *zFormat, ...){
346 va_list ap;
347 char *zSql;
348 va_start(ap, zFormat);
349 zSql = sqlite3_vmprintf(zFormat, ap);
350 va_end(ap);
351 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000352 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000353 }else{
drhe19f8322013-11-23 11:45:58 +0000354 char *zErrMsg = 0;
355 int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
356 if( zErrMsg ) fatal_error("SQL error: %s\n%s\n", zErrMsg, zSql);
357 if( rc!=SQLITE_OK ) fatal_error("exec error: %s\n", sqlite3_errmsg(g.db));
drhad1ca9a2013-11-23 04:16:58 +0000358 }
359 sqlite3_free(zSql);
drh0d847182015-07-02 01:38:39 +0000360 speedtest1_shrink_memory();
drhad1ca9a2013-11-23 04:16:58 +0000361}
362
363/* Prepare an SQL statement */
364void speedtest1_prepare(const char *zFormat, ...){
365 va_list ap;
366 char *zSql;
367 va_start(ap, zFormat);
368 zSql = sqlite3_vmprintf(zFormat, ap);
369 va_end(ap);
370 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000371 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000372 }else{
373 int rc;
374 if( g.pStmt ) sqlite3_finalize(g.pStmt);
375 rc = sqlite3_prepare_v2(g.db, zSql, -1, &g.pStmt, 0);
376 if( rc ){
377 fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
378 }
379 }
380 sqlite3_free(zSql);
381}
382
383/* Run an SQL statement previously prepared */
384void speedtest1_run(void){
385 int i, n, len;
386 if( g.bSqlOnly ) return;
387 assert( g.pStmt );
388 g.nResult = 0;
389 while( sqlite3_step(g.pStmt)==SQLITE_ROW ){
390 n = sqlite3_column_count(g.pStmt);
391 for(i=0; i<n; i++){
392 const char *z = (const char*)sqlite3_column_text(g.pStmt, i);
393 if( z==0 ) z = "nil";
394 len = (int)strlen(z);
395 if( g.nResult+len<sizeof(g.zResult)-2 ){
396 if( g.nResult>0 ) g.zResult[g.nResult++] = ' ';
397 memcpy(g.zResult + g.nResult, z, len+1);
398 g.nResult += len;
399 }
400 }
401 }
drh5995e292015-06-18 12:37:32 +0000402#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +0000403 if( g.bReprepare ){
404 sqlite3_stmt *pNew;
405 sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
406 sqlite3_finalize(g.pStmt);
407 g.pStmt = pNew;
drh5995e292015-06-18 12:37:32 +0000408 }else
409#endif
410 {
drhad1ca9a2013-11-23 04:16:58 +0000411 sqlite3_reset(g.pStmt);
412 }
drh0d847182015-07-02 01:38:39 +0000413 speedtest1_shrink_memory();
drhad1ca9a2013-11-23 04:16:58 +0000414}
415
416/* The sqlite3_trace() callback function */
417static void traceCallback(void *NotUsed, const char *zSql){
418 int n = (int)strlen(zSql);
drhc56fac72015-10-29 13:48:15 +0000419 while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ) n--;
drhad1ca9a2013-11-23 04:16:58 +0000420 fprintf(stderr,"%.*s;\n", n, zSql);
421}
422
423/* Substitute random() function that gives the same random
424** sequence on each run, for repeatability. */
425static void randomFunc(
426 sqlite3_context *context,
427 int NotUsed,
428 sqlite3_value **NotUsed2
429){
430 sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random());
431}
432
drhae28d6e2013-12-21 00:04:37 +0000433/* Estimate the square root of an integer */
434static int est_square_root(int x){
435 int y0 = x/2;
436 int y1;
437 int n;
438 for(n=0; y0>0 && n<10; n++){
439 y1 = (y0 + x/y0)/2;
440 if( y1==y0 ) break;
441 y0 = y1;
442 }
443 return y0;
444}
445
drhad1ca9a2013-11-23 04:16:58 +0000446/*
447** The main and default testset
448*/
449void testset_main(void){
450 int i; /* Loop counter */
451 int n; /* iteration count */
452 int sz; /* Size of the tables */
453 int maxb; /* Maximum swizzled value */
454 unsigned x1, x2; /* Parameters */
455 int len; /* Length of the zNum[] string */
456 char zNum[2000]; /* A number name */
457
458 sz = n = g.szTest*500;
459 maxb = roundup_allones(sz);
460 speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
461 speedtest1_exec("BEGIN");
462 speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
463 g.zNN, g.zNN, g.zNN);
464 speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n);
465 for(i=1; i<=n; i++){
466 x1 = swizzle(i,maxb);
467 speedtest1_numbername(x1, zNum, sizeof(zNum));
468 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
469 sqlite3_bind_int(g.pStmt, 2, i);
470 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
471 speedtest1_run();
472 }
473 speedtest1_exec("COMMIT");
474 speedtest1_end_test();
475
476
477 n = sz;
478 speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
479 speedtest1_exec("BEGIN");
480 speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
481 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
482 speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
483 for(i=1; i<=n; i++){
484 x1 = swizzle(i,maxb);
485 speedtest1_numbername(x1, zNum, sizeof(zNum));
486 sqlite3_bind_int(g.pStmt, 1, i);
487 sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1);
488 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
489 speedtest1_run();
490 }
491 speedtest1_exec("COMMIT");
492 speedtest1_end_test();
493
494
495 n = sz;
496 speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
497 speedtest1_exec("BEGIN");
498 speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
499 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
500 speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
501 for(i=1; i<=n; i++){
502 x1 = swizzle(i,maxb);
503 speedtest1_numbername(x1, zNum, sizeof(zNum));
504 sqlite3_bind_int(g.pStmt, 2, i);
505 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
506 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
507 speedtest1_run();
508 }
509 speedtest1_exec("COMMIT");
510 speedtest1_end_test();
511
512
drh5e8980d2014-03-25 20:28:38 +0000513 n = 25;
drhad1ca9a2013-11-23 04:16:58 +0000514 speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
515 speedtest1_exec("BEGIN");
516 speedtest1_prepare(
517 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
518 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
519 );
520 for(i=1; i<=n; i++){
521 x1 = speedtest1_random()%maxb;
522 x2 = speedtest1_random()%10 + sz/5000 + x1;
523 sqlite3_bind_int(g.pStmt, 1, x1);
524 sqlite3_bind_int(g.pStmt, 2, x2);
525 speedtest1_run();
526 }
527 speedtest1_exec("COMMIT");
528 speedtest1_end_test();
529
530
drh5e8980d2014-03-25 20:28:38 +0000531 n = 10;
drhad1ca9a2013-11-23 04:16:58 +0000532 speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
533 speedtest1_exec("BEGIN");
534 speedtest1_prepare(
535 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
536 " WHERE c LIKE ?1; -- %d times", n
537 );
538 for(i=1; i<=n; i++){
539 x1 = speedtest1_random()%maxb;
540 zNum[0] = '%';
541 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
542 zNum[len] = '%';
543 zNum[len+1] = 0;
544 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
545 speedtest1_run();
546 }
547 speedtest1_exec("COMMIT");
548 speedtest1_end_test();
549
550
drh5e8980d2014-03-25 20:28:38 +0000551 n = 10;
drhc8729662014-03-25 17:45:49 +0000552 speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
553 speedtest1_exec("BEGIN");
554 speedtest1_prepare(
555 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
556 " ORDER BY a; -- %d times", n
557 );
558 for(i=1; i<=n; i++){
559 x1 = speedtest1_random()%maxb;
560 zNum[0] = '%';
561 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
562 zNum[len] = '%';
563 zNum[len+1] = 0;
564 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
565 speedtest1_run();
566 }
567 speedtest1_exec("COMMIT");
568 speedtest1_end_test();
569
dan54fc2142015-03-05 16:21:20 +0000570 n = 10; /* g.szTest/5; */
drhc8729662014-03-25 17:45:49 +0000571 speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
drh0c60c1f2014-03-25 14:54:36 +0000572 speedtest1_exec("BEGIN");
573 speedtest1_prepare(
574 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
575 " ORDER BY a LIMIT 10; -- %d times", n
576 );
577 for(i=1; i<=n; i++){
578 x1 = speedtest1_random()%maxb;
579 zNum[0] = '%';
580 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
581 zNum[len] = '%';
582 zNum[len+1] = 0;
583 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
584 speedtest1_run();
585 }
586 speedtest1_exec("COMMIT");
587 speedtest1_end_test();
588
589
drhad1ca9a2013-11-23 04:16:58 +0000590 speedtest1_begin_test(150, "CREATE INDEX five times");
drh849a9d92013-12-21 15:46:06 +0000591 speedtest1_exec("BEGIN;");
592 speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
593 speedtest1_exec("CREATE INDEX t1c ON t1(c);");
594 speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
595 speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
596 speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
597 speedtest1_exec("COMMIT;");
drhad1ca9a2013-11-23 04:16:58 +0000598 speedtest1_end_test();
599
600
601 n = sz/5;
602 speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
603 speedtest1_exec("BEGIN");
604 speedtest1_prepare(
605 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
606 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
607 );
608 for(i=1; i<=n; i++){
609 x1 = speedtest1_random()%maxb;
610 x2 = speedtest1_random()%10 + sz/5000 + x1;
611 sqlite3_bind_int(g.pStmt, 1, x1);
612 sqlite3_bind_int(g.pStmt, 2, x2);
613 speedtest1_run();
614 }
615 speedtest1_exec("COMMIT");
616 speedtest1_end_test();
617
618
619 n = sz/5;
620 speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
621 speedtest1_exec("BEGIN");
622 speedtest1_prepare(
623 "SELECT count(*), avg(b), sum(length(c)) FROM t2\n"
624 " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
625 );
626 for(i=1; i<=n; i++){
627 x1 = speedtest1_random()%maxb;
628 x2 = speedtest1_random()%10 + sz/5000 + x1;
629 sqlite3_bind_int(g.pStmt, 1, x1);
630 sqlite3_bind_int(g.pStmt, 2, x2);
631 speedtest1_run();
632 }
633 speedtest1_exec("COMMIT");
634 speedtest1_end_test();
635
636
637 n = sz/5;
638 speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
639 speedtest1_exec("BEGIN");
640 speedtest1_prepare(
641 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
642 " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
643 );
644 for(i=1; i<=n; i++){
645 x1 = swizzle(i, maxb);
646 len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
647 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
648 speedtest1_run();
649 }
650 speedtest1_exec("COMMIT");
651 speedtest1_end_test();
652
653 n = sz;
654 speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
655 speedtest1_exec("BEGIN");
656 speedtest1_exec(
657 "CREATE TABLE t4(\n"
658 " a INTEGER %s %s,\n"
659 " b INTEGER %s,\n"
660 " c TEXT %s\n"
661 ") %s",
662 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
663 speedtest1_exec("CREATE INDEX t4b ON t4(b)");
664 speedtest1_exec("CREATE INDEX t4c ON t4(c)");
665 speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
666 speedtest1_exec("COMMIT");
667 speedtest1_end_test();
668
669 n = sz;
670 speedtest1_begin_test(190, "DELETE and REFILL one table", n);
drh849a9d92013-12-21 15:46:06 +0000671 speedtest1_exec("DELETE FROM t2;");
672 speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
drhad1ca9a2013-11-23 04:16:58 +0000673 speedtest1_end_test();
674
675
676 speedtest1_begin_test(200, "VACUUM");
677 speedtest1_exec("VACUUM");
678 speedtest1_end_test();
679
680
681 speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
682 speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123");
683 speedtest1_exec("SELECT sum(d) FROM t2");
684 speedtest1_end_test();
685
686
687 n = sz/5;
688 speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n);
689 speedtest1_exec("BEGIN");
690 speedtest1_prepare(
691 "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
692 );
693 for(i=1; i<=n; i++){
694 x1 = speedtest1_random()%maxb;
695 x2 = speedtest1_random()%10 + sz/5000 + x1;
696 sqlite3_bind_int(g.pStmt, 1, x1);
697 sqlite3_bind_int(g.pStmt, 2, x2);
698 speedtest1_run();
699 }
700 speedtest1_exec("COMMIT");
701 speedtest1_end_test();
702
703
704 n = sz;
705 speedtest1_begin_test(240, "%d UPDATES of individual rows", n);
706 speedtest1_exec("BEGIN");
707 speedtest1_prepare(
708 "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n
709 );
710 for(i=1; i<=n; i++){
711 x1 = speedtest1_random()%sz + 1;
712 sqlite3_bind_int(g.pStmt, 1, x1);
713 speedtest1_run();
714 }
715 speedtest1_exec("COMMIT");
716 speedtest1_end_test();
717
718 speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz);
719 speedtest1_exec("UPDATE t2 SET d=b*4");
720 speedtest1_end_test();
721
722
723 speedtest1_begin_test(260, "Query added column after filling");
724 speedtest1_exec("SELECT sum(d) FROM t2");
725 speedtest1_end_test();
726
727
728
729 n = sz/5;
730 speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n);
731 speedtest1_exec("BEGIN");
732 speedtest1_prepare(
733 "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
734 );
735 for(i=1; i<=n; i++){
736 x1 = speedtest1_random()%maxb + 1;
737 x2 = speedtest1_random()%10 + sz/5000 + x1;
738 sqlite3_bind_int(g.pStmt, 1, x1);
739 sqlite3_bind_int(g.pStmt, 2, x2);
740 speedtest1_run();
741 }
742 speedtest1_exec("COMMIT");
743 speedtest1_end_test();
744
745
746 n = sz;
747 speedtest1_begin_test(280, "%d DELETEs of individual rows", n);
748 speedtest1_exec("BEGIN");
749 speedtest1_prepare(
750 "DELETE FROM t3 WHERE a=?1; -- %d times", n
751 );
752 for(i=1; i<=n; i++){
753 x1 = speedtest1_random()%sz + 1;
754 sqlite3_bind_int(g.pStmt, 1, x1);
755 speedtest1_run();
756 }
757 speedtest1_exec("COMMIT");
758 speedtest1_end_test();
759
760
761 speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz);
drhe19f8322013-11-23 11:45:58 +0000762 speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1");
763 speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
drhad1ca9a2013-11-23 04:16:58 +0000764 speedtest1_end_test();
765
drh039468e2013-12-18 16:27:48 +0000766 speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
767 speedtest1_exec("DELETE FROM t2;");
drh849a9d92013-12-21 15:46:06 +0000768 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
769 " SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);");
770 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
771 " SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);");
drh039468e2013-12-18 16:27:48 +0000772 speedtest1_end_test();
773
drhad1ca9a2013-11-23 04:16:58 +0000774
775 n = sz/5;
drh039468e2013-12-18 16:27:48 +0000776 speedtest1_begin_test(310, "%d four-ways joins", n);
drhad1ca9a2013-11-23 04:16:58 +0000777 speedtest1_exec("BEGIN");
778 speedtest1_prepare(
779 "SELECT t1.c FROM t1, t2, t3, t4\n"
780 " WHERE t4.a BETWEEN ?1 AND ?2\n"
781 " AND t3.a=t4.b\n"
782 " AND t2.a=t3.b\n"
783 " AND t1.c=t2.c"
784 );
785 for(i=1; i<=n; i++){
786 x1 = speedtest1_random()%sz + 1;
787 x2 = speedtest1_random()%10 + x1 + 4;
788 sqlite3_bind_int(g.pStmt, 1, x1);
789 sqlite3_bind_int(g.pStmt, 2, x2);
790 speedtest1_run();
791 }
792 speedtest1_exec("COMMIT");
793 speedtest1_end_test();
794
drhae28d6e2013-12-21 00:04:37 +0000795 speedtest1_begin_test(320, "subquery in result set", n);
796 speedtest1_prepare(
797 "SELECT sum(a), max(c),\n"
798 " avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
799 " FROM t1 WHERE rowid<?1;"
800 );
801 sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
802 speedtest1_run();
803 speedtest1_end_test();
drhad1ca9a2013-11-23 04:16:58 +0000804
805 speedtest1_begin_test(980, "PRAGMA integrity_check");
806 speedtest1_exec("PRAGMA integrity_check");
807 speedtest1_end_test();
808
809
810 speedtest1_begin_test(990, "ANALYZE");
811 speedtest1_exec("ANALYZE");
812 speedtest1_end_test();
813}
814
815/*
drhc4754802014-02-09 00:18:21 +0000816** A testset for common table expressions. This exercises code
817** for views, subqueries, co-routines, etc.
818*/
819void testset_cte(void){
820 static const char *azPuzzle[] = {
821 /* Easy */
822 "534...9.."
823 "67.195..."
824 ".98....6."
825 "8...6...3"
826 "4..8.3..1"
827 "....2...6"
828 ".6....28."
829 "...419..5"
830 "...28..79",
831
832 /* Medium */
833 "53....9.."
834 "6..195..."
835 ".98....6."
836 "8...6...3"
837 "4..8.3..1"
838 "....2...6"
839 ".6....28."
840 "...419..5"
841 "....8..79",
842
843 /* Hard */
844 "53......."
845 "6..195..."
846 ".98....6."
847 "8...6...3"
848 "4..8.3..1"
849 "....2...6"
850 ".6....28."
851 "...419..5"
852 "....8..79",
853 };
854 const char *zPuz;
drhfa46bfb2014-02-09 00:52:53 +0000855 double rSpacing;
drh5574e3f2014-02-09 23:59:28 +0000856 int nElem;
drhc4754802014-02-09 00:18:21 +0000857
858 if( g.szTest<25 ){
859 zPuz = azPuzzle[0];
860 }else if( g.szTest<70 ){
861 zPuz = azPuzzle[1];
862 }else{
863 zPuz = azPuzzle[2];
864 }
865 speedtest1_begin_test(100, "Sudoku with recursive 'digits'");
866 speedtest1_prepare(
867 "WITH RECURSIVE\n"
868 " input(sud) AS (VALUES(?1)),\n"
869 " digits(z,lp) AS (\n"
870 " VALUES('1', 1)\n"
871 " UNION ALL\n"
872 " SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9\n"
873 " ),\n"
874 " x(s, ind) AS (\n"
875 " SELECT sud, instr(sud, '.') FROM input\n"
876 " UNION ALL\n"
877 " SELECT\n"
878 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
879 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
880 " FROM x, digits AS z\n"
881 " WHERE ind>0\n"
882 " AND NOT EXISTS (\n"
883 " SELECT 1\n"
884 " FROM digits AS lp\n"
885 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
886 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
887 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
888 " + ((ind-1)/27) * 27 + lp\n"
889 " + ((lp-1) / 3) * 6, 1)\n"
890 " )\n"
891 " )\n"
892 "SELECT s FROM x WHERE ind=0;"
893 );
894 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
895 speedtest1_run();
896 speedtest1_end_test();
897
898 speedtest1_begin_test(200, "Sudoku with VALUES 'digits'");
899 speedtest1_prepare(
900 "WITH RECURSIVE\n"
901 " input(sud) AS (VALUES(?1)),\n"
902 " digits(z,lp) AS (VALUES('1',1),('2',2),('3',3),('4',4),('5',5),\n"
903 " ('6',6),('7',7),('8',8),('9',9)),\n"
904 " x(s, ind) AS (\n"
905 " SELECT sud, instr(sud, '.') FROM input\n"
906 " UNION ALL\n"
907 " SELECT\n"
908 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
909 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
910 " FROM x, digits AS z\n"
911 " WHERE ind>0\n"
912 " AND NOT EXISTS (\n"
913 " SELECT 1\n"
914 " FROM digits AS lp\n"
915 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
916 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
917 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
918 " + ((ind-1)/27) * 27 + lp\n"
919 " + ((lp-1) / 3) * 6, 1)\n"
920 " )\n"
921 " )\n"
922 "SELECT s FROM x WHERE ind=0;"
923 );
924 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
925 speedtest1_run();
926 speedtest1_end_test();
drhfa46bfb2014-02-09 00:52:53 +0000927
928 rSpacing = 5.0/g.szTest;
929 speedtest1_begin_test(300, "Mandelbrot Set with spacing=%f", rSpacing);
930 speedtest1_prepare(
931 "WITH RECURSIVE \n"
932 " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+?1 FROM xaxis WHERE x<1.2),\n"
933 " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+?2 FROM yaxis WHERE y<1.0),\n"
934 " m(iter, cx, cy, x, y) AS (\n"
935 " SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis\n"
936 " UNION ALL\n"
937 " SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m \n"
938 " WHERE (x*x + y*y) < 4.0 AND iter<28\n"
939 " ),\n"
940 " m2(iter, cx, cy) AS (\n"
941 " SELECT max(iter), cx, cy FROM m GROUP BY cx, cy\n"
942 " ),\n"
943 " a(t) AS (\n"
944 " SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') \n"
945 " FROM m2 GROUP BY cy\n"
946 " )\n"
947 "SELECT group_concat(rtrim(t),x'0a') FROM a;"
948 );
949 sqlite3_bind_double(g.pStmt, 1, rSpacing*.05);
950 sqlite3_bind_double(g.pStmt, 2, rSpacing);
951 speedtest1_run();
952 speedtest1_end_test();
953
drh5574e3f2014-02-09 23:59:28 +0000954 nElem = 10000*g.szTest;
955 speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem);
956 speedtest1_prepare(
957 "WITH RECURSIVE \n"
958 " t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n"
959 " t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n"
960 "SELECT count(x), avg(x) FROM (\n"
961 " SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n"
962 ");",
963 nElem, nElem
964 );
965 speedtest1_run();
966 speedtest1_end_test();
967
drhc4754802014-02-09 00:18:21 +0000968}
969
drh8683e082014-10-11 10:52:54 +0000970#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000971/* Generate two numbers between 1 and mx. The first number is less than
972** the second. Usually the numbers are near each other but can sometimes
973** be far apart.
974*/
975static void twoCoords(
976 int p1, int p2, /* Parameters adjusting sizes */
977 unsigned mx, /* Range of 1..mx */
978 unsigned *pX0, unsigned *pX1 /* OUT: write results here */
979){
980 unsigned d, x0, x1, span;
981
982 span = mx/100 + 1;
983 if( speedtest1_random()%3==0 ) span *= p1;
984 if( speedtest1_random()%p2==0 ) span = mx/2;
985 d = speedtest1_random()%span + 1;
986 x0 = speedtest1_random()%(mx-d) + 1;
987 x1 = x0 + d;
988 *pX0 = x0;
989 *pX1 = x1;
990}
drh8683e082014-10-11 10:52:54 +0000991#endif
drh65e6b0d2014-04-28 17:56:19 +0000992
drh8683e082014-10-11 10:52:54 +0000993#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000994/* The following routine is an R-Tree geometry callback. It returns
995** true if the object overlaps a slice on the Y coordinate between the
996** two values given as arguments. In other words
997**
998** SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20);
999**
1000** Is the same as saying:
1001**
1002** SELECT count(*) FROM rt1 WHERE y1>=10 AND y0<=20;
1003*/
1004static int xsliceGeometryCallback(
1005 sqlite3_rtree_geometry *p,
1006 int nCoord,
1007 double *aCoord,
1008 int *pRes
1009){
1010 *pRes = aCoord[3]>=p->aParam[0] && aCoord[2]<=p->aParam[1];
1011 return SQLITE_OK;
1012}
drh8683e082014-10-11 10:52:54 +00001013#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +00001014
drh8683e082014-10-11 10:52:54 +00001015#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +00001016/*
1017** A testset for the R-Tree virtual table
1018*/
1019void testset_rtree(int p1, int p2){
1020 unsigned i, n;
1021 unsigned mxCoord;
1022 unsigned x0, x1, y0, y1, z0, z1;
1023 unsigned iStep;
1024 int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 );
1025
1026 mxCoord = 15000;
1027 n = g.szTest*100;
1028 speedtest1_begin_test(100, "%d INSERTs into an r-tree", n);
1029 speedtest1_exec("BEGIN");
1030 speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)");
1031 speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)"
1032 "VALUES(?1,?2,?3,?4,?5,?6,?7)");
1033 for(i=1; i<=n; i++){
1034 twoCoords(p1, p2, mxCoord, &x0, &x1);
1035 twoCoords(p1, p2, mxCoord, &y0, &y1);
1036 twoCoords(p1, p2, mxCoord, &z0, &z1);
1037 sqlite3_bind_int(g.pStmt, 1, i);
1038 sqlite3_bind_int(g.pStmt, 2, x0);
1039 sqlite3_bind_int(g.pStmt, 3, x1);
1040 sqlite3_bind_int(g.pStmt, 4, y0);
1041 sqlite3_bind_int(g.pStmt, 5, y1);
1042 sqlite3_bind_int(g.pStmt, 6, z0);
1043 sqlite3_bind_int(g.pStmt, 7, z1);
1044 speedtest1_run();
1045 }
1046 speedtest1_exec("COMMIT");
1047 speedtest1_end_test();
1048
1049 speedtest1_begin_test(101, "Copy from rtree to a regular table");
1050 speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
1051 speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
1052 speedtest1_end_test();
1053
1054 n = g.szTest*20;
1055 speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
1056 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
1057 iStep = mxCoord/n;
1058 for(i=0; i<n; i++){
1059 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1060 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1061 speedtest1_run();
1062 aCheck[i] = atoi(g.zResult);
1063 }
1064 speedtest1_end_test();
1065
1066 if( g.bVerify ){
1067 n = g.szTest*20;
1068 speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
1069 speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
1070 iStep = mxCoord/n;
1071 for(i=0; i<n; i++){
1072 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1073 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1074 speedtest1_run();
1075 if( aCheck[i]!=atoi(g.zResult) ){
1076 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1077 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1078 }
1079 }
1080 speedtest1_end_test();
1081 }
1082
1083 n = g.szTest*20;
1084 speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n);
1085 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2");
1086 iStep = mxCoord/n;
1087 for(i=0; i<n; i++){
1088 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1089 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1090 speedtest1_run();
1091 aCheck[i] = atoi(g.zResult);
1092 }
1093 speedtest1_end_test();
1094
1095 if( g.bVerify ){
1096 n = g.szTest*20;
1097 speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
1098 speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2");
1099 iStep = mxCoord/n;
1100 for(i=0; i<n; i++){
1101 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1102 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1103 speedtest1_run();
1104 if( aCheck[i]!=atoi(g.zResult) ){
1105 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1106 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1107 }
1108 }
1109 speedtest1_end_test();
1110 }
1111
1112
1113 n = g.szTest*20;
1114 speedtest1_begin_test(125, "%d custom geometry callback queries", n);
1115 sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0);
1116 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)");
1117 iStep = mxCoord/n;
1118 for(i=0; i<n; i++){
1119 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1120 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1121 speedtest1_run();
1122 if( aCheck[i]!=atoi(g.zResult) ){
1123 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1124 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1125 }
1126 }
1127 speedtest1_end_test();
1128
1129 n = g.szTest*80;
1130 speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n);
1131 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2"
1132 " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2");
1133 iStep = mxCoord/n;
1134 for(i=0; i<n; i++){
1135 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1136 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1137 speedtest1_run();
1138 aCheck[i] = atoi(g.zResult);
1139 }
1140 speedtest1_end_test();
1141
1142 n = g.szTest*100;
1143 speedtest1_begin_test(140, "%d rowid queries", n);
1144 speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
1145 for(i=1; i<=n; i++){
1146 sqlite3_bind_int(g.pStmt, 1, i);
1147 speedtest1_run();
1148 }
1149 speedtest1_end_test();
1150}
drh8683e082014-10-11 10:52:54 +00001151#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +00001152
drhc4754802014-02-09 00:18:21 +00001153/*
drhad1ca9a2013-11-23 04:16:58 +00001154** A testset used for debugging speedtest1 itself.
1155*/
1156void testset_debug1(void){
1157 unsigned i, n;
1158 unsigned x1, x2;
1159 char zNum[2000]; /* A number name */
1160
1161 n = g.szTest;
1162 for(i=1; i<=n; i++){
1163 x1 = swizzle(i, n);
1164 x2 = swizzle(x1, n);
1165 speedtest1_numbername(x1, zNum, sizeof(zNum));
1166 printf("%5d %5d %5d %s\n", i, x1, x2, zNum);
1167 }
1168}
1169
drhfc1a84c2016-02-27 19:19:22 +00001170#ifdef __linux__
1171#include <sys/types.h>
1172#include <unistd.h>
1173
1174/*
1175** Attempt to display I/O stats on Linux using /proc/PID/io
1176*/
1177static void displayLinuxIoStats(FILE *out){
1178 FILE *in;
1179 char z[200];
1180 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1181 in = fopen(z, "rb");
1182 if( in==0 ) return;
1183 while( fgets(z, sizeof(z), in)!=0 ){
1184 static const struct {
1185 const char *zPattern;
1186 const char *zDesc;
1187 } aTrans[] = {
1188 { "rchar: ", "Bytes received by read():" },
1189 { "wchar: ", "Bytes sent to write():" },
1190 { "syscr: ", "Read() system calls:" },
1191 { "syscw: ", "Write() system calls:" },
1192 { "read_bytes: ", "Bytes rcvd from storage:" },
1193 { "write_bytes: ", "Bytes sent to storage:" },
1194 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
1195 };
1196 int i;
1197 for(i=0; i<sizeof(aTrans)/sizeof(aTrans[0]); i++){
1198 int n = (int)strlen(aTrans[i].zPattern);
1199 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1200 fprintf(out, "-- %-28s %s", aTrans[i].zDesc, &z[n]);
1201 break;
1202 }
1203 }
1204 }
1205 fclose(in);
1206}
1207#endif
1208
drhad1ca9a2013-11-23 04:16:58 +00001209int main(int argc, char **argv){
1210 int doAutovac = 0; /* True for --autovacuum */
1211 int cacheSize = 0; /* Desired cache size. 0 means default */
1212 int doExclusive = 0; /* True for --exclusive */
1213 int nHeap = 0, mnHeap = 0; /* Heap size from --heap */
1214 int doIncrvac = 0; /* True for --incrvacuum */
1215 const char *zJMode = 0; /* Journal mode */
1216 const char *zKey = 0; /* Encryption key */
1217 int nLook = 0, szLook = 0; /* --lookaside configuration */
1218 int noSync = 0; /* True for --nosync */
1219 int pageSize = 0; /* Desired page size. 0 means default */
1220 int nPCache = 0, szPCache = 0;/* --pcache configuration */
drhee70a842015-07-06 18:54:52 +00001221 int doPCache = 0; /* True if --pcache is seen */
drh93307e92013-11-24 01:14:14 +00001222 int nScratch = 0, szScratch=0;/* --scratch configuration */
drhad1ca9a2013-11-23 04:16:58 +00001223 int showStats = 0; /* True for --stats */
drh46a06bb2014-04-18 13:57:39 +00001224 int nThread = 0; /* --threads value */
drhad1ca9a2013-11-23 04:16:58 +00001225 const char *zTSet = "main"; /* Which --testset torun */
1226 int doTrace = 0; /* True for --trace */
1227 const char *zEncoding = 0; /* --utf16be or --utf16le */
1228 const char *zDbName = 0; /* Name of the test database */
1229
1230 void *pHeap = 0; /* Allocated heap space */
1231 void *pLook = 0; /* Allocated lookaside space */
1232 void *pPCache = 0; /* Allocated storage for pcache */
drh93307e92013-11-24 01:14:14 +00001233 void *pScratch = 0; /* Allocated storage for scratch */
drhad1ca9a2013-11-23 04:16:58 +00001234 int iCur, iHi; /* Stats values, current and "highwater" */
drhe19f8322013-11-23 11:45:58 +00001235 int i; /* Loop counter */
1236 int rc; /* API return code */
drhad1ca9a2013-11-23 04:16:58 +00001237
drhb719e3a2016-02-19 16:19:23 +00001238 /* Display the version of SQLite being tested */
1239 printf("Speedtest1 for SQLite %s %.50s\n", sqlite3_libversion(), sqlite3_sourceid());
1240
drhad1ca9a2013-11-23 04:16:58 +00001241 /* Process command-line arguments */
1242 g.zWR = "";
1243 g.zNN = "";
1244 g.zPK = "UNIQUE";
1245 g.szTest = 100;
1246 for(i=1; i<argc; i++){
1247 const char *z = argv[i];
1248 if( z[0]=='-' ){
1249 do{ z++; }while( z[0]=='-' );
1250 if( strcmp(z,"autovacuum")==0 ){
1251 doAutovac = 1;
1252 }else if( strcmp(z,"cachesize")==0 ){
1253 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1254 i++;
drh93307e92013-11-24 01:14:14 +00001255 cacheSize = integerValue(argv[i]);
drhad1ca9a2013-11-23 04:16:58 +00001256 }else if( strcmp(z,"exclusive")==0 ){
1257 doExclusive = 1;
drh849a9d92013-12-21 15:46:06 +00001258 }else if( strcmp(z,"explain")==0 ){
1259 g.bSqlOnly = 1;
1260 g.bExplain = 1;
drhad1ca9a2013-11-23 04:16:58 +00001261 }else if( strcmp(z,"heap")==0 ){
1262 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001263 nHeap = integerValue(argv[i+1]);
1264 mnHeap = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001265 i += 2;
1266 }else if( strcmp(z,"incrvacuum")==0 ){
1267 doIncrvac = 1;
1268 }else if( strcmp(z,"journal")==0 ){
1269 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1270 zJMode = argv[++i];
1271 }else if( strcmp(z,"key")==0 ){
1272 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1273 zKey = argv[++i];
1274 }else if( strcmp(z,"lookaside")==0 ){
1275 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001276 nLook = integerValue(argv[i+1]);
1277 szLook = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001278 i += 2;
drh2e43e962015-07-03 14:34:25 +00001279 }else if( strcmp(z,"multithread")==0 ){
1280 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
1281 }else if( strcmp(z,"nomemstat")==0 ){
1282 sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);
drhad1ca9a2013-11-23 04:16:58 +00001283 }else if( strcmp(z,"nosync")==0 ){
1284 noSync = 1;
1285 }else if( strcmp(z,"notnull")==0 ){
1286 g.zNN = "NOT NULL";
drhcfb8f8d2015-07-23 20:44:49 +00001287#ifdef SQLITE_ENABLE_RBU
1288 }else if( strcmp(z,"rbu")==0 ){
1289 sqlite3ota_create_vfs("rbu", 0);
1290 sqlite3_vfs_register(sqlite3_vfs_find("rbu"), 1);
dan54fc2142015-03-05 16:21:20 +00001291#endif
drhad1ca9a2013-11-23 04:16:58 +00001292 }else if( strcmp(z,"pagesize")==0 ){
1293 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001294 pageSize = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001295 }else if( strcmp(z,"pcache")==0 ){
1296 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001297 nPCache = integerValue(argv[i+1]);
1298 szPCache = integerValue(argv[i+2]);
drhee70a842015-07-06 18:54:52 +00001299 doPCache = 1;
drhad1ca9a2013-11-23 04:16:58 +00001300 i += 2;
1301 }else if( strcmp(z,"primarykey")==0 ){
1302 g.zPK = "PRIMARY KEY";
1303 }else if( strcmp(z,"reprepare")==0 ){
1304 g.bReprepare = 1;
drh93307e92013-11-24 01:14:14 +00001305 }else if( strcmp(z,"scratch")==0 ){
1306 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
1307 nScratch = integerValue(argv[i+1]);
1308 szScratch = integerValue(argv[i+2]);
1309 i += 2;
drh2e43e962015-07-03 14:34:25 +00001310 }else if( strcmp(z,"serialized")==0 ){
1311 sqlite3_config(SQLITE_CONFIG_SERIALIZED);
1312 }else if( strcmp(z,"singlethread")==0 ){
1313 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhad1ca9a2013-11-23 04:16:58 +00001314 }else if( strcmp(z,"sqlonly")==0 ){
1315 g.bSqlOnly = 1;
drh0d847182015-07-02 01:38:39 +00001316 }else if( strcmp(z,"shrink-memory")==0 ){
1317 g.bMemShrink = 1;
drhad1ca9a2013-11-23 04:16:58 +00001318 }else if( strcmp(z,"size")==0 ){
1319 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001320 g.szTest = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001321 }else if( strcmp(z,"stats")==0 ){
1322 showStats = 1;
1323 }else if( strcmp(z,"testset")==0 ){
1324 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1325 zTSet = argv[++i];
1326 }else if( strcmp(z,"trace")==0 ){
1327 doTrace = 1;
drh46a06bb2014-04-18 13:57:39 +00001328 }else if( strcmp(z,"threads")==0 ){
1329 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1330 nThread = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001331 }else if( strcmp(z,"utf16le")==0 ){
1332 zEncoding = "utf16le";
1333 }else if( strcmp(z,"utf16be")==0 ){
1334 zEncoding = "utf16be";
drh65e6b0d2014-04-28 17:56:19 +00001335 }else if( strcmp(z,"verify")==0 ){
1336 g.bVerify = 1;
drhad1ca9a2013-11-23 04:16:58 +00001337 }else if( strcmp(z,"without-rowid")==0 ){
1338 g.zWR = "WITHOUT ROWID";
1339 g.zPK = "PRIMARY KEY";
1340 }else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){
1341 printf(zHelp, argv[0]);
1342 exit(0);
1343 }else{
1344 fatal_error("unknown option: %s\nUse \"%s -?\" for help\n",
1345 argv[i], argv[0]);
1346 }
1347 }else if( zDbName==0 ){
1348 zDbName = argv[i];
1349 }else{
1350 fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n",
1351 argv[i], argv[0]);
1352 }
1353 }
1354#if 0
1355 if( zDbName==0 ){
1356 fatal_error(zHelp, argv[0]);
1357 }
1358#endif
drh5995e292015-06-18 12:37:32 +00001359#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001360 if( nHeap>0 ){
1361 pHeap = malloc( nHeap );
1362 if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
drhe19f8322013-11-23 11:45:58 +00001363 rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
drh7b65ad32013-11-23 21:29:07 +00001364 if( rc ) fatal_error("heap configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001365 }
drhee70a842015-07-06 18:54:52 +00001366 if( doPCache ){
1367 if( nPCache>0 && szPCache>0 ){
1368 pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
1369 if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
1370 nPCache*(sqlite3_int64)szPCache);
1371 }
drhe19f8322013-11-23 11:45:58 +00001372 rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
drh7b65ad32013-11-23 21:29:07 +00001373 if( rc ) fatal_error("pcache configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001374 }
drh93307e92013-11-24 01:14:14 +00001375 if( nScratch>0 && szScratch>0 ){
1376 pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
1377 if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n",
1378 nScratch*(sqlite3_int64)szScratch);
1379 rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
1380 if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
1381 }
drhad1ca9a2013-11-23 04:16:58 +00001382 if( nLook>0 ){
1383 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
1384 }
drh5995e292015-06-18 12:37:32 +00001385#endif
drhad1ca9a2013-11-23 04:16:58 +00001386
1387 /* Open the database and the input file */
1388 if( sqlite3_open(zDbName, &g.db) ){
1389 fatal_error("Cannot open database file: %s\n", zDbName);
1390 }
drh5995e292015-06-18 12:37:32 +00001391#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001392 if( nLook>0 && szLook>0 ){
1393 pLook = malloc( nLook*szLook );
drhe19f8322013-11-23 11:45:58 +00001394 rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
drh7b65ad32013-11-23 21:29:07 +00001395 if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001396 }
drh5995e292015-06-18 12:37:32 +00001397#endif
drhad1ca9a2013-11-23 04:16:58 +00001398
1399 /* Set database connection options */
1400 sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
1401 if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
drh43cbe142014-08-29 18:06:33 +00001402 speedtest1_exec("PRAGMA threads=%d", nThread);
drhad1ca9a2013-11-23 04:16:58 +00001403 if( zKey ){
1404 speedtest1_exec("PRAGMA key('%s')", zKey);
1405 }
1406 if( zEncoding ){
1407 speedtest1_exec("PRAGMA encoding=%s", zEncoding);
1408 }
1409 if( doAutovac ){
1410 speedtest1_exec("PRAGMA auto_vacuum=FULL");
1411 }else if( doIncrvac ){
1412 speedtest1_exec("PRAGMA auto_vacuum=INCREMENTAL");
1413 }
1414 if( pageSize ){
1415 speedtest1_exec("PRAGMA page_size=%d", pageSize);
1416 }
1417 if( cacheSize ){
1418 speedtest1_exec("PRAGMA cache_size=%d", cacheSize);
1419 }
1420 if( noSync ) speedtest1_exec("PRAGMA synchronous=OFF");
1421 if( doExclusive ){
1422 speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE");
1423 }
1424 if( zJMode ){
1425 speedtest1_exec("PRAGMA journal_mode=%s", zJMode);
1426 }
1427
drh849a9d92013-12-21 15:46:06 +00001428 if( g.bExplain ) printf(".explain\n.echo on\n");
drhad1ca9a2013-11-23 04:16:58 +00001429 if( strcmp(zTSet,"main")==0 ){
1430 testset_main();
1431 }else if( strcmp(zTSet,"debug1")==0 ){
1432 testset_debug1();
drhc4754802014-02-09 00:18:21 +00001433 }else if( strcmp(zTSet,"cte")==0 ){
1434 testset_cte();
drh65e6b0d2014-04-28 17:56:19 +00001435 }else if( strcmp(zTSet,"rtree")==0 ){
drh8683e082014-10-11 10:52:54 +00001436#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +00001437 testset_rtree(6, 147);
drh8683e082014-10-11 10:52:54 +00001438#else
1439 fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
1440 "the R-Tree tests\n");
1441#endif
drhad1ca9a2013-11-23 04:16:58 +00001442 }else{
drh65e6b0d2014-04-28 17:56:19 +00001443 fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n",
1444 zTSet);
drhad1ca9a2013-11-23 04:16:58 +00001445 }
1446 speedtest1_final();
1447
1448 /* Database connection statistics printed after both prepared statements
1449 ** have been finalized */
drh290ea402013-12-01 18:10:01 +00001450#if SQLITE_VERSION_NUMBER>=3007009
drhad1ca9a2013-11-23 04:16:58 +00001451 if( showStats ){
1452 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0);
1453 printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi);
1454 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0);
1455 printf("-- Successful lookasides: %d\n", iHi);
1456 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0);
1457 printf("-- Lookaside size faults: %d\n", iHi);
1458 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0);
1459 printf("-- Lookaside OOM faults: %d\n", iHi);
1460 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0);
1461 printf("-- Pager Heap Usage: %d bytes\n", iCur);
1462 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1);
1463 printf("-- Page cache hits: %d\n", iCur);
1464 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1);
drh2a702db2013-12-02 21:25:40 +00001465 printf("-- Page cache misses: %d\n", iCur);
1466#if SQLITE_VERSION_NUMBER>=3007012
drhad1ca9a2013-11-23 04:16:58 +00001467 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1);
1468 printf("-- Page cache writes: %d\n", iCur);
drh2a702db2013-12-02 21:25:40 +00001469#endif
drhad1ca9a2013-11-23 04:16:58 +00001470 sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0);
1471 printf("-- Schema Heap Usage: %d bytes\n", iCur);
1472 sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
1473 printf("-- Statement Heap Usage: %d bytes\n", iCur);
1474 }
drh290ea402013-12-01 18:10:01 +00001475#endif
drhad1ca9a2013-11-23 04:16:58 +00001476
1477 sqlite3_close(g.db);
1478
drh5995e292015-06-18 12:37:32 +00001479#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001480 /* Global memory usage statistics printed after the database connection
1481 ** has closed. Memory usage should be zero at this point. */
1482 if( showStats ){
1483 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
1484 printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001485#if SQLITE_VERSION_NUMBER>=3007000
drhad1ca9a2013-11-23 04:16:58 +00001486 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
1487 printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001488#endif
drhad1ca9a2013-11-23 04:16:58 +00001489 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0);
1490 printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi);
1491 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0);
1492 printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi);
1493 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
1494 printf("-- Largest Allocation: %d bytes\n",iHi);
1495 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
1496 printf("-- Largest Pcache Allocation: %d bytes\n",iHi);
1497 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
1498 printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
1499 }
drh5995e292015-06-18 12:37:32 +00001500#endif
drhad1ca9a2013-11-23 04:16:58 +00001501
drhfc1a84c2016-02-27 19:19:22 +00001502#ifdef __linux__
1503 if( showStats ){
1504 displayLinuxIoStats(stdout);
1505 }
1506#endif
1507
drhad1ca9a2013-11-23 04:16:58 +00001508 /* Release memory */
1509 free( pLook );
1510 free( pPCache );
drh93307e92013-11-24 01:14:14 +00001511 free( pScratch );
drhad1ca9a2013-11-23 04:16:58 +00001512 free( pHeap );
1513 return 0;
1514}