Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The echo module test is now running. Added the tclvar module test but have not yet done anything with it. (CVS 3234) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
29199eeea4c46168ccaa7535d4941bd7 |
User & Date: | drh 2006-06-13 23:51:34.000 |
Context
2006-06-14
| ||
06:31 | Add tests for error conditions surrounding the creation/connection of virtual tables. (CVS 3235) (check-in: 5e592c422b user: danielk1977 tags: trunk) | |
2006-06-13
| ||
23:51 | The echo module test is now running. Added the tclvar module test but have not yet done anything with it. (CVS 3234) (check-in: 29199eeea4 user: drh tags: trunk) | |
19:26 | The (unsupported) soundex() function returns '?000' when given a NULL. Ticket #1845. (CVS 3233) (check-in: 9372481f23 user: drh tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
207 208 209 210 211 212 213 214 215 216 217 218 219 220 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_server.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/where.c # Header files used by all library source files. # | > | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/where.c # Header files used by all library source files. # |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_server.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/where.c # Header files used by all library source files. # | > | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/test7.c \ $(TOP)/src/test8.c \ $(TOP)/src/test_async.c \ $(TOP)/src/test_md5.c \ $(TOP)/src/test_server.c \ $(TOP)/src/test_tclvar.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/where.c # Header files used by all library source files. # |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.174 2006/06/13 23:51:34 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
922 923 924 925 926 927 928 929 930 931 932 933 934 935 | double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); sqlite_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol); /* ** The sqlite3_finalize() function is called to delete a compiled ** SQL statement obtained by a previous call to sqlite3_prepare() ** or sqlite3_prepare16(). If the statement was executed successfully, or ** not executed at all, then SQLITE_OK is returned. If execution of the ** statement failed then an error code is returned. | > | 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 | double sqlite3_column_double(sqlite3_stmt*, int iCol); int sqlite3_column_int(sqlite3_stmt*, int iCol); sqlite_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); int sqlite3_column_numeric_type(sqlite3_stmt*, int iCol); sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** The sqlite3_finalize() function is called to delete a compiled ** SQL statement obtained by a previous call to sqlite3_prepare() ** or sqlite3_prepare16(). If the statement was executed successfully, or ** not executed at all, then SQLITE_OK is returned. If execution of the ** statement failed then an error code is returned. |
︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 | int argc, char **argv, sqlite3_vtab **ppVTab); int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); int (*xDisconnect)(sqlite3_vtab *pVTab); int (*xDestroy)(sqlite3_vtab *pVTab); int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); int (*xClose)(sqlite3_vtab_cursor*); | | | 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 | int argc, char **argv, sqlite3_vtab **ppVTab); int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); int (*xDisconnect)(sqlite3_vtab *pVTab); int (*xDestroy)(sqlite3_vtab *pVTab); int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); int (*xClose)(sqlite3_vtab_cursor*); int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, int argc, sqlite3_value **argv); int (*xNext)(sqlite3_vtab_cursor*); int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid); int (*xInsert)(sqlite3_vtab *pVTab, sqlite3_value **apData); int (*xDelete)(sqlite3_vtab *pVTab, sqlite_int64 rowid); int (*xBegin)(sqlite3_vtab *pVTab); |
︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 | ** The xBestIndex method must fill aConstraintUsage[] with information ** about what parameters to pass to xFilter. If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and is not checked again by SQLite. ** | | > | 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 | ** The xBestIndex method must fill aConstraintUsage[] with information ** about what parameters to pass to xFilter. If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and is not checked again by SQLite. ** ** The idxNum and idxPtr values are recorded and passed into xFilter. ** sqlite3_free() is used to free idxPtr if needToFreeIdxPtr is true. ** ** The orderByConsumed means that output from xFilter will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** ** The estimatedCost value is an estimate of the cost of doing the ** particular lookup. A full scan of a table with N entries should have |
︙ | ︙ | |||
1622 1623 1624 1625 1626 1627 1628 | } *const aOrderBy; /* The ORDER BY clause */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *const aConstraintUsage; | | < | | | 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 | } *const aOrderBy; /* The ORDER BY clause */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *const aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ }; #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 |
︙ | ︙ | |||
1681 1682 1683 1684 1685 1686 1687 | /* ** The xCreate and xConnect methods of a module use the following API ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); | < < < < < < < | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 | /* ** The xCreate and xConnect methods of a module use the following API ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); /* ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** ** When the virtual-table mechanism stablizes, we will declare the |
︙ | ︙ |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.158 2006/06/13 23:51:35 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 | extern int Sqlitetest5_Init(Tcl_Interp*); extern int Sqlitetest6_Init(Tcl_Interp*); extern int Sqlitetest7_Init(Tcl_Interp*); extern int Sqlitetest8_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetest7_Init(interp); Sqlitetest8_Init(interp); Sqlitetestasync_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ | > > | 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 | extern int Sqlitetest5_Init(Tcl_Interp*); extern int Sqlitetest6_Init(Tcl_Interp*); extern int Sqlitetest7_Init(Tcl_Interp*); extern int Sqlitetest8_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetesttclvar_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Sqlitetest7_Init(interp); Sqlitetest8_Init(interp); Sqlitetestasync_Init(interp); Sqlitetesttclvar_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.11 2006/06/13 23:51:35 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
31 32 33 34 35 36 37 38 39 40 41 42 43 44 | ** the same number of entries as there are columns in the underlying ** real table. */ struct echo_vtab { sqlite3_vtab base; Tcl_Interp *interp; sqlite3 *db; char *zStmt; /* "SELECT rowid, * FROM <real-table-name> " */ int *aIndex; int nCol; char **aCol; }; | > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | ** the same number of entries as there are columns in the underlying ** real table. */ struct echo_vtab { sqlite3_vtab base; Tcl_Interp *interp; sqlite3 *db; char *zTableName; /* Name of the real table */ char *zStmt; /* "SELECT rowid, * FROM <real-table-name> " */ int *aIndex; int nCol; char **aCol; }; |
︙ | ︙ | |||
220 221 222 223 224 225 226 227 228 229 230 231 232 233 | pVtab = sqliteMalloc( sizeof(*pVtab) ); *ppVtab = &pVtab->base; pVtab->base.pModule = pModule; pVtab->interp = pModule->pAux; pVtab->db = db; for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, argv[i]); } echoDeclareVtab(pVtab, db, argc, argv); return 0; } | > | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | pVtab = sqliteMalloc( sizeof(*pVtab) ); *ppVtab = &pVtab->base; pVtab->base.pModule = pModule; pVtab->interp = pModule->pAux; pVtab->db = db; pVtab->zTableName = sqlite3MPrintf("%s", argv[1]); for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, argv[i]); } echoDeclareVtab(pVtab, db, argc, argv); return 0; } |
︙ | ︙ | |||
257 258 259 260 261 262 263 264 265 266 267 268 269 270 | echo_vtab *p = (echo_vtab*)pVtab; sqliteFree(p->zStmt); sqliteFree(p->aIndex); for(ii=0; ii<p->nCol; ii++){ sqliteFree(p->aCol[ii]); } sqliteFree(p->aCol); sqliteFree(p); return 0; } static int echoDisconnect(sqlite3_vtab *pVtab){ appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect"); return echoDestructor(pVtab); | > | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | echo_vtab *p = (echo_vtab*)pVtab; sqliteFree(p->zStmt); sqliteFree(p->aIndex); for(ii=0; ii<p->nCol; ii++){ sqliteFree(p->aCol[ii]); } sqliteFree(p->aCol); sqliteFree(p->zTableName); sqliteFree(p); return 0; } static int echoDisconnect(sqlite3_vtab *pVtab){ appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect"); return echoDestructor(pVtab); |
︙ | ︙ | |||
306 307 308 309 310 311 312 | } static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ int iCol = i + 1; sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt; assert( sqlite3_data_count(pStmt)>iCol ); | < < < < < < < < | < < < < < < < < < < < < < | < | | | | > | | > > > | > > > | > | > > > | > > > > | > > | > > > > > > > > | < | < > > | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | } static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ int iCol = i + 1; sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt; assert( sqlite3_data_count(pStmt)>iCol ); sqlite3_result_value(ctx, sqlite3_column_value(pStmt, iCol)); return SQLITE_OK; } static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt; *pRowid = sqlite3_column_int64(pStmt, 0); return SQLITE_OK; } static int echoFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ int rc; int i; echo_cursor *pCur = (echo_cursor *)pVtabCursor; echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab; sqlite3 *db = pVtab->db; sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; rc = sqlite3_prepare(db, idxStr, -1, &pCur->pStmt, 0); for(i=0; i<argc; i++){ switch( sqlite3_value_type(argv[i]) ){ case SQLITE_INTEGER: { sqlite3_bind_int64(pCur->pStmt, i+1, sqlite3_value_int64(argv[i])); break; } case SQLITE_FLOAT: { sqlite3_bind_double(pCur->pStmt, i+1, sqlite3_value_double(argv[i])); break; } case SQLITE_NULL: { sqlite3_bind_null(pCur->pStmt, i+1); break; } case SQLITE_TEXT: { sqlite3_bind_text(pCur->pStmt, i+1, sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); break; } case SQLITE_BLOB: { sqlite3_bind_blob(pCur->pStmt, i+1, sqlite3_value_blob(argv[i]), sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); break; } } } if( rc==SQLITE_OK ){ rc = echoNext(pVtabCursor); } appendToEchoModule(pVtab->interp, "xFilter"); appendToEchoModule(pVtab->interp, idxStr); for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, sqlite3_value_text(argv[i])); } return rc; } /* ** The echo module implements the subset of query constraints and sort ** orders that may take advantage of SQLite indices on the underlying ** real table. For example, if the real table is declared as: ** ** CREATE TABLE real(a, b, c); ** CREATE INDEX real_index ON real(b); ** ** then the echo module handles WHERE or ORDER BY clauses that refer ** to the column "b", but not "a" or "c". If a multi-column index is ** present, only it's left most column is considered. */ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; char *zQuery = 0; char *zNew; int nArg = 0; const char *zSep = "WHERE"; echo_vtab *pVtab = (echo_vtab *)tab; zQuery = sqlite3_mprintf("SELECT rowid, * FROM %Q", pVtab->zTableName); for(ii=0; ii<pIdxInfo->nConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; pConstraint = &pIdxInfo->aConstraint[ii]; pUsage = &pIdxInfo->aConstraintUsage[ii]; |
︙ | ︙ | |||
414 415 416 417 418 419 420 | case SQLITE_INDEX_CONSTRAINT_LE: zOp = "<="; break; case SQLITE_INDEX_CONSTRAINT_GE: zOp = ">="; break; case SQLITE_INDEX_CONSTRAINT_MATCH: zOp = "MATCH"; break; } | < < | | < < < | > < | < < < < < < < < | < < < < | < < | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | case SQLITE_INDEX_CONSTRAINT_LE: zOp = "<="; break; case SQLITE_INDEX_CONSTRAINT_GE: zOp = ">="; break; case SQLITE_INDEX_CONSTRAINT_MATCH: zOp = "MATCH"; break; } zNew = sqlite3_mprintf("%s %s %s %s ?", zQuery, zSep, zCol, zOp); sqlite3_free(zQuery); zQuery = zNew; zSep = "AND"; pUsage->argvIndex = ++nArg; pUsage->omit = 1; } } appendToEchoModule(pVtab->interp, "xBestIndex");; appendToEchoModule(pVtab->interp, zQuery); pIdxInfo->idxStr = zQuery; pIdxInfo->needToFreeIdxStr = 1; pIdxInfo->estimatedCost = 1.0; return SQLITE_OK; } /* ** A virtual table module that merely echos method calls into TCL ** variables. */ |
︙ | ︙ |
Added src/test_tclvar.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 | /* ** 2006 June 13 ** ** 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. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** The emphasis of this file is a virtual table that provides ** access to TCL variables. ** ** $Id: test_tclvar.c,v 1.1 2006/06/13 23:51:35 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> typedef struct tclvar_vtab tclvar_vtab; typedef struct tclvar_cursor tclvar_cursor; /* ** A tclvar virtual-table object */ struct tclvar_vtab { sqlite3_vtab base; Tcl_Interp *interp; }; /* A tclvar cursor object */ struct tclvar_cursor { sqlite3_vtab_cursor base; Tcl_Obj *pList1, *pList2; int i, j; }; /* Methods for the tclvar module */ static int tclvarConnect( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ tclvar_vtab *pVtab; static const char zSchema[] = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = sqliteMalloc( sizeof(*pVtab) ); if( pVtab==0 ) return SQLITE_NOMEM; *ppVtab = &pVtab->base; pVtab->base.pModule = pModule; pVtab->interp = pModule->pAux; #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_declare_vtab(db, zSchema); #endif return SQLITE_OK; } /* Note that for this virtual table, the xCreate and xConnect ** methods are identical. */ static int tclvarDisconnect(sqlite3_vtab *pVtab){ free(pVtab); } /* The xDisconnect and xDestroy methods are also the same */ static int tclvarOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ tclvar_cursor *pCur; pCur = sqliteMalloc(sizeof(tclvar_cursor)); *ppCursor = &pCur->base; return SQLITE_OK; } static int tclvarClose(sqlite3_vtab_cursor *cur){ tclvar_cursor *pCur = (tclvar_cursor *)cur; if( pCur->pList1 ){ Tcl_DecrRefCount(pCur->pList1); } if( pCur->pList2 ){ Tcl_DecrRefCount(pCur->pList2); } sqliteFree(pCur); return SQLITE_OK; } static int tclvarNext(sqlite3_vtab_cursor *cur){ tclvar_cursor *pCur = (tclvar_cursor *)cur; return 0; } static int tclvarColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ tclvar_cursor *pCur = (tclvar_cursor*)cur; return SQLITE_OK; } static int tclvarRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ tclvar_cursor *pCur = (tclvar_cursor*)cur; return SQLITE_OK; } static int tclvarFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ tclvar_cursor *pCur = (tclvar_cursor *)pVtabCursor; tclvar_vtab *pVtab = (tclvar_vtab *)pCur->base.pVtab; return 0; } /* */ static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ tclvar_vtab *pVtab = (tclvar_vtab *)tab; return SQLITE_OK; } /* ** A virtual table module that merely echos method calls into TCL ** variables. */ static sqlite3_module tclvarModule = { 0, /* iVersion */ "tclvar", /* zName */ 0, /* pAux */ tclvarConnect, tclvarConnect, tclvarBestIndex, tclvarDisconnect, tclvarDisconnect, tclvarOpen, /* xOpen - open a cursor */ tclvarClose, /* xClose - close a cursor */ tclvarFilter, /* xFilter - configure scan constraints */ tclvarNext, /* xNext - advance a cursor */ tclvarColumn, /* xColumn - read data */ tclvarRowid /* xRowid - read data */ }; /* ** Decode a pointer to an sqlite3 object. */ static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ *ppDb = (sqlite3*)sqlite3TextToPtr(zA); return TCL_OK; } /* ** Register the echo virtual table module. */ static int register_tclvar_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; tclvarModule.pAux = interp; #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_create_module(db, "tclvar", &tclvarModule); #endif return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetesttclvar_Init(Tcl_Interp *interp){ static struct { char *zName; Tcl_ObjCmdProc *xProc; void *clientData; } aObjCmd[] = { { "register_tclvar_module", register_tclvar_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; } |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.558 2006/06/13 23:51:35 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4589 4590 4591 4592 4593 4594 4595 | #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** | | > > | | | | | | | | | > | | 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 | #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** P3 is either NULL or a string that was generated by the xBestIndex ** method of the module. The interpretation of the P3 string is left ** to the module implementation. ** ** This opcode invokes the xFilter method on the virtual table specified ** by P1. The integer query plan parameter to xFilter is the top of the ** stack. Next down on the stack is the argc parameter. Beneath the ** next of stack are argc additional parameters which are passed to ** xFilter as argv. The topmost parameter (i.e. 3rd element popped from ** the stack) becomes argv[argc-1] when passed to xFilter. ** ** The integer query plan parameter, argc, and all argv stack values ** are popped from the stack before this instruction completes. ** ** A jump is made to P2 if the result set after filtering would be ** empty. */ case OP_VFilter: { int nArg; const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; /* Grab the index number and argc parameters off the top of the stack. */ assert( (&pTos[-1])>=p->aStack ); assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int ); nArg = pTos[-1].i; /* Invoke the xFilter method if one is defined. */ if( pModule->xFilter ){ int res; int i; Mem **apArg = p->apArg; for(i = 0; i<nArg; i++){ apArg[i] = &pTos[i+1-2-nArg]; storeTypeInfo(apArg[i], 0); } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; res = pModule->xFilter(pCur->pVtabCursor, pTos->i, pOp->p3, nArg, apArg); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( res==0 ){ pc = pOp->p2 - 1; } } |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.105 2006/06/13 23:51:35 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ #define P3_MPRINTF (-11) /* P3 is a string obtained from sqlite3_mprintf() */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
450 451 452 453 454 455 456 | return val; } const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } | < < | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | return val; } const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ return columnMem(pStmt, i); } #ifndef SQLITE_OMIT_UTF16 const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } #endif /* SQLITE_OMIT_UTF16 */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
259 260 261 262 263 264 265 | } }else if( opcode==OP_IdxInsert ){ if( pOp->p2 ){ doesStatementRollback = 1; } }else if( opcode==OP_Statement ){ hasStatementBegin = 1; | | > > > > > | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | } }else if( opcode==OP_IdxInsert ){ if( pOp->p2 ){ doesStatementRollback = 1; } }else if( opcode==OP_Statement ){ hasStatementBegin = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); assert( pOp[-2].opcode==OP_Integer ); n = pOp[-2].p1; if( n>nMaxArgs ) nMaxArgs = n; } if( opcodeNoPush(opcode) ){ nMaxStack--; } if( pOp->p2>=0 ) continue; assert( -1-pOp->p2<p->nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; |
︙ | ︙ | |||
375 376 377 378 379 380 381 382 383 384 385 386 387 388 | if( p3 ){ switch( p3type ){ case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { sqliteFree(p3); break; } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); break; } | > > > > | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | if( p3 ){ switch( p3type ){ case P3_DYNAMIC: case P3_KEYINFO: case P3_KEYINFO_HANDOFF: { sqliteFree(p3); break; } case P3_MPRINTF: { sqlite3_free(p3); break; } case P3_VDBEFUNC: { VdbeFunc *pVdbeFunc = (VdbeFunc *)p3; sqlite3VdbeDeleteAuxData(pVdbeFunc, 0); sqliteFree(pVdbeFunc); break; } |
︙ | ︙ |
Changes to src/vtab.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2006 June 10 ** ** 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 contains code used to help implement virtual tables. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2006 June 10 ** ** 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 contains code used to help implement virtual tables. ** ** $Id: vtab.c,v 1.8 2006/06/13 23:51:35 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" /* ** External API function used to create a new virtual-table module. */ |
︙ | ︙ | |||
273 274 275 276 277 278 279 | rc = sqlite3SafetyOn(db); } } return rc; } | < < < < < < < < < < | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | rc = sqlite3SafetyOn(db); } } return rc; } /* ** This function is used to set the schema of a virtual table. It is only ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. */ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.216 2006/06/13 23:51:35 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 | pUsage = pIdxInfo->aConstraintUsage; for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; pIdxCons->usable = (pTerm->prereqRight & notReady)==0; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); | > > > | > | | 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 | pUsage = pIdxInfo->aConstraintUsage; for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; pIdxCons->usable = (pTerm->prereqRight & notReady)==0; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ){ sqlite3_free(pIdxInfo->idxStr); } pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->needToFreeIdxStr = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL; nOrderBy = pIdxInfo->nOrderBy; if( pIdxInfo->nOrderBy && !orderByUsable ){ *(int*)&pIdxInfo->nOrderBy = 0; } pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); |
︙ | ︙ | |||
1568 1569 1570 1571 1572 1573 1574 | /* ** Free a WhereInfo structure */ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ | | > | > | | > | 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 | /* ** Free a WhereInfo structure */ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo; if( pInfo ){ if( pInfo->needToFreeIdxStr ){ sqlite3_free(pInfo->idxStr); } sqliteFree(pInfo); } } sqliteFree(pWInfo); } } /* |
︙ | ︙ | |||
1857 1858 1859 1860 1861 1862 1863 | if( (pIx = pLevel->pIdx)!=0 ){ zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ | > | | | 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 | if( (pIx = pLevel->pIdx)!=0 ){ zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo; zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d:%s", pIdxInfo->idxNum, pIdxInfo->idxStr); } #endif if( pLevel->flags & WHERE_ORDERBY ){ zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } |
︙ | ︙ | |||
1948 1949 1950 1951 1952 1953 1954 | } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ /* Case 0: The table is a virtual-table. Use the VFilter and VNext ** to access the data. */ | < < | > > > > > > | | > | | | | > | < < < | 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 | } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ /* Case 0: The table is a virtual-table. Use the VFilter and VNext ** to access the data. */ sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo; int nConstraint = pIdxInfo->nConstraint; struct sqlite3_index_constraint_usage *aUsage = pIdxInfo->aConstraintUsage; const struct sqlite3_index_constraint *aConstraint = pIdxInfo->aConstraint; for(i=1; i<=nConstraint; i++){ int j; for(j=0; j<nConstraint; j++){ if( aUsage[j].argvIndex==i ){ int k = aConstraint[j].iTermOffset; sqlite3ExprCode(pParse, wc.a[k].pExpr->pRight); break; } } if( j==nConstraint ) break; } sqlite3VdbeAddOp(v, OP_Integer, i-1, 0); sqlite3VdbeAddOp(v, OP_Integer, pIdxInfo->idxNum, 0); sqlite3VdbeOp3(v, OP_VFilter, iCur, brk, pIdxInfo->idxStr, pIdxInfo->needToFreeIdxStr ? P3_MPRINTF : P3_STATIC); pIdxInfo->needToFreeIdxStr = 0; for(i=0; i<pIdxInfo->nConstraint; i++){ if( pIdxInfo->aConstraintUsage[i].omit ){ disableTerm(pLevel, &wc.a[i]); } } pLevel->op = OP_VNext; pLevel->p1 = iCur; |
︙ | ︙ |
Changes to test/vtab1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2006 June 10 # # 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 regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2006 June 10 # # 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 regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # # $Id: vtab1.test,v 1.11 2006/06/13 23:51:35 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab { finish_test return |
︙ | ︙ | |||
140 141 142 143 144 145 146 | #---------------------------------------------------------------------- # Test case vtab1-3 tests simple linear scans (no filter conditions) of # virtual table modules. do_test vtab1-3.1 { set echo_module "" execsql { | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | #---------------------------------------------------------------------- # Test case vtab1-3 tests simple linear scans (no filter conditions) of # virtual table modules. do_test vtab1-3.1 { set echo_module "" execsql { CREATE TABLE treal(a INTEGER, b INTEGER, c); CREATE INDEX treal_idx ON treal(b); CREATE VIRTUAL TABLE t1 USING echo(treal); } set echo_module } [list xCreate echo treal] do_test vtab1-3.2 { # Test that a SELECT on t2 doesn't crash. No rows are returned |
︙ | ︙ | |||
177 178 179 180 181 182 183 184 | } {1 2} do_test vtab1-3.6 { set echo_module "" execsql { SELECT * FROM t1; } set echo_module | > > | | | > > | | > > | | | > > | < | 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 | } {1 2} do_test vtab1-3.6 { set echo_module "" execsql { SELECT * FROM t1; } } {1 2 3 4 5 6} do_test vtab1-3.7 { set echo_module } {xBestIndex {SELECT rowid, * FROM 'treal'} xFilter {SELECT rowid, * FROM 'treal'}} do_test vtab1-3.8 { set echo_module "" execsql { SELECT * FROM t1 WHERE b = 5; } } {4 5 6} do_test vtab1-3.9 { set echo_module } {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b = ?} 5} do_test vtab1-3.10 { set echo_module "" execsql { SELECT * FROM t1 WHERE b >= 5 AND b <= 10; } } {4 5 6} do_test vtab1-3.11 { set echo_module } {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10} do_test vtab1-3.12 { set echo_module "" execsql { SELECT * FROM t1 WHERE b BETWEEN 2 AND 10; } } {1 2 3 4 5 6} do_test vtab1-3.13 { set echo_module } {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10} finish_test |