]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Incremental work on parsing/storing and invoking the xCreate callback for virtual...
authordanielk1977 <danielk1977@noemail.net>
Mon, 12 Jun 2006 06:09:17 +0000 (06:09 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 12 Jun 2006 06:09:17 +0000 (06:09 +0000)
FossilOrigin-Name: 8ffbab79d5a76dea0f87cf551d5b6ad4f0fab337

manifest
manifest.uuid
src/prepare.c
src/sqliteInt.h
src/test8.c
src/vdbe.c
src/vtab.c
test/vtab1.test

index 6a0c4f192a4407d395b19d60d67736d1efea2c2d..823fad00dbb688f92b97d6e311b9e6c75a5f3274 100644 (file)
--- a/manifest
+++ b/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
index cb8e1fd491d98c0726a1895ef5cf01267c769fb1..adbc054d49b182c7024640961e5288bb1638b66c 100644 (file)
@@ -1 +1 @@
-898ec36b4102aaa03979f8f5c510936e57e2ae48
\ No newline at end of file
+8ffbab79d5a76dea0f87cf551d5b6ad4f0fab337
\ No newline at end of file
index 582cff08617e094dbdfe8f8dbd766c909ab3a4c3..d4c752a7c65178cfbe4376e2cc03086175bd5556 100644 (file)
@@ -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.
index 9a2de48755875f3ed2593f2b13c066b205874edd..de904fb3b9befb1d1879e882b914363caf6da151 100644 (file)
@@ -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"
index c0d08a4695399e2900ebf7a974b09d82f7f6f9e5..97e848346052d7d1204cbd156f8d68db6fe6c7ea 100644 (file)
@@ -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"
 #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,
 };
index a85d303153a2b88e82cd8f40749e87b339eed733..86796fce602bad44b9a8d2a5fbeb66279e8f3d09 100644 (file)
@@ -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: {
index d7d7515bd026a51d813ccbe49114483a89d38074..bd43e567ce70f0868c9805f8d0b29b1bdbd19c35 100644 (file)
@@ -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 */
index 18e034f159497865319dc5bd2691f8b17d207ffb..84e20048bfac7aed73a77fa2ab0b7a9066c9afd0 100644 (file)
@@ -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