Basic parsing of CREATE VIRTUAL TABLE statements. (CVS 3210)
FossilOrigin-Name: 66370cb99bd93abb33e1e8433672da45e1795f78
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
39e3427813135601a7417c96e55b410fa89ac1f5
|
||||
66370cb99bd93abb33e1e8433672da45e1795f78
|
||||
+7
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -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
|
||||
|
||||
+63
-1
@@ -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.
|
||||
|
||||
+7
-1
@@ -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;
|
||||
};
|
||||
|
||||
+39
-4
@@ -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 */
|
||||
|
||||
+25
-11
@@ -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];
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user