mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
The echo module test is now running. Added the tclvar module test but have
not yet done anything with it. (CVS 3234) FossilOrigin-Name: 29199eeea4c46168ccaa7535d4941bd740479dee
This commit is contained in:
@ -211,6 +211,7 @@ TESTSRC = \
|
||||
$(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 \
|
||||
|
1
main.mk
1
main.mk
@ -144,6 +144,7 @@ TESTSRC = \
|
||||
$(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 \
|
||||
|
35
manifest
35
manifest
@ -1,6 +1,6 @@
|
||||
C The\s(unsupported)\ssoundex()\sfunction\sreturns\s'?000'\swhen\sgiven\sa\sNULL.\nTicket\s#1845.\s(CVS\s3233)
|
||||
D 2006-06-13T19:26:11
|
||||
F Makefile.in 56fd6261e83f60724e6dcd764e06ab68cbd53909
|
||||
C The\secho\smodule\stest\sis\snow\srunning.\s\sAdded\sthe\stclvar\smodule\stest\sbut\shave\nnot\syet\sdone\sanything\swith\sit.\s(CVS\s3234)
|
||||
D 2006-06-13T23:51:34
|
||||
F Makefile.in 200f6dc376ecfd9b01e5359c4e0c10c02f649b34
|
||||
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
F VERSION 301ed2b2c08f5cca242ea56e50a9ed0264a3eb76
|
||||
@ -19,7 +19,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
|
||||
F main.mk a7796b31f0d7e16ea57ff00ac88b97befe519977
|
||||
F main.mk 2f02a26044baa6126127e7231b1cea172355d721
|
||||
F mkdll.sh 919df5efde876194e3102c6ebc60657d38949909
|
||||
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
|
||||
F mkopcodeh.awk cde995d269aa06c94adbf6455bea0acedb913fa5
|
||||
@ -72,11 +72,11 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||
F src/select.c 38eda11d950ed5e631ea9054f84a4a8b9e9b39d8
|
||||
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36
|
||||
F src/sqlite.h.in 92cbeeacf040bffe109057d3af2db9dc63db8a67
|
||||
F src/sqlite.h.in 84522f48a0a044987267a82d680121194d31fb7a
|
||||
F src/sqlite3ext.h 127bd394c8eea481f2ac9b754bf399dbfc818b75
|
||||
F src/sqliteInt.h e8710fd5c10c03ca4a2fb49802b8aae6689f27a0
|
||||
F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
|
||||
F src/tclsqlite.c 0b2a04cfc1b4298adfbe90a754cfbbe207aca11a
|
||||
F src/tclsqlite.c 4ad22f354b6e4e137889000e9f585a0590ca39c5
|
||||
F src/test1.c 88291fa6674dcd409b1c9d76d3119151d4b81a50
|
||||
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
||||
F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d
|
||||
@ -84,25 +84,26 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
||||
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
||||
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
||||
F src/test8.c 34b04bd826b3f7fa843c5b60052928412591c5c7
|
||||
F src/test8.c d21b301afbc35a5c4ded0ecc784d59bc8f795c75
|
||||
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
||||
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
||||
F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
|
||||
F src/test_tclvar.c 3157e17194caa73434041d310b66ec93803aa1be
|
||||
F src/tokenize.c 6ebcafa6622839968dda4418a7b6945f277a128f
|
||||
F src/trigger.c 48bbb94c11954c8e132efcc04478efe8304c4196
|
||||
F src/update.c 0186f09414a6578156d40666becc964f85c2a616
|
||||
F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44
|
||||
F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d
|
||||
F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9
|
||||
F src/vdbe.c 1d5ae83b7122146c0193f52750e37aacd633bccc
|
||||
F src/vdbe.h f72e5c00af759b7ed6fd606d508036d732098cc3
|
||||
F src/vdbe.c 51f94a1f1647a85f4e5eb6418624f8d1ef67622a
|
||||
F src/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
|
||||
F src/vdbeInt.h 6ccb7eaae76ebd761470f6a035501ff33aa92c20
|
||||
F src/vdbeapi.c 7dc662e7c905ce666bb506dced932e0307115cbf
|
||||
F src/vdbeaux.c 0168d770d03f9815511780a49cd8360d9a5f1ec5
|
||||
F src/vdbeapi.c af663689ef57e5506f190bbd1068d28936b0fb34
|
||||
F src/vdbeaux.c c9474fd27f1735170feb4f6a46885d282cf22d52
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||
F src/vtab.c 12d83f7de893d06592d6d37c285defefebbd2d48
|
||||
F src/where.c 7e614b0278c688aec94c79d42f602b24e9e4119f
|
||||
F src/vtab.c 7de1347022248edfb260c54f259148f413320cb7
|
||||
F src/where.c 299c385e32a7b98d42864c7c83cdc6a778fae562
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/all.test 5df90d015ca63fcef2a4b62c24f7316b66c4bfd4
|
||||
@ -287,7 +288,7 @@ F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f
|
||||
F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
|
||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||
F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
|
||||
F test/vtab1.test c94c8bdadfdd9c474146874562925830ab0413c5
|
||||
F test/vtab1.test 86e4c90c96cbf7f2c3b31069ed8c2d5dfd3bf378
|
||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
||||
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
||||
@ -363,7 +364,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 136bed496b89943522310ec511199b78198d0844
|
||||
R 4d340ce3b4963ceb6566edfe12edcd3d
|
||||
P 9372481f233e1563b5ee137535f0fbf19851ffad
|
||||
R e6ce8e5a9dba6e782016ada2d5443cc3
|
||||
U drh
|
||||
Z 16c6d69d2baed957168638e44a48c1df
|
||||
Z 6f9bc9c4a49544af7a028d3a571bcd52
|
||||
|
@ -1 +1 @@
|
||||
9372481f233e1563b5ee137535f0fbf19851ffad
|
||||
29199eeea4c46168ccaa7535d4941bd740479dee
|
@ -12,7 +12,7 @@
|
||||
** 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 $
|
||||
** @(#) $Id: sqlite.h.in,v 1.174 2006/06/13 23:51:34 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@ -926,6 +926,7 @@ 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
|
||||
@ -1547,7 +1548,7 @@ struct sqlite3_module {
|
||||
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 (*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);
|
||||
@ -1595,7 +1596,8 @@ struct sqlite3_module {
|
||||
** is true, then the constraint is assumed to be fully handled by the
|
||||
** virtual table and is not checked again by SQLite.
|
||||
**
|
||||
** The idxNum value is recorded and passed into xFilter.
|
||||
** 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
|
||||
@ -1626,10 +1628,9 @@ struct sqlite3_index_info {
|
||||
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 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 */
|
||||
};
|
||||
@ -1685,13 +1686,6 @@ struct sqlite3_vtab_cursor {
|
||||
*/
|
||||
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
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** A TCL Interface to SQLite
|
||||
**
|
||||
** $Id: tclsqlite.c,v 1.157 2006/06/11 23:41:56 drh Exp $
|
||||
** $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 */
|
||||
|
||||
@ -2155,6 +2155,7 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
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);
|
||||
@ -2165,6 +2166,7 @@ int TCLSH_MAIN(int argc, char **argv){
|
||||
Sqlitetest7_Init(interp);
|
||||
Sqlitetest8_Init(interp);
|
||||
Sqlitetestasync_Init(interp);
|
||||
Sqlitetesttclvar_Init(interp);
|
||||
Md5_Init(interp);
|
||||
#ifdef SQLITE_SSE
|
||||
Sqlitetestsse_Init(interp);
|
||||
|
119
src/test8.c
119
src/test8.c
@ -13,7 +13,7 @@
|
||||
** 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 $
|
||||
** $Id: test8.c,v 1.11 2006/06/13 23:51:35 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -35,6 +35,7 @@ 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;
|
||||
@ -224,6 +225,7 @@ static int echoConstructor(
|
||||
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]);
|
||||
}
|
||||
@ -261,6 +263,7 @@ static int echoDestructor(sqlite3_vtab *pVtab){
|
||||
sqliteFree(p->aCol[ii]);
|
||||
}
|
||||
sqliteFree(p->aCol);
|
||||
sqliteFree(p->zTableName);
|
||||
sqliteFree(p);
|
||||
return 0;
|
||||
}
|
||||
@ -310,28 +313,7 @@ static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
|
||||
sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt;
|
||||
|
||||
assert( sqlite3_data_count(pStmt)>iCol );
|
||||
switch( sqlite3_column_type(pStmt, iCol) ){
|
||||
case SQLITE_INTEGER:
|
||||
sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol));
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol));
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
sqlite3_result_text(ctx,
|
||||
sqlite3_column_text(pStmt, iCol),
|
||||
sqlite3_column_bytes(pStmt, iCol),
|
||||
SQLITE_TRANSIENT
|
||||
);
|
||||
break;
|
||||
case SQLITE_BLOB:
|
||||
sqlite3_result_blob(ctx,
|
||||
sqlite3_column_blob(pStmt, iCol),
|
||||
sqlite3_column_bytes(pStmt, iCol),
|
||||
SQLITE_TRANSIENT
|
||||
);
|
||||
break;
|
||||
}
|
||||
sqlite3_result_value(ctx, sqlite3_column_value(pStmt, iCol));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@ -344,31 +326,55 @@ static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
|
||||
|
||||
static int echoFilter(
|
||||
sqlite3_vtab_cursor *pVtabCursor,
|
||||
char *zPlan, int nPlan,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
int idxNum, const char *idxStr,
|
||||
int argc, sqlite3_value **argv
|
||||
){
|
||||
int rc;
|
||||
int ii;
|
||||
int i;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -386,13 +392,13 @@ static int echoFilter(
|
||||
*/
|
||||
static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
int ii;
|
||||
char *zWhere = 0;
|
||||
char *zOrder = 0;
|
||||
char *zPlan = 0;
|
||||
int nPlan = 0;
|
||||
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;
|
||||
@ -418,39 +424,20 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
case SQLITE_INDEX_CONSTRAINT_MATCH:
|
||||
zOp = "MATCH"; break;
|
||||
}
|
||||
if( zWhere ){
|
||||
char *zTmp = zWhere;
|
||||
zWhere = sqlite3MPrintf("%s AND %s %s ?", zWhere, zCol, zOp);
|
||||
sqliteFree(zTmp);
|
||||
} else {
|
||||
zWhere = sqlite3MPrintf("WHERE %s %s ?", zCol, zOp);
|
||||
}
|
||||
|
||||
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, 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);
|
||||
appendToEchoModule(pVtab->interp, zQuery);
|
||||
|
||||
pIdxInfo->idxStr = zQuery;
|
||||
pIdxInfo->needToFreeIdxStr = 1;
|
||||
pIdxInfo->estimatedCost = 1.0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
193
src/test_tclvar.c
Normal file
193
src/test_tclvar.c
Normal file
@ -0,0 +1,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;
|
||||
}
|
27
src/vdbe.c
27
src/vdbe.c
@ -43,7 +43,7 @@
|
||||
** 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 $
|
||||
** $Id: vdbe.c,v 1.558 2006/06/13 23:51:35 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -4593,17 +4593,19 @@ case OP_VOpen: {
|
||||
** 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.
|
||||
** 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 query plan parameter to xFilter is the top of the stack.
|
||||
** Next down on the stack is the argc parameter. Beneath the
|
||||
** 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 query plan, argc, and all argv stack values are popped from the
|
||||
** stack before this instruction completes.
|
||||
** 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.
|
||||
@ -4619,20 +4621,21 @@ case OP_VFilter: {
|
||||
|
||||
/* 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 );
|
||||
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 ii;
|
||||
Mem **apArg = (Mem **)pOp->p3;
|
||||
for(ii = 0; ii<nArg; ii++){
|
||||
apArg[ii] = &pTos[ii+1-2-nArg];
|
||||
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->z, pTos->n, nArg, apArg);
|
||||
res = pModule->xFilter(pCur->pVtabCursor, pTos->i, pOp->p3, nArg, apArg);
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
|
||||
if( res==0 ){
|
||||
|
@ -15,7 +15,7 @@
|
||||
** 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.104 2006/06/13 01:04:53 drh Exp $
|
||||
** $Id: vdbe.h,v 1.105 2006/06/13 23:51:35 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE_VDBE_H_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@ -71,6 +71,7 @@ typedef struct VdbeOpList VdbeOpList;
|
||||
#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
|
||||
|
@ -454,11 +454,9 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
|
||||
columnMallocFailure(pStmt);
|
||||
return val;
|
||||
}
|
||||
#if 0
|
||||
sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
|
||||
return columnMem(pStmt, i);
|
||||
}
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
|
||||
const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
|
||||
|
@ -263,8 +263,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
|
||||
}
|
||||
}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--;
|
||||
}
|
||||
@ -380,6 +385,10 @@ static void freeP3(int p3type, void *p3){
|
||||
sqliteFree(p3);
|
||||
break;
|
||||
}
|
||||
case P3_MPRINTF: {
|
||||
sqlite3_free(p3);
|
||||
break;
|
||||
}
|
||||
case P3_VDBEFUNC: {
|
||||
VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
|
||||
sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
|
||||
|
12
src/vtab.c
12
src/vtab.c
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.7 2006/06/13 15:00:55 danielk1977 Exp $
|
||||
** $Id: vtab.c,v 1.8 2006/06/13 23:51:35 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@ -277,16 +277,6 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
||||
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
|
||||
|
53
src/where.c
53
src/where.c
@ -16,7 +16,7 @@
|
||||
** 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.215 2006/06/13 17:39:01 drh Exp $
|
||||
** $Id: where.c,v 1.216 2006/06/13 23:51:35 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@ -1108,8 +1108,12 @@ static double bestVirtualIndex(
|
||||
pIdxCons->usable = (pTerm->prereqRight & notReady)==0;
|
||||
}
|
||||
memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
|
||||
pIdxInfo->zPlan = 0;
|
||||
pIdxInfo->nPlan = 0;
|
||||
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;
|
||||
@ -1572,10 +1576,13 @@ 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);
|
||||
sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
|
||||
if( pInfo ){
|
||||
if( pInfo->needToFreeIdxStr ){
|
||||
sqlite3_free(pInfo->idxStr);
|
||||
}
|
||||
sqliteFree(pInfo);
|
||||
}
|
||||
sqliteFree(pWInfo->a[i].pIdxInfo);
|
||||
}
|
||||
sqliteFree(pWInfo);
|
||||
}
|
||||
@ -1861,8 +1868,9 @@ WhereInfo *sqlite3WhereBegin(
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( pLevel->pIdxInfo ){
|
||||
zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %s",
|
||||
pLevel->pIdxInfo->zPlan);
|
||||
sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo;
|
||||
zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d:%s",
|
||||
pIdxInfo->idxNum, pIdxInfo->idxStr);
|
||||
}
|
||||
#endif
|
||||
if( pLevel->flags & WHERE_ORDERBY ){
|
||||
@ -1952,26 +1960,29 @@ WhereInfo *sqlite3WhereBegin(
|
||||
/* Case 0: The table is a virtual-table. Use the VFilter and VNext
|
||||
** to access the data.
|
||||
*/
|
||||
char *zSpace; /* Space for OP_VFilter to marshall it's arguments */
|
||||
|
||||
sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo;
|
||||
for(i=1; i<=pIdxInfo->nConstraint; i++){
|
||||
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<pIdxInfo->nConstraint; j++){
|
||||
if( pIdxInfo->aConstraintUsage[j].argvIndex==i ){
|
||||
sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight);
|
||||
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==pIdxInfo->nConstraint ) break;
|
||||
if( j==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);
|
||||
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]);
|
||||
|
@ -11,7 +11,7 @@
|
||||
# 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 $
|
||||
# $Id: vtab1.test,v 1.11 2006/06/13 23:51:35 drh Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -144,7 +144,7 @@ do_test vtab1-2.9 {
|
||||
do_test vtab1-3.1 {
|
||||
set echo_module ""
|
||||
execsql {
|
||||
CREATE TABLE treal(a INTEGER, b VARCHAR(32), c);
|
||||
CREATE TABLE treal(a INTEGER, b INTEGER, c);
|
||||
CREATE INDEX treal_idx ON treal(b);
|
||||
CREATE VIRTUAL TABLE t1 USING echo(treal);
|
||||
}
|
||||
@ -181,29 +181,36 @@ do_test vtab1-3.6 {
|
||||
execsql {
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
set echo_module
|
||||
} {xBestIndex {} {} xFilter {}}
|
||||
} {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 = 10;
|
||||
SELECT * FROM t1 WHERE b = 5;
|
||||
}
|
||||
} {4 5 6}
|
||||
do_test vtab1-3.9 {
|
||||
set echo_module
|
||||
} {xBestIndex {WHERE b = ?} {} xFilter {WHERE b = ?} 10}
|
||||
do_test vtab1-3.8 {
|
||||
} {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 {WHERE b >= ? AND b <= ?} {} xFilter {WHERE b >= ? AND b <= ?} 5 10}
|
||||
do_test vtab1-3.9 {
|
||||
} {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 5 AND 10;
|
||||
SELECT * FROM t1 WHERE b BETWEEN 2 AND 10;
|
||||
}
|
||||
} {1 2 3 4 5 6}
|
||||
do_test vtab1-3.13 {
|
||||
set echo_module
|
||||
} {xBestIndex {WHERE b >= ? AND b <= ?} {} xFilter {WHERE b >= ? AND b <= ?} 5 10}
|
||||
} {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user