Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Get the optfuzz program working. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
21346bbce9fd161e8a2037834a6e8eb4 |
User & Date: | drh 2018-03-21 20:21:29.680 |
Context
2018-03-22
| ||
11:28 | Add the --valid-sql option to the optfuzz test program. (check-in: a8dfeec73b user: drh tags: trunk) | |
2018-03-21
| ||
20:21 | Get the optfuzz program working. (check-in: 21346bbce9 user: drh tags: trunk) | |
19:25 | Add the optfuzz.c program for verifying the query planner using a fuzzer. This is an initial code check-in. (check-in: 3fb21251b0 user: drh tags: trunk) | |
Changes
Changes to test/optfuzz.c.
︙ | ︙ | |||
79 80 81 82 83 84 85 | ** Run one or more SQL statements contained in zSql against database dbRun. ** Store the input in database dbOut. */ static int optfuzz_exec( sqlite3 *dbRun, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite3 *dbOut, /* Store results in this database */ | | > > > | | > | > > | > > > > | < | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | ** Run one or more SQL statements contained in zSql against database dbRun. ** Store the input in database dbOut. */ static int optfuzz_exec( sqlite3 *dbRun, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ sqlite3 *dbOut, /* Store results in this database */ const char *zOutTab, /* Store results in this table of dbOut */ int *pnStmt, /* Write the number of statements here */ int *pnRow, /* Write the number of rows here */ int bTrace /* Print query results if true */ ){ int rc = SQLITE_OK; /* Return code */ const char *zLeftover; /* Tail of unprocessed SQL */ sqlite3_stmt *pStmt = 0; /* The current SQL statement */ sqlite3_stmt *pIns = 0; /* Statement to insert into dbOut */ const char *zCol; /* Single column value */ int nCol; /* Number of output columns */ char zLine[4000]; /* Complete row value */ run_sql(dbOut, "BEGIN"); run_sql(dbOut, "CREATE TABLE IF NOT EXISTS staging(x TEXT)"); run_sql(dbOut, "CREATE TABLE IF NOT EXISTS \"%w\"(x TEXT)", zOutTab); pIns = prepare_sql(dbOut, "INSERT INTO staging(x) VALUES(?1)"); *pnRow = *pnStmt = 0; while( rc==SQLITE_OK && zSql && zSql[0] ){ zLeftover = 0; rc = sqlite3_prepare_v2(dbRun, zSql, -1, &pStmt, &zLeftover); zSql = zLeftover; assert( rc==SQLITE_OK || pStmt==0 ); if( rc!=SQLITE_OK ){ printf("Error with [%s]\n%s\n", zSql, sqlite3_errmsg(dbRun)); break; } if( !pStmt ) continue; (*pnStmt)++; nCol = sqlite3_column_count(pStmt); run_sql(dbOut, "DELETE FROM staging;"); while( sqlite3_step(pStmt)==SQLITE_ROW ){ int i, j; for(i=j=0; i<nCol && j<sizeof(zLine)-50; i++){ int eType = sqlite3_column_type(pStmt, i); if( eType==SQLITE_NULL ){ zCol = "NULL"; }else{ zCol = (const char*)sqlite3_column_text(pStmt, i); } |
︙ | ︙ | |||
124 125 126 127 128 129 130 131 132 133 | } /* Detect if any row is too large and throw an error, because we will ** want to go back and look more closely at that case */ if( j>=sizeof(zLine)-100 ){ printf("Excessively long output line: %d bytes\n" ,j); exit(1); } sqlite3_bind_text(pIns, 1, zLine, j, SQLITE_TRANSIENT); rc = sqlite3_step(pIns); assert( rc==SQLITE_DONE ); | > > > > | | | < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | } /* Detect if any row is too large and throw an error, because we will ** want to go back and look more closely at that case */ if( j>=sizeof(zLine)-100 ){ printf("Excessively long output line: %d bytes\n" ,j); exit(1); } if( bTrace ){ printf("%s\n", zLine); } (*pnRow)++; sqlite3_bind_text(pIns, 1, zLine, j, SQLITE_TRANSIENT); rc = sqlite3_step(pIns); assert( rc==SQLITE_DONE ); rc = sqlite3_reset(pIns); } run_sql(dbOut, "INSERT INTO \"%w\"(x) VALUES('### %q ###')", zOutTab, sqlite3_sql(pStmt) ); run_sql(dbOut, "INSERT INTO \"%w\"(x) SELECT group_concat(x,char(10))" " FROM (SELECT x FROM staging ORDER BY x)", zOutTab ); run_sql(dbOut, "COMMIT"); sqlite3_finalize(pStmt); pStmt = 0; } sqlite3_finalize(pStmt); sqlite3_finalize(pIns); return rc; } /* |
︙ | ︙ | |||
190 191 192 193 194 195 196 197 198 199 200 201 202 | } int main(int argc, char **argv){ int nIn = 0; /* Number of input files */ char **azIn = 0; /* Names of input files */ sqlite3 *dbOut = 0; /* Database to hold results */ sqlite3 *dbRun = 0; /* Database used for tests */ int i, rc; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' && z[1]=='-' ) z++; if( strcmp(z,"-help")==0 ){ | > > | > > > > > > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | } int main(int argc, char **argv){ int nIn = 0; /* Number of input files */ char **azIn = 0; /* Names of input files */ sqlite3 *dbOut = 0; /* Database to hold results */ sqlite3 *dbRun = 0; /* Database used for tests */ int bTrace = 0; /* Show query results */ int nRow, nStmt; /* Number of rows and statements */ int i, rc; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' && z[1]=='-' ) z++; if( strcmp(z,"-help")==0 ){ printf("Usage: %s [OPTIONS] FILENAME ...\n", argv[0]); printf("Options:\n"); printf(" --help Show his message\n"); printf(" --output-trace Show each line of SQL output\n"); return 0; } else if( strcmp(z,"-output-trace")==0 ){ bTrace = 1; } else if( z[0]=='-' ){ printf("unknown option \"%s\". Use --help for details\n", argv[i]); return 1; } else { nIn++; |
︙ | ︙ | |||
222 223 224 225 226 227 228 | sqlite3_open(":memory:", &dbRun); sqlite3_deserialize(dbRun, "main", data001, sizeof(data001), sizeof(data001), SQLITE_DESERIALIZE_READONLY); for(i=0; i<nIn; i++){ char *zSql = readFile(azIn[i], 0); sqlite3_stmt *pCk; sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0); | > | | > > > > | > | | | | | > > > > > > > > > > | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | sqlite3_open(":memory:", &dbRun); sqlite3_deserialize(dbRun, "main", data001, sizeof(data001), sizeof(data001), SQLITE_DESERIALIZE_READONLY); for(i=0; i<nIn; i++){ char *zSql = readFile(azIn[i], 0); sqlite3_stmt *pCk; sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0); if( bTrace ) printf("%s: Optimized\n", azIn[i]); rc = optfuzz_exec(dbRun, zSql, dbOut, "opt", &nStmt, &nRow, bTrace); if( rc ){ printf("%s: optimized run failed: %s\n", azIn[i], sqlite3_errmsg(dbRun)); }else{ sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0xffff); if( bTrace ) printf("%s: Non-optimized\n", azIn[i]); rc = optfuzz_exec(dbRun, zSql, dbOut, "noopt", &nStmt, &nRow, bTrace); if( rc ){ printf("%s: non-optimized run failed: %s\n", azIn[i], sqlite3_errmsg(dbRun)); exit(1); } pCk = prepare_sql(dbOut, "SELECT (SELECT group_concat(x,char(10)) FROM opt)==" " (SELECT group_concat(x,char(10)) FROM noopt)"); rc = sqlite3_step(pCk); if( rc!=SQLITE_ROW ){ printf("%s: comparison failed\n", sqlite3_errmsg(dbOut)); exit(1); } if( !sqlite3_column_int(pCk, 0) ){ printf("%s: opt/no-opt outputs differ\n", azIn[i]); pCk = prepare_sql(dbOut, "SELECT group_concat(x,char(10)) FROM opt " "UNION ALL " "SELECT group_concat(x,char(10)) FROM noopt"); sqlite3_step(pCk); printf("opt:\n%s\n", sqlite3_column_text(pCk,0)); sqlite3_step(pCk); printf("noopt:\n%s\n", sqlite3_column_text(pCk,0)); exit(1); }else{ printf("%s: %d stmts %d rows ok\n", azIn[i], nStmt, nRow); } sqlite3_finalize(pCk); } sqlite3_free(zSql); } sqlite3_close(dbRun); sqlite3_close(dbOut); |
︙ | ︙ |