]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Basic parsing of CREATE VIRTUAL TABLE statements. (CVS 3210)
authordrh <drh@noemail.net>
Sat, 10 Jun 2006 13:29:31 +0000 (13:29 +0000)
committerdrh <drh@noemail.net>
Sat, 10 Jun 2006 13:29:31 +0000 (13:29 +0000)
FossilOrigin-Name: 66370cb99bd93abb33e1e8433672da45e1795f78

manifest
manifest.uuid
src/build.c
src/parse.y
src/sqlite.h.in
src/sqliteInt.h
tool/lemon.c
tool/lempar.c
tool/mkkeywordhash.c

index fd6933a15e39ca5bf206f77319b064ecca32a4f7..d87618f2c194f679a510e4f241eac99dea6b07c6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C In\sthe\sshell,\smake\ssure\sthe\sdatabase\sis\sopened\sbefore\strying\sto\sdo\nan\s".import".\s\sBug\sreported\son\sthe\smailing\slist.\s(CVS\s3209)
-D 2006-06-08T16:10:15
+C Basic\sparsing\sof\sCREATE\sVIRTUAL\sTABLE\sstatements.\s(CVS\s3210)
+D 2006-06-10T13:29:32
 F Makefile.in 50d948a8c4eda30ebb5799b661bd4c2de11824d0
 F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -36,7 +36,7 @@ F src/attach.c 27a31d3b89d7ebb5b358847607b1ec795384123c
 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
 F src/btree.c ed343b3dbcbc7da9ac481ef2b98c4239fe6d9629
 F src/btree.h 40055cfc09defd1146bc5b922399c035f969e56d
-F src/build.c eefefdc88cb342bc0f7cb41ccdf3930739ab50e9
+F src/build.c a64e4765ca1148e191742af306db5b70d821d0c9
 F src/callback.c fd9bb39f7ff6b52bad8365617abc61c720640429
 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
@@ -64,7 +64,7 @@ F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c ddd05666bb89808a516baef2c186d6a75887ae90
 F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818
-F src/parse.y 50ab45ec8e01a90cb5d75f53ce4bf95f0ca10481
+F src/parse.y 79c324627c8145d307a80a13fb18be1d1d63dff8
 F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55
 F src/prepare.c bbf12d3147116b284b157232efaef3bbe5df08fc
 F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240
@@ -72,9 +72,9 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
 F src/select.c 8daba07a04a6d41f5267ea8353324cbe5a210e14
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c b9eb3ed4d3ab41fbf630eabb602f3c9d20fc737a
-F src/sqlite.h.in d33c4688ba292af5f84fea49b2e3946b9129673a
+F src/sqlite.h.in fadc690a16e8da1215d3f4bdf6a2501e41516c25
 F src/sqlite3ext.h 127bd394c8eea481f2ac9b754bf399dbfc818b75
-F src/sqliteInt.h 029ae294180139e3ead077b548dd9e08f99010aa
+F src/sqliteInt.h c1c752970e90570750be529d9d22111211614381
 F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e
 F src/tclsqlite.c 5ae9f08f7af7fe80d38fbccc4f5359f272643af1
 F src/test1.c becd9202b733debc607b5aec43002769730e1f71
@@ -289,12 +289,12 @@ F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df
 F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394
 F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
-F tool/lemon.c b0b881c172b5375444ef1c13d80ab01efec3605e
-F tool/lempar.c 5112eda4ad6dc8694b6a68004542da174b436ad9
+F tool/lemon.c 64aa2436ef7fcc1a6dc49bf205225a542fc05c48
+F tool/lempar.c 880cc102baa30c521498b15f6de34dc4b2d56972
 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
 F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
-F tool/mkkeywordhash.c a36f0f5e0168e8f37d0771fb4331f5f462326940
+F tool/mkkeywordhash.c 966af86ab29e2d152eebd40dfd9c8f45b3f0716b
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
 F tool/omittest.tcl 3d07c8f67e7e6c369b07d31d97aaa3e434f0e9e7
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
@@ -360,7 +360,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 327e6909c9d35b651ab6f3a1a270022b354538c6
-R 021001a8617a3717aaf8a0dc8bd5a726
+P 39e3427813135601a7417c96e55b410fa89ac1f5
+R ca50c82454da9812f6118b6e9d547ee0
 U drh
