Incremental work on parsing/storing and invoking the xCreate callback for virtual tables. (CVS 3212)
FossilOrigin-Name: 8ffbab79d5a76dea0f87cf551d5b6ad4f0fab337
This commit is contained in:
parent
b9bb7c187e
commit
78efaba10e
24
manifest
24
manifest
@ -1,5 +1,5 @@
|
||||
C Progress\stoward\sCREATE\sVIRTUAL\sTABLE.\s\sStill\snot\seven\sclose\sto\sworking...\s(CVS\s3211)
|
||||
D 2006-06-11T23:41:55
|
||||
C Incremental\swork\son\sparsing/storing\sand\sinvoking\sthe\sxCreate\scallback\sfor\svirtual\stables.\s(CVS\s3212)
|
||||
D 2006-06-12T06:09:18
|
||||
F Makefile.in 56fd6261e83f60724e6dcd764e06ab68cbd53909
|
||||
F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -66,7 +66,7 @@ F src/pager.c ddd05666bb89808a516baef2c186d6a75887ae90
|
||||
F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818
|
||||
F src/parse.y 05cd1419b625df99ea9776e2c767d2a792d84345
|
||||
F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55
|
||||
F src/prepare.c bbf12d3147116b284b157232efaef3bbe5df08fc
|
||||
F src/prepare.c 6dc945dab34cf97364c661d2b7a12be65d338267
|
||||
F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240
|
||||
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||
F src/select.c 38eda11d950ed5e631ea9054f84a4a8b9e9b39d8
|
||||
@ -74,7 +74,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
||||
F src/shell.c b9eb3ed4d3ab41fbf630eabb602f3c9d20fc737a
|
||||
F src/sqlite.h.in ca30260d7815ee68be410e1fa0bd1f131c86cf10
|
||||
F src/sqlite3ext.h 127bd394c8eea481f2ac9b754bf399dbfc818b75
|
||||
F src/sqliteInt.h 90957da628f83fa7d57c35b239573496642393c0
|
||||
F src/sqliteInt.h 4ac8c35fec748b1886bed00f1086fa2520faea80
|
||||
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 210f2109333e3373a1cb814e22e7b6b33e1e0a20
|
||||
F src/test8.c c1a91a3307e4d8d8a46211498111d1c5778b9294
|
||||
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 2547e931baf0f35cc8df77fdb18004a9f987bc6a
|
||||
F src/vdbe.c 5c77e8b57c07e7776ec34df8088749c639bbfe7c
|
||||
F src/vdbe.h 190d85a37658c2397be75a4c70bbc02ebc4ec0ba
|
||||
F src/vdbeInt.h 85cd5f81d38edb1b8f4786f407c77a7a3ba636fb
|
||||
F src/vdbeapi.c 7dc662e7c905ce666bb506dced932e0307115cbf
|
||||
F src/vdbeaux.c 4002e6b19d7c9719cb81f9797316b9ad118e4370
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
|
||||
F src/vtab.c 4ace1448bdba6a13d93c7642aa66447f8a5cd63c
|
||||
F src/vtab.c 6872f6a6ca33aac85b62bcd66d883f4deffab00d
|
||||
F src/where.c 3dc5269ba552c0db39247f6bbc98b312ae786863
|
||||
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 9029c3ef19f1db3eebb2554b4db12e04b39a30ca
|
||||
F test/vtab1.test 5bf2bebe96272953928596b256cefb21d9c765b1
|
||||
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 66370cb99bd93abb33e1e8433672da45e1795f78
|
||||
R 9ff37f743d5a6a690e7a66e29bc79ec5
|
||||
U drh
|
||||
Z 6146abfd990542c70d1912af93fdb676
|
||||
P 898ec36b4102aaa03979f8f5c510936e57e2ae48
|
||||
R fd0d79bfdfee01e76c00d486659426af
|
||||
U danielk1977
|
||||
Z 21ad209dbac4dc09cf972c3f2b10f101
|
||||
|
@ -1 +1 @@
|
||||
898ec36b4102aaa03979f8f5c510936e57e2ae48
|
||||
8ffbab79d5a76dea0f87cf551d5b6ad4f0fab337
|
@ -13,7 +13,7 @@
|
||||
** interface, and routines that contribute to loading the database schema
|
||||
** from disk.
|
||||
**
|
||||
** $Id: prepare.c,v 1.34 2006/05/23 23:22:29 drh Exp $
|
||||
** $Id: prepare.c,v 1.35 2006/06/12 06:09:18 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -38,7 +38,7 @@ static void corruptSchema(InitData *pData, const char *zExtra){
|
||||
** Each callback contains the following information:
|
||||
**
|
||||
** argv[0] = name of thing being created
|
||||
** argv[1] = root page number for table or index. NULL for trigger or view.
|
||||
** argv[1] = root page number for table or index. 0 for trigger or view.
|
||||
** argv[2] = SQL text for the CREATE statement.
|
||||
** argv[3] = "1" for temporary files, "0" for main database, "2" or more
|
||||
** for auxiliary database files.
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.497 2006/06/11 23:41:56 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.498 2006/06/12 06:09:18 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -1790,6 +1790,7 @@ void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
|
||||
void sqlite3VtabFinishParse(Parse*, Token*);
|
||||
void sqlite3VtabArgInit(Parse*);
|
||||
void sqlite3VtabArgExtend(Parse*, Token*);
|
||||
int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **);
|
||||
|
||||
#ifdef SQLITE_SSE
|
||||
#include "sseInt.h"
|
||||
|
25
src/test8.c
25
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.1 2006/06/11 23:41:56 drh Exp $
|
||||
** $Id: test8.c,v 1.2 2006/06/12 06:09:19 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -21,6 +21,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
** Global Tcl variable $echo_module is a list. This routine appends
|
||||
** the string element zArg to that list in interpreter interp.
|
||||
*/
|
||||
static void appendToEchoModule(const sqlite3_module *pModule, const char *zArg){
|
||||
int flags = (TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar((Tcl_Interp *)(pModule->pAux), "echo_module", zArg, flags);
|
||||
}
|
||||
|
||||
/* Methods for the echo module */
|
||||
static int echoCreate(
|
||||
sqlite3 *db,
|
||||
@ -32,11 +41,11 @@ static int echoCreate(
|
||||
Tcl_Interp *interp = pModule->pAux;
|
||||
*ppVtab = pModule->pAux;
|
||||
|
||||
Tcl_SetVar(interp, "echo_module", "xCreate", TCL_GLOBAL_ONLY);
|
||||
appendToEchoModule(pModule, "xCreate");
|
||||
for(i=0; i<argc; i++){
|
||||
Tcl_SetVar(interp, "echo_module", argv[i],
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY);
|
||||
appendToEchoModule(pModule, argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int echoConnect(
|
||||
@ -74,12 +83,12 @@ static int echoDestroy(sqlite3_vtab *pVtab){
|
||||
** variables.
|
||||
*/
|
||||
static sqlite3_module echoModule = {
|
||||
0,
|
||||
"echo",
|
||||
0,
|
||||
0, /* iVersion */
|
||||
"echo", /* zName */
|
||||
0, /* pAux */
|
||||
echoCreate,
|
||||
echoConnect,
|
||||
0,
|
||||
0, /* xBestIndex */
|
||||
echoDisconnect,
|
||||
echoDestroy,
|
||||
};
|
||||
|
11
src/vdbe.c
11
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.551 2006/06/11 23:41:56 drh Exp $
|
||||
** $Id: vdbe.c,v 1.552 2006/06/12 06:09:19 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -4534,12 +4534,13 @@ case OP_TableLock: { /* no-push */
|
||||
#endif /* SQLITE_OMIT_SHARED_CACHE */
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Opcode: VCreate * * P3
|
||||
/* Opcode: VCreate P1 * P3
|
||||
**
|
||||
** P3 is the name of a virtual table. Call the xCreate method for
|
||||
** that table.
|
||||
** P3 is the name of a virtual table in database P1. Call the xCreate method
|
||||
** for that table.
|
||||
*/
|
||||
case OP_VCreate: {
|
||||
rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p3, &p->zErrMsg);
|
||||
break;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@ -4547,7 +4548,7 @@ case OP_VCreate: {
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Opcode: VDestroy * * P3
|
||||
**
|
||||
** P3 is the name of a virtual table. Call the xCreate method for
|
||||
** P3 is the name of a virtual table. Call the xDestroy method for
|
||||
** that table.
|
||||
*/
|
||||
case OP_VDestroy: {
|
||||
|
90
src/vtab.c
90
src/vtab.c
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.1 2006/06/11 23:41:56 drh Exp $
|
||||
** $Id: vtab.c,v 1.2 2006/06/12 06:09:19 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@ -81,7 +81,14 @@ void sqlite3VtabBeginParse(
|
||||
){
|
||||
Table *pTable; /* The new virtual table */
|
||||
|
||||
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 0);
|
||||
/* TODO: The 5th argument to sqlite3StartTable() - isView - is being
|
||||
** passed a true value at present. This prevents sqlite3StartTable()
|
||||
** from coding OP_CreateTable, which is correct, but causes it
|
||||
** to invoke the authorization function as if a CREATE VIEW statement
|
||||
** were attempted, which is incorrect.
|
||||
*/
|
||||
sqlite3StartTable(pParse, pName1, pName2, 0, 1, 0);
|
||||
|
||||
pTable = pParse->pNewTable;
|
||||
if( pTable==0 ) return;
|
||||
pTable->isVirtual = 1;
|
||||
@ -134,6 +141,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
*/
|
||||
if( !db->init.busy ){
|
||||
char *zStmt;
|
||||
char *zWhere;
|
||||
int iDb;
|
||||
Vdbe *v;
|
||||
if( pTab->pModule==0 ){
|
||||
@ -148,14 +156,18 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
|
||||
/* A slot for the record has already been allocated in the
|
||||
** SQLITE_MASTER table. We just need to update that slot with all
|
||||
** the information we've collected. The rowid for the preallocated
|
||||
** slot is the top the stack.
|
||||
** the information we've collected.
|
||||
**
|
||||
** The top of the stack is the rootpage allocated by sqlite3StartTable().
|
||||
** This value is always 0 and is ignored, a virtual table does not have a
|
||||
** rootpage. The next entry on the stack is the rowid of the record
|
||||
** in the sqlite_master table.
|
||||
*/
|
||||
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s "
|
||||
"SET type='table', name=%Q, tbl_name=%Q, rootpage=NULL, sql=%Q "
|
||||
"WHERE rowid=#0",
|
||||
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
|
||||
"WHERE rowid=#1",
|
||||
db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
|
||||
pTab->zName,
|
||||
pTab->zName,
|
||||
@ -163,18 +175,36 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
);
|
||||
sqliteFree(zStmt);
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeOp3(v, OP_VCreate, 0, 0, pTab->zName, P3_DYNAMIC);
|
||||
sqlite3ChangeCookie(db, v, iDb);
|
||||
|
||||
sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
|
||||
zWhere = sqlite3MPrintf("name='%q'", pTab->zName);
|
||||
sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
|
||||
sqlite3VdbeOp3(v, OP_VCreate, iDb, 0, pTab->zName, strlen(pTab->zName) + 1);
|
||||
}
|
||||
|
||||
/* If we are rereading the sqlite_master table and we happen to
|
||||
** currently know the module for the new table, create an
|
||||
** sqlite3_vtab instance.
|
||||
/* If we are rereading the sqlite_master table create the in-memory
|
||||
** record of the table.
|
||||
**
|
||||
** TODO: If the module is already registered, should we call xConnect()
|
||||
** here, or should it wait until the table is first referenced. Maybe
|
||||
** it's better to be lazy here, in case xConnect() is expensive to call.
|
||||
*/
|
||||
else if( pTab->pModule ){
|
||||
else {
|
||||
#if 0
|
||||
sqlite3_module *pMod = pTab->pModule;
|
||||
assert( pMod->xConnect );
|
||||
pMod->xConnect(db, pMod, pTab->nModuleArg, pTab->azModuleArg, &pTab->pVtab);
|
||||
#endif
|
||||
Table *pOld;
|
||||
Schema *pSchema = pTab->pSchema;
|
||||
const char *zName = pTab->zName;
|
||||
int nName = strlen(zName) + 1;
|
||||
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
|
||||
if( pOld ){
|
||||
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,4 +238,42 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){
|
||||
pParse->zArg[pParse->nArgUsed] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is invoked by the vdbe to call the xCreate method
|
||||
** of the virtual table named zTab in database iDb.
|
||||
**
|
||||
** If an error occurs, *pzErr is set to point an an English language
|
||||
** description of the error and an SQLITE_XXX error code is returned.
|
||||
** In this case the caller must call sqliteFree() on *pzErr.
|
||||
*/
|
||||
int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
|
||||
int rc = SQLITE_OK;
|
||||
Table *pTab;
|
||||
sqlite3_module *pModule;
|
||||
|
||||
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
|
||||
assert(pTab && pTab->isVirtual);
|
||||
pModule = pTab->pModule;
|
||||
const char *zModule = pTab->azModuleArg[0];
|
||||
|
||||
/* If the module has been registered and includes a Create method,
|
||||
** invoke it now. If the module has not been registered, return an
|
||||
** error. Otherwise, do nothing.
|
||||
*/
|
||||
if( !pModule ){
|
||||
*pzErr = sqlite3MPrintf("unknown module: %s", zModule);
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( pModule->xCreate ){
|
||||
/* TODO: Maybe the above condition should refer to pTable->needCreate. */
|
||||
char **azArg = pTab->azModuleArg;
|
||||
int nArg = pTab->nModuleArg;
|
||||
rc = pModule->xCreate(db, pModule, nArg, azArg, &pTab->pVtab);
|
||||
}
|
||||
|
||||
if( SQLITE_OK==rc ){
|
||||
pTab->needCreate = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
@ -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.1 2006/06/11 23:41:56 drh Exp $
|
||||
# $Id: vtab1.test,v 1.2 2006/06/12 06:09:19 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
@ -35,7 +35,6 @@ do_test vtab1-1.2 {
|
||||
#
|
||||
do_test vtab1-1.3 {
|
||||
register_echo_module [sqlite3_connection_pointer db]
|
||||
execsql {pragma vdbe_listing=on; pragma vdbe_trace=on}
|
||||
catchsql {
|
||||
CREATE VIRTUAL TABLE t1 USING echo;
|
||||
}
|
||||
@ -49,5 +48,4 @@ do_test vtab1-1.5 {
|
||||
}
|
||||
} {t1 {CREATE VIRTUAL TABLE t1 USING echo}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user