diff --git a/manifest b/manifest index 42da551941..ff416ad566 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bugfixes:\sFix\sa\ssegfault\sintroduced\sas\spart\sof\sthe\snew\svtab\scode,\sdeallocate\smemory\sin\sthe\sDestroy()\smethod\sof\sthe\secho\smodule.\s(CVS\s3222) -D 2006-06-13T04:11:44 +C Add\simplementations\sfor\sopcodes\srequired\sfor\slinear\sscans\sof\svirtual\stables.\s(CVS\s3223) +D 2006-06-13T10:24:43 F Makefile.in 56fd6261e83f60724e6dcd764e06ab68cbd53909 F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -74,7 +74,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 55bf6335dae7146f7a300039f5d6bb35010f1996 F src/sqlite.h.in 6fb7062da7e9c446623fa26b042bcf4b4050d702 F src/sqlite3ext.h 127bd394c8eea481f2ac9b754bf399dbfc818b75 -F src/sqliteInt.h 9562411b336b77123d1f569d4144fe3ba1ecb3bf +F src/sqliteInt.h 91cc3603fe2e1be18d52490a2fa65ed9640fb338 F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e F src/tclsqlite.c 0b2a04cfc1b4298adfbe90a754cfbbe207aca11a F src/test1.c 88291fa6674dcd409b1c9d76d3119151d4b81a50 @@ -84,7 +84,7 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3 -F src/test8.c c85eba7e98405e6c3d22ece241ee4e9ea4d154f8 +F src/test8.c d29427a0254f7609b0dd2561e62cf78e21c9d689 F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3 F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c @@ -94,14 +94,14 @@ F src/update.c 0186f09414a6578156d40666becc964f85c2a616 F src/utf.c ab81ac59084ff1c07d421eb1a0a84ec809603b44 F src/util.c ca6ee72772c0f5dc04d2e0ab1973fd3b6a9bf79d F src/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9 -F src/vdbe.c 59cb0d8cd19f090061f41715c44b3ed2af6bf264 +F src/vdbe.c 1f68000f8690e13535106f1b1bbaedc2da045457 F src/vdbe.h f72e5c00af759b7ed6fd606d508036d732098cc3 F src/vdbeInt.h 6ccb7eaae76ebd761470f6a035501ff33aa92c20 F src/vdbeapi.c 7dc662e7c905ce666bb506dced932e0307115cbf -F src/vdbeaux.c bcad5264196266118eb4ed0b2db3829fe335a67d +F src/vdbeaux.c 0168d770d03f9815511780a49cd8360d9a5f1ec5 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3 -F src/vtab.c 4ec6ac7e5e4fccb38401285d0e329d018622859f +F src/vtab.c 0e39af5822bb17b0007b0df7fad527aa0e3ebd38 F src/where.c c0f3cd3831cd9defb7c7788038d439a5922e7bd6 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -287,7 +287,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 b3a93d0b4667bf27adfbb555154086c7e25ee597 +F test/vtab1.test 67fed6f9b91b75d3e1988b47a972b30dd5ed2d97 F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394 F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa @@ -363,7 +363,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P f9ea9704755eee3fd29af7a47be1d41620be8835 -R b50ded4b4061c3fa2b3bc042599da575 +P 00f3c249bc79556d0cb3999f543887bd4f160347 +R 0931417f268857ba4bba3e3f6b5bc6db U danielk1977 -Z 42d9f8623c9300c98d0eb90f55c29716 +Z 7ec75a36e0232c7c8167de06e4e6d3ac diff --git a/manifest.uuid b/manifest.uuid index 435b26c465..d7799386dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00f3c249bc79556d0cb3999f543887bd4f160347 \ No newline at end of file +1f20e1832b38c76d2b0dde5fd720670c2ad0438b \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f78bfb8d60..9c882f89b2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.502 2006/06/12 21:59:14 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.503 2006/06/13 10:24:43 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -709,7 +709,6 @@ struct Table { sqlite3_vtab *pVtab; /* Pointer to the module instance */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ - u8 needCreate; /* Need to call pMod->xCreate() */ u8 isVirtual; /* True if this is a virtual table */ #endif Schema *pSchema; diff --git a/src/test8.c b/src/test8.c index 5f8112d092..0176d7b2e5 100644 --- a/src/test8.c +++ b/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.7 2006/06/13 04:11:44 danielk1977 Exp $ +** $Id: test8.c,v 1.8 2006/06/13 10:24:43 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -21,6 +21,24 @@ #include #include +typedef struct echo_vtab echo_vtab; +typedef struct echo_cursor echo_cursor; + +/* An echo vtab object */ +struct echo_vtab { + sqlite3_vtab base; + Tcl_Interp *interp; + sqlite3 *db; + char *zStmt; +}; + +/* An echo cursor object */ +struct echo_cursor { + sqlite3_vtab_cursor base; + sqlite3_stmt *pStmt; + int errcode; /* Error code */ +}; + /* ** Global Tcl variable $echo_module is a list. This routine appends ** the string element zArg to that list in interpreter interp. @@ -47,7 +65,12 @@ static void appendToEchoModule(Tcl_Interp *interp, const char *zArg){ ** Hence, the virtual table should have exactly the same column names and ** types as the real table. */ -static int echoDeclareVtab(sqlite3 *db, int argc, char **argv){ +static int echoDeclareVtab( + echo_vtab *pVtab, + sqlite3 *db, + int argc, + char **argv +){ int rc = SQLITE_OK; if( argc==2 ){ @@ -65,17 +88,34 @@ static int echoDeclareVtab(sqlite3 *db, int argc, char **argv){ rc = SQLITE_ERROR; } sqlite3_finalize(pStmt); + pVtab->zStmt = sqlite3MPrintf("SELECT rowid, * FROM %s ", argv[1]); } return rc; } -/* An echo vtab object */ -typedef struct echo_vtab echo_vtab; -struct echo_vtab { - sqlite3_vtab base; - Tcl_Interp *interp; -}; +static int echoConstructor( + sqlite3 *db, + const sqlite3_module *pModule, + int argc, char **argv, + sqlite3_vtab **ppVtab +){ + int i; + echo_vtab *pVtab; + + pVtab = sqliteMalloc( sizeof(*pVtab) ); + + *ppVtab = &pVtab->base; + pVtab->base.pModule = pModule; + pVtab->interp = pModule->pAux; + pVtab->db = db; + for(i=0; iinterp, argv[i]); + } + + echoDeclareVtab(pVtab, db, argc, argv); + return 0; +} /* Methods for the echo module */ static int echoCreate( @@ -84,20 +124,8 @@ static int echoCreate( int argc, char **argv, sqlite3_vtab **ppVtab ){ - int i; - echo_vtab *pVtab; - - pVtab = sqliteMalloc( sizeof(*pVtab) ); - *ppVtab = &pVtab->base; - pVtab->base.pModule = pModule; - pVtab->interp = pModule->pAux; - appendToEchoModule(pVtab->interp, "xCreate"); - for(i=0; iinterp, argv[i]); - } - - echoDeclareVtab(db, argc, argv); - return 0; + appendToEchoModule((Tcl_Interp *)(pModule->pAux), "xCreate"); + return echoConstructor(db, pModule, argc, argv, ppVtab); } static int echoConnect( sqlite3 *db, @@ -105,35 +133,122 @@ static int echoConnect( int argc, char **argv, sqlite3_vtab **ppVtab ){ - int i; - Tcl_Interp *interp = pModule->pAux; - echo_vtab *pVtab; - - pVtab = sqliteMalloc( sizeof(*pVtab) ); - *ppVtab = &pVtab->base; - pVtab->base.pModule = pModule; - pVtab->interp = pModule->pAux; - appendToEchoModule(pVtab->interp, "xConnect"); - for(i=0; iinterp, argv[i]); - } - - echoDeclareVtab(db, argc, argv); - return 0; + appendToEchoModule((Tcl_Interp *)(pModule->pAux), "xConnect"); + return echoConstructor(db, pModule, argc, argv, ppVtab); } + static int echoDisconnect(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; appendToEchoModule(p->interp, "xDisconnect"); - sqliteFree(pVtab); + sqliteFree(p->zStmt); + sqliteFree(p); return 0; } static int echoDestroy(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; appendToEchoModule(p->interp, "xDestroy"); - sqliteFree(pVtab); + sqliteFree(p->zStmt); + sqliteFree(p); return 0; } +static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) +{ + echo_cursor *pCur; + pCur = sqliteMalloc(sizeof(echo_cursor)); + *ppCursor = (sqlite3_vtab_cursor *)pCur; + return SQLITE_OK; +} + +static int echoClose(sqlite3_vtab_cursor *cur) +{ + echo_cursor *pCur = (echo_cursor *)cur; + sqlite3_finalize(pCur->pStmt); + sqliteFree(pCur); + return SQLITE_OK; +} + +static int echoNext(sqlite3_vtab_cursor *cur) +{ + int rc; + echo_cursor *pCur = (echo_cursor *)cur; + + rc = sqlite3_step(pCur->pStmt); + + if( rc==SQLITE_ROW ){ + rc = 1; + } else { + pCur->errcode = sqlite3_finalize(pCur->pStmt); + pCur->pStmt = 0; + rc = 0; + } + + return rc; +} + +static int echoFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idx, + int argc, + sqlite3_value **argv +){ + int rc; + + 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, pVtab->zStmt, -1, &pCur->pStmt, 0); + + if( rc==SQLITE_OK ){ + rc = echoNext(pVtabCursor); + } + + return rc; +} + +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 ); + 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; + } + 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; +} + + + /* ** The xBestIndex method for the echo module always returns ** an index of 123. @@ -156,6 +271,12 @@ static sqlite3_module echoModule = { echoBestIndex, echoDisconnect, echoDestroy, + echoOpen, /* xOpen - open a cursor */ + echoClose, /* xClose - close a cursor */ + echoFilter, /* xFilter - configure scan constraints */ + echoNext, /* xNext - advance a cursor */ + echoColumn, /* xColumn - read data */ + echoRowid /* xRowid - read data */ }; /* diff --git a/src/vdbe.c b/src/vdbe.c index a98b703f64..95bd95d274 100644 --- a/src/vdbe.c +++ b/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.554 2006/06/12 21:59:14 drh Exp $ +** $Id: vdbe.c,v 1.555 2006/06/13 10:24:43 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -4565,6 +4565,24 @@ case OP_VDestroy: { ** table and stores that cursor in P1. */ case OP_VOpen: { + Cursor *pCur = 0; + sqlite3_vtab_cursor *pVtabCursor = 0; + + sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3); + sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; + + assert(pVtab && pModule); + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xOpen(pVtab, &pVtabCursor); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + if( SQLITE_OK==rc ){ + /* Initialise sqlite3_vtab_cursor base class */ + pVtabCursor->pVtab = pVtab; + + /* Initialise vdbe cursor object */ + pCur = allocateCursor(p, pOp->p1, -1); + pCur->pVtabCursor = pVtabCursor; + } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -4579,13 +4597,48 @@ case OP_VOpen: { ** by P1. The index number 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 index number, argc, and all argv stack values -** are popped from the stack before this instruction completes. +** xFilter as argv. The topmost parameter (i.e. 3rd element popped from +** the stack) becomes argv[argc-1] when passed to xFilter. +** +** The index number, 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 iIndex; + 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 && pTos[-1].flags==MEM_Int ); + iIndex = pTos[0].i; + nArg = pTos[-1].i; + + /* Invoke the xFilter method if one is defined. */ + if( pModule->xFilter ){ + int res; + Mem *apArg; + apArg = &pTos[1-2-nArg]; + + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + res = pModule->xFilter(pCur->pVtabCursor, iIndex, nArg, &apArg); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + if( res==0 ){ + pc = pOp->p2 - 1; + } + } + + /* Pop the index number, argc value and parameters off the stack */ + popStack(&pTos, 2+nArg); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -4597,6 +4650,26 @@ case OP_VFilter: { ** the virtual-table that the P1 cursor is pointing to. */ case OP_VRowid: { + const sqlite3_module *pModule; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xRowid==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0); + rc = SQLITE_ERROR; + } else { + sqlite_int64 iRow; + + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xRowid(pCur->pVtabCursor, &iRow); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + pTos++; + pTos->flags = MEM_Int; + pTos->i = iRow; + } + break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -4608,6 +4681,33 @@ case OP_VRowid: { ** the row of the virtual-table that the P1 cursor is pointing to. */ case OP_VColumn: { + const sqlite3_module *pModule; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xColumn==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0); + rc = SQLITE_ERROR; + } else { + sqlite3_context sContext; + memset(&sContext, 0, sizeof(sContext)); + sContext.s.flags = MEM_Null; + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); + + /* Copy the result of the function to the top of the stack. We + ** do this regardless of whether or not an error occured to ensure any + ** dynamic allocation in sContext.s (a Mem struct) is released. + */ + sqlite3VdbeChangeEncoding(&sContext.s, encoding); + pTos++; + pTos->flags = 0; + sqlite3VdbeMemMove(pTos, &sContext.s); + + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + } + break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -4620,6 +4720,32 @@ case OP_VColumn: { ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { + const sqlite3_module *pModule; + int res = 0; + + Cursor *pCur = p->apCsr[pOp->p1]; + assert( pCur->pVtabCursor ); + pModule = pCur->pVtabCursor->pVtab->pModule; + if( pModule->xNext==0 ){ + sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xNext", 0); + rc = SQLITE_ERROR; + } else { + /* Invoke the xNext() method of the module. There is no way for the + ** underlying implementation to return an error if one occurs during + ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** data is available) and the error code returned when xColumn or + ** some other method is next invoked on the save virtual table cursor. + */ + if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; + res = pModule->xNext(pCur->pVtabCursor); + if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; + + if( res ){ + /* If there is data (or an error), jump to P2 */ + pc = pOp->p2 - 1; + } + } + break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8b5f66c624..fa3450c157 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -839,7 +839,7 @@ void sqlite3VdbeFreeCursor(Cursor *pCx){ if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; sqlite3_vtab *pVtab = pVtabCursor->pVtab; - sqlite3_module *pModule = pVtab->pModule; + const sqlite3_module *pModule = pVtab->pModule; pModule->xClose(pVtabCursor); } #endif diff --git a/src/vtab.c b/src/vtab.c index b8484c1cc6..8c8ba246d2 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.5 2006/06/12 16:01:22 danielk1977 Exp $ +** $Id: vtab.c,v 1.6 2006/06/13 10:24:43 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -367,9 +367,6 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ } } - if( SQLITE_OK==rc ){ - pTab->needCreate = 0; - } return rc; } diff --git a/test/vtab1.test b/test/vtab1.test index 689ae2e95f..32193562b0 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -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.7 2006/06/13 04:11:44 danielk1977 Exp $ +# $Id: vtab1.test,v 1.8 2006/06/13 10:24:44 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -110,8 +110,6 @@ do_test vtab1-2.5 { set echo_module } [list xDestroy] -finish_test - do_test vtab1-2.6 { execsql { PRAGMA table_info(t2); @@ -138,4 +136,42 @@ do_test vtab1-2.9 { } } [list] +#---------------------------------------------------------------------- +# 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 VARCHAR(32), c); + 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 + # because the underlying real table, is currently empty. + execsql { + SELECT a, b, c FROM t1; + } +} {} +do_test vtab1-3.3 { + # Put some data into the table treal. Then try a select on t1. + execsql { + INSERT INTO treal VALUES(1, 2, 3); + INSERT INTO treal VALUES(4, 5, 6); + SELECT * FROM t1; + } +} {1 2 3 4 5 6} +do_test vtab1-3.4 { + execsql { + SELECT a FROM t1; + } +} {1 4} +do_test vtab1-3.5 { + execsql { + SELECT rowid FROM t1; + } +} {1 2} + finish_test +