-Z b4d12d966b938862d92a3ccf0d06a9d1
+Z 20f490cb0723888395733c25c97f6fa4
index 66d4fd919215d56b58feb0242536f5797d95de4b..cd1dbfe70c20211277757b949bf6ce4c909c1825 100644 (file)
@@ -1 +1 @@
-39e3427813135601a7417c96e55b410fa89ac1f5
\ No newline at end of file
+66370cb99bd93abb33e1e8433672da45e1795f78
\ No newline at end of file
index 343c87525d00b9b6a36529619e4227ed4c9847d7..74cf00accc242961714c65c1ac1d2facf7a1a6c3 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.394 2006/05/11 23:14:59 drh Exp $
+** $Id: build.c,v 1.395 2006/06/10 13:29:32 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -533,6 +533,12 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
 #ifndef SQLITE_OMIT_CHECK
   sqlite3ExprDelete(pTable->pCheck);
 #endif
+#ifndef SQLITE_OMIT_MODULE
+  sqliteFree(pTable->zModuleName);
+  if( pTable->pMod && pTable->pVTab ){
+    pTable->pMod->xDisconnect(pTable->pVTab);
+  }
+#endif SQLITE_OMIT_MODULE
   sqliteFree(pTable);
 }
 
index dd25152777cadc9f236b7f671a4f485b26895a49..922d4730b8159118d2accd86d3f2be0e5ee81f23 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.200 2006/05/25 12:17:31 drh Exp $
+** @(#) $Id: parse.y,v 1.201 2006/06/10 13:29:33 drh Exp $
 */
 
 // All token codes are small integers with #defines that begin with "TK_"
@@ -176,12 +176,13 @@ id(A) ::= ID(X).         {A = X;}
   DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
   IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN QUERY KEY
   OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
-  TEMP TRIGGER VACUUM VIEW
+  TEMP TRIGGER VACUUM VIEW VIRTUAL
 %ifdef SQLITE_OMIT_COMPOUND_SELECT
   EXCEPT INTERSECT UNION
 %endif
   REINDEX RENAME CTIME_KW IF
   .
+%wildcard ANY.
 
 // Define operator precedence early so that this is the first occurance
 // of the operator tokens in the grammer.  Keeping the operators together
@@ -1058,3 +1059,14 @@ add_column_fullname ::= fullname(X). {
 kwcolumn_opt ::= .
 kwcolumn_opt ::= COLUMNKW.
 %endif
+
+//////////////////////// CREATE VIRTUAL TABLE ... /////////////////////////////
+%ifndef SQLITE_OMIT_VIRTUALTABLE
+cmd ::= CREATE VIRTUAL TABLE nm(X) dbnm(Y) USING nm(Z) vtabargsopt.
+vtabargsopt ::= .
+vtabargsopt ::= LP vtabarglist RP.
+vtabarglist ::= vtabarg.
+vtabarglist ::= vtabarglist COMMA vtabarg.
+vtabarg ::= ANY.
+vtabarg ::= vtabarg ANY.
+%endif
index 375e694d122a1cbffca0814025a42143e1faf786..6a25f67cc5e96c52a181e9096a41f32effc85676 100644 (file)
@@ -12,7 +12,7 @@
 ** This header file defines the interface that the SQLite library
 ** presents to client programs.
 **
-** @(#) $Id: sqlite.h.in,v 1.166 2006/06/08 15:28:44 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.167 2006/06/10 13:29:33 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1508,6 +1508,68 @@ int sqlite3_load_extension(
   char **pzErrMsg       /* Put error message here if not 0 */
 );
 
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+*/
+typedef struct sqlite3_vtab sqlite3_vtab;
+typedef struct sqlite3_index_info sqlite3_index_info;
+typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor;
+typedef struct sqlite3_module sqlite3_module;
+struct sqlite3_module {
+  int iVersion;
+  void *pAux;
+  int (*xCreate)(sqlite3*, const sqlite3_module *pModule,
+               int argc, char **argv,
+               sqlite3_vtab **ppVTab);
+  int (*xConnect)(sqlite3*, const sqlite3_module *pModule,
+               int argc, char **argv,
+               sqlite3_vtab **ppVTab);
+  int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
+  int (*xDisconnect)(sqlite3_vtab *pVTab);
+  int (*xDestroy)(sqlite3_vtab *pVTab);
+  int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor);
+  int (*xClose)(sqlite3_vtab_cursor*);
+  int (*xFilter)(sqlite3_vtab_cursor*, int idx,
+                int argc, sqlite3_value **argv);
+  int (*xNext)(sqlite3_vtab_cursor*);
+  int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int);
+  int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid);
+  int (*xInsert)(sqlite3_vtab *pVTab, sqlite3_value **apData);
+  int (*xDelete)(sqlite3_vtab *pVTab, sqlite_int64 rowid);
+  int (*xBegin)(sqlite3_vtab *pVTab);
+  int (*xSync)(sqlite3_vtab *pVTab);
+  int (*xCommit)(sqlite3_vtab *pVTab);
+  int (*xRollback)(sqlite3_vtab *pVTab);
+  int (*xIsInTrans)(sqlite3_vtab *pVTab);
+};
+struct sqlite3_index_info {
+  /* Inputs */
+  int nConstraint;
+  struct sqlite3_index_constraint {
+     int iColumn;
+     unsigned char op;
+     unsigned char omit;
+  } *aConstraint;
+  int nOrderBy;
+  struct sqlite3_index_orderby {
+     int iColumn;
+     unsigned char desc;
+  } *aOrderBy;
+
+  /* Outputs */
+  int idxNum;
+  int columnCount;
+  int *aColumn;
+  int orderByConsumed;
+};
+#define SQLITE_INDEX_CONSTRAINT_EQ    1
+#define SQLITE_INDEX_CONSTRAINT_GT    3
+#define SQLITE_INDEX_CONSTRAINT_LE    4
+#define SQLITE_INDEX_CONSTRAINT_LT    5
+#define SQLITE_INDEX_CONSTRAINT_GE    6
+#define SQLITE_INDEX_CONSTRAINT_MATCH 7
+
+
 /*
 ** Undo the hack that converts floating point types to integer for
 ** builds on processors without floating point support.
index 44210e3604bcb4ba6c96824595e14f00d9457f59..6e78e07826868fac5cf0a4666ed6dd2901678cc1 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.495 2006/06/08 15:48:01 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.496 2006/06/10 13:29:33 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -702,6 +702,12 @@ struct Table {
 #endif
 #ifndef SQLITE_OMIT_ALTERTABLE
   int addColOffset;  /* Offset in CREATE TABLE statement to add a new column */
