Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the tentative sqlite3_allocate_queryplan() API. (CVS 3228) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7a3e97f76b1f4f97a04f7c5a9daa4004 |
User & Date: | danielk1977 2006-06-13 15:00:55.000 |
Context
2006-06-13
| ||
15:12 | Improved comments and documentation of sqlite3_load_extension(). (CVS 3229) (check-in: 0bcec95963 user: drh tags: trunk) | |
15:00 | Add the tentative sqlite3_allocate_queryplan() API. (CVS 3228) (check-in: 7a3e97f76b user: danielk1977 tags: trunk) | |
14:16 | Add simple tests for the xFilter and xBestIndex methods. (CVS 3227) (check-in: 0f4657ea69 user: danielk1977 tags: trunk) | |
Changes
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.173 2006/06/13 15:00:55 danielk1977 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++. |
︙ | ︙ | |||
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*); | | | 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 | 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*, char *zPlan, int nPlan, 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); |
︙ | ︙ | |||
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; | | > > > | 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 | } *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; char *zPlan; /* xBestIndex blob passed to xFilter */ int nPlan; /* Size of nPlan */ 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 |
︙ | ︙ | |||
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 | /* ** 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 | > > > > > > > | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 | /* ** 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); /* ** This function is called by the xBestIndex method of a module to ** allocate space to store the query-plan passed to the corresponding ** xFilter invocation(s). */ char *sqlite3_allocate_queryplan(sqlite3_index_info *, int); /* ** 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/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.10 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
340 341 342 343 344 345 346 | *pRowid = sqlite3_column_int64(pStmt, 0); return SQLITE_OK; } static int echoFilter( sqlite3_vtab_cursor *pVtabCursor, | | < < | | 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 | *pRowid = sqlite3_column_int64(pStmt, 0); return SQLITE_OK; } static int echoFilter( sqlite3_vtab_cursor *pVtabCursor, char *zPlan, int nPlan, int argc, sqlite3_value **argv ){ int rc; int ii; echo_cursor *pCur = (echo_cursor *)pVtabCursor; echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab; sqlite3 *db = pVtab->db; appendToEchoModule(pVtab->interp, "xFilter"); appendToEchoModule(pVtab->interp, zPlan); for(ii=0; ii<argc; ii++){ appendToEchoModule(pVtab->interp, sqlite3_value_text(argv[ii])); } sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; rc = sqlite3_prepare(db, pVtab->zStmt, -1, &pCur->pStmt, 0); |
︙ | ︙ | |||
386 387 388 389 390 391 392 393 394 395 396 397 398 399 | ** 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 *zWhere = 0; char *zOrder = 0; int nArg = 0; echo_vtab *pVtab = (echo_vtab *)tab; for(ii=0; ii<pIdxInfo->nConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; | > > | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | ** 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 *zWhere = 0; char *zOrder = 0; char *zPlan = 0; int nPlan = 0; int nArg = 0; echo_vtab *pVtab = (echo_vtab *)tab; for(ii=0; ii<pIdxInfo->nConstraint; ii++){ const struct sqlite3_index_constraint *pConstraint; struct sqlite3_index_constraint_usage *pUsage; |
︙ | ︙ | |||
430 431 432 433 434 435 436 437 438 439 440 | pUsage->omit = 1; } } appendToEchoModule(pVtab->interp, "xBestIndex");; appendToEchoModule(pVtab->interp, zWhere); appendToEchoModule(pVtab->interp, zOrder); sqliteFree(zWhere); sqliteFree(zOrder); | > > > > > > > > > > > > > < | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 | pUsage->omit = 1; } } appendToEchoModule(pVtab->interp, "xBestIndex");; appendToEchoModule(pVtab->interp, zWhere); appendToEchoModule(pVtab->interp, zOrder); nPlan = 2; if( zWhere ){ nPlan += strlen(zWhere); } if( zOrder ){ nPlan += strlen(zWhere); } zPlan = sqlite3_allocate_queryplan(pIdxInfo, nPlan); if( zPlan ){ sprintf(zPlan, "%s%s%s", zWhere?zWhere:"", (zOrder&&zWhere)?" ":"", zOrder?zOrder:""); } sqliteFree(zWhere); sqliteFree(zOrder); return SQLITE_OK; } /* ** A virtual table module that merely echos method calls into TCL ** variables. */ |
︙ | ︙ |
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.557 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4592 4593 4594 4595 4596 4597 4598 | ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** P3 points to enough free space to use to marshall the arguments. ** ** This opcode invokes the xFilter method on the virtual table specified | | | < | < | | | 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 | ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** P3 points to enough free space to use to marshall the arguments. ** ** This opcode invokes the xFilter method on the virtual table specified ** by P1. The 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 query plan, 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_Blob && pTos[-1].flags==MEM_Int ); nArg = pTos[-1].i; /* Invoke the xFilter method if one is defined. */ if( pModule->xFilter ){ int res; int ii; Mem **apArg = (Mem **)pOp->p3; for(ii = 0; ii<nArg; ii++){ apArg[ii] = &pTos[ii+1-2-nArg]; } if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; res = pModule->xFilter(pCur->pVtabCursor, pTos->z, pTos->n, nArg, apArg); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( res==0 ){ pc = pOp->p2 - 1; } } |
︙ | ︙ |
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.7 2006/06/13 15:00:55 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" /* ** External API function used to create a new virtual-table module. */ |
︙ | ︙ | |||
272 273 274 275 276 277 278 279 280 281 282 283 284 285 | } else { 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){ | > > > > > > > > > > > | 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 | } else { rc = sqlite3SafetyOn(db); } } return rc; } /* ** Resize pInfo->zPlan to nBytes bytes using realloc(). Set pInfo->nPlan ** to nBytes and return a pointer to the allocated memory. */ char *sqlite3_allocate_queryplan(sqlite3_index_info *pInfo, int nBytes){ pInfo->nPlan = nBytes; sqlite3ReallocOrFree(&pInfo->zPlan, nBytes); return pInfo->zPlan; } /* ** 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.214 2006/06/13 15:00:55 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1001 1002 1003 1004 1005 1006 1007 | 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); | | > | 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | 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); pIdxInfo->zPlan = 0; pIdxInfo->nPlan = 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); |
︙ | ︙ | |||
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 | /* ** Free a WhereInfo structure */ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ sqliteFree(pWInfo->a[i].pIdxInfo); } sqliteFree(pWInfo); } } | > > > | 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 | /* ** Free a WhereInfo structure */ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ if( pWInfo->a[i].pIdxInfo ){ sqliteFree(pWInfo->a[i].pIdxInfo->zPlan); } sqliteFree(pWInfo->a[i].pIdxInfo); } sqliteFree(pWInfo); } } |
︙ | ︙ | |||
1750 1751 1752 1753 1754 1755 1756 | 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 ){ | | | | 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 | 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 ){ zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %s", pLevel->pIdxInfo->zPlan); } #endif if( pLevel->flags & WHERE_ORDERBY ){ zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } |
︙ | ︙ | |||
1854 1855 1856 1857 1858 1859 1860 | sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight); break; } } if( j==pIdxInfo->nConstraint ) break; } sqlite3VdbeAddOp(v, OP_Integer, i-1, 0); | | > > | 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 | sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight); break; } } if( j==pIdxInfo->nConstraint ) break; } sqlite3VdbeAddOp(v, OP_Integer, i-1, 0); sqlite3VdbeAddOp(v, OP_Blob, pIdxInfo->nPlan, 0); sqlite3VdbeChangeP3(v, -1, pIdxInfo->zPlan, P3_DYNAMIC); pIdxInfo->zPlan = 0; sqlite3VdbeAddOp(v, OP_VFilter, iCur, brk); zSpace = (char *)sqliteMalloc(sizeof(sqlite3_value*)*(i-1)); sqlite3VdbeChangeP3(v, -1, zSpace, P3_DYNAMIC); for(i=0; i<pIdxInfo->nConstraint; i++){ if( pIdxInfo->aConstraintUsage[i].omit ){ disableTerm(pLevel, &wc.a[i]); } |
︙ | ︙ |
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.10 2006/06/13 15:00:55 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab { finish_test return |
︙ | ︙ | |||
178 179 180 181 182 183 184 | do_test vtab1-3.6 { set echo_module "" execsql { SELECT * FROM t1; } set echo_module | | | | | | 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 | do_test vtab1-3.6 { set echo_module "" execsql { SELECT * FROM t1; } set echo_module } {xBestIndex {} {} xFilter {}} do_test vtab1-3.7 { set echo_module "" execsql { SELECT * FROM t1 WHERE b = 10; } set echo_module } {xBestIndex {WHERE b = ?} {} xFilter {WHERE b = ?} 10} do_test vtab1-3.8 { set echo_module "" execsql { SELECT * FROM t1 WHERE b >= 5 AND b <= 10; } set echo_module } {xBestIndex {WHERE b >= ? AND b <= ?} {} xFilter {WHERE b >= ? AND b <= ?} 5 10} do_test vtab1-3.9 { set echo_module "" execsql { SELECT * FROM t1 WHERE b BETWEEN 5 AND 10; } set echo_module } {xBestIndex {WHERE b >= ? AND b <= ?} {} xFilter {WHERE b >= ? AND b <= ?} 5 10} finish_test |