Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the "wholenumber" virtual table module to the test suite - useful in populating tables with many rows of content prior to a test. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
975dff155bd9db42f2b6855b24c86185 |
User & Date: | drh 2011-04-01 23:49:44.644 |
Context
2011-04-02
| ||
06:44 | Fix additional test cases so that they work with DEFAULT_AUTOVACUUM. (check-in: 139bc5655e user: dan tags: trunk) | |
2011-04-01
| ||
23:49 | Add the "wholenumber" virtual table module to the test suite - useful in populating tables with many rows of content prior to a test. (check-in: 975dff155b user: drh tags: trunk) | |
20:54 | Fix up the Makefile.in so that the configuration script works for "make test". (check-in: 2e03830c1e user: drh tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
373 374 375 376 377 378 379 380 381 382 383 384 385 386 | $(TOP)/src/test_server.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ $(TOP)/src/test_stat.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_wsd.c # Source code to the library files needed by the test fixture # TESTSRC2 = \ $(TOP)/src/attach.c \ $(TOP)/src/backup.c \ | > | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | $(TOP)/src/test_server.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ $(TOP)/src/test_stat.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_wholenumber.c \ $(TOP)/src/test_wsd.c # Source code to the library files needed by the test fixture # TESTSRC2 = \ $(TOP)/src/attach.c \ $(TOP)/src/backup.c \ |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
254 255 256 257 258 259 260 261 262 263 264 265 266 267 | $(TOP)/src/test_server.c \ $(TOP)/src/test_stat.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_wsd.c #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c TESTSRC2 = \ $(TOP)/src/attach.c \ | > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | $(TOP)/src/test_server.c \ $(TOP)/src/test_stat.c \ $(TOP)/src/test_superlock.c \ $(TOP)/src/test_syscall.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/test_thread.c \ $(TOP)/src/test_vfs.c \ $(TOP)/src/test_wholenumber.c \ $(TOP)/src/test_wsd.c #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c TESTSRC2 = \ $(TOP)/src/attach.c \ |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 | extern int SqlitetestStat_Init(Tcl_Interp*); extern int Sqlitetestrtree_Init(Tcl_Interp*); extern int Sqlitequota_Init(Tcl_Interp*); extern int Sqlitemultiplex_Init(Tcl_Interp*); extern int SqliteSuperlock_Init(Tcl_Interp*); extern int SqlitetestSyscall_Init(Tcl_Interp*); extern int Sqlitetestfuzzer_Init(Tcl_Interp*); #ifdef SQLITE_ENABLE_ZIPVFS extern int Zipvfs_Init(Tcl_Interp*); Zipvfs_Init(interp); #endif Sqliteconfig_Init(interp); | > | 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 | extern int SqlitetestStat_Init(Tcl_Interp*); extern int Sqlitetestrtree_Init(Tcl_Interp*); extern int Sqlitequota_Init(Tcl_Interp*); extern int Sqlitemultiplex_Init(Tcl_Interp*); extern int SqliteSuperlock_Init(Tcl_Interp*); extern int SqlitetestSyscall_Init(Tcl_Interp*); extern int Sqlitetestfuzzer_Init(Tcl_Interp*); extern int Sqlitetestwholenumber_Init(Tcl_Interp*); #ifdef SQLITE_ENABLE_ZIPVFS extern int Zipvfs_Init(Tcl_Interp*); Zipvfs_Init(interp); #endif Sqliteconfig_Init(interp); |
︙ | ︙ | |||
3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 | SqlitetestStat_Init(interp); Sqlitetestrtree_Init(interp); Sqlitequota_Init(interp); Sqlitemultiplex_Init(interp); SqliteSuperlock_Init(interp); SqlitetestSyscall_Init(interp); Sqlitetestfuzzer_Init(interp); Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } | > | 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 | SqlitetestStat_Init(interp); Sqlitetestrtree_Init(interp); Sqlitequota_Init(interp); Sqlitemultiplex_Init(interp); SqliteSuperlock_Init(interp); SqlitetestSyscall_Init(interp); Sqlitetestfuzzer_Init(interp); Sqlitetestwholenumber_Init(interp); Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } |
︙ | ︙ |
Added src/test_wholenumber.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 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 126 127 128 129 130 131 132 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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 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 232 233 234 235 236 237 238 239 240 241 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 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | /* ** 2011 April 02 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file implements a virtual table that returns the whole numbers ** between 1 and 4294967295, inclusive. ** ** Example: ** ** CREATE VIRTUAL TABLE nums USING wholenumber; ** SELECT value FROM nums WHERE value<10; ** ** Results in: ** ** 1 2 3 4 5 6 7 8 9 */ #include "sqlite3.h" #include <assert.h> #include <string.h> #ifndef SQLITE_OMIT_VIRTUALTABLE /* A wholenumber cursor object */ typedef struct wholenumber_cursor wholenumber_cursor; struct wholenumber_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ unsigned iValue; /* Current value */ unsigned mxValue; /* Maximum value */ }; /* Methods for the wholenumber module */ static int wholenumberConnect( sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ sqlite3_vtab *pNew; pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; sqlite3_declare_vtab(db, "CREATE TABLE x(value)"); memset(pNew, 0, sizeof(*pNew)); return SQLITE_OK; } /* Note that for this virtual table, the xCreate and xConnect ** methods are identical. */ static int wholenumberDisconnect(sqlite3_vtab *pVtab){ sqlite3_free(pVtab); return SQLITE_OK; } /* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new wholenumber cursor. */ static int wholenumberOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ wholenumber_cursor *pCur; pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); *ppCursor = &pCur->base; return SQLITE_OK; } /* ** Close a wholenumber cursor. */ static int wholenumberClose(sqlite3_vtab_cursor *cur){ sqlite3_free(cur); return SQLITE_OK; } /* ** Advance a cursor to its next row of output */ static int wholenumberNext(sqlite3_vtab_cursor *cur){ wholenumber_cursor *pCur = (wholenumber_cursor*)cur; pCur->iValue++; return SQLITE_OK; } /* ** Return the value associated with a wholenumber. */ static int wholenumberColumn( sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i ){ wholenumber_cursor *pCur = (wholenumber_cursor*)cur; sqlite3_result_int64(ctx, pCur->iValue); return SQLITE_OK; } /* ** The rowid. */ static int wholenumberRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ wholenumber_cursor *pCur = (wholenumber_cursor*)cur; *pRowid = pCur->iValue; return SQLITE_OK; } /* ** When the wholenumber_cursor.rLimit value is 0 or less, that is a signal ** that the cursor has nothing more to output. */ static int wholenumberEof(sqlite3_vtab_cursor *cur){ wholenumber_cursor *pCur = (wholenumber_cursor*)cur; return pCur->iValue>pCur->mxValue || pCur->iValue==0; } /* ** Called to "rewind" a cursor back to the beginning so that ** it starts its output over again. Always called at least once ** prior to any wholenumberColumn, wholenumberRowid, or wholenumberEof call. ** ** idxNum Constraints ** ------ --------------------- ** 0 (none) ** 1 value > $argv0 ** 2 value >= $argv0 ** 4 value < $argv0 ** 8 value <= $argv0 ** ** 5 value > $argv0 AND value < $argv1 ** 6 value >= $argv0 AND value < $argv1 ** 9 value > $argv0 AND value <= $argv1 ** 10 value >= $argv0 AND value <= $argv1 */ static int wholenumberFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ wholenumber_cursor *pCur = (wholenumber_cursor *)pVtabCursor; sqlite3_int64 v; int i = 0; pCur->iValue = 1; pCur->mxValue = 0xffffffff; /* 4294967295 */ if( idxNum & 3 ){ v = sqlite3_value_int64(argv[0]) + (idxNum&1); if( v>pCur->iValue && v<=pCur->mxValue ) pCur->iValue = v; i++; } if( idxNum & 12 ){ v = sqlite3_value_int64(argv[i]) - ((idxNum>>2)&1); if( v>=pCur->iValue && v<pCur->mxValue ) pCur->mxValue = v; } return SQLITE_OK; } /* ** Search for terms of these forms: ** ** (1) value > $value ** (2) value >= $value ** (4) value < $value ** (8) value <= $value ** ** idxNum is an ORed combination of 1 or 2 with 4 or 8. */ static int wholenumberBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ int i; int idxNum = 0; int argvIdx = 1; int ltIdx = -1; int gtIdx = -1; const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ if( pConstraint->usable==0 ) continue; if( (idxNum & 3)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_GT ){ idxNum |= 1; ltIdx = i; } if( (idxNum & 3)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_GE ){ idxNum |= 2; ltIdx = i; } if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){ idxNum |= 4; gtIdx = i; } if( (idxNum & 12)==0 && pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){ idxNum |= 8; gtIdx = i; } } pIdxInfo->idxNum = idxNum; if( ltIdx>=0 ){ pIdxInfo->aConstraintUsage[ltIdx].argvIndex = argvIdx++; pIdxInfo->aConstraintUsage[ltIdx].omit = 1; } if( gtIdx>=0 ){ pIdxInfo->aConstraintUsage[gtIdx].argvIndex = argvIdx; pIdxInfo->aConstraintUsage[gtIdx].omit = 1; } if( pIdxInfo->nOrderBy==1 && pIdxInfo->aOrderBy[0].desc==0 ){ pIdxInfo->orderByConsumed = 1; } pIdxInfo->estimatedCost = (double)1; return SQLITE_OK; } /* ** A virtual table module that provides read-only access to a ** Tcl global variable namespace. */ static sqlite3_module wholenumberModule = { 0, /* iVersion */ wholenumberConnect, wholenumberConnect, wholenumberBestIndex, wholenumberDisconnect, wholenumberDisconnect, wholenumberOpen, /* xOpen - open a cursor */ wholenumberClose, /* xClose - close a cursor */ wholenumberFilter, /* xFilter - configure scan constraints */ wholenumberNext, /* xNext - advance a cursor */ wholenumberEof, /* xEof - check for end of scan */ wholenumberColumn, /* xColumn - read data */ wholenumberRowid, /* xRowid - read data */ 0, /* xUpdate */ 0, /* xBegin */ 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Register the wholenumber virtual table */ int wholenumber_register(sqlite3 *db){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_create_module(db, "wholenumber", &wholenumberModule, 0); #endif return rc; } #ifdef SQLITE_TEST #include <tcl.h> /* ** Decode a pointer to an sqlite3 object. */ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); /* ** Register the echo virtual table module. */ static int register_wholenumber_module( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3 *db; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; wholenumber_register(db); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetestwholenumber_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; void *clientData; } aObjCmd[] = { { "register_wholenumber_module", register_wholenumber_module, 0 }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, aObjCmd[i].clientData, 0); } return TCL_OK; } #endif /* SQLITE_TEST */ |
Changes to test/analyze7.test.
︙ | ︙ | |||
22 23 24 25 26 27 28 29 | finish_test return } # Generate some test data # do_test analyze7-1.0 { execsql { | > < < < < < < < < < < < > | > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | finish_test return } # Generate some test data # do_test analyze7-1.0 { register_wholenumber_module db execsql { CREATE TABLE t1(a,b,c,d); CREATE INDEX t1a ON t1(a); CREATE INDEX t1b ON t1(b); CREATE INDEX t1cd ON t1(c,d); CREATE VIRTUAL TABLE nums USING wholenumber; INSERT INTO t1 SELECT value, value, value/100, value FROM nums WHERE value BETWEEN 1 AND 256; EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123; } } {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~10 rows)}} do_test analyze7-1.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~10 rows)}} do_test analyze7-1.2 { |
︙ | ︙ |
Changes to test/memdb.test.
︙ | ︙ | |||
361 362 363 364 365 366 367 368 369 | DELETE FROM t5 WHERE x>0; SELECT * FROM t5; } } {} ifcapable subquery { do_test memdb-7.1 { execsql { CREATE TABLE t6(x); | > < | | < < < < < < | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | DELETE FROM t5 WHERE x>0; SELECT * FROM t5; } } {} ifcapable subquery { do_test memdb-7.1 { register_wholenumber_module db execsql { CREATE TABLE t6(x); CREATE VIRTUAL TABLE nums USING wholenumber; INSERT INTO t6 SELECT value FROM nums WHERE value BETWEEN 1 AND 256; SELECT count(*) FROM (SELECT DISTINCT x FROM t6); } } {256} for {set i 1} {$i<=256} {incr i} { do_test memdb-7.2.$i { execsql "DELETE FROM t6 WHERE x=\ (SELECT x FROM t6 ORDER BY random() LIMIT 1)" |
︙ | ︙ |