+#endif
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+  char *zModuleName;     /* Name of module implementing this virtual table */
+  sqlite3_module *pMod;  /* Pointer to the implementation of the module */
+  sqlite3_vtab *pVTab;   /* Pointer to the module instance */
+  u8 needCreate;         /* Need to call pMod->xCreate() */
 #endif
   Schema *pSchema;
 };
index 3d5a3d14480465f3af4b00075c90a2beee6c57a3..f7c12814bc0174835a64750cb8caad5e19dcc2a3 100644 (file)
@@ -241,6 +241,7 @@ struct lemon {
   struct symbol **symbols; /* Sorted array of pointers to symbols */
   int errorcnt;            /* Number of errors */
   struct symbol *errsym;   /* The error symbol */
+  struct symbol *wildcard; /* Token that matches anything */
   char *name;              /* Name of the generated parser */
   char *arg;               /* Declaration of the 3th argument to parser */
   char *tokentype;         /* Type of terminal symbols in the parser stack */
@@ -1442,6 +1443,7 @@ char **argv;
   lem.tablesize = 0;
   Symbol_new("$");
   lem.errsym = Symbol_new("error");
+  lem.wildcard = 0;
 
   /* Parse the input file */
   Parse(&lem);
@@ -1960,7 +1962,8 @@ struct pstate {
     RESYNC_AFTER_DECL_ERROR,
     WAITING_FOR_DESTRUCTOR_SYMBOL,
     WAITING_FOR_DATATYPE_SYMBOL,
-    WAITING_FOR_FALLBACK_ID
+    WAITING_FOR_FALLBACK_ID,
+    WAITING_FOR_WILDCARD_ID
   } state;                   /* The state of the parser */
   struct symbol *fallback;   /* The fallback token */
   struct symbol *lhs;        /* Left-hand side of current rule */
@@ -2264,6 +2267,8 @@ to follow the previous rule.");
         }else if( strcmp(x,"fallback")==0 ){
           psp->fallback = 0;
           psp->state = WAITING_FOR_FALLBACK_ID;
+        }else if( strcmp(x,"wildcard")==0 ){
+          psp->state = WAITING_FOR_WILDCARD_ID;
         }else{
           ErrorMsg(psp->filename,psp->tokenlineno,
             "Unknown declaration keyword: \"%%%s\".",x);
@@ -2364,6 +2369,24 @@ to follow the previous rule.");
         }
       }
       break;
+    case WAITING_FOR_WILDCARD_ID:
+      if( x[0]=='.' ){
+        psp->state = WAITING_FOR_DECL_OR_RULE;
+      }else if( !isupper(x[0]) ){
+        ErrorMsg(psp->filename, psp->tokenlineno,
+          "%%wildcard argument \"%s\" should be a token", x);
+        psp->errorcnt++;
+      }else{
+        struct symbol *sp = Symbol_new(x);
+        if( psp->gp->wildcard==0 ){
+          psp->gp->wildcard = sp;
+        }else{
+          ErrorMsg(psp->filename, psp->tokenlineno,
+            "Extra wildcard to token: %s", x);
+          psp->errorcnt++;
+        }
+      }
+      break;
     case RESYNC_AFTER_RULE_ERROR:
 /*      if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
 **      break; */
