blob: b34dae65aedf8255c7833fda7b717d95801a144d [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>
50
drh43076902015-06-18 15:26:09 +000051#if SQLITE_VERSION_NUMBER<3005000
52# define sqlite3_int64 sqlite_int64
53#endif
drhcfb8f8d2015-07-23 20:44:49 +000054#ifdef SQLITE_ENABLE_RBU
55# include "sqlite3rbu.h"
dan54fc2142015-03-05 16:21:20 +000056#endif
57
drhad1ca9a2013-11-23 04:16:58 +000058/* All global state is held in this structure */
59static struct Global {
60 sqlite3 *db; /* The open database connection */
61 sqlite3_stmt *pStmt; /* Current SQL statement */
62 sqlite3_int64 iStart; /* Start-time for the current test */
63 sqlite3_int64 iTotal; /* Total time */
64 int bWithoutRowid; /* True for --without-rowid */
65 int bReprepare; /* True to reprepare the SQL on each rerun */
66 int bSqlOnly; /* True to print the SQL once only */
drh849a9d92013-12-21 15:46:06 +000067 int bExplain; /* Print SQL with EXPLAIN prefix */
drh65e6b0d2014-04-28 17:56:19 +000068 int bVerify; /* Try to verify that results are correct */
drh0d847182015-07-02 01:38:39 +000069 int bMemShrink; /* Call sqlite3_db_release_memory() often */
drhad1ca9a2013-11-23 04:16:58 +000070 int szTest; /* Scale factor for test iterations */
71 const char *zWR; /* Might be WITHOUT ROWID */
72 const char *zNN; /* Might be NOT NULL */
73 const char *zPK; /* Might be UNIQUE or PRIMARY KEY */
74 unsigned int x, y; /* Pseudo-random number generator state */
75 int nResult; /* Size of the current result */
76 char zResult[3000]; /* Text of the current result */
77} g;
78
drhad1ca9a2013-11-23 04:16:58 +000079
drh93307e92013-11-24 01:14:14 +000080/* Print an error message and exit */
81static void fatal_error(const char *zMsg, ...){
82 va_list ap;
83 va_start(ap, zMsg);
84 vfprintf(stderr, zMsg, ap);
85 va_end(ap);
86 exit(1);
drhad1ca9a2013-11-23 04:16:58 +000087}
88
89/*
90** Return the value of a hexadecimal digit. Return -1 if the input
91** is not a hex digit.
92*/
93static int hexDigitValue(char c){
94 if( c>='0' && c<='9' ) return c - '0';
95 if( c>='a' && c<='f' ) return c - 'a' + 10;
96 if( c>='A' && c<='F' ) return c - 'A' + 10;
97 return -1;
98}
99
drh290ea402013-12-01 18:10:01 +0000100/* Provide an alternative to sqlite3_stricmp() in older versions of
101** SQLite */
102#if SQLITE_VERSION_NUMBER<3007011
103# define sqlite3_stricmp strcmp
104#endif
105
drhad1ca9a2013-11-23 04:16:58 +0000106/*
107** Interpret zArg as an integer value, possibly with suffixes.
108*/
drh93307e92013-11-24 01:14:14 +0000109static int integerValue(const char *zArg){
drhad1ca9a2013-11-23 04:16:58 +0000110 sqlite3_int64 v = 0;
111 static const struct { char *zSuffix; int iMult; } aMult[] = {
112 { "KiB", 1024 },
113 { "MiB", 1024*1024 },
114 { "GiB", 1024*1024*1024 },
115 { "KB", 1000 },
116 { "MB", 1000000 },
117 { "GB", 1000000000 },
118 { "K", 1000 },
119 { "M", 1000000 },
120 { "G", 1000000000 },
121 };
122 int i;
123 int isNeg = 0;
124 if( zArg[0]=='-' ){
125 isNeg = 1;
126 zArg++;
127 }else if( zArg[0]=='+' ){
128 zArg++;
129 }
130 if( zArg[0]=='0' && zArg[1]=='x' ){
131 int x;
132 zArg += 2;
133 while( (x = hexDigitValue(zArg[0]))>=0 ){
134 v = (v<<4) + x;
135 zArg++;
136 }
137 }else{
138 while( isdigit(zArg[0]) ){
139 v = v*10 + zArg[0] - '0';
140 zArg++;
141 }
142 }
143 for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
144 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
145 v *= aMult[i].iMult;
146 break;
147 }
148 }
mistachkinb87875a2013-11-27 18:00:20 +0000149 if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
drhdcb5fa02013-11-27 14:50:51 +0000150 return (int)(isNeg? -v : v);
drhad1ca9a2013-11-23 04:16:58 +0000151}
152
153/* Return the current wall-clock time, in milliseconds */
154sqlite3_int64 speedtest1_timestamp(void){
drh43076902015-06-18 15:26:09 +0000155#if SQLITE_VERSION_NUMBER<3005000
156 return 0;
157#else
drhad1ca9a2013-11-23 04:16:58 +0000158 static sqlite3_vfs *clockVfs = 0;
159 sqlite3_int64 t;
160 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
drhd79e9c52013-12-02 01:24:05 +0000161#if SQLITE_VERSION_NUMBER>=3007000
drh290ea402013-12-01 18:10:01 +0000162 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drhad1ca9a2013-11-23 04:16:58 +0000163 clockVfs->xCurrentTimeInt64(clockVfs, &t);
drhd79e9c52013-12-02 01:24:05 +0000164 }else
165#endif
166 {
drhad1ca9a2013-11-23 04:16:58 +0000167 double r;
168 clockVfs->xCurrentTime(clockVfs, &r);
169 t = (sqlite3_int64)(r*86400000.0);
170 }
171 return t;
drh43076902015-06-18 15:26:09 +0000172#endif
drhad1ca9a2013-11-23 04:16:58 +0000173}
174
175/* Return a pseudo-random unsigned integer */
176unsigned int speedtest1_random(void){
177 g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001);
178 g.y = g.y*1103515245 + 12345;
179 return g.x ^ g.y;
180}
181
182/* Map the value in within the range of 1...limit into another
183** number in a way that is chatic and invertable.
184*/
185unsigned swizzle(unsigned in, unsigned limit){
186 unsigned out = 0;
187 while( limit ){
188 out = (out<<1) | (in&1);
189 in >>= 1;
190 limit >>= 1;
191 }
192 return out;
193}
194
195/* Round up a number so that it is a power of two minus one
196*/
197unsigned roundup_allones(unsigned limit){
198 unsigned m = 1;
199 while( m<limit ) m = (m<<1)+1;
200 return m;
201}
202
203/* The speedtest1_numbername procedure below converts its argment (an integer)
204** into a string which is the English-language name for that number.
205** The returned string should be freed with sqlite3_free().
206**
207** Example:
208**
209** speedtest1_numbername(123) -> "one hundred twenty three"
210*/
211int speedtest1_numbername(unsigned int n, char *zOut, int nOut){
212 static const char *ones[] = { "zero", "one", "two", "three", "four", "five",
213 "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
214 "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
215 "eighteen", "nineteen" };
216 static const char *tens[] = { "", "ten", "twenty", "thirty", "forty",
217 "fifty", "sixty", "seventy", "eighty", "ninety" };
218 int i = 0;
219
220 if( n>=1000000000 ){
221 i += speedtest1_numbername(n/1000000000, zOut+i, nOut-i);
222 sqlite3_snprintf(nOut-i, zOut+i, " billion");
223 i += (int)strlen(zOut+i);
224 n = n % 1000000000;
225 }
226 if( n>=1000000 ){
227 if( i && i<nOut-1 ) zOut[i++] = ' ';
228 i += speedtest1_numbername(n/1000000, zOut+i, nOut-i);
229 sqlite3_snprintf(nOut-i, zOut+i, " million");
230 i += (int)strlen(zOut+i);
231 n = n % 1000000;
232 }
233 if( n>=1000 ){
234 if( i && i<nOut-1 ) zOut[i++] = ' ';
235 i += speedtest1_numbername(n/1000, zOut+i, nOut-i);
236 sqlite3_snprintf(nOut-i, zOut+i, " thousand");
237 i += (int)strlen(zOut+i);
238 n = n % 1000;
239 }
240 if( n>=100 ){
241 if( i && i<nOut-1 ) zOut[i++] = ' ';
242 sqlite3_snprintf(nOut-i, zOut+i, "%s hundred", ones[n/100]);
243 i += (int)strlen(zOut+i);
244 n = n % 100;
245 }
246 if( n>=20 ){
247 if( i && i<nOut-1 ) zOut[i++] = ' ';
248 sqlite3_snprintf(nOut-i, zOut+i, "%s", tens[n/10]);
249 i += (int)strlen(zOut+i);
250 n = n % 10;
251 }
252 if( n>0 ){
253 if( i && i<nOut-1 ) zOut[i++] = ' ';
254 sqlite3_snprintf(nOut-i, zOut+i, "%s", ones[n]);
255 i += (int)strlen(zOut+i);
256 }
257 if( i==0 ){
258 sqlite3_snprintf(nOut-i, zOut+i, "zero");
259 i += (int)strlen(zOut+i);
260 }
261 return i;
262}
263
264
265/* Start a new test case */
266#define NAMEWIDTH 60
267static const char zDots[] =
268 ".......................................................................";
269void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){
270 int n = (int)strlen(zTestName);
271 char *zName;
272 va_list ap;
273 va_start(ap, zTestName);
274 zName = sqlite3_vmprintf(zTestName, ap);
275 va_end(ap);
276 n = (int)strlen(zName);
277 if( n>NAMEWIDTH ){
278 zName[NAMEWIDTH] = 0;
279 n = NAMEWIDTH;
280 }
281 if( g.bSqlOnly ){
282 printf("/* %4d - %s%.*s */\n", iTestNum, zName, NAMEWIDTH-n, zDots);
283 }else{
284 printf("%4d - %s%.*s ", iTestNum, zName, NAMEWIDTH-n, zDots);
285 fflush(stdout);
286 }
287 sqlite3_free(zName);
288 g.nResult = 0;
289 g.iStart = speedtest1_timestamp();
drhdcb5fa02013-11-27 14:50:51 +0000290 g.x = 0xad131d0b;
291 g.y = 0x44f9eac8;
drhad1ca9a2013-11-23 04:16:58 +0000292}
293
294/* Complete a test case */
295void speedtest1_end_test(void){
296 sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart;
297 if( !g.bSqlOnly ){
298 g.iTotal += iElapseTime;
299 printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000));
300 }
301 if( g.pStmt ){
302 sqlite3_finalize(g.pStmt);
303 g.pStmt = 0;
304 }
305}
306
307/* Report end of testing */
308void speedtest1_final(void){
309 if( !g.bSqlOnly ){
310 printf(" TOTAL%.*s %4d.%03ds\n", NAMEWIDTH-5, zDots,
311 (int)(g.iTotal/1000), (int)(g.iTotal%1000));
312 }
313}
314
drh849a9d92013-12-21 15:46:06 +0000315/* Print an SQL statement to standard output */
316static void printSql(const char *zSql){
317 int n = (int)strlen(zSql);
318 while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
319 if( g.bExplain ) printf("EXPLAIN ");
320 printf("%.*s;\n", n, zSql);
321 if( g.bExplain
drh5995e292015-06-18 12:37:32 +0000322#if SQLITE_VERSION_NUMBER>=3007017
drh25555502013-12-21 17:14:58 +0000323 && ( sqlite3_strglob("CREATE *", zSql)==0
324 || sqlite3_strglob("DROP *", zSql)==0
325 || sqlite3_strglob("ALTER *", zSql)==0
drh849a9d92013-12-21 15:46:06 +0000326 )
drh25555502013-12-21 17:14:58 +0000327#endif
drh849a9d92013-12-21 15:46:06 +0000328 ){
329 printf("%.*s;\n", n, zSql);
330 }
331}
332
drh0d847182015-07-02 01:38:39 +0000333/* Shrink memory used, if appropriate and if the SQLite version is capable
334** of doing so.
335*/
336void speedtest1_shrink_memory(void){
337#if SQLITE_VERSION_NUMBER>=3007010
338 if( g.bMemShrink ) sqlite3_db_release_memory(g.db);
339#endif
340}
341
drhad1ca9a2013-11-23 04:16:58 +0000342/* Run SQL */
343void speedtest1_exec(const char *zFormat, ...){
344 va_list ap;
345 char *zSql;
346 va_start(ap, zFormat);
347 zSql = sqlite3_vmprintf(zFormat, ap);
348 va_end(ap);
349 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000350 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000351 }else{
drhe19f8322013-11-23 11:45:58 +0000352 char *zErrMsg = 0;
353 int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
354 if( zErrMsg ) fatal_error("SQL error: %s\n%s\n", zErrMsg, zSql);
355 if( rc!=SQLITE_OK ) fatal_error("exec error: %s\n", sqlite3_errmsg(g.db));
drhad1ca9a2013-11-23 04:16:58 +0000356 }
357 sqlite3_free(zSql);
drh0d847182015-07-02 01:38:39 +0000358 speedtest1_shrink_memory();
drhad1ca9a2013-11-23 04:16:58 +0000359}
360
361/* Prepare an SQL statement */
362void speedtest1_prepare(const char *zFormat, ...){
363 va_list ap;
364 char *zSql;
365 va_start(ap, zFormat);
366 zSql = sqlite3_vmprintf(zFormat, ap);
367 va_end(ap);
368 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000369 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000370 }else{
371 int rc;
372 if( g.pStmt ) sqlite3_finalize(g.pStmt);
373 rc = sqlite3_prepare_v2(g.db, zSql, -1, &g.pStmt, 0);
374 if( rc ){
375 fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
376 }
377 }
378 sqlite3_free(zSql);
379}
380
381/* Run an SQL statement previously prepared */
382void speedtest1_run(void){
383 int i, n, len;
384 if( g.bSqlOnly ) return;
385 assert( g.pStmt );
386 g.nResult = 0;
387 while( sqlite3_step(g.pStmt)==SQLITE_ROW ){
388 n = sqlite3_column_count(g.pStmt);
389 for(i=0; i<n; i++){
390 const char *z = (const char*)sqlite3_column_text(g.pStmt, i);
391 if( z==0 ) z = "nil";
392 len = (int)strlen(z);
393 if( g.nResult+len<sizeof(g.zResult)-2 ){
394 if( g.nResult>0 ) g.zResult[g.nResult++] = ' ';
395 memcpy(g.zResult + g.nResult, z, len+1);
396 g.nResult += len;
397 }
398 }
399 }
drh5995e292015-06-18 12:37:32 +0000400#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +0000401 if( g.bReprepare ){
402 sqlite3_stmt *pNew;
403 sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
404 sqlite3_finalize(g.pStmt);
405 g.pStmt = pNew;
drh5995e292015-06-18 12:37:32 +0000406 }else
407#endif
408 {
drhad1ca9a2013-11-23 04:16:58 +0000409 sqlite3_reset(g.pStmt);
410 }
drh0d847182015-07-02 01:38:39 +0000411 speedtest1_shrink_memory();
drhad1ca9a2013-11-23 04:16:58 +0000412}
413
414/* The sqlite3_trace() callback function */
415static void traceCallback(void *NotUsed, const char *zSql){
416 int n = (int)strlen(zSql);
417 while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ) n--;
418 fprintf(stderr,"%.*s;\n", n, zSql);
419}
420
421/* Substitute random() function that gives the same random
422** sequence on each run, for repeatability. */
423static void randomFunc(
424 sqlite3_context *context,
425 int NotUsed,
426 sqlite3_value **NotUsed2
427){
428 sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random());
429}
430
drhae28d6e2013-12-21 00:04:37 +0000431/* Estimate the square root of an integer */
432static int est_square_root(int x){
433 int y0 = x/2;
434 int y1;
435 int n;
436 for(n=0; y0>0 && n<10; n++){
437 y1 = (y0 + x/y0)/2;
438 if( y1==y0 ) break;
439 y0 = y1;
440 }
441 return y0;
442}
443
drhad1ca9a2013-11-23 04:16:58 +0000444/*
445** The main and default testset
446*/
447void testset_main(void){
448 int i; /* Loop counter */
449 int n; /* iteration count */
450 int sz; /* Size of the tables */
451 int maxb; /* Maximum swizzled value */
452 unsigned x1, x2; /* Parameters */
453 int len; /* Length of the zNum[] string */
454 char zNum[2000]; /* A number name */
455
456 sz = n = g.szTest*500;
457 maxb = roundup_allones(sz);
458 speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
459 speedtest1_exec("BEGIN");
460 speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
461 g.zNN, g.zNN, g.zNN);
462 speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n);
463 for(i=1; i<=n; i++){
464 x1 = swizzle(i,maxb);
465 speedtest1_numbername(x1, zNum, sizeof(zNum));
466 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
467 sqlite3_bind_int(g.pStmt, 2, i);
468 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
469 speedtest1_run();
470 }
471 speedtest1_exec("COMMIT");
472 speedtest1_end_test();
473
474
475 n = sz;
476 speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
477 speedtest1_exec("BEGIN");
478 speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
479 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
480 speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
481 for(i=1; i<=n; i++){
482 x1 = swizzle(i,maxb);
483 speedtest1_numbername(x1, zNum, sizeof(zNum));
484 sqlite3_bind_int(g.pStmt, 1, i);
485 sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1);
486 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
487 speedtest1_run();
488 }
489 speedtest1_exec("COMMIT");
490 speedtest1_end_test();
491
492
493 n = sz;
494 speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
495 speedtest1_exec("BEGIN");
496 speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
497 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
498 speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
499 for(i=1; i<=n; i++){
500 x1 = swizzle(i,maxb);
501 speedtest1_numbername(x1, zNum, sizeof(zNum));
502 sqlite3_bind_int(g.pStmt, 2, i);
503 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
504 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
505 speedtest1_run();
506 }
507 speedtest1_exec("COMMIT");
508 speedtest1_end_test();
509
510
drh5e8980d2014-03-25 20:28:38 +0000511 n = 25;
drhad1ca9a2013-11-23 04:16:58 +0000512 speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
513 speedtest1_exec("BEGIN");
514 speedtest1_prepare(
515 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
516 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
517 );
518 for(i=1; i<=n; i++){
519 x1 = speedtest1_random()%maxb;
520 x2 = speedtest1_random()%10 + sz/5000 + x1;
521 sqlite3_bind_int(g.pStmt, 1, x1);
522 sqlite3_bind_int(g.pStmt, 2, x2);
523 speedtest1_run();
524 }
525 speedtest1_exec("COMMIT");
526 speedtest1_end_test();
527
528
drh5e8980d2014-03-25 20:28:38 +0000529 n = 10;
drhad1ca9a2013-11-23 04:16:58 +0000530 speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
531 speedtest1_exec("BEGIN");
532 speedtest1_prepare(
533 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
534 " WHERE c LIKE ?1; -- %d times", n
535 );
536 for(i=1; i<=n; i++){
537 x1 = speedtest1_random()%maxb;
538 zNum[0] = '%';
539 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
540 zNum[len] = '%';
541 zNum[len+1] = 0;
542 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
543 speedtest1_run();
544 }
545 speedtest1_exec("COMMIT");
546 speedtest1_end_test();
547
548
drh5e8980d2014-03-25 20:28:38 +0000549 n = 10;
drhc8729662014-03-25 17:45:49 +0000550 speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
551 speedtest1_exec("BEGIN");
552 speedtest1_prepare(
553 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
554 " ORDER BY a; -- %d times", n
555 );
556 for(i=1; i<=n; i++){
557 x1 = speedtest1_random()%maxb;
558 zNum[0] = '%';
559 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
560 zNum[len] = '%';
561 zNum[len+1] = 0;
562 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
563 speedtest1_run();
564 }
565 speedtest1_exec("COMMIT");
566 speedtest1_end_test();
567
dan54fc2142015-03-05 16:21:20 +0000568 n = 10; /* g.szTest/5; */
drhc8729662014-03-25 17:45:49 +0000569 speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
drh0c60c1f2014-03-25 14:54:36 +0000570 speedtest1_exec("BEGIN");
571 speedtest1_prepare(
572 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
573 " ORDER BY a LIMIT 10; -- %d times", n
574 );
575 for(i=1; i<=n; i++){
576 x1 = speedtest1_random()%maxb;
577 zNum[0] = '%';
578 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
579 zNum[len] = '%';
580 zNum[len+1] = 0;
581 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
582 speedtest1_run();
583 }
584 speedtest1_exec("COMMIT");
585 speedtest1_end_test();
586
587
drhad1ca9a2013-11-23 04:16:58 +0000588 speedtest1_begin_test(150, "CREATE INDEX five times");
drh849a9d92013-12-21 15:46:06 +0000589 speedtest1_exec("BEGIN;");
590 speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
591 speedtest1_exec("CREATE INDEX t1c ON t1(c);");
592 speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
593 speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
594 speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
595 speedtest1_exec("COMMIT;");
drhad1ca9a2013-11-23 04:16:58 +0000596 speedtest1_end_test();
597
598
599 n = sz/5;
600 speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
601 speedtest1_exec("BEGIN");
602 speedtest1_prepare(
603 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
604 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
605 );
606 for(i=1; i<=n; i++){
607 x1 = speedtest1_random()%maxb;
608 x2 = speedtest1_random()%10 + sz/5000 + x1;
609 sqlite3_bind_int(g.pStmt, 1, x1);
610 sqlite3_bind_int(g.pStmt, 2, x2);
611 speedtest1_run();
612 }
613 speedtest1_exec("COMMIT");
614 speedtest1_end_test();
615
616
617 n = sz/5;
618 speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
619 speedtest1_exec("BEGIN");
620 speedtest1_prepare(
621 "SELECT count(*), avg(b), sum(length(c)) FROM t2\n"
622 " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
623 );
624 for(i=1; i<=n; i++){
625 x1 = speedtest1_random()%maxb;
626 x2 = speedtest1_random()%10 + sz/5000 + x1;
627 sqlite3_bind_int(g.pStmt, 1, x1);
628 sqlite3_bind_int(g.pStmt, 2, x2);
629 speedtest1_run();
630 }
631 speedtest1_exec("COMMIT");
632 speedtest1_end_test();
633
634
635 n = sz/5;
636 speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
637 speedtest1_exec("BEGIN");
638 speedtest1_prepare(
639 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
640 " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
641 );
642 for(i=1; i<=n; i++){
643 x1 = swizzle(i, maxb);
644 len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
645 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
646 speedtest1_run();
647 }
648 speedtest1_exec("COMMIT");
649 speedtest1_end_test();
650
651 n = sz;
652 speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
653 speedtest1_exec("BEGIN");
654 speedtest1_exec(
655 "CREATE TABLE t4(\n"
656 " a INTEGER %s %s,\n"
657 " b INTEGER %s,\n"
658 " c TEXT %s\n"
659 ") %s",
660 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
661 speedtest1_exec("CREATE INDEX t4b ON t4(b)");
662 speedtest1_exec("CREATE INDEX t4c ON t4(c)");
663 speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
664 speedtest1_exec("COMMIT");
665 speedtest1_end_test();
666
667 n = sz;
668 speedtest1_begin_test(190, "DELETE and REFILL one table", n);
drh849a9d92013-12-21 15:46:06 +0000669 speedtest1_exec("DELETE FROM t2;");
670 speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
drhad1ca9a2013-11-23 04:16:58 +0000671 speedtest1_end_test();
672
673
674 speedtest1_begin_test(200, "VACUUM");
675 speedtest1_exec("VACUUM");
676 speedtest1_end_test();
677
678
679 speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
680 speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123");
681 speedtest1_exec("SELECT sum(d) FROM t2");
682 speedtest1_end_test();
683
684
685 n = sz/5;
686 speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n);
687 speedtest1_exec("BEGIN");
688 speedtest1_prepare(
689 "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
690 );
691 for(i=1; i<=n; i++){
692 x1 = speedtest1_random()%maxb;
693 x2 = speedtest1_random()%10 + sz/5000 + x1;
694 sqlite3_bind_int(g.pStmt, 1, x1);
695 sqlite3_bind_int(g.pStmt, 2, x2);
696 speedtest1_run();
697 }
698 speedtest1_exec("COMMIT");
699 speedtest1_end_test();
700
701
702 n = sz;
703 speedtest1_begin_test(240, "%d UPDATES of individual rows", n);
704 speedtest1_exec("BEGIN");
705 speedtest1_prepare(
706 "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n
707 );
708 for(i=1; i<=n; i++){
709 x1 = speedtest1_random()%sz + 1;
710 sqlite3_bind_int(g.pStmt, 1, x1);
711 speedtest1_run();
712 }
713 speedtest1_exec("COMMIT");
714 speedtest1_end_test();
715
716 speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz);
717 speedtest1_exec("UPDATE t2 SET d=b*4");
718 speedtest1_end_test();
719
720
721 speedtest1_begin_test(260, "Query added column after filling");
722 speedtest1_exec("SELECT sum(d) FROM t2");
723 speedtest1_end_test();
724
725
726
727 n = sz/5;
728 speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n);
729 speedtest1_exec("BEGIN");
730 speedtest1_prepare(
731 "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
732 );
733 for(i=1; i<=n; i++){
734 x1 = speedtest1_random()%maxb + 1;
735 x2 = speedtest1_random()%10 + sz/5000 + x1;
736 sqlite3_bind_int(g.pStmt, 1, x1);
737 sqlite3_bind_int(g.pStmt, 2, x2);
738 speedtest1_run();
739 }
740 speedtest1_exec("COMMIT");
741 speedtest1_end_test();
742
743
744 n = sz;
745 speedtest1_begin_test(280, "%d DELETEs of individual rows", n);
746 speedtest1_exec("BEGIN");
747 speedtest1_prepare(
748 "DELETE FROM t3 WHERE a=?1; -- %d times", n
749 );
750 for(i=1; i<=n; i++){
751 x1 = speedtest1_random()%sz + 1;
752 sqlite3_bind_int(g.pStmt, 1, x1);
753 speedtest1_run();
754 }
755 speedtest1_exec("COMMIT");
756 speedtest1_end_test();
757
758
759 speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz);
drhe19f8322013-11-23 11:45:58 +0000760 speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1");
761 speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
drhad1ca9a2013-11-23 04:16:58 +0000762 speedtest1_end_test();
763
drh039468e2013-12-18 16:27:48 +0000764 speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
765 speedtest1_exec("DELETE FROM t2;");
drh849a9d92013-12-21 15:46:06 +0000766 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
767 " SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);");
768 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
769 " SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);");
drh039468e2013-12-18 16:27:48 +0000770 speedtest1_end_test();
771
drhad1ca9a2013-11-23 04:16:58 +0000772
773 n = sz/5;
drh039468e2013-12-18 16:27:48 +0000774 speedtest1_begin_test(310, "%d four-ways joins", n);
drhad1ca9a2013-11-23 04:16:58 +0000775 speedtest1_exec("BEGIN");
776 speedtest1_prepare(
777 "SELECT t1.c FROM t1, t2, t3, t4\n"
778 " WHERE t4.a BETWEEN ?1 AND ?2\n"
779 " AND t3.a=t4.b\n"
780 " AND t2.a=t3.b\n"
781 " AND t1.c=t2.c"
782 );
783 for(i=1; i<=n; i++){
784 x1 = speedtest1_random()%sz + 1;
785 x2 = speedtest1_random()%10 + x1 + 4;
786 sqlite3_bind_int(g.pStmt, 1, x1);
787 sqlite3_bind_int(g.pStmt, 2, x2);
788 speedtest1_run();
789 }
790 speedtest1_exec("COMMIT");
791 speedtest1_end_test();
792
drhae28d6e2013-12-21 00:04:37 +0000793 speedtest1_begin_test(320, "subquery in result set", n);
794 speedtest1_prepare(
795 "SELECT sum(a), max(c),\n"
796 " avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
797 " FROM t1 WHERE rowid<?1;"
798 );
799 sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
800 speedtest1_run();
801 speedtest1_end_test();
drhad1ca9a2013-11-23 04:16:58 +0000802
803 speedtest1_begin_test(980, "PRAGMA integrity_check");
804 speedtest1_exec("PRAGMA integrity_check");
805 speedtest1_end_test();
806
807
808 speedtest1_begin_test(990, "ANALYZE");
809 speedtest1_exec("ANALYZE");
810 speedtest1_end_test();
811}
812
813/*
drhc4754802014-02-09 00:18:21 +0000814** A testset for common table expressions. This exercises code
815** for views, subqueries, co-routines, etc.
816*/
817void testset_cte(void){
818 static const char *azPuzzle[] = {
819 /* Easy */
820 "534...9.."
821 "67.195..."
822 ".98....6."
823 "8...6...3"
824 "4..8.3..1"
825 "....2...6"
826 ".6....28."
827 "...419..5"
828 "...28..79",
829
830 /* Medium */
831 "53....9.."
832 "6..195..."
833 ".98....6."
834 "8...6...3"
835 "4..8.3..1"
836 "....2...6"
837 ".6....28."
838 "...419..5"
839 "....8..79",
840
841 /* Hard */
842 "53......."
843 "6..195..."
844 ".98....6."
845 "8...6...3"
846 "4..8.3..1"
847 "....2...6"
848 ".6....28."
849 "...419..5"
850 "....8..79",
851 };
852 const char *zPuz;
drhfa46bfb2014-02-09 00:52:53 +0000853 double rSpacing;
drh5574e3f2014-02-09 23:59:28 +0000854 int nElem;
drhc4754802014-02-09 00:18:21 +0000855
856 if( g.szTest<25 ){
857 zPuz = azPuzzle[0];
858 }else if( g.szTest<70 ){
859 zPuz = azPuzzle[1];
860 }else{
861 zPuz = azPuzzle[2];
862 }
863 speedtest1_begin_test(100, "Sudoku with recursive 'digits'");
864 speedtest1_prepare(
865 "WITH RECURSIVE\n"
866 " input(sud) AS (VALUES(?1)),\n"
867 " digits(z,lp) AS (\n"
868 " VALUES('1', 1)\n"
869 " UNION ALL\n"
870 " SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9\n"
871 " ),\n"
872 " x(s, ind) AS (\n"
873 " SELECT sud, instr(sud, '.') FROM input\n"
874 " UNION ALL\n"
875 " SELECT\n"
876 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
877 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
878 " FROM x, digits AS z\n"
879 " WHERE ind>0\n"
880 " AND NOT EXISTS (\n"
881 " SELECT 1\n"
882 " FROM digits AS lp\n"
883 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
884 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
885 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
886 " + ((ind-1)/27) * 27 + lp\n"
887 " + ((lp-1) / 3) * 6, 1)\n"
888 " )\n"
889 " )\n"
890 "SELECT s FROM x WHERE ind=0;"
891 );
892 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
893 speedtest1_run();
894 speedtest1_end_test();
895
896 speedtest1_begin_test(200, "Sudoku with VALUES 'digits'");
897 speedtest1_prepare(
898 "WITH RECURSIVE\n"
899 " input(sud) AS (VALUES(?1)),\n"
900 " digits(z,lp) AS (VALUES('1',1),('2',2),('3',3),('4',4),('5',5),\n"
901 " ('6',6),('7',7),('8',8),('9',9)),\n"
902 " x(s, ind) AS (\n"
903 " SELECT sud, instr(sud, '.') FROM input\n"
904 " UNION ALL\n"
905 " SELECT\n"
906 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
907 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
908 " FROM x, digits AS z\n"
909 " WHERE ind>0\n"
910 " AND NOT EXISTS (\n"
911 " SELECT 1\n"
912 " FROM digits AS lp\n"
913 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
914 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
915 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
916 " + ((ind-1)/27) * 27 + lp\n"
917 " + ((lp-1) / 3) * 6, 1)\n"
918 " )\n"
919 " )\n"
920 "SELECT s FROM x WHERE ind=0;"
921 );
922 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
923 speedtest1_run();
924 speedtest1_end_test();
drhfa46bfb2014-02-09 00:52:53 +0000925
926 rSpacing = 5.0/g.szTest;
927 speedtest1_begin_test(300, "Mandelbrot Set with spacing=%f", rSpacing);
928 speedtest1_prepare(
929 "WITH RECURSIVE \n"
930 " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+?1 FROM xaxis WHERE x<1.2),\n"
931 " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+?2 FROM yaxis WHERE y<1.0),\n"
932 " m(iter, cx, cy, x, y) AS (\n"
933 " SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis\n"
934 " UNION ALL\n"
935 " SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m \n"
936 " WHERE (x*x + y*y) < 4.0 AND iter<28\n"
937 " ),\n"
938 " m2(iter, cx, cy) AS (\n"
939 " SELECT max(iter), cx, cy FROM m GROUP BY cx, cy\n"
940 " ),\n"
941 " a(t) AS (\n"
942 " SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') \n"
943 " FROM m2 GROUP BY cy\n"
944 " )\n"
945 "SELECT group_concat(rtrim(t),x'0a') FROM a;"
946 );
947 sqlite3_bind_double(g.pStmt, 1, rSpacing*.05);
948 sqlite3_bind_double(g.pStmt, 2, rSpacing);
949 speedtest1_run();
950 speedtest1_end_test();
951
drh5574e3f2014-02-09 23:59:28 +0000952 nElem = 10000*g.szTest;
953 speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem);
954 speedtest1_prepare(
955 "WITH RECURSIVE \n"
956 " t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n"
957 " t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n"
958 "SELECT count(x), avg(x) FROM (\n"
959 " SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n"
960 ");",
961 nElem, nElem
962 );
963 speedtest1_run();
964 speedtest1_end_test();
965
drhc4754802014-02-09 00:18:21 +0000966}
967
drh8683e082014-10-11 10:52:54 +0000968#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000969/* Generate two numbers between 1 and mx. The first number is less than
970** the second. Usually the numbers are near each other but can sometimes
971** be far apart.
972*/
973static void twoCoords(
974 int p1, int p2, /* Parameters adjusting sizes */
975 unsigned mx, /* Range of 1..mx */
976 unsigned *pX0, unsigned *pX1 /* OUT: write results here */
977){
978 unsigned d, x0, x1, span;
979
980 span = mx/100 + 1;
981 if( speedtest1_random()%3==0 ) span *= p1;
982 if( speedtest1_random()%p2==0 ) span = mx/2;
983 d = speedtest1_random()%span + 1;
984 x0 = speedtest1_random()%(mx-d) + 1;
985 x1 = x0 + d;
986 *pX0 = x0;
987 *pX1 = x1;
988}
drh8683e082014-10-11 10:52:54 +0000989#endif
drh65e6b0d2014-04-28 17:56:19 +0000990
drh8683e082014-10-11 10:52:54 +0000991#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000992/* The following routine is an R-Tree geometry callback. It returns
993** true if the object overlaps a slice on the Y coordinate between the
994** two values given as arguments. In other words
995**
996** SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20);
997**
998** Is the same as saying:
999**
1000** SELECT count(*) FROM rt1 WHERE y1>=10 AND y0<=20;
1001*/
1002static int xsliceGeometryCallback(
1003 sqlite3_rtree_geometry *p,
1004 int nCoord,
1005 double *aCoord,
1006 int *pRes
1007){
1008 *pRes = aCoord[3]>=p->aParam[0] && aCoord[2]<=p->aParam[1];
1009 return SQLITE_OK;
1010}
drh8683e082014-10-11 10:52:54 +00001011#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +00001012
drh8683e082014-10-11 10:52:54 +00001013#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +00001014/*
1015** A testset for the R-Tree virtual table
1016*/
1017void testset_rtree(int p1, int p2){
1018 unsigned i, n;
1019 unsigned mxCoord;
1020 unsigned x0, x1, y0, y1, z0, z1;
1021 unsigned iStep;
1022 int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 );
1023
1024 mxCoord = 15000;
1025 n = g.szTest*100;
1026 speedtest1_begin_test(100, "%d INSERTs into an r-tree", n);
1027 speedtest1_exec("BEGIN");
1028 speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)");
1029 speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)"
1030 "VALUES(?1,?2,?3,?4,?5,?6,?7)");
1031 for(i=1; i<=n; i++){
1032 twoCoords(p1, p2, mxCoord, &x0, &x1);
1033 twoCoords(p1, p2, mxCoord, &y0, &y1);
1034 twoCoords(p1, p2, mxCoord, &z0, &z1);
1035 sqlite3_bind_int(g.pStmt, 1, i);
1036 sqlite3_bind_int(g.pStmt, 2, x0);
1037 sqlite3_bind_int(g.pStmt, 3, x1);
1038 sqlite3_bind_int(g.pStmt, 4, y0);
1039 sqlite3_bind_int(g.pStmt, 5, y1);
1040 sqlite3_bind_int(g.pStmt, 6, z0);
1041 sqlite3_bind_int(g.pStmt, 7, z1);
1042 speedtest1_run();
1043 }
1044 speedtest1_exec("COMMIT");
1045 speedtest1_end_test();
1046
1047 speedtest1_begin_test(101, "Copy from rtree to a regular table");
1048 speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
1049 speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
1050 speedtest1_end_test();
1051
1052 n = g.szTest*20;
1053 speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
1054 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
1055 iStep = mxCoord/n;
1056 for(i=0; i<n; i++){
1057 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1058 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1059 speedtest1_run();
1060 aCheck[i] = atoi(g.zResult);
1061 }
1062 speedtest1_end_test();
1063
1064 if( g.bVerify ){
1065 n = g.szTest*20;
1066 speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
1067 speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
1068 iStep = mxCoord/n;
1069 for(i=0; i<n; i++){
1070 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1071 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1072 speedtest1_run();
1073 if( aCheck[i]!=atoi(g.zResult) ){
1074 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1075 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1076 }
1077 }
1078 speedtest1_end_test();
1079 }
1080
1081 n = g.szTest*20;
1082 speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n);
1083 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?2");
1084 iStep = mxCoord/n;
1085 for(i=0; i<n; i++){
1086 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1087 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1088 speedtest1_run();
1089 aCheck[i] = atoi(g.zResult);
1090 }
1091 speedtest1_end_test();
1092
1093 if( g.bVerify ){
1094 n = g.szTest*20;
1095 speedtest1_begin_test(121, "Verify result from 1-D overlap slice queries");
1096 speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?2");
1097 iStep = mxCoord/n;
1098 for(i=0; i<n; i++){
1099 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1100 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1101 speedtest1_run();
1102 if( aCheck[i]!=atoi(g.zResult) ){
1103 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1104 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1105 }
1106 }
1107 speedtest1_end_test();
1108 }
1109
1110
1111 n = g.szTest*20;
1112 speedtest1_begin_test(125, "%d custom geometry callback queries", n);
1113 sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0);
1114 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)");
1115 iStep = mxCoord/n;
1116 for(i=0; i<n; i++){
1117 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1118 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1119 speedtest1_run();
1120 if( aCheck[i]!=atoi(g.zResult) ){
1121 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1122 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1123 }
1124 }
1125 speedtest1_end_test();
1126
1127 n = g.szTest*80;
1128 speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n);
1129 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2"
1130 " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2");
1131 iStep = mxCoord/n;
1132 for(i=0; i<n; i++){
1133 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1134 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1135 speedtest1_run();
1136 aCheck[i] = atoi(g.zResult);
1137 }
1138 speedtest1_end_test();
1139
1140 n = g.szTest*100;
1141 speedtest1_begin_test(140, "%d rowid queries", n);
1142 speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
1143 for(i=1; i<=n; i++){
1144 sqlite3_bind_int(g.pStmt, 1, i);
1145 speedtest1_run();
1146 }
1147 speedtest1_end_test();
1148}
drh8683e082014-10-11 10:52:54 +00001149#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +00001150
drhc4754802014-02-09 00:18:21 +00001151/*
drhad1ca9a2013-11-23 04:16:58 +00001152** A testset used for debugging speedtest1 itself.
1153*/
1154void testset_debug1(void){
1155 unsigned i, n;
1156 unsigned x1, x2;
1157 char zNum[2000]; /* A number name */
1158
1159 n = g.szTest;
1160 for(i=1; i<=n; i++){
1161 x1 = swizzle(i, n);
1162 x2 = swizzle(x1, n);
1163 speedtest1_numbername(x1, zNum, sizeof(zNum));
1164 printf("%5d %5d %5d %s\n", i, x1, x2, zNum);
1165 }
1166}
1167
1168int main(int argc, char **argv){
1169 int doAutovac = 0; /* True for --autovacuum */
1170 int cacheSize = 0; /* Desired cache size. 0 means default */
1171 int doExclusive = 0; /* True for --exclusive */
1172 int nHeap = 0, mnHeap = 0; /* Heap size from --heap */
1173 int doIncrvac = 0; /* True for --incrvacuum */
1174 const char *zJMode = 0; /* Journal mode */
1175 const char *zKey = 0; /* Encryption key */
1176 int nLook = 0, szLook = 0; /* --lookaside configuration */
1177 int noSync = 0; /* True for --nosync */
1178 int pageSize = 0; /* Desired page size. 0 means default */
1179 int nPCache = 0, szPCache = 0;/* --pcache configuration */
drhee70a842015-07-06 18:54:52 +00001180 int doPCache = 0; /* True if --pcache is seen */
drh93307e92013-11-24 01:14:14 +00001181 int nScratch = 0, szScratch=0;/* --scratch configuration */
drhad1ca9a2013-11-23 04:16:58 +00001182 int showStats = 0; /* True for --stats */
drh46a06bb2014-04-18 13:57:39 +00001183 int nThread = 0; /* --threads value */
drhad1ca9a2013-11-23 04:16:58 +00001184 const char *zTSet = "main"; /* Which --testset torun */
1185 int doTrace = 0; /* True for --trace */
1186 const char *zEncoding = 0; /* --utf16be or --utf16le */
1187 const char *zDbName = 0; /* Name of the test database */
1188
1189 void *pHeap = 0; /* Allocated heap space */
1190 void *pLook = 0; /* Allocated lookaside space */
1191 void *pPCache = 0; /* Allocated storage for pcache */
drh93307e92013-11-24 01:14:14 +00001192 void *pScratch = 0; /* Allocated storage for scratch */
drhad1ca9a2013-11-23 04:16:58 +00001193 int iCur, iHi; /* Stats values, current and "highwater" */
drhe19f8322013-11-23 11:45:58 +00001194 int i; /* Loop counter */
1195 int rc; /* API return code */
drhad1ca9a2013-11-23 04:16:58 +00001196
1197 /* Process command-line arguments */
1198 g.zWR = "";
1199 g.zNN = "";
1200 g.zPK = "UNIQUE";
1201 g.szTest = 100;
1202 for(i=1; i<argc; i++){
1203 const char *z = argv[i];
1204 if( z[0]=='-' ){
1205 do{ z++; }while( z[0]=='-' );
1206 if( strcmp(z,"autovacuum")==0 ){
1207 doAutovac = 1;
1208 }else if( strcmp(z,"cachesize")==0 ){
1209 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1210 i++;
drh93307e92013-11-24 01:14:14 +00001211 cacheSize = integerValue(argv[i]);
drhad1ca9a2013-11-23 04:16:58 +00001212 }else if( strcmp(z,"exclusive")==0 ){
1213 doExclusive = 1;
drh849a9d92013-12-21 15:46:06 +00001214 }else if( strcmp(z,"explain")==0 ){
1215 g.bSqlOnly = 1;
1216 g.bExplain = 1;
drhad1ca9a2013-11-23 04:16:58 +00001217 }else if( strcmp(z,"heap")==0 ){
1218 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001219 nHeap = integerValue(argv[i+1]);
1220 mnHeap = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001221 i += 2;
1222 }else if( strcmp(z,"incrvacuum")==0 ){
1223 doIncrvac = 1;
1224 }else if( strcmp(z,"journal")==0 ){
1225 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1226 zJMode = argv[++i];
1227 }else if( strcmp(z,"key")==0 ){
1228 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1229 zKey = argv[++i];
1230 }else if( strcmp(z,"lookaside")==0 ){
1231 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001232 nLook = integerValue(argv[i+1]);
1233 szLook = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001234 i += 2;
drh2e43e962015-07-03 14:34:25 +00001235 }else if( strcmp(z,"multithread")==0 ){
1236 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
1237 }else if( strcmp(z,"nomemstat")==0 ){
1238 sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);
drhad1ca9a2013-11-23 04:16:58 +00001239 }else if( strcmp(z,"nosync")==0 ){
1240 noSync = 1;
1241 }else if( strcmp(z,"notnull")==0 ){
1242 g.zNN = "NOT NULL";
drhcfb8f8d2015-07-23 20:44:49 +00001243#ifdef SQLITE_ENABLE_RBU
1244 }else if( strcmp(z,"rbu")==0 ){
1245 sqlite3ota_create_vfs("rbu", 0);
1246 sqlite3_vfs_register(sqlite3_vfs_find("rbu"), 1);
dan54fc2142015-03-05 16:21:20 +00001247#endif
drhad1ca9a2013-11-23 04:16:58 +00001248 }else if( strcmp(z,"pagesize")==0 ){
1249 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001250 pageSize = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001251 }else if( strcmp(z,"pcache")==0 ){
1252 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001253 nPCache = integerValue(argv[i+1]);
1254 szPCache = integerValue(argv[i+2]);
drhee70a842015-07-06 18:54:52 +00001255 doPCache = 1;
drhad1ca9a2013-11-23 04:16:58 +00001256 i += 2;
1257 }else if( strcmp(z,"primarykey")==0 ){
1258 g.zPK = "PRIMARY KEY";
1259 }else if( strcmp(z,"reprepare")==0 ){
1260 g.bReprepare = 1;
drh93307e92013-11-24 01:14:14 +00001261 }else if( strcmp(z,"scratch")==0 ){
1262 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
1263 nScratch = integerValue(argv[i+1]);
1264 szScratch = integerValue(argv[i+2]);
1265 i += 2;
drh2e43e962015-07-03 14:34:25 +00001266 }else if( strcmp(z,"serialized")==0 ){
1267 sqlite3_config(SQLITE_CONFIG_SERIALIZED);
1268 }else if( strcmp(z,"singlethread")==0 ){
1269 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhad1ca9a2013-11-23 04:16:58 +00001270 }else if( strcmp(z,"sqlonly")==0 ){
1271 g.bSqlOnly = 1;
drh0d847182015-07-02 01:38:39 +00001272 }else if( strcmp(z,"shrink-memory")==0 ){
1273 g.bMemShrink = 1;
drhad1ca9a2013-11-23 04:16:58 +00001274 }else if( strcmp(z,"size")==0 ){
1275 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001276 g.szTest = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001277 }else if( strcmp(z,"stats")==0 ){
1278 showStats = 1;
1279 }else if( strcmp(z,"testset")==0 ){
1280 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1281 zTSet = argv[++i];
1282 }else if( strcmp(z,"trace")==0 ){
1283 doTrace = 1;
drh46a06bb2014-04-18 13:57:39 +00001284 }else if( strcmp(z,"threads")==0 ){
1285 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1286 nThread = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001287 }else if( strcmp(z,"utf16le")==0 ){
1288 zEncoding = "utf16le";
1289 }else if( strcmp(z,"utf16be")==0 ){
1290 zEncoding = "utf16be";
drh65e6b0d2014-04-28 17:56:19 +00001291 }else if( strcmp(z,"verify")==0 ){
1292 g.bVerify = 1;
drhad1ca9a2013-11-23 04:16:58 +00001293 }else if( strcmp(z,"without-rowid")==0 ){
1294 g.zWR = "WITHOUT ROWID";
1295 g.zPK = "PRIMARY KEY";
1296 }else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){
1297 printf(zHelp, argv[0]);
1298 exit(0);
1299 }else{
1300 fatal_error("unknown option: %s\nUse \"%s -?\" for help\n",
1301 argv[i], argv[0]);
1302 }
1303 }else if( zDbName==0 ){
1304 zDbName = argv[i];
1305 }else{
1306 fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n",
1307 argv[i], argv[0]);
1308 }
1309 }
1310#if 0
1311 if( zDbName==0 ){
1312 fatal_error(zHelp, argv[0]);
1313 }
1314#endif
drh5995e292015-06-18 12:37:32 +00001315#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001316 if( nHeap>0 ){
1317 pHeap = malloc( nHeap );
1318 if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
drhe19f8322013-11-23 11:45:58 +00001319 rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
drh7b65ad32013-11-23 21:29:07 +00001320 if( rc ) fatal_error("heap configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001321 }
drhee70a842015-07-06 18:54:52 +00001322 if( doPCache ){
1323 if( nPCache>0 && szPCache>0 ){
1324 pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
1325 if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
1326 nPCache*(sqlite3_int64)szPCache);
1327 }
drhe19f8322013-11-23 11:45:58 +00001328 rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
drh7b65ad32013-11-23 21:29:07 +00001329 if( rc ) fatal_error("pcache configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001330 }
drh93307e92013-11-24 01:14:14 +00001331 if( nScratch>0 && szScratch>0 ){
1332 pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
1333 if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n",
1334 nScratch*(sqlite3_int64)szScratch);
1335 rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
1336 if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
1337 }
drhad1ca9a2013-11-23 04:16:58 +00001338 if( nLook>0 ){
1339 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
1340 }
drh5995e292015-06-18 12:37:32 +00001341#endif
drhad1ca9a2013-11-23 04:16:58 +00001342
1343 /* Open the database and the input file */
1344 if( sqlite3_open(zDbName, &g.db) ){
1345 fatal_error("Cannot open database file: %s\n", zDbName);
1346 }
drh5995e292015-06-18 12:37:32 +00001347#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001348 if( nLook>0 && szLook>0 ){
1349 pLook = malloc( nLook*szLook );
drhe19f8322013-11-23 11:45:58 +00001350 rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
drh7b65ad32013-11-23 21:29:07 +00001351 if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001352 }
drh5995e292015-06-18 12:37:32 +00001353#endif
drhad1ca9a2013-11-23 04:16:58 +00001354
1355 /* Set database connection options */
1356 sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
1357 if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
drh43cbe142014-08-29 18:06:33 +00001358 speedtest1_exec("PRAGMA threads=%d", nThread);
drhad1ca9a2013-11-23 04:16:58 +00001359 if( zKey ){
1360 speedtest1_exec("PRAGMA key('%s')", zKey);
1361 }
1362 if( zEncoding ){
1363 speedtest1_exec("PRAGMA encoding=%s", zEncoding);
1364 }
1365 if( doAutovac ){
1366 speedtest1_exec("PRAGMA auto_vacuum=FULL");
1367 }else if( doIncrvac ){
1368 speedtest1_exec("PRAGMA auto_vacuum=INCREMENTAL");
1369 }
1370 if( pageSize ){
1371 speedtest1_exec("PRAGMA page_size=%d", pageSize);
1372 }
1373 if( cacheSize ){
1374 speedtest1_exec("PRAGMA cache_size=%d", cacheSize);
1375 }
1376 if( noSync ) speedtest1_exec("PRAGMA synchronous=OFF");
1377 if( doExclusive ){
1378 speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE");
1379 }
1380 if( zJMode ){
1381 speedtest1_exec("PRAGMA journal_mode=%s", zJMode);
1382 }
1383
drh849a9d92013-12-21 15:46:06 +00001384 if( g.bExplain ) printf(".explain\n.echo on\n");
drhad1ca9a2013-11-23 04:16:58 +00001385 if( strcmp(zTSet,"main")==0 ){
1386 testset_main();
1387 }else if( strcmp(zTSet,"debug1")==0 ){
1388 testset_debug1();
drhc4754802014-02-09 00:18:21 +00001389 }else if( strcmp(zTSet,"cte")==0 ){
1390 testset_cte();
drh65e6b0d2014-04-28 17:56:19 +00001391 }else if( strcmp(zTSet,"rtree")==0 ){
drh8683e082014-10-11 10:52:54 +00001392#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +00001393 testset_rtree(6, 147);
drh8683e082014-10-11 10:52:54 +00001394#else
1395 fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
1396 "the R-Tree tests\n");
1397#endif
drhad1ca9a2013-11-23 04:16:58 +00001398 }else{
drh65e6b0d2014-04-28 17:56:19 +00001399 fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n",
1400 zTSet);
drhad1ca9a2013-11-23 04:16:58 +00001401 }
1402 speedtest1_final();
1403
1404 /* Database connection statistics printed after both prepared statements
1405 ** have been finalized */
drh290ea402013-12-01 18:10:01 +00001406#if SQLITE_VERSION_NUMBER>=3007009
drhad1ca9a2013-11-23 04:16:58 +00001407 if( showStats ){
1408 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0);
1409 printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi);
1410 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0);
1411 printf("-- Successful lookasides: %d\n", iHi);
1412 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0);
1413 printf("-- Lookaside size faults: %d\n", iHi);
1414 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0);
1415 printf("-- Lookaside OOM faults: %d\n", iHi);
1416 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0);
1417 printf("-- Pager Heap Usage: %d bytes\n", iCur);
1418 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1);
1419 printf("-- Page cache hits: %d\n", iCur);
1420 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1);
drh2a702db2013-12-02 21:25:40 +00001421 printf("-- Page cache misses: %d\n", iCur);
1422#if SQLITE_VERSION_NUMBER>=3007012
drhad1ca9a2013-11-23 04:16:58 +00001423 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1);
1424 printf("-- Page cache writes: %d\n", iCur);
drh2a702db2013-12-02 21:25:40 +00001425#endif
drhad1ca9a2013-11-23 04:16:58 +00001426 sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0);
1427 printf("-- Schema Heap Usage: %d bytes\n", iCur);
1428 sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
1429 printf("-- Statement Heap Usage: %d bytes\n", iCur);
1430 }
drh290ea402013-12-01 18:10:01 +00001431#endif
drhad1ca9a2013-11-23 04:16:58 +00001432
1433 sqlite3_close(g.db);
1434
drh5995e292015-06-18 12:37:32 +00001435#if SQLITE_VERSION_NUMBER>=3006001
drhad1ca9a2013-11-23 04:16:58 +00001436 /* Global memory usage statistics printed after the database connection
1437 ** has closed. Memory usage should be zero at this point. */
1438 if( showStats ){
1439 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
1440 printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001441#if SQLITE_VERSION_NUMBER>=3007000
drhad1ca9a2013-11-23 04:16:58 +00001442 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
1443 printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001444#endif
drhad1ca9a2013-11-23 04:16:58 +00001445 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0);
1446 printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi);
1447 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0);
1448 printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi);
1449 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
1450 printf("-- Largest Allocation: %d bytes\n",iHi);
1451 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
1452 printf("-- Largest Pcache Allocation: %d bytes\n",iHi);
1453 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
1454 printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
1455 }
drh5995e292015-06-18 12:37:32 +00001456#endif
drhad1ca9a2013-11-23 04:16:58 +00001457
1458 /* Release memory */
1459 free( pLook );
1460 free( pPCache );
drh93307e92013-11-24 01:14:14 +00001461 free( pScratch );
drhad1ca9a2013-11-23 04:16:58 +00001462 free( pHeap );
1463 return 0;
1464}