blob: 8f3f579557ae3949eccaf5f17e271af38a606b54 [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"
18 " --nosync Set PRAGMA synchronous=OFF\n"
19 " --notnull Add NOT NULL constraints to table columns\n"
20 " --pagesize N Set the page size to N\n"
21 " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n"
22 " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n"
23 " --reprepare Reprepare each statement upon every invocation\n"
drh93307e92013-11-24 01:14:14 +000024 " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n"
drhad1ca9a2013-11-23 04:16:58 +000025 " --sqlonly No-op. Only show the SQL that would have been run.\n"
26 " --size N Relative test size. Default=100\n"
27 " --stats Show statistics at the end\n"
28 " --testset T Run test-set T\n"
29 " --trace Turn on SQL tracing\n"
drh46a06bb2014-04-18 13:57:39 +000030 " --threads N Use up to N threads for sorting\n"
drhad1ca9a2013-11-23 04:16:58 +000031 " --utf16be Set text encoding to UTF-16BE\n"
32 " --utf16le Set text encoding to UTF-16LE\n"
drh65e6b0d2014-04-28 17:56:19 +000033 " --verify Run additional verification steps.\n"
drhad1ca9a2013-11-23 04:16:58 +000034 " --without-rowid Use WITHOUT ROWID where appropriate\n"
35;
36
37
38#include "sqlite3.h"
39#include <assert.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <stdarg.h>
43#include <string.h>
44#include <ctype.h>
45
dan54fc2142015-03-05 16:21:20 +000046#ifdef SQLITE_ENABLE_OTA
47# include "sqlite3ota.h"
48#endif
49
drhad1ca9a2013-11-23 04:16:58 +000050/* All global state is held in this structure */
51static struct Global {
52 sqlite3 *db; /* The open database connection */
53 sqlite3_stmt *pStmt; /* Current SQL statement */
54 sqlite3_int64 iStart; /* Start-time for the current test */
55 sqlite3_int64 iTotal; /* Total time */
56 int bWithoutRowid; /* True for --without-rowid */
57 int bReprepare; /* True to reprepare the SQL on each rerun */
58 int bSqlOnly; /* True to print the SQL once only */
drh849a9d92013-12-21 15:46:06 +000059 int bExplain; /* Print SQL with EXPLAIN prefix */
drh65e6b0d2014-04-28 17:56:19 +000060 int bVerify; /* Try to verify that results are correct */
drhad1ca9a2013-11-23 04:16:58 +000061 int szTest; /* Scale factor for test iterations */
62 const char *zWR; /* Might be WITHOUT ROWID */
63 const char *zNN; /* Might be NOT NULL */
64 const char *zPK; /* Might be UNIQUE or PRIMARY KEY */
65 unsigned int x, y; /* Pseudo-random number generator state */
66 int nResult; /* Size of the current result */
67 char zResult[3000]; /* Text of the current result */
68} g;
69
drhad1ca9a2013-11-23 04:16:58 +000070
drh93307e92013-11-24 01:14:14 +000071/* Print an error message and exit */
72static void fatal_error(const char *zMsg, ...){
73 va_list ap;
74 va_start(ap, zMsg);
75 vfprintf(stderr, zMsg, ap);
76 va_end(ap);
77 exit(1);
drhad1ca9a2013-11-23 04:16:58 +000078}
79
80/*
81** Return the value of a hexadecimal digit. Return -1 if the input
82** is not a hex digit.
83*/
84static int hexDigitValue(char c){
85 if( c>='0' && c<='9' ) return c - '0';
86 if( c>='a' && c<='f' ) return c - 'a' + 10;
87 if( c>='A' && c<='F' ) return c - 'A' + 10;
88 return -1;
89}
90
drh290ea402013-12-01 18:10:01 +000091/* Provide an alternative to sqlite3_stricmp() in older versions of
92** SQLite */
93#if SQLITE_VERSION_NUMBER<3007011
94# define sqlite3_stricmp strcmp
95#endif
96
drhad1ca9a2013-11-23 04:16:58 +000097/*
98** Interpret zArg as an integer value, possibly with suffixes.
99*/
drh93307e92013-11-24 01:14:14 +0000100static int integerValue(const char *zArg){
drhad1ca9a2013-11-23 04:16:58 +0000101 sqlite3_int64 v = 0;
102 static const struct { char *zSuffix; int iMult; } aMult[] = {
103 { "KiB", 1024 },
104 { "MiB", 1024*1024 },
105 { "GiB", 1024*1024*1024 },
106 { "KB", 1000 },
107 { "MB", 1000000 },
108 { "GB", 1000000000 },
109 { "K", 1000 },
110 { "M", 1000000 },
111 { "G", 1000000000 },
112 };
113 int i;
114 int isNeg = 0;
115 if( zArg[0]=='-' ){
116 isNeg = 1;
117 zArg++;
118 }else if( zArg[0]=='+' ){
119 zArg++;
120 }
121 if( zArg[0]=='0' && zArg[1]=='x' ){
122 int x;
123 zArg += 2;
124 while( (x = hexDigitValue(zArg[0]))>=0 ){
125 v = (v<<4) + x;
126 zArg++;
127 }
128 }else{
129 while( isdigit(zArg[0]) ){
130 v = v*10 + zArg[0] - '0';
131 zArg++;
132 }
133 }
134 for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
135 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
136 v *= aMult[i].iMult;
137 break;
138 }
139 }
mistachkinb87875a2013-11-27 18:00:20 +0000140 if( v>0x7fffffff ) fatal_error("parameter too large - max 2147483648");
drhdcb5fa02013-11-27 14:50:51 +0000141 return (int)(isNeg? -v : v);
drhad1ca9a2013-11-23 04:16:58 +0000142}
143
144/* Return the current wall-clock time, in milliseconds */
145sqlite3_int64 speedtest1_timestamp(void){
146 static sqlite3_vfs *clockVfs = 0;
147 sqlite3_int64 t;
148 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
drhd79e9c52013-12-02 01:24:05 +0000149#if SQLITE_VERSION_NUMBER>=3007000
drh290ea402013-12-01 18:10:01 +0000150 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drhad1ca9a2013-11-23 04:16:58 +0000151 clockVfs->xCurrentTimeInt64(clockVfs, &t);
drhd79e9c52013-12-02 01:24:05 +0000152 }else
153#endif
154 {
drhad1ca9a2013-11-23 04:16:58 +0000155 double r;
156 clockVfs->xCurrentTime(clockVfs, &r);
157 t = (sqlite3_int64)(r*86400000.0);
158 }
159 return t;
160}
161
162/* Return a pseudo-random unsigned integer */
163unsigned int speedtest1_random(void){
164 g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001);
165 g.y = g.y*1103515245 + 12345;
166 return g.x ^ g.y;
167}
168
169/* Map the value in within the range of 1...limit into another
170** number in a way that is chatic and invertable.
171*/
172unsigned swizzle(unsigned in, unsigned limit){
173 unsigned out = 0;
174 while( limit ){
175 out = (out<<1) | (in&1);
176 in >>= 1;
177 limit >>= 1;
178 }
179 return out;
180}
181
182/* Round up a number so that it is a power of two minus one
183*/
184unsigned roundup_allones(unsigned limit){
185 unsigned m = 1;
186 while( m<limit ) m = (m<<1)+1;
187 return m;
188}
189
190/* The speedtest1_numbername procedure below converts its argment (an integer)
191** into a string which is the English-language name for that number.
192** The returned string should be freed with sqlite3_free().
193**
194** Example:
195**
196** speedtest1_numbername(123) -> "one hundred twenty three"
197*/
198int speedtest1_numbername(unsigned int n, char *zOut, int nOut){
199 static const char *ones[] = { "zero", "one", "two", "three", "four", "five",
200 "six", "seven", "eight", "nine", "ten", "eleven", "twelve",
201 "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
202 "eighteen", "nineteen" };
203 static const char *tens[] = { "", "ten", "twenty", "thirty", "forty",
204 "fifty", "sixty", "seventy", "eighty", "ninety" };
205 int i = 0;
206
207 if( n>=1000000000 ){
208 i += speedtest1_numbername(n/1000000000, zOut+i, nOut-i);
209 sqlite3_snprintf(nOut-i, zOut+i, " billion");
210 i += (int)strlen(zOut+i);
211 n = n % 1000000000;
212 }
213 if( n>=1000000 ){
214 if( i && i<nOut-1 ) zOut[i++] = ' ';
215 i += speedtest1_numbername(n/1000000, zOut+i, nOut-i);
216 sqlite3_snprintf(nOut-i, zOut+i, " million");
217 i += (int)strlen(zOut+i);
218 n = n % 1000000;
219 }
220 if( n>=1000 ){
221 if( i && i<nOut-1 ) zOut[i++] = ' ';
222 i += speedtest1_numbername(n/1000, zOut+i, nOut-i);
223 sqlite3_snprintf(nOut-i, zOut+i, " thousand");
224 i += (int)strlen(zOut+i);
225 n = n % 1000;
226 }
227 if( n>=100 ){
228 if( i && i<nOut-1 ) zOut[i++] = ' ';
229 sqlite3_snprintf(nOut-i, zOut+i, "%s hundred", ones[n/100]);
230 i += (int)strlen(zOut+i);
231 n = n % 100;
232 }
233 if( n>=20 ){
234 if( i && i<nOut-1 ) zOut[i++] = ' ';
235 sqlite3_snprintf(nOut-i, zOut+i, "%s", tens[n/10]);
236 i += (int)strlen(zOut+i);
237 n = n % 10;
238 }
239 if( n>0 ){
240 if( i && i<nOut-1 ) zOut[i++] = ' ';
241 sqlite3_snprintf(nOut-i, zOut+i, "%s", ones[n]);
242 i += (int)strlen(zOut+i);
243 }
244 if( i==0 ){
245 sqlite3_snprintf(nOut-i, zOut+i, "zero");
246 i += (int)strlen(zOut+i);
247 }
248 return i;
249}
250
251
252/* Start a new test case */
253#define NAMEWIDTH 60
254static const char zDots[] =
255 ".......................................................................";
256void speedtest1_begin_test(int iTestNum, const char *zTestName, ...){
257 int n = (int)strlen(zTestName);
258 char *zName;
259 va_list ap;
260 va_start(ap, zTestName);
261 zName = sqlite3_vmprintf(zTestName, ap);
262 va_end(ap);
263 n = (int)strlen(zName);
264 if( n>NAMEWIDTH ){
265 zName[NAMEWIDTH] = 0;
266 n = NAMEWIDTH;
267 }
268 if( g.bSqlOnly ){
269 printf("/* %4d - %s%.*s */\n", iTestNum, zName, NAMEWIDTH-n, zDots);
270 }else{
271 printf("%4d - %s%.*s ", iTestNum, zName, NAMEWIDTH-n, zDots);
272 fflush(stdout);
273 }
274 sqlite3_free(zName);
275 g.nResult = 0;
276 g.iStart = speedtest1_timestamp();
drhdcb5fa02013-11-27 14:50:51 +0000277 g.x = 0xad131d0b;
278 g.y = 0x44f9eac8;
drhad1ca9a2013-11-23 04:16:58 +0000279}
280
281/* Complete a test case */
282void speedtest1_end_test(void){
283 sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart;
284 if( !g.bSqlOnly ){
285 g.iTotal += iElapseTime;
286 printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000));
287 }
288 if( g.pStmt ){
289 sqlite3_finalize(g.pStmt);
290 g.pStmt = 0;
291 }
292}
293
294/* Report end of testing */
295void speedtest1_final(void){
296 if( !g.bSqlOnly ){
297 printf(" TOTAL%.*s %4d.%03ds\n", NAMEWIDTH-5, zDots,
298 (int)(g.iTotal/1000), (int)(g.iTotal%1000));
299 }
300}
301
drh849a9d92013-12-21 15:46:06 +0000302/* Print an SQL statement to standard output */
303static void printSql(const char *zSql){
304 int n = (int)strlen(zSql);
305 while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
306 if( g.bExplain ) printf("EXPLAIN ");
307 printf("%.*s;\n", n, zSql);
308 if( g.bExplain
drh25555502013-12-21 17:14:58 +0000309#if SQLITE_VERSION_NUMBER>=3007010
310 && ( sqlite3_strglob("CREATE *", zSql)==0
311 || sqlite3_strglob("DROP *", zSql)==0
312 || sqlite3_strglob("ALTER *", zSql)==0
drh849a9d92013-12-21 15:46:06 +0000313 )
drh25555502013-12-21 17:14:58 +0000314#endif
drh849a9d92013-12-21 15:46:06 +0000315 ){
316 printf("%.*s;\n", n, zSql);
317 }
318}
319
drhad1ca9a2013-11-23 04:16:58 +0000320/* Run SQL */
321void speedtest1_exec(const char *zFormat, ...){
322 va_list ap;
323 char *zSql;
324 va_start(ap, zFormat);
325 zSql = sqlite3_vmprintf(zFormat, ap);
326 va_end(ap);
327 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000328 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000329 }else{
drhe19f8322013-11-23 11:45:58 +0000330 char *zErrMsg = 0;
331 int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
332 if( zErrMsg ) fatal_error("SQL error: %s\n%s\n", zErrMsg, zSql);
333 if( rc!=SQLITE_OK ) fatal_error("exec error: %s\n", sqlite3_errmsg(g.db));
drhad1ca9a2013-11-23 04:16:58 +0000334 }
335 sqlite3_free(zSql);
336}
337
338/* Prepare an SQL statement */
339void speedtest1_prepare(const char *zFormat, ...){
340 va_list ap;
341 char *zSql;
342 va_start(ap, zFormat);
343 zSql = sqlite3_vmprintf(zFormat, ap);
344 va_end(ap);
345 if( g.bSqlOnly ){
drh849a9d92013-12-21 15:46:06 +0000346 printSql(zSql);
drhad1ca9a2013-11-23 04:16:58 +0000347 }else{
348 int rc;
349 if( g.pStmt ) sqlite3_finalize(g.pStmt);
350 rc = sqlite3_prepare_v2(g.db, zSql, -1, &g.pStmt, 0);
351 if( rc ){
352 fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db));
353 }
354 }
355 sqlite3_free(zSql);
356}
357
358/* Run an SQL statement previously prepared */
359void speedtest1_run(void){
360 int i, n, len;
361 if( g.bSqlOnly ) return;
362 assert( g.pStmt );
363 g.nResult = 0;
364 while( sqlite3_step(g.pStmt)==SQLITE_ROW ){
365 n = sqlite3_column_count(g.pStmt);
366 for(i=0; i<n; i++){
367 const char *z = (const char*)sqlite3_column_text(g.pStmt, i);
368 if( z==0 ) z = "nil";
369 len = (int)strlen(z);
370 if( g.nResult+len<sizeof(g.zResult)-2 ){
371 if( g.nResult>0 ) g.zResult[g.nResult++] = ' ';
372 memcpy(g.zResult + g.nResult, z, len+1);
373 g.nResult += len;
374 }
375 }
376 }
377 if( g.bReprepare ){
378 sqlite3_stmt *pNew;
379 sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0);
380 sqlite3_finalize(g.pStmt);
381 g.pStmt = pNew;
382 }else{
383 sqlite3_reset(g.pStmt);
384 }
385}
386
387/* The sqlite3_trace() callback function */
388static void traceCallback(void *NotUsed, const char *zSql){
389 int n = (int)strlen(zSql);
390 while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ) n--;
391 fprintf(stderr,"%.*s;\n", n, zSql);
392}
393
394/* Substitute random() function that gives the same random
395** sequence on each run, for repeatability. */
396static void randomFunc(
397 sqlite3_context *context,
398 int NotUsed,
399 sqlite3_value **NotUsed2
400){
401 sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random());
402}
403
drhae28d6e2013-12-21 00:04:37 +0000404/* Estimate the square root of an integer */
405static int est_square_root(int x){
406 int y0 = x/2;
407 int y1;
408 int n;
409 for(n=0; y0>0 && n<10; n++){
410 y1 = (y0 + x/y0)/2;
411 if( y1==y0 ) break;
412 y0 = y1;
413 }
414 return y0;
415}
416
drhad1ca9a2013-11-23 04:16:58 +0000417/*
418** The main and default testset
419*/
420void testset_main(void){
421 int i; /* Loop counter */
422 int n; /* iteration count */
423 int sz; /* Size of the tables */
424 int maxb; /* Maximum swizzled value */
425 unsigned x1, x2; /* Parameters */
426 int len; /* Length of the zNum[] string */
427 char zNum[2000]; /* A number name */
428
429 sz = n = g.szTest*500;
430 maxb = roundup_allones(sz);
431 speedtest1_begin_test(100, "%d INSERTs into table with no index", n);
432 speedtest1_exec("BEGIN");
433 speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);",
434 g.zNN, g.zNN, g.zNN);
435 speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n);
436 for(i=1; i<=n; i++){
437 x1 = swizzle(i,maxb);
438 speedtest1_numbername(x1, zNum, sizeof(zNum));
439 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
440 sqlite3_bind_int(g.pStmt, 2, i);
441 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
442 speedtest1_run();
443 }
444 speedtest1_exec("COMMIT");
445 speedtest1_end_test();
446
447
448 n = sz;
449 speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n);
450 speedtest1_exec("BEGIN");
451 speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
452 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
453 speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n);
454 for(i=1; i<=n; i++){
455 x1 = swizzle(i,maxb);
456 speedtest1_numbername(x1, zNum, sizeof(zNum));
457 sqlite3_bind_int(g.pStmt, 1, i);
458 sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1);
459 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
460 speedtest1_run();
461 }
462 speedtest1_exec("COMMIT");
463 speedtest1_end_test();
464
465
466 n = sz;
467 speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n);
468 speedtest1_exec("BEGIN");
469 speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s",
470 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
471 speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n);
472 for(i=1; i<=n; i++){
473 x1 = swizzle(i,maxb);
474 speedtest1_numbername(x1, zNum, sizeof(zNum));
475 sqlite3_bind_int(g.pStmt, 2, i);
476 sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1);
477 sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC);
478 speedtest1_run();
479 }
480 speedtest1_exec("COMMIT");
481 speedtest1_end_test();
482
483
drh5e8980d2014-03-25 20:28:38 +0000484 n = 25;
drhad1ca9a2013-11-23 04:16:58 +0000485 speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n);
486 speedtest1_exec("BEGIN");
487 speedtest1_prepare(
488 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
489 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
490 );
491 for(i=1; i<=n; i++){
492 x1 = speedtest1_random()%maxb;
493 x2 = speedtest1_random()%10 + sz/5000 + x1;
494 sqlite3_bind_int(g.pStmt, 1, x1);
495 sqlite3_bind_int(g.pStmt, 2, x2);
496 speedtest1_run();
497 }
498 speedtest1_exec("COMMIT");
499 speedtest1_end_test();
500
501
drh5e8980d2014-03-25 20:28:38 +0000502 n = 10;
drhad1ca9a2013-11-23 04:16:58 +0000503 speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n);
504 speedtest1_exec("BEGIN");
505 speedtest1_prepare(
506 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
507 " WHERE c LIKE ?1; -- %d times", n
508 );
509 for(i=1; i<=n; i++){
510 x1 = speedtest1_random()%maxb;
511 zNum[0] = '%';
512 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
513 zNum[len] = '%';
514 zNum[len+1] = 0;
515 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
516 speedtest1_run();
517 }
518 speedtest1_exec("COMMIT");
519 speedtest1_end_test();
520
521
drh5e8980d2014-03-25 20:28:38 +0000522 n = 10;
drhc8729662014-03-25 17:45:49 +0000523 speedtest1_begin_test(142, "%d SELECTS w/ORDER BY, unindexed", n);
524 speedtest1_exec("BEGIN");
525 speedtest1_prepare(
526 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
527 " ORDER BY a; -- %d times", n
528 );
529 for(i=1; i<=n; i++){
530 x1 = speedtest1_random()%maxb;
531 zNum[0] = '%';
532 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
533 zNum[len] = '%';
534 zNum[len+1] = 0;
535 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
536 speedtest1_run();
537 }
538 speedtest1_exec("COMMIT");
539 speedtest1_end_test();
540
dan54fc2142015-03-05 16:21:20 +0000541 n = 10; /* g.szTest/5; */
drhc8729662014-03-25 17:45:49 +0000542 speedtest1_begin_test(145, "%d SELECTS w/ORDER BY and LIMIT, unindexed", n);
drh0c60c1f2014-03-25 14:54:36 +0000543 speedtest1_exec("BEGIN");
544 speedtest1_prepare(
545 "SELECT a, b, c FROM t1 WHERE c LIKE ?1\n"
546 " ORDER BY a LIMIT 10; -- %d times", n
547 );
548 for(i=1; i<=n; i++){
549 x1 = speedtest1_random()%maxb;
550 zNum[0] = '%';
551 len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2);
552 zNum[len] = '%';
553 zNum[len+1] = 0;
554 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
555 speedtest1_run();
556 }
557 speedtest1_exec("COMMIT");
558 speedtest1_end_test();
559
560
drhad1ca9a2013-11-23 04:16:58 +0000561 speedtest1_begin_test(150, "CREATE INDEX five times");
drh849a9d92013-12-21 15:46:06 +0000562 speedtest1_exec("BEGIN;");
563 speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
564 speedtest1_exec("CREATE INDEX t1c ON t1(c);");
565 speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
566 speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
567 speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
568 speedtest1_exec("COMMIT;");
drhad1ca9a2013-11-23 04:16:58 +0000569 speedtest1_end_test();
570
571
572 n = sz/5;
573 speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n);
574 speedtest1_exec("BEGIN");
575 speedtest1_prepare(
576 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
577 " WHERE b BETWEEN ?1 AND ?2; -- %d times", n
578 );
579 for(i=1; i<=n; i++){
580 x1 = speedtest1_random()%maxb;
581 x2 = speedtest1_random()%10 + sz/5000 + x1;
582 sqlite3_bind_int(g.pStmt, 1, x1);
583 sqlite3_bind_int(g.pStmt, 2, x2);
584 speedtest1_run();
585 }
586 speedtest1_exec("COMMIT");
587 speedtest1_end_test();
588
589
590 n = sz/5;
591 speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n);
592 speedtest1_exec("BEGIN");
593 speedtest1_prepare(
594 "SELECT count(*), avg(b), sum(length(c)) FROM t2\n"
595 " WHERE a BETWEEN ?1 AND ?2; -- %d times", n
596 );
597 for(i=1; i<=n; i++){
598 x1 = speedtest1_random()%maxb;
599 x2 = speedtest1_random()%10 + sz/5000 + x1;
600 sqlite3_bind_int(g.pStmt, 1, x1);
601 sqlite3_bind_int(g.pStmt, 2, x2);
602 speedtest1_run();
603 }
604 speedtest1_exec("COMMIT");
605 speedtest1_end_test();
606
607
608 n = sz/5;
609 speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n);
610 speedtest1_exec("BEGIN");
611 speedtest1_prepare(
612 "SELECT count(*), avg(b), sum(length(c)) FROM t1\n"
613 " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n
614 );
615 for(i=1; i<=n; i++){
616 x1 = swizzle(i, maxb);
617 len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1);
618 sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC);
619 speedtest1_run();
620 }
621 speedtest1_exec("COMMIT");
622 speedtest1_end_test();
623
624 n = sz;
625 speedtest1_begin_test(180, "%d INSERTS with three indexes", n);
626 speedtest1_exec("BEGIN");
627 speedtest1_exec(
628 "CREATE TABLE t4(\n"
629 " a INTEGER %s %s,\n"
630 " b INTEGER %s,\n"
631 " c TEXT %s\n"
632 ") %s",
633 g.zNN, g.zPK, g.zNN, g.zNN, g.zWR);
634 speedtest1_exec("CREATE INDEX t4b ON t4(b)");
635 speedtest1_exec("CREATE INDEX t4c ON t4(c)");
636 speedtest1_exec("INSERT INTO t4 SELECT * FROM t1");
637 speedtest1_exec("COMMIT");
638 speedtest1_end_test();
639
640 n = sz;
641 speedtest1_begin_test(190, "DELETE and REFILL one table", n);
drh849a9d92013-12-21 15:46:06 +0000642 speedtest1_exec("DELETE FROM t2;");
643 speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
drhad1ca9a2013-11-23 04:16:58 +0000644 speedtest1_end_test();
645
646
647 speedtest1_begin_test(200, "VACUUM");
648 speedtest1_exec("VACUUM");
649 speedtest1_end_test();
650
651
652 speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query");
653 speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123");
654 speedtest1_exec("SELECT sum(d) FROM t2");
655 speedtest1_end_test();
656
657
658 n = sz/5;
659 speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n);
660 speedtest1_exec("BEGIN");
661 speedtest1_prepare(
662 "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
663 );
664 for(i=1; i<=n; i++){
665 x1 = speedtest1_random()%maxb;
666 x2 = speedtest1_random()%10 + sz/5000 + x1;
667 sqlite3_bind_int(g.pStmt, 1, x1);
668 sqlite3_bind_int(g.pStmt, 2, x2);
669 speedtest1_run();
670 }
671 speedtest1_exec("COMMIT");
672 speedtest1_end_test();
673
674
675 n = sz;
676 speedtest1_begin_test(240, "%d UPDATES of individual rows", n);
677 speedtest1_exec("BEGIN");
678 speedtest1_prepare(
679 "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n
680 );
681 for(i=1; i<=n; i++){
682 x1 = speedtest1_random()%sz + 1;
683 sqlite3_bind_int(g.pStmt, 1, x1);
684 speedtest1_run();
685 }
686 speedtest1_exec("COMMIT");
687 speedtest1_end_test();
688
689 speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz);
690 speedtest1_exec("UPDATE t2 SET d=b*4");
691 speedtest1_end_test();
692
693
694 speedtest1_begin_test(260, "Query added column after filling");
695 speedtest1_exec("SELECT sum(d) FROM t2");
696 speedtest1_end_test();
697
698
699
700 n = sz/5;
701 speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n);
702 speedtest1_exec("BEGIN");
703 speedtest1_prepare(
704 "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n
705 );
706 for(i=1; i<=n; i++){
707 x1 = speedtest1_random()%maxb + 1;
708 x2 = speedtest1_random()%10 + sz/5000 + x1;
709 sqlite3_bind_int(g.pStmt, 1, x1);
710 sqlite3_bind_int(g.pStmt, 2, x2);
711 speedtest1_run();
712 }
713 speedtest1_exec("COMMIT");
714 speedtest1_end_test();
715
716
717 n = sz;
718 speedtest1_begin_test(280, "%d DELETEs of individual rows", n);
719 speedtest1_exec("BEGIN");
720 speedtest1_prepare(
721 "DELETE FROM t3 WHERE a=?1; -- %d times", n
722 );
723 for(i=1; i<=n; i++){
724 x1 = speedtest1_random()%sz + 1;
725 sqlite3_bind_int(g.pStmt, 1, x1);
726 speedtest1_run();
727 }
728 speedtest1_exec("COMMIT");
729 speedtest1_end_test();
730
731
732 speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz);
drhe19f8322013-11-23 11:45:58 +0000733 speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1");
734 speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
drhad1ca9a2013-11-23 04:16:58 +0000735 speedtest1_end_test();
736
drh039468e2013-12-18 16:27:48 +0000737 speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
738 speedtest1_exec("DELETE FROM t2;");
drh849a9d92013-12-21 15:46:06 +0000739 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
740 " SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);");
741 speedtest1_exec("INSERT INTO t2(a,b,c)\n"
742 " SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);");
drh039468e2013-12-18 16:27:48 +0000743 speedtest1_end_test();
744
drhad1ca9a2013-11-23 04:16:58 +0000745
746 n = sz/5;
drh039468e2013-12-18 16:27:48 +0000747 speedtest1_begin_test(310, "%d four-ways joins", n);
drhad1ca9a2013-11-23 04:16:58 +0000748 speedtest1_exec("BEGIN");
749 speedtest1_prepare(
750 "SELECT t1.c FROM t1, t2, t3, t4\n"
751 " WHERE t4.a BETWEEN ?1 AND ?2\n"
752 " AND t3.a=t4.b\n"
753 " AND t2.a=t3.b\n"
754 " AND t1.c=t2.c"
755 );
756 for(i=1; i<=n; i++){
757 x1 = speedtest1_random()%sz + 1;
758 x2 = speedtest1_random()%10 + x1 + 4;
759 sqlite3_bind_int(g.pStmt, 1, x1);
760 sqlite3_bind_int(g.pStmt, 2, x2);
761 speedtest1_run();
762 }
763 speedtest1_exec("COMMIT");
764 speedtest1_end_test();
765
drhae28d6e2013-12-21 00:04:37 +0000766 speedtest1_begin_test(320, "subquery in result set", n);
767 speedtest1_prepare(
768 "SELECT sum(a), max(c),\n"
769 " avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
770 " FROM t1 WHERE rowid<?1;"
771 );
772 sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
773 speedtest1_run();
774 speedtest1_end_test();
drhad1ca9a2013-11-23 04:16:58 +0000775
776 speedtest1_begin_test(980, "PRAGMA integrity_check");
777 speedtest1_exec("PRAGMA integrity_check");
778 speedtest1_end_test();
779
780
781 speedtest1_begin_test(990, "ANALYZE");
782 speedtest1_exec("ANALYZE");
783 speedtest1_end_test();
784}
785
786/*
drhc4754802014-02-09 00:18:21 +0000787** A testset for common table expressions. This exercises code
788** for views, subqueries, co-routines, etc.
789*/
790void testset_cte(void){
791 static const char *azPuzzle[] = {
792 /* Easy */
793 "534...9.."
794 "67.195..."
795 ".98....6."
796 "8...6...3"
797 "4..8.3..1"
798 "....2...6"
799 ".6....28."
800 "...419..5"
801 "...28..79",
802
803 /* Medium */
804 "53....9.."
805 "6..195..."
806 ".98....6."
807 "8...6...3"
808 "4..8.3..1"
809 "....2...6"
810 ".6....28."
811 "...419..5"
812 "....8..79",
813
814 /* Hard */
815 "53......."
816 "6..195..."
817 ".98....6."
818 "8...6...3"
819 "4..8.3..1"
820 "....2...6"
821 ".6....28."
822 "...419..5"
823 "....8..79",
824 };
825 const char *zPuz;
drhfa46bfb2014-02-09 00:52:53 +0000826 double rSpacing;
drh5574e3f2014-02-09 23:59:28 +0000827 int nElem;
drhc4754802014-02-09 00:18:21 +0000828
829 if( g.szTest<25 ){
830 zPuz = azPuzzle[0];
831 }else if( g.szTest<70 ){
832 zPuz = azPuzzle[1];
833 }else{
834 zPuz = azPuzzle[2];
835 }
836 speedtest1_begin_test(100, "Sudoku with recursive 'digits'");
837 speedtest1_prepare(
838 "WITH RECURSIVE\n"
839 " input(sud) AS (VALUES(?1)),\n"
840 " digits(z,lp) AS (\n"
841 " VALUES('1', 1)\n"
842 " UNION ALL\n"
843 " SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9\n"
844 " ),\n"
845 " x(s, ind) AS (\n"
846 " SELECT sud, instr(sud, '.') FROM input\n"
847 " UNION ALL\n"
848 " SELECT\n"
849 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
850 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
851 " FROM x, digits AS z\n"
852 " WHERE ind>0\n"
853 " AND NOT EXISTS (\n"
854 " SELECT 1\n"
855 " FROM digits AS lp\n"
856 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
857 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
858 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
859 " + ((ind-1)/27) * 27 + lp\n"
860 " + ((lp-1) / 3) * 6, 1)\n"
861 " )\n"
862 " )\n"
863 "SELECT s FROM x WHERE ind=0;"
864 );
865 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
866 speedtest1_run();
867 speedtest1_end_test();
868
869 speedtest1_begin_test(200, "Sudoku with VALUES 'digits'");
870 speedtest1_prepare(
871 "WITH RECURSIVE\n"
872 " input(sud) AS (VALUES(?1)),\n"
873 " digits(z,lp) AS (VALUES('1',1),('2',2),('3',3),('4',4),('5',5),\n"
874 " ('6',6),('7',7),('8',8),('9',9)),\n"
875 " x(s, ind) AS (\n"
876 " SELECT sud, instr(sud, '.') FROM input\n"
877 " UNION ALL\n"
878 " SELECT\n"
879 " substr(s, 1, ind-1) || z || substr(s, ind+1),\n"
880 " instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' )\n"
881 " FROM x, digits AS z\n"
882 " WHERE ind>0\n"
883 " AND NOT EXISTS (\n"
884 " SELECT 1\n"
885 " FROM digits AS lp\n"
886 " WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)\n"
887 " OR z.z = substr(s, ((ind-1)%%9) + (lp-1)*9 + 1, 1)\n"
888 " OR z.z = substr(s, (((ind-1)/3) %% 3) * 3\n"
889 " + ((ind-1)/27) * 27 + lp\n"
890 " + ((lp-1) / 3) * 6, 1)\n"
891 " )\n"
892 " )\n"
893 "SELECT s FROM x WHERE ind=0;"
894 );
895 sqlite3_bind_text(g.pStmt, 1, zPuz, -1, SQLITE_STATIC);
896 speedtest1_run();
897 speedtest1_end_test();
drhfa46bfb2014-02-09 00:52:53 +0000898
899 rSpacing = 5.0/g.szTest;
900 speedtest1_begin_test(300, "Mandelbrot Set with spacing=%f", rSpacing);
901 speedtest1_prepare(
902 "WITH RECURSIVE \n"
903 " xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+?1 FROM xaxis WHERE x<1.2),\n"
904 " yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+?2 FROM yaxis WHERE y<1.0),\n"
905 " m(iter, cx, cy, x, y) AS (\n"
906 " SELECT 0, x, y, 0.0, 0.0 FROM xaxis, yaxis\n"
907 " UNION ALL\n"
908 " SELECT iter+1, cx, cy, x*x-y*y + cx, 2.0*x*y + cy FROM m \n"
909 " WHERE (x*x + y*y) < 4.0 AND iter<28\n"
910 " ),\n"
911 " m2(iter, cx, cy) AS (\n"
912 " SELECT max(iter), cx, cy FROM m GROUP BY cx, cy\n"
913 " ),\n"
914 " a(t) AS (\n"
915 " SELECT group_concat( substr(' .+*#', 1+min(iter/7,4), 1), '') \n"
916 " FROM m2 GROUP BY cy\n"
917 " )\n"
918 "SELECT group_concat(rtrim(t),x'0a') FROM a;"
919 );
920 sqlite3_bind_double(g.pStmt, 1, rSpacing*.05);
921 sqlite3_bind_double(g.pStmt, 2, rSpacing);
922 speedtest1_run();
923 speedtest1_end_test();
924
drh5574e3f2014-02-09 23:59:28 +0000925 nElem = 10000*g.szTest;
926 speedtest1_begin_test(400, "EXCEPT operator on %d-element tables", nElem);
927 speedtest1_prepare(
928 "WITH RECURSIVE \n"
929 " t1(x) AS (VALUES(2) UNION ALL SELECT x+2 FROM t1 WHERE x<%d),\n"
930 " t2(y) AS (VALUES(3) UNION ALL SELECT y+3 FROM t2 WHERE y<%d)\n"
931 "SELECT count(x), avg(x) FROM (\n"
932 " SELECT x FROM t1 EXCEPT SELECT y FROM t2 ORDER BY 1\n"
933 ");",
934 nElem, nElem
935 );
936 speedtest1_run();
937 speedtest1_end_test();
938
drhc4754802014-02-09 00:18:21 +0000939}
940
drh8683e082014-10-11 10:52:54 +0000941#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000942/* Generate two numbers between 1 and mx. The first number is less than
943** the second. Usually the numbers are near each other but can sometimes
944** be far apart.
945*/
946static void twoCoords(
947 int p1, int p2, /* Parameters adjusting sizes */
948 unsigned mx, /* Range of 1..mx */
949 unsigned *pX0, unsigned *pX1 /* OUT: write results here */
950){
951 unsigned d, x0, x1, span;
952
953 span = mx/100 + 1;
954 if( speedtest1_random()%3==0 ) span *= p1;
955 if( speedtest1_random()%p2==0 ) span = mx/2;
956 d = speedtest1_random()%span + 1;
957 x0 = speedtest1_random()%(mx-d) + 1;
958 x1 = x0 + d;
959 *pX0 = x0;
960 *pX1 = x1;
961}
drh8683e082014-10-11 10:52:54 +0000962#endif
drh65e6b0d2014-04-28 17:56:19 +0000963
drh8683e082014-10-11 10:52:54 +0000964#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000965/* The following routine is an R-Tree geometry callback. It returns
966** true if the object overlaps a slice on the Y coordinate between the
967** two values given as arguments. In other words
968**
969** SELECT count(*) FROM rt1 WHERE id MATCH xslice(10,20);
970**
971** Is the same as saying:
972**
973** SELECT count(*) FROM rt1 WHERE y1>=10 AND y0<=20;
974*/
975static int xsliceGeometryCallback(
976 sqlite3_rtree_geometry *p,
977 int nCoord,
978 double *aCoord,
979 int *pRes
980){
981 *pRes = aCoord[3]>=p->aParam[0] && aCoord[2]<=p->aParam[1];
982 return SQLITE_OK;
983}
drh8683e082014-10-11 10:52:54 +0000984#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +0000985
drh8683e082014-10-11 10:52:54 +0000986#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +0000987/*
988** A testset for the R-Tree virtual table
989*/
990void testset_rtree(int p1, int p2){
991 unsigned i, n;
992 unsigned mxCoord;
993 unsigned x0, x1, y0, y1, z0, z1;
994 unsigned iStep;
995 int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*100 );
996
997 mxCoord = 15000;
998 n = g.szTest*100;
999 speedtest1_begin_test(100, "%d INSERTs into an r-tree", n);
1000 speedtest1_exec("BEGIN");
1001 speedtest1_exec("CREATE VIRTUAL TABLE rt1 USING rtree(id,x0,x1,y0,y1,z0,z1)");
1002 speedtest1_prepare("INSERT INTO rt1(id,x0,x1,y0,y1,z0,z1)"
1003 "VALUES(?1,?2,?3,?4,?5,?6,?7)");
1004 for(i=1; i<=n; i++){
1005 twoCoords(p1, p2, mxCoord, &x0, &x1);
1006 twoCoords(p1, p2, mxCoord, &y0, &y1);
1007 twoCoords(p1, p2, mxCoord, &z0, &z1);
1008 sqlite3_bind_int(g.pStmt, 1, i);
1009 sqlite3_bind_int(g.pStmt, 2, x0);
1010 sqlite3_bind_int(g.pStmt, 3, x1);
1011 sqlite3_bind_int(g.pStmt, 4, y0);
1012 sqlite3_bind_int(g.pStmt, 5, y1);
1013 sqlite3_bind_int(g.pStmt, 6, z0);
1014 sqlite3_bind_int(g.pStmt, 7, z1);
1015 speedtest1_run();
1016 }
1017 speedtest1_exec("COMMIT");
1018 speedtest1_end_test();
1019
1020 speedtest1_begin_test(101, "Copy from rtree to a regular table");
1021 speedtest1_exec("CREATE TABLE t1(id INTEGER PRIMARY KEY,x0,x1,y0,y1,z0,z1)");
1022 speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
1023 speedtest1_end_test();
1024
1025 n = g.szTest*20;
1026 speedtest1_begin_test(110, "%d one-dimensional intersect slice queries", n);
1027 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x0>=?1 AND x1<=?2");
1028 iStep = mxCoord/n;
1029 for(i=0; i<n; i++){
1030 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1031 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1032 speedtest1_run();
1033 aCheck[i] = atoi(g.zResult);
1034 }
1035 speedtest1_end_test();
1036
1037 if( g.bVerify ){
1038 n = g.szTest*20;
1039 speedtest1_begin_test(111, "Verify result from 1-D intersect slice queries");
1040 speedtest1_prepare("SELECT count(*) FROM t1 WHERE x0>=?1 AND x1<=?2");
1041 iStep = mxCoord/n;
1042 for(i=0; i<n; i++){
1043 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1044 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1045 speedtest1_run();
1046 if( aCheck[i]!=atoi(g.zResult) ){
1047 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1048 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1049 }
1050 }
1051 speedtest1_end_test();
1052 }
1053
1054 n = g.szTest*20;
1055 speedtest1_begin_test(120, "%d one-dimensional overlap slice queries", n);
1056 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE y1>=?1 AND y0<=?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(121, "Verify result from 1-D overlap slice queries");
1069 speedtest1_prepare("SELECT count(*) FROM t1 WHERE y1>=?1 AND y0<=?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
1084 n = g.szTest*20;
1085 speedtest1_begin_test(125, "%d custom geometry callback queries", n);
1086 sqlite3_rtree_geometry_callback(g.db, "xslice", xsliceGeometryCallback, 0);
1087 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE id MATCH xslice(?1,?2)");
1088 iStep = mxCoord/n;
1089 for(i=0; i<n; i++){
1090 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1091 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1092 speedtest1_run();
1093 if( aCheck[i]!=atoi(g.zResult) ){
1094 fatal_error("Count disagree step %d: %d..%d. %d vs %d",
1095 i, i*iStep, (i+1)*iStep, aCheck[i], atoi(g.zResult));
1096 }
1097 }
1098 speedtest1_end_test();
1099
1100 n = g.szTest*80;
1101 speedtest1_begin_test(130, "%d three-dimensional intersect box queries", n);
1102 speedtest1_prepare("SELECT count(*) FROM rt1 WHERE x1>=?1 AND x0<=?2"
1103 " AND y1>=?1 AND y0<=?2 AND z1>=?1 AND z0<=?2");
1104 iStep = mxCoord/n;
1105 for(i=0; i<n; i++){
1106 sqlite3_bind_int(g.pStmt, 1, i*iStep);
1107 sqlite3_bind_int(g.pStmt, 2, (i+1)*iStep);
1108 speedtest1_run();
1109 aCheck[i] = atoi(g.zResult);
1110 }
1111 speedtest1_end_test();
1112
1113 n = g.szTest*100;
1114 speedtest1_begin_test(140, "%d rowid queries", n);
1115 speedtest1_prepare("SELECT * FROM rt1 WHERE id=?1");
1116 for(i=1; i<=n; i++){
1117 sqlite3_bind_int(g.pStmt, 1, i);
1118 speedtest1_run();
1119 }
1120 speedtest1_end_test();
1121}
drh8683e082014-10-11 10:52:54 +00001122#endif /* SQLITE_ENABLE_RTREE */
drh65e6b0d2014-04-28 17:56:19 +00001123
drhc4754802014-02-09 00:18:21 +00001124/*
drhad1ca9a2013-11-23 04:16:58 +00001125** A testset used for debugging speedtest1 itself.
1126*/
1127void testset_debug1(void){
1128 unsigned i, n;
1129 unsigned x1, x2;
1130 char zNum[2000]; /* A number name */
1131
1132 n = g.szTest;
1133 for(i=1; i<=n; i++){
1134 x1 = swizzle(i, n);
1135 x2 = swizzle(x1, n);
1136 speedtest1_numbername(x1, zNum, sizeof(zNum));
1137 printf("%5d %5d %5d %s\n", i, x1, x2, zNum);
1138 }
1139}
1140
1141int main(int argc, char **argv){
1142 int doAutovac = 0; /* True for --autovacuum */
1143 int cacheSize = 0; /* Desired cache size. 0 means default */
1144 int doExclusive = 0; /* True for --exclusive */
1145 int nHeap = 0, mnHeap = 0; /* Heap size from --heap */
1146 int doIncrvac = 0; /* True for --incrvacuum */
1147 const char *zJMode = 0; /* Journal mode */
1148 const char *zKey = 0; /* Encryption key */
1149 int nLook = 0, szLook = 0; /* --lookaside configuration */
1150 int noSync = 0; /* True for --nosync */
1151 int pageSize = 0; /* Desired page size. 0 means default */
1152 int nPCache = 0, szPCache = 0;/* --pcache configuration */
drh93307e92013-11-24 01:14:14 +00001153 int nScratch = 0, szScratch=0;/* --scratch configuration */
drhad1ca9a2013-11-23 04:16:58 +00001154 int showStats = 0; /* True for --stats */
drh46a06bb2014-04-18 13:57:39 +00001155 int nThread = 0; /* --threads value */
drhad1ca9a2013-11-23 04:16:58 +00001156 const char *zTSet = "main"; /* Which --testset torun */
1157 int doTrace = 0; /* True for --trace */
1158 const char *zEncoding = 0; /* --utf16be or --utf16le */
1159 const char *zDbName = 0; /* Name of the test database */
1160
1161 void *pHeap = 0; /* Allocated heap space */
1162 void *pLook = 0; /* Allocated lookaside space */
1163 void *pPCache = 0; /* Allocated storage for pcache */
drh93307e92013-11-24 01:14:14 +00001164 void *pScratch = 0; /* Allocated storage for scratch */
drhad1ca9a2013-11-23 04:16:58 +00001165 int iCur, iHi; /* Stats values, current and "highwater" */
drhe19f8322013-11-23 11:45:58 +00001166 int i; /* Loop counter */
1167 int rc; /* API return code */
drhad1ca9a2013-11-23 04:16:58 +00001168
1169 /* Process command-line arguments */
1170 g.zWR = "";
1171 g.zNN = "";
1172 g.zPK = "UNIQUE";
1173 g.szTest = 100;
1174 for(i=1; i<argc; i++){
1175 const char *z = argv[i];
1176 if( z[0]=='-' ){
1177 do{ z++; }while( z[0]=='-' );
1178 if( strcmp(z,"autovacuum")==0 ){
1179 doAutovac = 1;
1180 }else if( strcmp(z,"cachesize")==0 ){
1181 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1182 i++;
drh93307e92013-11-24 01:14:14 +00001183 cacheSize = integerValue(argv[i]);
drhad1ca9a2013-11-23 04:16:58 +00001184 }else if( strcmp(z,"exclusive")==0 ){
1185 doExclusive = 1;
drh849a9d92013-12-21 15:46:06 +00001186 }else if( strcmp(z,"explain")==0 ){
1187 g.bSqlOnly = 1;
1188 g.bExplain = 1;
drhad1ca9a2013-11-23 04:16:58 +00001189 }else if( strcmp(z,"heap")==0 ){
1190 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001191 nHeap = integerValue(argv[i+1]);
1192 mnHeap = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001193 i += 2;
1194 }else if( strcmp(z,"incrvacuum")==0 ){
1195 doIncrvac = 1;
1196 }else if( strcmp(z,"journal")==0 ){
1197 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1198 zJMode = argv[++i];
1199 }else if( strcmp(z,"key")==0 ){
1200 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1201 zKey = argv[++i];
1202 }else if( strcmp(z,"lookaside")==0 ){
1203 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001204 nLook = integerValue(argv[i+1]);
1205 szLook = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001206 i += 2;
1207 }else if( strcmp(z,"nosync")==0 ){
1208 noSync = 1;
1209 }else if( strcmp(z,"notnull")==0 ){
1210 g.zNN = "NOT NULL";
dan54fc2142015-03-05 16:21:20 +00001211#ifdef SQLITE_ENABLE_OTA
1212 }else if( strcmp(z,"ota")==0 ){
1213 sqlite3ota_create_vfs("ota", 0);
1214 sqlite3_vfs_register(sqlite3_vfs_find("ota"), 1);
1215#endif
drhad1ca9a2013-11-23 04:16:58 +00001216 }else if( strcmp(z,"pagesize")==0 ){
1217 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001218 pageSize = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001219 }else if( strcmp(z,"pcache")==0 ){
1220 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001221 nPCache = integerValue(argv[i+1]);
1222 szPCache = integerValue(argv[i+2]);
drhad1ca9a2013-11-23 04:16:58 +00001223 i += 2;
1224 }else if( strcmp(z,"primarykey")==0 ){
1225 g.zPK = "PRIMARY KEY";
1226 }else if( strcmp(z,"reprepare")==0 ){
1227 g.bReprepare = 1;
drh93307e92013-11-24 01:14:14 +00001228 }else if( strcmp(z,"scratch")==0 ){
1229 if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
1230 nScratch = integerValue(argv[i+1]);
1231 szScratch = integerValue(argv[i+2]);
1232 i += 2;
drhad1ca9a2013-11-23 04:16:58 +00001233 }else if( strcmp(z,"sqlonly")==0 ){
1234 g.bSqlOnly = 1;
1235 }else if( strcmp(z,"size")==0 ){
1236 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
drh93307e92013-11-24 01:14:14 +00001237 g.szTest = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001238 }else if( strcmp(z,"stats")==0 ){
1239 showStats = 1;
1240 }else if( strcmp(z,"testset")==0 ){
1241 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1242 zTSet = argv[++i];
1243 }else if( strcmp(z,"trace")==0 ){
1244 doTrace = 1;
drh46a06bb2014-04-18 13:57:39 +00001245 }else if( strcmp(z,"threads")==0 ){
1246 if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]);
1247 nThread = integerValue(argv[++i]);
drhad1ca9a2013-11-23 04:16:58 +00001248 }else if( strcmp(z,"utf16le")==0 ){
1249 zEncoding = "utf16le";
1250 }else if( strcmp(z,"utf16be")==0 ){
1251 zEncoding = "utf16be";
drh65e6b0d2014-04-28 17:56:19 +00001252 }else if( strcmp(z,"verify")==0 ){
1253 g.bVerify = 1;
drhad1ca9a2013-11-23 04:16:58 +00001254 }else if( strcmp(z,"without-rowid")==0 ){
1255 g.zWR = "WITHOUT ROWID";
1256 g.zPK = "PRIMARY KEY";
1257 }else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){
1258 printf(zHelp, argv[0]);
1259 exit(0);
1260 }else{
1261 fatal_error("unknown option: %s\nUse \"%s -?\" for help\n",
1262 argv[i], argv[0]);
1263 }
1264 }else if( zDbName==0 ){
1265 zDbName = argv[i];
1266 }else{
1267 fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n",
1268 argv[i], argv[0]);
1269 }
1270 }
1271#if 0
1272 if( zDbName==0 ){
1273 fatal_error(zHelp, argv[0]);
1274 }
1275#endif
1276 if( nHeap>0 ){
1277 pHeap = malloc( nHeap );
1278 if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap);
drhe19f8322013-11-23 11:45:58 +00001279 rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap);
drh7b65ad32013-11-23 21:29:07 +00001280 if( rc ) fatal_error("heap configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001281 }
1282 if( nPCache>0 && szPCache>0 ){
drh93307e92013-11-24 01:14:14 +00001283 pPCache = malloc( nPCache*(sqlite3_int64)szPCache );
1284 if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n",
1285 nPCache*(sqlite3_int64)szPCache);
drhe19f8322013-11-23 11:45:58 +00001286 rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache);
drh7b65ad32013-11-23 21:29:07 +00001287 if( rc ) fatal_error("pcache configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001288 }
drh93307e92013-11-24 01:14:14 +00001289 if( nScratch>0 && szScratch>0 ){
1290 pScratch = malloc( nScratch*(sqlite3_int64)szScratch );
1291 if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n",
1292 nScratch*(sqlite3_int64)szScratch);
1293 rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch);
1294 if( rc ) fatal_error("scratch configuration failed: %d\n", rc);
1295 }
drhad1ca9a2013-11-23 04:16:58 +00001296 if( nLook>0 ){
1297 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0);
1298 }
1299
1300 /* Open the database and the input file */
1301 if( sqlite3_open(zDbName, &g.db) ){
1302 fatal_error("Cannot open database file: %s\n", zDbName);
1303 }
1304 if( nLook>0 && szLook>0 ){
1305 pLook = malloc( nLook*szLook );
drhe19f8322013-11-23 11:45:58 +00001306 rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook);
drh7b65ad32013-11-23 21:29:07 +00001307 if( rc ) fatal_error("lookaside configuration failed: %d\n", rc);
drhad1ca9a2013-11-23 04:16:58 +00001308 }
1309
1310 /* Set database connection options */
1311 sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0);
1312 if( doTrace ) sqlite3_trace(g.db, traceCallback, 0);
drh43cbe142014-08-29 18:06:33 +00001313 speedtest1_exec("PRAGMA threads=%d", nThread);
drhad1ca9a2013-11-23 04:16:58 +00001314 if( zKey ){
1315 speedtest1_exec("PRAGMA key('%s')", zKey);
1316 }
1317 if( zEncoding ){
1318 speedtest1_exec("PRAGMA encoding=%s", zEncoding);
1319 }
1320 if( doAutovac ){
1321 speedtest1_exec("PRAGMA auto_vacuum=FULL");
1322 }else if( doIncrvac ){
1323 speedtest1_exec("PRAGMA auto_vacuum=INCREMENTAL");
1324 }
1325 if( pageSize ){
1326 speedtest1_exec("PRAGMA page_size=%d", pageSize);
1327 }
1328 if( cacheSize ){
1329 speedtest1_exec("PRAGMA cache_size=%d", cacheSize);
1330 }
1331 if( noSync ) speedtest1_exec("PRAGMA synchronous=OFF");
1332 if( doExclusive ){
1333 speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE");
1334 }
1335 if( zJMode ){
1336 speedtest1_exec("PRAGMA journal_mode=%s", zJMode);
1337 }
1338
drh849a9d92013-12-21 15:46:06 +00001339 if( g.bExplain ) printf(".explain\n.echo on\n");
drhad1ca9a2013-11-23 04:16:58 +00001340 if( strcmp(zTSet,"main")==0 ){
1341 testset_main();
1342 }else if( strcmp(zTSet,"debug1")==0 ){
1343 testset_debug1();
drhc4754802014-02-09 00:18:21 +00001344 }else if( strcmp(zTSet,"cte")==0 ){
1345 testset_cte();
drh65e6b0d2014-04-28 17:56:19 +00001346 }else if( strcmp(zTSet,"rtree")==0 ){
drh8683e082014-10-11 10:52:54 +00001347#ifdef SQLITE_ENABLE_RTREE
drh65e6b0d2014-04-28 17:56:19 +00001348 testset_rtree(6, 147);
drh8683e082014-10-11 10:52:54 +00001349#else
1350 fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable "
1351 "the R-Tree tests\n");
1352#endif
drhad1ca9a2013-11-23 04:16:58 +00001353 }else{
drh65e6b0d2014-04-28 17:56:19 +00001354 fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree\n",
1355 zTSet);
drhad1ca9a2013-11-23 04:16:58 +00001356 }
1357 speedtest1_final();
1358
1359 /* Database connection statistics printed after both prepared statements
1360 ** have been finalized */
drh290ea402013-12-01 18:10:01 +00001361#if SQLITE_VERSION_NUMBER>=3007009
drhad1ca9a2013-11-23 04:16:58 +00001362 if( showStats ){
1363 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0);
1364 printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi);
1365 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0);
1366 printf("-- Successful lookasides: %d\n", iHi);
1367 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0);
1368 printf("-- Lookaside size faults: %d\n", iHi);
1369 sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0);
1370 printf("-- Lookaside OOM faults: %d\n", iHi);
1371 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0);
1372 printf("-- Pager Heap Usage: %d bytes\n", iCur);
1373 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1);
1374 printf("-- Page cache hits: %d\n", iCur);
1375 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1);
drh2a702db2013-12-02 21:25:40 +00001376 printf("-- Page cache misses: %d\n", iCur);
1377#if SQLITE_VERSION_NUMBER>=3007012
drhad1ca9a2013-11-23 04:16:58 +00001378 sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1);
1379 printf("-- Page cache writes: %d\n", iCur);
drh2a702db2013-12-02 21:25:40 +00001380#endif
drhad1ca9a2013-11-23 04:16:58 +00001381 sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0);
1382 printf("-- Schema Heap Usage: %d bytes\n", iCur);
1383 sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0);
1384 printf("-- Statement Heap Usage: %d bytes\n", iCur);
1385 }
drh290ea402013-12-01 18:10:01 +00001386#endif
drhad1ca9a2013-11-23 04:16:58 +00001387
1388 sqlite3_close(g.db);
1389
1390 /* Global memory usage statistics printed after the database connection
1391 ** has closed. Memory usage should be zero at this point. */
1392 if( showStats ){
1393 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0);
1394 printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001395#if SQLITE_VERSION_NUMBER>=3007000
drhad1ca9a2013-11-23 04:16:58 +00001396 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0);
1397 printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi);
drhd79e9c52013-12-02 01:24:05 +00001398#endif
drhad1ca9a2013-11-23 04:16:58 +00001399 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0);
1400 printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi);
1401 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0);
1402 printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi);
1403 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0);
1404 printf("-- Largest Allocation: %d bytes\n",iHi);
1405 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
1406 printf("-- Largest Pcache Allocation: %d bytes\n",iHi);
1407 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
1408 printf("-- Largest Scratch Allocation: %d bytes\n", iHi);
1409 }
1410
1411 /* Release memory */
1412 free( pLook );
1413 free( pPCache );
drh93307e92013-11-24 01:14:14 +00001414 free( pScratch );
drhad1ca9a2013-11-23 04:16:58 +00001415 free( pHeap );
1416 return 0;
1417}