@@ -3489,6 +3512,10 @@ int mhflag;     /* Output in makeheaders format if true */
   fprintf(out,"#define YYNOCODE %d\n",lemp->nsymbol+1);  lineno++;
   fprintf(out,"#define YYACTIONTYPE %s\n",
     minimum_size_type(0, lemp->nstate+lemp->nrule+5));  lineno++;
+  if( lemp->wildcard ){
+    fprintf(out,"#define YYWILDCARD %d\n",
+       lemp->wildcard->index); lineno++;
+  }
   print_stack_union(out,lemp,&lineno,mhflag);
   if( lemp->stacksize ){
     if( atoi(lemp->stacksize)<=0 ){
@@ -3885,7 +3912,8 @@ struct lemon *lemp;
 ** of defaults.
 **
 ** In this version, we take the most frequent REDUCE action and make
-** it the default.
+** it the default.  Except, there is no default if the wildcard token
+** is a possible look-ahead.
 */
 void CompressTables(lemp)
 struct lemon *lemp;
@@ -3895,13 +3923,18 @@ struct lemon *lemp;
   struct rule *rp, *rp2, *rbest;
   int nbest, n;
   int i;
+  int usesWildcard;
 
   for(i=0; i<lemp->nstate; i++){
     stp = lemp->sorted[i];
     nbest = 0;
     rbest = 0;
+    usesWildcard = 0;
 
     for(ap=stp->ap; ap; ap=ap->next){
+      if( ap->type==SHIFT && ap->sp==lemp->wildcard ){
+        usesWildcard = 1;
+      }
       if( ap->type!=REDUCE ) continue;
       rp = ap->x.rp;
       if( rp==rbest ) continue;
@@ -3919,8 +3952,10 @@ struct lemon *lemp;
     }
  
     /* Do not make a default if the number of rules to default
-    ** is not at least 1 */
-    if( nbest<1 ) continue;
+    ** is not at least 1 or if the wildcard token is a possible
+    ** lookahead.
+    */
+    if( nbest<1 || usesWildcard ) continue;
 
 
     /* Combine matching REDUCE actions into a single default */
index fb1e5c01cea1f10f667d6ada1cb724c82469d07a..c220e0ff6bf0741b26a7194860553765da07850f 100644 (file)
@@ -334,19 +334,33 @@ static int yy_find_shift_action(
   }
   i += iLookAhead;
   if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
-#ifdef YYFALLBACK
-    int iFallback;            /* Fallback token */
-    if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
-           && (iFallback = yyFallback[iLookAhead])!=0 ){
-#ifndef NDEBUG
-      if( yyTraceFILE ){
-        fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
-           yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+    if( iLookAhead>0 ){
+  #ifdef YYFALLBACK
+      int iFallback;            /* Fallback token */
+      if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+             && (iFallback = yyFallback[iLookAhead])!=0 ){
+  #ifndef NDEBUG
+        if( yyTraceFILE ){
+          fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+             yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+        }
+  #endif
+        return yy_find_shift_action(pParser, iFallback);
       }
-#endif
-      return yy_find_shift_action(pParser, iFallback);
+  #endif
+  #ifdef YYWILDCARD
+      int j = i - iLookAhead + YYWILDCARD;
+      if( j>=0 && j<YY_SZ_ACTTAB && yy_lookahead[j]==YYWILDCARD ){
+  #ifndef NDEBUG
+        if( yyTraceFILE ){
+          fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+             yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
+        }
+  #endif
+        return yy_action[j];
+      }
+  #endif
     }
-#endif
     return yy_default[stateno];
   }else{
     return yy_action[i];
index 8bbefa14fdca888ee17ea02c8a63d1ea3324d155..a1df7827cd8c418ffbbce991677f4c60117a5517 100644 (file)
@@ -105,7 +105,11 @@ struct Keyword {
 #else
 #  define VIEW       0x00008000
 #endif
-
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+#  define VTAB       0
+#else
+#  define VTAB       0x00010000
+#endif
 
 /*
 ** These are the keywords
@@ -225,6 +229,7 @@ static Keyword aKeywordTable[] = {
   { "VACUUM",           "TK_VACUUM",       VACUUM                 },
   { "VALUES",           "TK_VALUES",       ALWAYS                 },
   { "VIEW",             "TK_VIEW",         VIEW                   },
+  { "VIRTUAL",          "TK_VIRTUAL",      VTAB                   },
   { "WHEN",             "TK_WHEN",         ALWAYS                 },
   { "WHERE",            "TK_WHERE",        ALWAYS                 },
 };