mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Add tests for error conditions surrounding the creation/connection of virtual tables. (CVS 3235)
FossilOrigin-Name: 5e592c422b86deb5802c6536e91661717ee9bbe1
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
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)
|
C Add\stests\sfor\serror\sconditions\ssurrounding\sthe\screation/connection\sof\svirtual\stables.\s(CVS\s3235)
|
||||||
D 2006-06-13T23:51:34
|
D 2006-06-14T06:31:28
|
||||||
F Makefile.in 200f6dc376ecfd9b01e5359c4e0c10c02f649b34
|
F Makefile.in 200f6dc376ecfd9b01e5359c4e0c10c02f649b34
|
||||||
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
||||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||||
@@ -84,7 +84,7 @@ F src/test4.c 8b784cd82de158a2317cb4ac4bc86f91ad315e25
|
|||||||
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||||
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de
|
||||||
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
F src/test7.c 03fa8d787f6aebc6d1f72504d52f33013ad2c8e3
|
||||||
F src/test8.c d21b301afbc35a5c4ded0ecc784d59bc8f795c75
|
F src/test8.c f91c78d8ad3aecf3e670e66c087a79ff806b21b2
|
||||||
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
F src/test_async.c e3deaedd4d86a56391b81808fde9e44fbd92f1d3
|
||||||
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3
|
||||||
F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
|
F src/test_server.c a6460daed0b92ecbc2531b6dc73717470e7a648c
|
||||||
@@ -102,7 +102,7 @@ F src/vdbeapi.c af663689ef57e5506f190bbd1068d28936b0fb34
|
|||||||
F src/vdbeaux.c c9474fd27f1735170feb4f6a46885d282cf22d52
|
F src/vdbeaux.c c9474fd27f1735170feb4f6a46885d282cf22d52
|
||||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||||
F src/vtab.c 7de1347022248edfb260c54f259148f413320cb7
|
F src/vtab.c 6af0aa0ef2ebca743a4647eb22fd5d5d3813d83e
|
||||||
F src/where.c 299c385e32a7b98d42864c7c83cdc6a778fae562
|
F src/where.c 299c385e32a7b98d42864c7c83cdc6a778fae562
|
||||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
@@ -288,7 +288,7 @@ F test/vacuum.test 37f998b841cb335397c26d9bbc3457182af2565f
|
|||||||
F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
|
F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c
|
||||||
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
|
||||||
F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
|
F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5
|
||||||
F test/vtab1.test 86e4c90c96cbf7f2c3b31069ed8c2d5dfd3bf378
|
F test/vtab1.test e445b10cb9662f180c96f2af4f82841656c35373
|
||||||
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
|
||||||
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
|
||||||
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
|
||||||
@@ -364,7 +364,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||||
P 9372481f233e1563b5ee137535f0fbf19851ffad
|
P 29199eeea4c46168ccaa7535d4941bd740479dee
|
||||||
R e6ce8e5a9dba6e782016ada2d5443cc3
|
R dc5e6094d3fe7373d35dfb54c78f916b
|
||||||
U drh
|
U danielk1977
|
||||||
Z 6f9bc9c4a49544af7a028d3a571bcd52
|
Z 267156075d7b55f7a94e810698d71dbc
|
||||||
|
@@ -1 +1 @@
|
|||||||
29199eeea4c46168ccaa7535d4941bd740479dee
|
5e592c422b86deb5802c6536e91661717ee9bbe1
|
50
src/test8.c
50
src/test8.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test8.c,v 1.11 2006/06/13 23:51:35 drh Exp $
|
** $Id: test8.c,v 1.12 2006/06/14 06:31:28 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -35,12 +35,11 @@ struct echo_vtab {
|
|||||||
sqlite3_vtab base;
|
sqlite3_vtab base;
|
||||||
Tcl_Interp *interp;
|
Tcl_Interp *interp;
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
char *zTableName; /* Name of the real table */
|
|
||||||
char *zStmt; /* "SELECT rowid, * FROM <real-table-name> " */
|
|
||||||
|
|
||||||
int *aIndex;
|
char *zTableName; /* Name of the real table */
|
||||||
int nCol;
|
int nCol; /* Number of columns in the real table */
|
||||||
char **aCol;
|
int *aIndex; /* Array of size nCol. True if column has an index */
|
||||||
|
char **aCol; /* Array of size nCol. Column names */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An echo cursor object */
|
/* An echo cursor object */
|
||||||
@@ -198,7 +197,6 @@ static int echoDeclareVtab(
|
|||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
pVtab->zStmt = sqlite3MPrintf("SELECT rowid, * FROM %s ", argv[1]);
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = getIndexArray(db, argv[1], &pVtab->aIndex);
|
rc = getIndexArray(db, argv[1], &pVtab->aIndex);
|
||||||
}
|
}
|
||||||
@@ -210,6 +208,19 @@ static int echoDeclareVtab(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int echoDestructor(sqlite3_vtab *pVtab){
|
||||||
|
int ii;
|
||||||
|
echo_vtab *p = (echo_vtab*)pVtab;
|
||||||
|
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 echoConstructor(
|
static int echoConstructor(
|
||||||
sqlite3 *db,
|
sqlite3 *db,
|
||||||
const sqlite3_module *pModule,
|
const sqlite3_module *pModule,
|
||||||
@@ -220,8 +231,6 @@ static int echoConstructor(
|
|||||||
echo_vtab *pVtab;
|
echo_vtab *pVtab;
|
||||||
|
|
||||||
pVtab = sqliteMalloc( sizeof(*pVtab) );
|
pVtab = sqliteMalloc( sizeof(*pVtab) );
|
||||||
|
|
||||||
*ppVtab = &pVtab->base;
|
|
||||||
pVtab->base.pModule = pModule;
|
pVtab->base.pModule = pModule;
|
||||||
pVtab->interp = pModule->pAux;
|
pVtab->interp = pModule->pAux;
|
||||||
pVtab->db = db;
|
pVtab->db = db;
|
||||||
@@ -230,8 +239,13 @@ static int echoConstructor(
|
|||||||
appendToEchoModule(pVtab->interp, argv[i]);
|
appendToEchoModule(pVtab->interp, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
echoDeclareVtab(pVtab, db, argc, argv);
|
if( echoDeclareVtab(pVtab, db, argc, argv) ){
|
||||||
return 0;
|
echoDestructor((sqlite3_vtab *)pVtab);
|
||||||
|
return SQLITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppVtab = &pVtab->base;
|
||||||
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Methods for the echo module */
|
/* Methods for the echo module */
|
||||||
@@ -254,20 +268,6 @@ static int echoConnect(
|
|||||||
return echoConstructor(db, pModule, argc, argv, ppVtab);
|
return echoConstructor(db, pModule, argc, argv, ppVtab);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int echoDestructor(sqlite3_vtab *pVtab){
|
|
||||||
int ii;
|
|
||||||
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){
|
static int echoDisconnect(sqlite3_vtab *pVtab){
|
||||||
appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");
|
appendToEchoModule(((echo_vtab *)pVtab)->interp, "xDisconnect");
|
||||||
return echoDestructor(pVtab);
|
return echoDestructor(pVtab);
|
||||||
|
29
src/vtab.c
29
src/vtab.c
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file contains code used to help implement virtual tables.
|
** This file contains code used to help implement virtual tables.
|
||||||
**
|
**
|
||||||
** $Id: vtab.c,v 1.8 2006/06/13 23:51:35 drh Exp $
|
** $Id: vtab.c,v 1.9 2006/06/14 06:31:28 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -144,7 +144,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
|||||||
int iDb;
|
int iDb;
|
||||||
Vdbe *v;
|
Vdbe *v;
|
||||||
if( pTab->pModule==0 ){
|
if( pTab->pModule==0 ){
|
||||||
sqlite3ErrorMsg(pParse, "unknown module: %s", zModule);
|
sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the complete text of the CREATE VIRTUAL TABLE statement */
|
/* Compute the complete text of the CREATE VIRTUAL TABLE statement */
|
||||||
@@ -254,7 +254,7 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
|
|||||||
zModule = pTab->azModuleArg[0];
|
zModule = pTab->azModuleArg[0];
|
||||||
if( !pModule || !pModule->xConnect ){
|
if( !pModule || !pModule->xConnect ){
|
||||||
const char *zModule = pTab->azModuleArg[0];
|
const char *zModule = pTab->azModuleArg[0];
|
||||||
sqlite3ErrorMsg(pParse, "unknown module: %s", zModule);
|
sqlite3ErrorMsg(pParse, "no such module: %s", zModule);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
char **azArg = pTab->azModuleArg;
|
char **azArg = pTab->azModuleArg;
|
||||||
@@ -349,22 +349,31 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
|
|||||||
** error. Otherwise, do nothing.
|
** error. Otherwise, do nothing.
|
||||||
*/
|
*/
|
||||||
if( !pModule ){
|
if( !pModule ){
|
||||||
*pzErr = sqlite3MPrintf("unknown module: %s", zModule);
|
*pzErr = sqlite3MPrintf("no such module: %s", zModule);
|
||||||
rc = SQLITE_ERROR;
|
rc = SQLITE_ERROR;
|
||||||
}else if( pModule->xCreate ){
|
}else{
|
||||||
|
int rc2;
|
||||||
char **azArg = pTab->azModuleArg;
|
char **azArg = pTab->azModuleArg;
|
||||||
int nArg = pTab->nModuleArg;
|
int nArg = pTab->nModuleArg;
|
||||||
|
|
||||||
assert( !db->pVTab );
|
assert( !db->pVTab );
|
||||||
|
assert( pModule->xCreate );
|
||||||
db->pVTab = pTab;
|
db->pVTab = pTab;
|
||||||
rc = sqlite3SafetyOff(db);
|
rc = sqlite3SafetyOff(db);
|
||||||
assert( rc==SQLITE_OK );
|
assert( rc==SQLITE_OK );
|
||||||
rc = pModule->xCreate(db, pModule, nArg, azArg, &pTab->pVtab);
|
rc = pModule->xCreate(db, pModule, nArg, azArg, &pTab->pVtab);
|
||||||
|
rc2 = sqlite3SafetyOn(db);
|
||||||
|
|
||||||
|
if( SQLITE_OK!=rc ){
|
||||||
|
*pzErr = sqlite3MPrintf("vtable constructor failed: %s", zTab);
|
||||||
|
} else if( db->pVTab ){
|
||||||
|
const char *zFormat = "vtable constructor did not declare schema: %s";
|
||||||
|
*pzErr = sqlite3MPrintf(zFormat, zTab);
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
}
|
||||||
db->pVTab = 0;
|
db->pVTab = 0;
|
||||||
if( rc ){
|
if( rc==SQLITE_OK ){
|
||||||
*pzErr = sqlite3MPrintf("module create failed: %s", zModule);
|
rc = rc2;
|
||||||
sqlite3SafetyOn(db);
|
|
||||||
} else {
|
|
||||||
rc = sqlite3SafetyOn(db);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
215
test/vtab1.test
215
test/vtab1.test
@@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is creating and dropping virtual tables.
|
# focus of this file is creating and dropping virtual tables.
|
||||||
#
|
#
|
||||||
# $Id: vtab1.test,v 1.11 2006/06/13 23:51:35 drh Exp $
|
# $Id: vtab1.test,v 1.12 2006/06/14 06:31:28 danielk1977 Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -21,37 +21,107 @@ ifcapable !vtab {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# We cannot create a virtual table if the module has not
|
#----------------------------------------------------------------------
|
||||||
# been registered.
|
# Organization of tests in this file:
|
||||||
|
#
|
||||||
|
# vtab1-1.*: Error conditions and other issues surrounding creation/connection
|
||||||
|
# of a virtual module.
|
||||||
|
# vtab1-2.*: Test sqlite3_declare_vtab() and the xConnect/xDisconnect methods.
|
||||||
|
# vtab1-3.*: Table scans and WHERE clauses.
|
||||||
|
# vtab1-4.*: Table scans and ORDER BY clauses.
|
||||||
|
# vtab1-5.*: Test queries that include joins. This brings the
|
||||||
|
# sqlite3_index_info.estimatedCost variable into play.
|
||||||
|
#
|
||||||
|
# This file uses the "echo" module (see src/test8.c). Refer to comments
|
||||||
|
# in that file for the special behaviour of the Tcl $echo_module variable.
|
||||||
|
#
|
||||||
|
# TODO:
|
||||||
|
#
|
||||||
|
# * How to test the sqlite3_index_constraint_usage.omit field? Or
|
||||||
|
# sqlite3_index_info.orderByConsumed?
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
# Test cases vtab1.1.*
|
||||||
|
#
|
||||||
|
|
||||||
|
# We cannot create a virtual table if the module has not been registered.
|
||||||
#
|
#
|
||||||
do_test vtab1-1.1 {
|
do_test vtab1-1.1 {
|
||||||
catchsql {
|
catchsql {
|
||||||
CREATE VIRTUAL TABLE t1 USING echo;
|
CREATE VIRTUAL TABLE t1 USING echo;
|
||||||
}
|
}
|
||||||
} {1 {unknown module: echo}}
|
} {1 {no such module: echo}}
|
||||||
do_test vtab1-1.2 {
|
do_test vtab1-1.2 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT name FROM sqlite_master ORDER BY 1
|
SELECT name FROM sqlite_master ORDER BY 1
|
||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
# After we register the echo module, we are allowed to create
|
# Register the module
|
||||||
# virtual tables using that module.
|
register_echo_module [sqlite3_connection_pointer db]
|
||||||
|
|
||||||
|
# Once a module has been registered, virtual tables using that module
|
||||||
|
# may be created. However if a module xCreate() fails to call
|
||||||
|
# sqlite3_declare_vtab() an error will be raised and the table not created.
|
||||||
|
#
|
||||||
|
# The "echo" module does not invoke sqlite3_declare_vtab() if it is
|
||||||
|
# passed zero arguments.
|
||||||
#
|
#
|
||||||
do_test vtab1-1.3 {
|
do_test vtab1-1.3 {
|
||||||
register_echo_module [sqlite3_connection_pointer db]
|
|
||||||
catchsql {
|
catchsql {
|
||||||
CREATE VIRTUAL TABLE t1 USING echo;
|
CREATE VIRTUAL TABLE t1 USING echo;
|
||||||
}
|
}
|
||||||
} {0 {}}
|
} {1 {vtable constructor did not declare schema: t1}}
|
||||||
do_test vtab1-1.4 {
|
do_test vtab1-1.4 {
|
||||||
set echo_module
|
|
||||||
} {xCreate echo}
|
|
||||||
do_test vtab1-1.5 {
|
|
||||||
execsql {
|
execsql {
|
||||||
SELECT name, sql FROM sqlite_master ORDER BY 1
|
SELECT name FROM sqlite_master ORDER BY 1
|
||||||
}
|
}
|
||||||
} {t1 {CREATE VIRTUAL TABLE t1 USING echo}}
|
} {}
|
||||||
|
|
||||||
|
# The "echo" module xCreate method returns an error and does not create
|
||||||
|
# the virtual table if it is passed an argument that does not correspond
|
||||||
|
# to an existing real table in the same database.
|
||||||
|
#
|
||||||
|
do_test vtab1-1.5 {
|
||||||
|
catchsql {
|
||||||
|
CREATE VIRTUAL TABLE t1 USING echo(no_such_table);
|
||||||
|
}
|
||||||
|
} {1 {vtable constructor failed: t1}}
|
||||||
|
do_test vtab1-1.6 {
|
||||||
|
execsql {
|
||||||
|
SELECT name FROM sqlite_master ORDER BY 1
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
# Test to make sure nothing goes wrong and no memory is leaked if we
|
||||||
|
# select an illegal table-name (i.e a reserved name or the name of a
|
||||||
|
# table that already exists).
|
||||||
|
#
|
||||||
|
do_test vtab1-1.7 {
|
||||||
|
catchsql {
|
||||||
|
CREATE VIRTUAL TABLE sqlite_master USING echo;
|
||||||
|
}
|
||||||
|
} {1 {object name reserved for internal use: sqlite_master}}
|
||||||
|
do_test vtab1-1.8 {
|
||||||
|
catchsql {
|
||||||
|
CREATE TABLE treal(a, b, c);
|
||||||
|
CREATE VIRTUAL TABLE treal USING echo(treal);
|
||||||
|
}
|
||||||
|
} {1 {table treal already exists}}
|
||||||
|
do_test vtab1-1.9 {
|
||||||
|
execsql {
|
||||||
|
DROP TABLE treal;
|
||||||
|
SELECT name FROM sqlite_master ORDER BY 1
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
# Test cases vtab1.2.*
|
||||||
|
#
|
||||||
|
# At this point, the database is completely empty. The echo module
|
||||||
|
# has already been registered.
|
||||||
|
|
||||||
# If a single argument is passed to the echo module during table
|
# If a single argument is passed to the echo module during table
|
||||||
# creation, it is assumed to be the name of a table in the same
|
# creation, it is assumed to be the name of a table in the same
|
||||||
@@ -70,77 +140,92 @@ do_test vtab1-2.1 {
|
|||||||
]
|
]
|
||||||
do_test vtab1-2.2 {
|
do_test vtab1-2.2 {
|
||||||
execsql {
|
execsql {
|
||||||
CREATE VIRTUAL TABLE t2 USING echo(template);
|
CREATE VIRTUAL TABLE t1 USING echo(template);
|
||||||
}
|
}
|
||||||
execsql { PRAGMA table_info(t2); }
|
execsql { PRAGMA table_info(t1); }
|
||||||
} [list \
|
} [list \
|
||||||
0 a {} 0 {} 0 \
|
0 a {} 0 {} 0 \
|
||||||
1 b {} 0 {} 0 \
|
1 b {} 0 {} 0 \
|
||||||
2 c {} 0 {} 0 \
|
2 c {} 0 {} 0 \
|
||||||
]
|
]
|
||||||
|
|
||||||
# Test that the database can be unloaded. This should invoke
|
# Test that the database can be unloaded. This should invoke the xDisconnect()
|
||||||
# the xDisconnect() callback each of the two virtual tables - t1 and t2.
|
# callback for the successfully create virtual table (t1).
|
||||||
|
#
|
||||||
do_test vtab1-2.3 {
|
do_test vtab1-2.3 {
|
||||||
breakpoint
|
|
||||||
set echo_module [list]
|
set echo_module [list]
|
||||||
db close
|
db close
|
||||||
set echo_module
|
set echo_module
|
||||||
} [list xDisconnect xDisconnect]
|
} [list xDisconnect]
|
||||||
|
|
||||||
set echo_module [list]
|
# Re-open the database. This should not cause any virtual methods to
|
||||||
# Re-open the database. Check that the schema of the virtual
|
# be called. The invocation of xConnect() is delayed until the virtual
|
||||||
# table is still correct.
|
# table schema is first required by the compiler.
|
||||||
|
#
|
||||||
do_test vtab1-2.4 {
|
do_test vtab1-2.4 {
|
||||||
|
set echo_module [list]
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
db cache size 0
|
db cache size 0
|
||||||
register_echo_module [sqlite3_connection_pointer db]
|
set echo_module
|
||||||
execsql { PRAGMA table_info(t2); }
|
} {}
|
||||||
|
|
||||||
|
# Try to query the virtual table schema. This should fail, as the
|
||||||
|
# echo module has not been registered with this database connection.
|
||||||
|
#
|
||||||
|
do_test vtab1.2.6 {
|
||||||
|
breakpoint
|
||||||
|
catchsql { PRAGMA table_info(t1); }
|
||||||
|
} {1 {no such module: echo}}
|
||||||
|
|
||||||
|
# Register the module
|
||||||
|
register_echo_module [sqlite3_connection_pointer db]
|
||||||
|
|
||||||
|
# Try to query the virtual table schema again. This time it should
|
||||||
|
# invoke the xConnect method and succeed.
|
||||||
|
#
|
||||||
|
do_test vtab1.2.7 {
|
||||||
|
execsql { PRAGMA table_info(t1); }
|
||||||
} [list \
|
} [list \
|
||||||
0 a {} 0 {} 0 \
|
0 a {} 0 {} 0 \
|
||||||
1 b {} 0 {} 0 \
|
1 b {} 0 {} 0 \
|
||||||
2 c {} 0 {} 0 \
|
2 c {} 0 {} 0 \
|
||||||
]
|
]
|
||||||
|
do_test vtab1.2.8 {
|
||||||
|
set echo_module
|
||||||
|
} {xConnect echo template}
|
||||||
|
|
||||||
# Drop the table t2. This should cause the xDestroy (but not xDisconnect)
|
# Drop table t1. This should cause the xDestroy (but not xDisconnect) method
|
||||||
# method to be invoked.
|
# to be invoked.
|
||||||
do_test vtab1-2.5 {
|
do_test vtab1-2.5 {
|
||||||
set echo_module [list]
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
DROP TABLE t2;
|
DROP TABLE t1;
|
||||||
}
|
}
|
||||||
set echo_module
|
set echo_module
|
||||||
} [list xDestroy]
|
} {xDestroy}
|
||||||
|
|
||||||
do_test vtab1-2.6 {
|
do_test vtab1-2.6 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA table_info(t2);
|
PRAGMA table_info(t1);
|
||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
do_test vtab1-2.7 {
|
do_test vtab1-2.7 {
|
||||||
execsql {
|
execsql {
|
||||||
SELECT sql FROM sqlite_master;
|
SELECT sql FROM sqlite_master;
|
||||||
}
|
}
|
||||||
} [list {CREATE VIRTUAL TABLE t1 USING echo} \
|
} [list {CREATE TABLE template(a, b, c)}]
|
||||||
{CREATE TABLE template(a, b, c)} \
|
|
||||||
]
|
# Clean up other test artifacts:
|
||||||
do_test vtab1-2.8 {
|
do_test vtab1-2.8 {
|
||||||
set echo_module [list]
|
|
||||||
execsql {
|
execsql {
|
||||||
DROP TABLE t1;
|
|
||||||
DROP TABLE template;
|
DROP TABLE template;
|
||||||
}
|
|
||||||
set echo_module
|
|
||||||
} [list]
|
|
||||||
do_test vtab1-2.9 {
|
|
||||||
execsql {
|
|
||||||
SELECT sql FROM sqlite_master;
|
SELECT sql FROM sqlite_master;
|
||||||
}
|
}
|
||||||
} [list]
|
} [list]
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
# Test case vtab1-3 tests simple linear scans (no filter conditions) of
|
# Test case vtab1-3 test table scans and the echo module's
|
||||||
# virtual table modules.
|
# xBestIndex/xFilter handling of WHERE conditions.
|
||||||
|
|
||||||
do_test vtab1-3.1 {
|
do_test vtab1-3.1 {
|
||||||
set echo_module ""
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
@@ -150,15 +235,20 @@ do_test vtab1-3.1 {
|
|||||||
}
|
}
|
||||||
set echo_module
|
set echo_module
|
||||||
} [list xCreate echo treal]
|
} [list xCreate echo treal]
|
||||||
|
|
||||||
|
# Test that a SELECT on t1 doesn't crash. No rows are returned
|
||||||
|
# because the underlying real table is currently empty.
|
||||||
|
#
|
||||||
do_test vtab1-3.2 {
|
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 {
|
execsql {
|
||||||
SELECT a, b, c FROM t1;
|
SELECT a, b, c FROM t1;
|
||||||
}
|
}
|
||||||
} {}
|
} {}
|
||||||
|
|
||||||
|
# Put some data into the table treal. Then try a few simple SELECT
|
||||||
|
# statements on t1.
|
||||||
|
#
|
||||||
do_test vtab1-3.3 {
|
do_test vtab1-3.3 {
|
||||||
# Put some data into the table treal. Then try a select on t1.
|
|
||||||
execsql {
|
execsql {
|
||||||
INSERT INTO treal VALUES(1, 2, 3);
|
INSERT INTO treal VALUES(1, 2, 3);
|
||||||
INSERT INTO treal VALUES(4, 5, 6);
|
INSERT INTO treal VALUES(4, 5, 6);
|
||||||
@@ -175,7 +265,6 @@ do_test vtab1-3.5 {
|
|||||||
SELECT rowid FROM t1;
|
SELECT rowid FROM t1;
|
||||||
}
|
}
|
||||||
} {1 2}
|
} {1 2}
|
||||||
|
|
||||||
do_test vtab1-3.6 {
|
do_test vtab1-3.6 {
|
||||||
set echo_module ""
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
@@ -183,17 +272,34 @@ do_test vtab1-3.6 {
|
|||||||
}
|
}
|
||||||
} {1 2 3 4 5 6}
|
} {1 2 3 4 5 6}
|
||||||
do_test vtab1-3.7 {
|
do_test vtab1-3.7 {
|
||||||
set echo_module
|
execsql {
|
||||||
} {xBestIndex {SELECT rowid, * FROM 'treal'} xFilter {SELECT rowid, * FROM 'treal'}}
|
SELECT rowid, * FROM t1;
|
||||||
|
}
|
||||||
|
} {1 1 2 3 2 4 5 6}
|
||||||
|
|
||||||
|
# Execute some SELECT statements with WHERE clauses on the t1 table.
|
||||||
|
# Then check the echo_module variable (written to by the module methods
|
||||||
|
# in test8.c) to make sure the xBestIndex() and xFilter() methods were
|
||||||
|
# called correctly.
|
||||||
|
#
|
||||||
do_test vtab1-3.8 {
|
do_test vtab1-3.8 {
|
||||||
|
set echo_module ""
|
||||||
|
execsql {
|
||||||
|
SELECT * FROM t1;
|
||||||
|
}
|
||||||
|
set echo_module
|
||||||
|
} [list xBestIndex {SELECT rowid, * FROM 'treal'} \
|
||||||
|
xFilter {SELECT rowid, * FROM 'treal'} ]
|
||||||
|
do_test vtab1-3.9 {
|
||||||
set echo_module ""
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
SELECT * FROM t1 WHERE b = 5;
|
SELECT * FROM t1 WHERE b = 5;
|
||||||
}
|
}
|
||||||
} {4 5 6}
|
} {4 5 6}
|
||||||
do_test vtab1-3.9 {
|
do_test vtab1-3.10 {
|
||||||
set echo_module
|
set echo_module
|
||||||
} {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b = ?} 5}
|
} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b = ?} \
|
||||||
|
xFilter {SELECT rowid, * FROM 'treal' WHERE b = ?} 5 ]
|
||||||
do_test vtab1-3.10 {
|
do_test vtab1-3.10 {
|
||||||
set echo_module ""
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
@@ -202,7 +308,8 @@ do_test vtab1-3.10 {
|
|||||||
} {4 5 6}
|
} {4 5 6}
|
||||||
do_test vtab1-3.11 {
|
do_test vtab1-3.11 {
|
||||||
set echo_module
|
set echo_module
|
||||||
} {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 5 10}
|
} [list 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 {
|
do_test vtab1-3.12 {
|
||||||
set echo_module ""
|
set echo_module ""
|
||||||
execsql {
|
execsql {
|
||||||
@@ -211,6 +318,8 @@ do_test vtab1-3.12 {
|
|||||||
} {1 2 3 4 5 6}
|
} {1 2 3 4 5 6}
|
||||||
do_test vtab1-3.13 {
|
do_test vtab1-3.13 {
|
||||||
set echo_module
|
set echo_module
|
||||||
} {xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10}
|
} [list xBestIndex {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} \
|
||||||
|
xFilter {SELECT rowid, * FROM 'treal' WHERE b >= ? AND b <= ?} 2 10 ]
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user