xref: /titanic_53/usr/src/lib/libsqlite/src/parse.y (revision c5c4113dfcabb1eed3d4bdf7609de5170027a794)
1*c5c4113dSnw141292 /*
2*c5c4113dSnw141292 ** 2001 September 15
3*c5c4113dSnw141292 **
4*c5c4113dSnw141292 ** The author disclaims copyright to this source code.  In place of
5*c5c4113dSnw141292 ** a legal notice, here is a blessing:
6*c5c4113dSnw141292 **
7*c5c4113dSnw141292 **    May you do good and not evil.
8*c5c4113dSnw141292 **    May you find forgiveness for yourself and forgive others.
9*c5c4113dSnw141292 **    May you share freely, never taking more than you give.
10*c5c4113dSnw141292 **
11*c5c4113dSnw141292 *************************************************************************
12*c5c4113dSnw141292 ** This file contains SQLite's grammar for SQL.  Process this file
13*c5c4113dSnw141292 ** using the lemon parser generator to generate C code that runs
14*c5c4113dSnw141292 ** the parser.  Lemon will also generate a header file containing
15*c5c4113dSnw141292 ** numeric codes for all of the tokens.
16*c5c4113dSnw141292 **
17*c5c4113dSnw141292 ** @(#) $Id: parse.y,v 1.112 2004/02/22 18:40:57 drh Exp $
18*c5c4113dSnw141292 */
19*c5c4113dSnw141292 %token_prefix TK_
20*c5c4113dSnw141292 %token_type {Token}
21*c5c4113dSnw141292 %default_type {Token}
22*c5c4113dSnw141292 %extra_argument {Parse *pParse}
23*c5c4113dSnw141292 %syntax_error {
24*c5c4113dSnw141292   if( pParse->zErrMsg==0 ){
25*c5c4113dSnw141292     if( TOKEN.z[0] ){
26*c5c4113dSnw141292       sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
27*c5c4113dSnw141292     }else{
28*c5c4113dSnw141292       sqliteErrorMsg(pParse, "incomplete SQL statement");
29*c5c4113dSnw141292     }
30*c5c4113dSnw141292   }
31*c5c4113dSnw141292 }
32*c5c4113dSnw141292 %name sqliteParser
33*c5c4113dSnw141292 %include {
34*c5c4113dSnw141292 
35*c5c4113dSnw141292 #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*c5c4113dSnw141292 
37*c5c4113dSnw141292 #include "sqliteInt.h"
38*c5c4113dSnw141292 #include "parse.h"
39*c5c4113dSnw141292 
40*c5c4113dSnw141292 /*
41*c5c4113dSnw141292 ** An instance of this structure holds information about the
42*c5c4113dSnw141292 ** LIMIT clause of a SELECT statement.
43*c5c4113dSnw141292 */
44*c5c4113dSnw141292 struct LimitVal {
45*c5c4113dSnw141292   int limit;    /* The LIMIT value.  -1 if there is no limit */
46*c5c4113dSnw141292   int offset;   /* The OFFSET.  0 if there is none */
47*c5c4113dSnw141292 };
48*c5c4113dSnw141292 
49*c5c4113dSnw141292 /*
50*c5c4113dSnw141292 ** An instance of the following structure describes the event of a
51*c5c4113dSnw141292 ** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
52*c5c4113dSnw141292 ** TK_DELETE, or TK_INSTEAD.  If the event is of the form
53*c5c4113dSnw141292 **
54*c5c4113dSnw141292 **      UPDATE ON (a,b,c)
55*c5c4113dSnw141292 **
56*c5c4113dSnw141292 ** Then the "b" IdList records the list "a,b,c".
57*c5c4113dSnw141292 */
58*c5c4113dSnw141292 struct TrigEvent { int a; IdList * b; };
59*c5c4113dSnw141292 
60*c5c4113dSnw141292 } // end %include
61*c5c4113dSnw141292 
62*c5c4113dSnw141292 // These are extra tokens used by the lexer but never seen by the
63*c5c4113dSnw141292 // parser.  We put them in a rule so that the parser generator will
64*c5c4113dSnw141292 // add them to the parse.h output file.
65*c5c4113dSnw141292 //
66*c5c4113dSnw141292 %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
67*c5c4113dSnw141292           COLUMN AGG_FUNCTION.
68*c5c4113dSnw141292 
69*c5c4113dSnw141292 // Input is a single SQL command
70*c5c4113dSnw141292 input ::= cmdlist.
71*c5c4113dSnw141292 cmdlist ::= cmdlist ecmd.
72*c5c4113dSnw141292 cmdlist ::= ecmd.
73*c5c4113dSnw141292 ecmd ::= explain cmdx SEMI.
74*c5c4113dSnw141292 ecmd ::= SEMI.
75*c5c4113dSnw141292 cmdx ::= cmd.           { sqliteExec(pParse); }
76*c5c4113dSnw141292 explain ::= EXPLAIN.    { sqliteBeginParse(pParse, 1); }
77*c5c4113dSnw141292 explain ::= .           { sqliteBeginParse(pParse, 0); }
78*c5c4113dSnw141292 
79*c5c4113dSnw141292 ///////////////////// Begin and end transactions. ////////////////////////////
80*c5c4113dSnw141292 //
81*c5c4113dSnw141292 
onconf(R)82*c5c4113dSnw141292 cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
83*c5c4113dSnw141292 trans_opt ::= .
84*c5c4113dSnw141292 trans_opt ::= TRANSACTION.
85*c5c4113dSnw141292 trans_opt ::= TRANSACTION nm.
86*c5c4113dSnw141292 cmd ::= COMMIT trans_opt.      {sqliteCommitTransaction(pParse);}
87*c5c4113dSnw141292 cmd ::= END trans_opt.         {sqliteCommitTransaction(pParse);}
88*c5c4113dSnw141292 cmd ::= ROLLBACK trans_opt.    {sqliteRollbackTransaction(pParse);}
89*c5c4113dSnw141292 
90*c5c4113dSnw141292 ///////////////////// The CREATE TABLE statement ////////////////////////////
91*c5c4113dSnw141292 //
92*c5c4113dSnw141292 cmd ::= create_table create_table_args.
CREATE(X)93*c5c4113dSnw141292 create_table ::= CREATE(X) temp(T) TABLE nm(Y). {
94*c5c4113dSnw141292    sqliteStartTable(pParse,&X,&Y,T,0);
95*c5c4113dSnw141292 }
96*c5c4113dSnw141292 %type temp {int}
temp(A)97*c5c4113dSnw141292 temp(A) ::= TEMP.  {A = 1;}
temp(A)98*c5c4113dSnw141292 temp(A) ::= .      {A = 0;}
RP(X)99*c5c4113dSnw141292 create_table_args ::= LP columnlist conslist_opt RP(X). {
100*c5c4113dSnw141292   sqliteEndTable(pParse,&X,0);
101*c5c4113dSnw141292 }
select(S)102*c5c4113dSnw141292 create_table_args ::= AS select(S). {
103*c5c4113dSnw141292   sqliteEndTable(pParse,0,S);
104*c5c4113dSnw141292   sqliteSelectDelete(S);
105*c5c4113dSnw141292 }
106*c5c4113dSnw141292 columnlist ::= columnlist COMMA column.
107*c5c4113dSnw141292 columnlist ::= column.
108*c5c4113dSnw141292 
109*c5c4113dSnw141292 // About the only information used for a column is the name of the
110*c5c4113dSnw141292 // column.  The type is always just "text".  But the code will accept
111*c5c4113dSnw141292 // an elaborate typename.  Perhaps someday we'll do something with it.
112*c5c4113dSnw141292 //
113*c5c4113dSnw141292 column ::= columnid type carglist.
nm(X)114*c5c4113dSnw141292 columnid ::= nm(X).                {sqliteAddColumn(pParse,&X);}
115*c5c4113dSnw141292 
116*c5c4113dSnw141292 // An IDENTIFIER can be a generic identifier, or one of several
117*c5c4113dSnw141292 // keywords.  Any non-standard keyword can also be an identifier.
118*c5c4113dSnw141292 //
119*c5c4113dSnw141292 %type id {Token}
id(A)120*c5c4113dSnw141292 id(A) ::= ID(X).         {A = X;}
121*c5c4113dSnw141292 
122*c5c4113dSnw141292 // The following directive causes tokens ABORT, AFTER, ASC, etc. to
123*c5c4113dSnw141292 // fallback to ID if they will not parse as their original value.
124*c5c4113dSnw141292 // This obviates the need for the "id" nonterminal.
125*c5c4113dSnw141292 //
126*c5c4113dSnw141292 %fallback ID
127*c5c4113dSnw141292   ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT
128*c5c4113dSnw141292   COPY DATABASE DEFERRED DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR
129*c5c4113dSnw141292   GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
130*c5c4113dSnw141292   OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
131*c5c4113dSnw141292   TEMP TRIGGER VACUUM VIEW.
132*c5c4113dSnw141292 
133*c5c4113dSnw141292 // Define operator precedence early so that this is the first occurance
134*c5c4113dSnw141292 // of the operator tokens in the grammer.  Keeping the operators together
135*c5c4113dSnw141292 // causes them to be assigned integer values that are close together,
136*c5c4113dSnw141292 // which keeps parser tables smaller.
137*c5c4113dSnw141292 //
138*c5c4113dSnw141292 %left OR.
139*c5c4113dSnw141292 %left AND.
140*c5c4113dSnw141292 %right NOT.
141*c5c4113dSnw141292 %left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
142*c5c4113dSnw141292 %left GT GE LT LE.
143*c5c4113dSnw141292 %left BITAND BITOR LSHIFT RSHIFT.
144*c5c4113dSnw141292 %left PLUS MINUS.
145*c5c4113dSnw141292 %left STAR SLASH REM.
146*c5c4113dSnw141292 %left CONCAT.
147*c5c4113dSnw141292 %right UMINUS UPLUS BITNOT.
148*c5c4113dSnw141292 
149*c5c4113dSnw141292 // And "ids" is an identifer-or-string.
150*c5c4113dSnw141292 //
151*c5c4113dSnw141292 %type ids {Token}
ids(A)152*c5c4113dSnw141292 ids(A) ::= ID(X).        {A = X;}
ids(A)153*c5c4113dSnw141292 ids(A) ::= STRING(X).    {A = X;}
154*c5c4113dSnw141292 
155*c5c4113dSnw141292 // The name of a column or table can be any of the following:
156*c5c4113dSnw141292 //
157*c5c4113dSnw141292 %type nm {Token}
nm(A)158*c5c4113dSnw141292 nm(A) ::= ID(X).         {A = X;}
nm(A)159*c5c4113dSnw141292 nm(A) ::= STRING(X).     {A = X;}
nm(A)160*c5c4113dSnw141292 nm(A) ::= JOIN_KW(X).    {A = X;}
161*c5c4113dSnw141292 
162*c5c4113dSnw141292 type ::= .
typename(X)163*c5c4113dSnw141292 type ::= typename(X).                    {sqliteAddColumnType(pParse,&X,&X);}
typename(X)164*c5c4113dSnw141292 type ::= typename(X) LP signed RP(Y).    {sqliteAddColumnType(pParse,&X,&Y);}
typename(X)165*c5c4113dSnw141292 type ::= typename(X) LP signed COMMA signed RP(Y).
166*c5c4113dSnw141292                                          {sqliteAddColumnType(pParse,&X,&Y);}
167*c5c4113dSnw141292 %type typename {Token}
typename(A)168*c5c4113dSnw141292 typename(A) ::= ids(X).           {A = X;}
typename(A)169*c5c4113dSnw141292 typename(A) ::= typename(X) ids.  {A = X;}
170*c5c4113dSnw141292 %type signed {int}
INTEGER(X)171*c5c4113dSnw141292 signed(A) ::= INTEGER(X).         { A = atoi(X.z); }
INTEGER(X)172*c5c4113dSnw141292 signed(A) ::= PLUS INTEGER(X).    { A = atoi(X.z); }
INTEGER(X)173*c5c4113dSnw141292 signed(A) ::= MINUS INTEGER(X).   { A = -atoi(X.z); }
174*c5c4113dSnw141292 carglist ::= carglist carg.
175*c5c4113dSnw141292 carglist ::= .
176*c5c4113dSnw141292 carg ::= CONSTRAINT nm ccons.
177*c5c4113dSnw141292 carg ::= ccons.
STRING(X)178*c5c4113dSnw141292 carg ::= DEFAULT STRING(X).          {sqliteAddDefaultValue(pParse,&X,0);}
ID(X)179*c5c4113dSnw141292 carg ::= DEFAULT ID(X).              {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)180*c5c4113dSnw141292 carg ::= DEFAULT INTEGER(X).         {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)181*c5c4113dSnw141292 carg ::= DEFAULT PLUS INTEGER(X).    {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)182*c5c4113dSnw141292 carg ::= DEFAULT MINUS INTEGER(X).   {sqliteAddDefaultValue(pParse,&X,1);}
FLOAT(X)183*c5c4113dSnw141292 carg ::= DEFAULT FLOAT(X).           {sqliteAddDefaultValue(pParse,&X,0);}
FLOAT(X)184*c5c4113dSnw141292 carg ::= DEFAULT PLUS FLOAT(X).      {sqliteAddDefaultValue(pParse,&X,0);}
FLOAT(X)185*c5c4113dSnw141292 carg ::= DEFAULT MINUS FLOAT(X).     {sqliteAddDefaultValue(pParse,&X,1);}
186*c5c4113dSnw141292 carg ::= DEFAULT NULL.
187*c5c4113dSnw141292 
188*c5c4113dSnw141292 // In addition to the type name, we also care about the primary key and
189*c5c4113dSnw141292 // UNIQUE constraints.
190*c5c4113dSnw141292 //
191*c5c4113dSnw141292 ccons ::= NULL onconf.
onconf(R)192*c5c4113dSnw141292 ccons ::= NOT NULL onconf(R).               {sqliteAddNotNull(pParse, R);}
onconf(R)193*c5c4113dSnw141292 ccons ::= PRIMARY KEY sortorder onconf(R).  {sqliteAddPrimaryKey(pParse,0,R);}
onconf(R)194*c5c4113dSnw141292 ccons ::= UNIQUE onconf(R).           {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
195*c5c4113dSnw141292 ccons ::= CHECK LP expr RP onconf.
nm(T)196*c5c4113dSnw141292 ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
197*c5c4113dSnw141292                                 {sqliteCreateForeignKey(pParse,0,&T,TA,R);}
defer_subclause(D)198*c5c4113dSnw141292 ccons ::= defer_subclause(D).   {sqliteDeferForeignKey(pParse,D);}
id(C)199*c5c4113dSnw141292 ccons ::= COLLATE id(C).  {
200*c5c4113dSnw141292    sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
201*c5c4113dSnw141292 }
202*c5c4113dSnw141292 
203*c5c4113dSnw141292 // The next group of rules parses the arguments to a REFERENCES clause
204*c5c4113dSnw141292 // that determine if the referential integrity checking is deferred or
205*c5c4113dSnw141292 // or immediate and which determine what action to take if a ref-integ
206*c5c4113dSnw141292 // check fails.
207*c5c4113dSnw141292 //
208*c5c4113dSnw141292 %type refargs {int}
refargs(A)209*c5c4113dSnw141292 refargs(A) ::= .                     { A = OE_Restrict * 0x010101; }
refargs(A)210*c5c4113dSnw141292 refargs(A) ::= refargs(X) refarg(Y). { A = (X & Y.mask) | Y.value; }
211*c5c4113dSnw141292 %type refarg {struct {int value; int mask;}}
212*c5c4113dSnw141292 refarg(A) ::= MATCH nm.              { A.value = 0;     A.mask = 0x000000; }
213*c5c4113dSnw141292 refarg(A) ::= ON DELETE refact(X).   { A.value = X;     A.mask = 0x0000ff; }
214*c5c4113dSnw141292 refarg(A) ::= ON UPDATE refact(X).   { A.value = X<<8;  A.mask = 0x00ff00; }
215*c5c4113dSnw141292 refarg(A) ::= ON INSERT refact(X).   { A.value = X<<16; A.mask = 0xff0000; }
216*c5c4113dSnw141292 %type refact {int}
217*c5c4113dSnw141292 refact(A) ::= SET NULL.              { A = OE_SetNull; }
218*c5c4113dSnw141292 refact(A) ::= SET DEFAULT.           { A = OE_SetDflt; }
219*c5c4113dSnw141292 refact(A) ::= CASCADE.               { A = OE_Cascade; }
220*c5c4113dSnw141292 refact(A) ::= RESTRICT.              { A = OE_Restrict; }
221*c5c4113dSnw141292 %type defer_subclause {int}
222*c5c4113dSnw141292 defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt(X).  {A = X;}
223*c5c4113dSnw141292 defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
224*c5c4113dSnw141292 %type init_deferred_pred_opt {int}
225*c5c4113dSnw141292 init_deferred_pred_opt(A) ::= .                       {A = 0;}
226*c5c4113dSnw141292 init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
227*c5c4113dSnw141292 init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}
228*c5c4113dSnw141292 
229*c5c4113dSnw141292 // For the time being, the only constraint we care about is the primary
230*c5c4113dSnw141292 // key and UNIQUE.  Both create indices.
231*c5c4113dSnw141292 //
232*c5c4113dSnw141292 conslist_opt ::= .
233*c5c4113dSnw141292 conslist_opt ::= COMMA conslist.
234*c5c4113dSnw141292 conslist ::= conslist COMMA tcons.
235*c5c4113dSnw141292 conslist ::= conslist tcons.
236*c5c4113dSnw141292 conslist ::= tcons.
237*c5c4113dSnw141292 tcons ::= CONSTRAINT nm.
238*c5c4113dSnw141292 tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
239*c5c4113dSnw141292                                              {sqliteAddPrimaryKey(pParse,X,R);}
240*c5c4113dSnw141292 tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
241*c5c4113dSnw141292                                        {sqliteCreateIndex(pParse,0,0,X,R,0,0);}
242*c5c4113dSnw141292 tcons ::= CHECK expr onconf.
243*c5c4113dSnw141292 tcons ::= FOREIGN KEY LP idxlist(FA) RP
244*c5c4113dSnw141292           REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
245*c5c4113dSnw141292     sqliteCreateForeignKey(pParse, FA, &T, TA, R);
246*c5c4113dSnw141292     sqliteDeferForeignKey(pParse, D);
247*c5c4113dSnw141292 }
248*c5c4113dSnw141292 %type defer_subclause_opt {int}
249*c5c4113dSnw141292 defer_subclause_opt(A) ::= .                    {A = 0;}
250*c5c4113dSnw141292 defer_subclause_opt(A) ::= defer_subclause(X).  {A = X;}
251*c5c4113dSnw141292 
252*c5c4113dSnw141292 // The following is a non-standard extension that allows us to declare the
253*c5c4113dSnw141292 // default behavior when there is a constraint conflict.
254*c5c4113dSnw141292 //
255*c5c4113dSnw141292 %type onconf {int}
256*c5c4113dSnw141292 %type orconf {int}
257*c5c4113dSnw141292 %type resolvetype {int}
258*c5c4113dSnw141292 onconf(A) ::= .                              { A = OE_Default; }
259*c5c4113dSnw141292 onconf(A) ::= ON CONFLICT resolvetype(X).    { A = X; }
260*c5c4113dSnw141292 orconf(A) ::= .                              { A = OE_Default; }
261*c5c4113dSnw141292 orconf(A) ::= OR resolvetype(X).             { A = X; }
262*c5c4113dSnw141292 resolvetype(A) ::= ROLLBACK.                 { A = OE_Rollback; }
263*c5c4113dSnw141292 resolvetype(A) ::= ABORT.                    { A = OE_Abort; }
264*c5c4113dSnw141292 resolvetype(A) ::= FAIL.                     { A = OE_Fail; }
265*c5c4113dSnw141292 resolvetype(A) ::= IGNORE.                   { A = OE_Ignore; }
266*c5c4113dSnw141292 resolvetype(A) ::= REPLACE.                  { A = OE_Replace; }
267*c5c4113dSnw141292 
268*c5c4113dSnw141292 ////////////////////////// The DROP TABLE /////////////////////////////////////
269*c5c4113dSnw141292 //
270*c5c4113dSnw141292 cmd ::= DROP TABLE nm(X).          {sqliteDropTable(pParse,&X,0);}
271*c5c4113dSnw141292 
272*c5c4113dSnw141292 ///////////////////// The CREATE VIEW statement /////////////////////////////
273*c5c4113dSnw141292 //
274*c5c4113dSnw141292 cmd ::= CREATE(X) temp(T) VIEW nm(Y) AS select(S). {
275*c5c4113dSnw141292   sqliteCreateView(pParse, &X, &Y, S, T);
276*c5c4113dSnw141292 }
277*c5c4113dSnw141292 cmd ::= DROP VIEW nm(X). {
278*c5c4113dSnw141292   sqliteDropTable(pParse, &X, 1);
279*c5c4113dSnw141292 }
280*c5c4113dSnw141292 
281*c5c4113dSnw141292 //////////////////////// The SELECT statement /////////////////////////////////
282*c5c4113dSnw141292 //
283*c5c4113dSnw141292 cmd ::= select(X).  {
284*c5c4113dSnw141292   sqliteSelect(pParse, X, SRT_Callback, 0, 0, 0, 0);
285*c5c4113dSnw141292   sqliteSelectDelete(X);
286*c5c4113dSnw141292 }
287*c5c4113dSnw141292 
288*c5c4113dSnw141292 %type select {Select*}
289*c5c4113dSnw141292 %destructor select {sqliteSelectDelete($$);}
290*c5c4113dSnw141292 %type oneselect {Select*}
291*c5c4113dSnw141292 %destructor oneselect {sqliteSelectDelete($$);}
292*c5c4113dSnw141292 
293*c5c4113dSnw141292 select(A) ::= oneselect(X).                      {A = X;}
294*c5c4113dSnw141292 select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
295*c5c4113dSnw141292   if( Z ){
296*c5c4113dSnw141292     Z->op = Y;
297*c5c4113dSnw141292     Z->pPrior = X;
298*c5c4113dSnw141292   }
299*c5c4113dSnw141292   A = Z;
300*c5c4113dSnw141292 }
301*c5c4113dSnw141292 %type multiselect_op {int}
302*c5c4113dSnw141292 multiselect_op(A) ::= UNION.      {A = TK_UNION;}
303*c5c4113dSnw141292 multiselect_op(A) ::= UNION ALL.  {A = TK_ALL;}
304*c5c4113dSnw141292 multiselect_op(A) ::= INTERSECT.  {A = TK_INTERSECT;}
305*c5c4113dSnw141292 multiselect_op(A) ::= EXCEPT.     {A = TK_EXCEPT;}
306*c5c4113dSnw141292 oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
307*c5c4113dSnw141292                  groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
308*c5c4113dSnw141292   A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
309*c5c4113dSnw141292 }
310*c5c4113dSnw141292 
311*c5c4113dSnw141292 // The "distinct" nonterminal is true (1) if the DISTINCT keyword is
312*c5c4113dSnw141292 // present and false (0) if it is not.
313*c5c4113dSnw141292 //
314*c5c4113dSnw141292 %type distinct {int}
315*c5c4113dSnw141292 distinct(A) ::= DISTINCT.   {A = 1;}
316*c5c4113dSnw141292 distinct(A) ::= ALL.        {A = 0;}
317*c5c4113dSnw141292 distinct(A) ::= .           {A = 0;}
318*c5c4113dSnw141292 
319*c5c4113dSnw141292 // selcollist is a list of expressions that are to become the return
320*c5c4113dSnw141292 // values of the SELECT statement.  The "*" in statements like
321*c5c4113dSnw141292 // "SELECT * FROM ..." is encoded as a special expression with an
322*c5c4113dSnw141292 // opcode of TK_ALL.
323*c5c4113dSnw141292 //
324*c5c4113dSnw141292 %type selcollist {ExprList*}
325*c5c4113dSnw141292 %destructor selcollist {sqliteExprListDelete($$);}
326*c5c4113dSnw141292 %type sclp {ExprList*}
327*c5c4113dSnw141292 %destructor sclp {sqliteExprListDelete($$);}
328*c5c4113dSnw141292 sclp(A) ::= selcollist(X) COMMA.             {A = X;}
329*c5c4113dSnw141292 sclp(A) ::= .                                {A = 0;}
330*c5c4113dSnw141292 selcollist(A) ::= sclp(P) expr(X) as(Y).     {
331*c5c4113dSnw141292    A = sqliteExprListAppend(P,X,Y.n?&Y:0);
332*c5c4113dSnw141292 }
333*c5c4113dSnw141292 selcollist(A) ::= sclp(P) STAR. {
334*c5c4113dSnw141292   A = sqliteExprListAppend(P, sqliteExpr(TK_ALL, 0, 0, 0), 0);
335*c5c4113dSnw141292 }
336*c5c4113dSnw141292 selcollist(A) ::= sclp(P) nm(X) DOT STAR. {
337*c5c4113dSnw141292   Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
338*c5c4113dSnw141292   Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &X);
339*c5c4113dSnw141292   A = sqliteExprListAppend(P, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
340*c5c4113dSnw141292 }
341*c5c4113dSnw141292 
342*c5c4113dSnw141292 // An option "AS <id>" phrase that can follow one of the expressions that
343*c5c4113dSnw141292 // define the result set, or one of the tables in the FROM clause.
344*c5c4113dSnw141292 //
345*c5c4113dSnw141292 %type as {Token}
346*c5c4113dSnw141292 as(X) ::= AS nm(Y).    { X = Y; }
347*c5c4113dSnw141292 as(X) ::= ids(Y).      { X = Y; }
348*c5c4113dSnw141292 as(X) ::= .            { X.n = 0; }
349*c5c4113dSnw141292 
350*c5c4113dSnw141292 
351*c5c4113dSnw141292 %type seltablist {SrcList*}
352*c5c4113dSnw141292 %destructor seltablist {sqliteSrcListDelete($$);}
353*c5c4113dSnw141292 %type stl_prefix {SrcList*}
354*c5c4113dSnw141292 %destructor stl_prefix {sqliteSrcListDelete($$);}
355*c5c4113dSnw141292 %type from {SrcList*}
356*c5c4113dSnw141292 %destructor from {sqliteSrcListDelete($$);}
357*c5c4113dSnw141292 
358*c5c4113dSnw141292 // A complete FROM clause.
359*c5c4113dSnw141292 //
360*c5c4113dSnw141292 from(A) ::= .                                 {A = sqliteMalloc(sizeof(*A));}
361*c5c4113dSnw141292 from(A) ::= FROM seltablist(X).               {A = X;}
362*c5c4113dSnw141292 
363*c5c4113dSnw141292 // "seltablist" is a "Select Table List" - the content of the FROM clause
364*c5c4113dSnw141292 // in a SELECT statement.  "stl_prefix" is a prefix of this list.
365*c5c4113dSnw141292 //
366*c5c4113dSnw141292 stl_prefix(A) ::= seltablist(X) joinop(Y).    {
367*c5c4113dSnw141292    A = X;
368*c5c4113dSnw141292    if( A && A->nSrc>0 ) A->a[A->nSrc-1].jointype = Y;
369*c5c4113dSnw141292 }
370*c5c4113dSnw141292 stl_prefix(A) ::= .                           {A = 0;}
371*c5c4113dSnw141292 seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
372*c5c4113dSnw141292   A = sqliteSrcListAppend(X,&Y,&D);
373*c5c4113dSnw141292   if( Z.n ) sqliteSrcListAddAlias(A,&Z);
374*c5c4113dSnw141292   if( N ){
375*c5c4113dSnw141292     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
376*c5c4113dSnw141292     else { sqliteExprDelete(N); }
377*c5c4113dSnw141292   }
378*c5c4113dSnw141292   if( U ){
379*c5c4113dSnw141292     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
380*c5c4113dSnw141292     else { sqliteIdListDelete(U); }
381*c5c4113dSnw141292   }
382*c5c4113dSnw141292 }
383*c5c4113dSnw141292 seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
384*c5c4113dSnw141292                   as(Z) on_opt(N) using_opt(U). {
385*c5c4113dSnw141292   A = sqliteSrcListAppend(X,0,0);
386*c5c4113dSnw141292   A->a[A->nSrc-1].pSelect = S;
387*c5c4113dSnw141292   if( Z.n ) sqliteSrcListAddAlias(A,&Z);
388*c5c4113dSnw141292   if( N ){
389*c5c4113dSnw141292     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
390*c5c4113dSnw141292     else { sqliteExprDelete(N); }
391*c5c4113dSnw141292   }
392*c5c4113dSnw141292   if( U ){
393*c5c4113dSnw141292     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
394*c5c4113dSnw141292     else { sqliteIdListDelete(U); }
395*c5c4113dSnw141292   }
396*c5c4113dSnw141292 }
397*c5c4113dSnw141292 
398*c5c4113dSnw141292 // A seltablist_paren nonterminal represents anything in a FROM that
399*c5c4113dSnw141292 // is contained inside parentheses.  This can be either a subquery or
400*c5c4113dSnw141292 // a grouping of table and subqueries.
401*c5c4113dSnw141292 //
402*c5c4113dSnw141292 %type seltablist_paren {Select*}
403*c5c4113dSnw141292 %destructor seltablist_paren {sqliteSelectDelete($$);}
404*c5c4113dSnw141292 seltablist_paren(A) ::= select(S).      {A = S;}
405*c5c4113dSnw141292 seltablist_paren(A) ::= seltablist(F).  {
406*c5c4113dSnw141292    A = sqliteSelectNew(0,F,0,0,0,0,0,-1,0);
407*c5c4113dSnw141292 }
408*c5c4113dSnw141292 
409*c5c4113dSnw141292 %type dbnm {Token}
410*c5c4113dSnw141292 dbnm(A) ::= .          {A.z=0; A.n=0;}
411*c5c4113dSnw141292 dbnm(A) ::= DOT nm(X). {A = X;}
412*c5c4113dSnw141292 
413*c5c4113dSnw141292 %type joinop {int}
414*c5c4113dSnw141292 %type joinop2 {int}
415*c5c4113dSnw141292 joinop(X) ::= COMMA.                   { X = JT_INNER; }
416*c5c4113dSnw141292 joinop(X) ::= JOIN.                    { X = JT_INNER; }
417*c5c4113dSnw141292 joinop(X) ::= JOIN_KW(A) JOIN.         { X = sqliteJoinType(pParse,&A,0,0); }
418*c5c4113dSnw141292 joinop(X) ::= JOIN_KW(A) nm(B) JOIN.   { X = sqliteJoinType(pParse,&A,&B,0); }
419*c5c4113dSnw141292 joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
420*c5c4113dSnw141292                                        { X = sqliteJoinType(pParse,&A,&B,&C); }
421*c5c4113dSnw141292 
422*c5c4113dSnw141292 %type on_opt {Expr*}
423*c5c4113dSnw141292 %destructor on_opt {sqliteExprDelete($$);}
424*c5c4113dSnw141292 on_opt(N) ::= ON expr(E).   {N = E;}
425*c5c4113dSnw141292 on_opt(N) ::= .             {N = 0;}
426*c5c4113dSnw141292 
427*c5c4113dSnw141292 %type using_opt {IdList*}
428*c5c4113dSnw141292 %destructor using_opt {sqliteIdListDelete($$);}
429*c5c4113dSnw141292 using_opt(U) ::= USING LP idxlist(L) RP.  {U = L;}
430*c5c4113dSnw141292 using_opt(U) ::= .                        {U = 0;}
431*c5c4113dSnw141292 
432*c5c4113dSnw141292 
433*c5c4113dSnw141292 %type orderby_opt {ExprList*}
434*c5c4113dSnw141292 %destructor orderby_opt {sqliteExprListDelete($$);}
435*c5c4113dSnw141292 %type sortlist {ExprList*}
436*c5c4113dSnw141292 %destructor sortlist {sqliteExprListDelete($$);}
437*c5c4113dSnw141292 %type sortitem {Expr*}
438*c5c4113dSnw141292 %destructor sortitem {sqliteExprDelete($$);}
439*c5c4113dSnw141292 
440*c5c4113dSnw141292 orderby_opt(A) ::= .                          {A = 0;}
441*c5c4113dSnw141292 orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
442*c5c4113dSnw141292 sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
443*c5c4113dSnw141292   A = sqliteExprListAppend(X,Y,0);
444*c5c4113dSnw141292   if( A ) A->a[A->nExpr-1].sortOrder = C+Z;
445*c5c4113dSnw141292 }
446*c5c4113dSnw141292 sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
447*c5c4113dSnw141292   A = sqliteExprListAppend(0,Y,0);
448*c5c4113dSnw141292   if( A ) A->a[0].sortOrder = C+Z;
449*c5c4113dSnw141292 }
450*c5c4113dSnw141292 sortitem(A) ::= expr(X).   {A = X;}
451*c5c4113dSnw141292 
452*c5c4113dSnw141292 %type sortorder {int}
453*c5c4113dSnw141292 %type collate {int}
454*c5c4113dSnw141292 
455*c5c4113dSnw141292 sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
456*c5c4113dSnw141292 sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
457*c5c4113dSnw141292 sortorder(A) ::= .              {A = SQLITE_SO_ASC;}
458*c5c4113dSnw141292 collate(C) ::= .                {C = SQLITE_SO_UNK;}
459*c5c4113dSnw141292 collate(C) ::= COLLATE id(X).   {C = sqliteCollateType(X.z, X.n);}
460*c5c4113dSnw141292 
461*c5c4113dSnw141292 %type groupby_opt {ExprList*}
462*c5c4113dSnw141292 %destructor groupby_opt {sqliteExprListDelete($$);}
463*c5c4113dSnw141292 groupby_opt(A) ::= .                      {A = 0;}
464*c5c4113dSnw141292 groupby_opt(A) ::= GROUP BY exprlist(X).  {A = X;}
465*c5c4113dSnw141292 
466*c5c4113dSnw141292 %type having_opt {Expr*}
467*c5c4113dSnw141292 %destructor having_opt {sqliteExprDelete($$);}
468*c5c4113dSnw141292 having_opt(A) ::= .                {A = 0;}
469*c5c4113dSnw141292 having_opt(A) ::= HAVING expr(X).  {A = X;}
470*c5c4113dSnw141292 
471*c5c4113dSnw141292 %type limit_opt {struct LimitVal}
472*c5c4113dSnw141292 limit_opt(A) ::= .                     {A.limit = -1; A.offset = 0;}
473*c5c4113dSnw141292 limit_opt(A) ::= LIMIT signed(X).      {A.limit = X; A.offset = 0;}
474*c5c4113dSnw141292 limit_opt(A) ::= LIMIT signed(X) OFFSET signed(Y).
475*c5c4113dSnw141292                                        {A.limit = X; A.offset = Y;}
476*c5c4113dSnw141292 limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y).
477*c5c4113dSnw141292                                        {A.limit = Y; A.offset = X;}
478*c5c4113dSnw141292 
479*c5c4113dSnw141292 /////////////////////////// The DELETE statement /////////////////////////////
480*c5c4113dSnw141292 //
481*c5c4113dSnw141292 cmd ::= DELETE FROM nm(X) dbnm(D) where_opt(Y). {
482*c5c4113dSnw141292    sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&X,&D), Y);
483*c5c4113dSnw141292 }
484*c5c4113dSnw141292 
485*c5c4113dSnw141292 %type where_opt {Expr*}
486*c5c4113dSnw141292 %destructor where_opt {sqliteExprDelete($$);}
487*c5c4113dSnw141292 
488*c5c4113dSnw141292 where_opt(A) ::= .                    {A = 0;}
489*c5c4113dSnw141292 where_opt(A) ::= WHERE expr(X).       {A = X;}
490*c5c4113dSnw141292 
491*c5c4113dSnw141292 %type setlist {ExprList*}
492*c5c4113dSnw141292 %destructor setlist {sqliteExprListDelete($$);}
493*c5c4113dSnw141292 
494*c5c4113dSnw141292 ////////////////////////// The UPDATE command ////////////////////////////////
495*c5c4113dSnw141292 //
496*c5c4113dSnw141292 cmd ::= UPDATE orconf(R) nm(X) dbnm(D) SET setlist(Y) where_opt(Z).
497*c5c4113dSnw141292     {sqliteUpdate(pParse,sqliteSrcListAppend(0,&X,&D),Y,Z,R);}
498*c5c4113dSnw141292 
499*c5c4113dSnw141292 setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y).
500*c5c4113dSnw141292     {A = sqliteExprListAppend(Z,Y,&X);}
501*c5c4113dSnw141292 setlist(A) ::= nm(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
502*c5c4113dSnw141292 
503*c5c4113dSnw141292 ////////////////////////// The INSERT command /////////////////////////////////
504*c5c4113dSnw141292 //
505*c5c4113dSnw141292 cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F)
506*c5c4113dSnw141292         VALUES LP itemlist(Y) RP.
507*c5c4113dSnw141292             {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), Y, 0, F, R);}
508*c5c4113dSnw141292 cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F) select(S).
509*c5c4113dSnw141292             {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), 0, S, F, R);}
510*c5c4113dSnw141292 
511*c5c4113dSnw141292 %type insert_cmd {int}
512*c5c4113dSnw141292 insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
513*c5c4113dSnw141292 insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}
514*c5c4113dSnw141292 
515*c5c4113dSnw141292 
516*c5c4113dSnw141292 %type itemlist {ExprList*}
517*c5c4113dSnw141292 %destructor itemlist {sqliteExprListDelete($$);}
518*c5c4113dSnw141292 
519*c5c4113dSnw141292 itemlist(A) ::= itemlist(X) COMMA expr(Y).  {A = sqliteExprListAppend(X,Y,0);}
520*c5c4113dSnw141292 itemlist(A) ::= expr(X).                    {A = sqliteExprListAppend(0,X,0);}
521*c5c4113dSnw141292 
522*c5c4113dSnw141292 %type inscollist_opt {IdList*}
523*c5c4113dSnw141292 %destructor inscollist_opt {sqliteIdListDelete($$);}
524*c5c4113dSnw141292 %type inscollist {IdList*}
525*c5c4113dSnw141292 %destructor inscollist {sqliteIdListDelete($$);}
526*c5c4113dSnw141292 
527*c5c4113dSnw141292 inscollist_opt(A) ::= .                       {A = 0;}
528*c5c4113dSnw141292 inscollist_opt(A) ::= LP inscollist(X) RP.    {A = X;}
529*c5c4113dSnw141292 inscollist(A) ::= inscollist(X) COMMA nm(Y).  {A = sqliteIdListAppend(X,&Y);}
530*c5c4113dSnw141292 inscollist(A) ::= nm(Y).                      {A = sqliteIdListAppend(0,&Y);}
531*c5c4113dSnw141292 
532*c5c4113dSnw141292 /////////////////////////// Expression Processing /////////////////////////////
533*c5c4113dSnw141292 //
534*c5c4113dSnw141292 
535*c5c4113dSnw141292 %type expr {Expr*}
536*c5c4113dSnw141292 %destructor expr {sqliteExprDelete($$);}
537*c5c4113dSnw141292 
538*c5c4113dSnw141292 expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E); }
539*c5c4113dSnw141292 expr(A) ::= NULL(X).             {A = sqliteExpr(TK_NULL, 0, 0, &X);}
540*c5c4113dSnw141292 expr(A) ::= ID(X).               {A = sqliteExpr(TK_ID, 0, 0, &X);}
541*c5c4113dSnw141292 expr(A) ::= JOIN_KW(X).          {A = sqliteExpr(TK_ID, 0, 0, &X);}
542*c5c4113dSnw141292 expr(A) ::= nm(X) DOT nm(Y). {
543*c5c4113dSnw141292   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
544*c5c4113dSnw141292   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
545*c5c4113dSnw141292   A = sqliteExpr(TK_DOT, temp1, temp2, 0);
546*c5c4113dSnw141292 }
547*c5c4113dSnw141292 expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
548*c5c4113dSnw141292   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
549*c5c4113dSnw141292   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
550*c5c4113dSnw141292   Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &Z);
551*c5c4113dSnw141292   Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
552*c5c4113dSnw141292   A = sqliteExpr(TK_DOT, temp1, temp4, 0);
553*c5c4113dSnw141292 }
554*c5c4113dSnw141292 expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
555*c5c4113dSnw141292 expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
556*c5c4113dSnw141292 expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
557*c5c4113dSnw141292 expr(A) ::= VARIABLE(X).     {
558*c5c4113dSnw141292   A = sqliteExpr(TK_VARIABLE, 0, 0, &X);
559*c5c4113dSnw141292   if( A ) A->iTable = ++pParse->nVar;
560*c5c4113dSnw141292 }
561*c5c4113dSnw141292 expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
562*c5c4113dSnw141292   A = sqliteExprFunction(Y, &X);
563*c5c4113dSnw141292   sqliteExprSpan(A,&X,&E);
564*c5c4113dSnw141292 }
565*c5c4113dSnw141292 expr(A) ::= ID(X) LP STAR RP(E). {
566*c5c4113dSnw141292   A = sqliteExprFunction(0, &X);
567*c5c4113dSnw141292   sqliteExprSpan(A,&X,&E);
568*c5c4113dSnw141292 }
569*c5c4113dSnw141292 expr(A) ::= expr(X) AND expr(Y).   {A = sqliteExpr(TK_AND, X, Y, 0);}
570*c5c4113dSnw141292 expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
571*c5c4113dSnw141292 expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
572*c5c4113dSnw141292 expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
573*c5c4113dSnw141292 expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
574*c5c4113dSnw141292 expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
575*c5c4113dSnw141292 expr(A) ::= expr(X) NE expr(Y).    {A = sqliteExpr(TK_NE, X, Y, 0);}
576*c5c4113dSnw141292 expr(A) ::= expr(X) EQ expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
577*c5c4113dSnw141292 expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
578*c5c4113dSnw141292 expr(A) ::= expr(X) BITOR expr(Y).  {A = sqliteExpr(TK_BITOR, X, Y, 0);}
579*c5c4113dSnw141292 expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
580*c5c4113dSnw141292 expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
581*c5c4113dSnw141292 expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
582*c5c4113dSnw141292   ExprList *pList = sqliteExprListAppend(0, Y, 0);
583*c5c4113dSnw141292   pList = sqliteExprListAppend(pList, X, 0);
584*c5c4113dSnw141292   A = sqliteExprFunction(pList, 0);
585*c5c4113dSnw141292   if( A ) A->op = OP;
586*c5c4113dSnw141292   sqliteExprSpan(A, &X->span, &Y->span);
587*c5c4113dSnw141292 }
588*c5c4113dSnw141292 expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
589*c5c4113dSnw141292   ExprList *pList = sqliteExprListAppend(0, Y, 0);
590*c5c4113dSnw141292   pList = sqliteExprListAppend(pList, X, 0);
591*c5c4113dSnw141292   A = sqliteExprFunction(pList, 0);
592*c5c4113dSnw141292   if( A ) A->op = OP;
593*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, A, 0, 0);
594*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&Y->span);
595*c5c4113dSnw141292 }
596*c5c4113dSnw141292 %type likeop {int}
597*c5c4113dSnw141292 likeop(A) ::= LIKE. {A = TK_LIKE;}
598*c5c4113dSnw141292 likeop(A) ::= GLOB. {A = TK_GLOB;}
599*c5c4113dSnw141292 expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
600*c5c4113dSnw141292 expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
601*c5c4113dSnw141292 expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
602*c5c4113dSnw141292 expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
603*c5c4113dSnw141292 expr(A) ::= expr(X) REM expr(Y).   {A = sqliteExpr(TK_REM, X, Y, 0);}
604*c5c4113dSnw141292 expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
605*c5c4113dSnw141292 expr(A) ::= expr(X) ISNULL(E). {
606*c5c4113dSnw141292   A = sqliteExpr(TK_ISNULL, X, 0, 0);
607*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
608*c5c4113dSnw141292 }
609*c5c4113dSnw141292 expr(A) ::= expr(X) IS NULL(E). {
610*c5c4113dSnw141292   A = sqliteExpr(TK_ISNULL, X, 0, 0);
611*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
612*c5c4113dSnw141292 }
613*c5c4113dSnw141292 expr(A) ::= expr(X) NOTNULL(E). {
614*c5c4113dSnw141292   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
615*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
616*c5c4113dSnw141292 }
617*c5c4113dSnw141292 expr(A) ::= expr(X) NOT NULL(E). {
618*c5c4113dSnw141292   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
619*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
620*c5c4113dSnw141292 }
621*c5c4113dSnw141292 expr(A) ::= expr(X) IS NOT NULL(E). {
622*c5c4113dSnw141292   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
623*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
624*c5c4113dSnw141292 }
625*c5c4113dSnw141292 expr(A) ::= NOT(B) expr(X). {
626*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, X, 0, 0);
627*c5c4113dSnw141292   sqliteExprSpan(A,&B,&X->span);
628*c5c4113dSnw141292 }
629*c5c4113dSnw141292 expr(A) ::= BITNOT(B) expr(X). {
630*c5c4113dSnw141292   A = sqliteExpr(TK_BITNOT, X, 0, 0);
631*c5c4113dSnw141292   sqliteExprSpan(A,&B,&X->span);
632*c5c4113dSnw141292 }
633*c5c4113dSnw141292 expr(A) ::= MINUS(B) expr(X). [UMINUS] {
634*c5c4113dSnw141292   A = sqliteExpr(TK_UMINUS, X, 0, 0);
635*c5c4113dSnw141292   sqliteExprSpan(A,&B,&X->span);
636*c5c4113dSnw141292 }
637*c5c4113dSnw141292 expr(A) ::= PLUS(B) expr(X). [UPLUS] {
638*c5c4113dSnw141292   A = sqliteExpr(TK_UPLUS, X, 0, 0);
639*c5c4113dSnw141292   sqliteExprSpan(A,&B,&X->span);
640*c5c4113dSnw141292 }
641*c5c4113dSnw141292 expr(A) ::= LP(B) select(X) RP(E). {
642*c5c4113dSnw141292   A = sqliteExpr(TK_SELECT, 0, 0, 0);
643*c5c4113dSnw141292   if( A ) A->pSelect = X;
644*c5c4113dSnw141292   sqliteExprSpan(A,&B,&E);
645*c5c4113dSnw141292 }
646*c5c4113dSnw141292 expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
647*c5c4113dSnw141292   ExprList *pList = sqliteExprListAppend(0, X, 0);
648*c5c4113dSnw141292   pList = sqliteExprListAppend(pList, Y, 0);
649*c5c4113dSnw141292   A = sqliteExpr(TK_BETWEEN, W, 0, 0);
650*c5c4113dSnw141292   if( A ) A->pList = pList;
651*c5c4113dSnw141292   sqliteExprSpan(A,&W->span,&Y->span);
652*c5c4113dSnw141292 }
653*c5c4113dSnw141292 expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
654*c5c4113dSnw141292   ExprList *pList = sqliteExprListAppend(0, X, 0);
655*c5c4113dSnw141292   pList = sqliteExprListAppend(pList, Y, 0);
656*c5c4113dSnw141292   A = sqliteExpr(TK_BETWEEN, W, 0, 0);
657*c5c4113dSnw141292   if( A ) A->pList = pList;
658*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, A, 0, 0);
659*c5c4113dSnw141292   sqliteExprSpan(A,&W->span,&Y->span);
660*c5c4113dSnw141292 }
661*c5c4113dSnw141292 expr(A) ::= expr(X) IN LP exprlist(Y) RP(E).  {
662*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
663*c5c4113dSnw141292   if( A ) A->pList = Y;
664*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
665*c5c4113dSnw141292 }
666*c5c4113dSnw141292 expr(A) ::= expr(X) IN LP select(Y) RP(E).  {
667*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
668*c5c4113dSnw141292   if( A ) A->pSelect = Y;
669*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
670*c5c4113dSnw141292 }
671*c5c4113dSnw141292 expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E).  {
672*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
673*c5c4113dSnw141292   if( A ) A->pList = Y;
674*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, A, 0, 0);
675*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
676*c5c4113dSnw141292 }
677*c5c4113dSnw141292 expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
678*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
679*c5c4113dSnw141292   if( A ) A->pSelect = Y;
680*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, A, 0, 0);
681*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,&E);
682*c5c4113dSnw141292 }
683*c5c4113dSnw141292 expr(A) ::= expr(X) IN nm(Y) dbnm(D). {
684*c5c4113dSnw141292   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
685*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
686*c5c4113dSnw141292   if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
687*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,D.z?&D:&Y);
688*c5c4113dSnw141292 }
689*c5c4113dSnw141292 expr(A) ::= expr(X) NOT IN nm(Y) dbnm(D). {
690*c5c4113dSnw141292   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
691*c5c4113dSnw141292   A = sqliteExpr(TK_IN, X, 0, 0);
692*c5c4113dSnw141292   if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
693*c5c4113dSnw141292   A = sqliteExpr(TK_NOT, A, 0, 0);
694*c5c4113dSnw141292   sqliteExprSpan(A,&X->span,D.z?&D:&Y);
695*c5c4113dSnw141292 }
696*c5c4113dSnw141292 
697*c5c4113dSnw141292 
698*c5c4113dSnw141292 /* CASE expressions */
699*c5c4113dSnw141292 expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
700*c5c4113dSnw141292   A = sqliteExpr(TK_CASE, X, Z, 0);
701*c5c4113dSnw141292   if( A ) A->pList = Y;
702*c5c4113dSnw141292   sqliteExprSpan(A, &C, &E);
703*c5c4113dSnw141292 }
704*c5c4113dSnw141292 %type case_exprlist {ExprList*}
705*c5c4113dSnw141292 %destructor case_exprlist {sqliteExprListDelete($$);}
706*c5c4113dSnw141292 case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
707*c5c4113dSnw141292   A = sqliteExprListAppend(X, Y, 0);
708*c5c4113dSnw141292   A = sqliteExprListAppend(A, Z, 0);
709*c5c4113dSnw141292 }
710*c5c4113dSnw141292 case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
711*c5c4113dSnw141292   A = sqliteExprListAppend(0, Y, 0);
712*c5c4113dSnw141292   A = sqliteExprListAppend(A, Z, 0);
713*c5c4113dSnw141292 }
714*c5c4113dSnw141292 %type case_else {Expr*}
715*c5c4113dSnw141292 case_else(A) ::=  ELSE expr(X).         {A = X;}
716*c5c4113dSnw141292 case_else(A) ::=  .                     {A = 0;}
717*c5c4113dSnw141292 %type case_operand {Expr*}
718*c5c4113dSnw141292 case_operand(A) ::= expr(X).            {A = X;}
719*c5c4113dSnw141292 case_operand(A) ::= .                   {A = 0;}
720*c5c4113dSnw141292 
721*c5c4113dSnw141292 %type exprlist {ExprList*}
722*c5c4113dSnw141292 %destructor exprlist {sqliteExprListDelete($$);}
723*c5c4113dSnw141292 %type expritem {Expr*}
724*c5c4113dSnw141292 %destructor expritem {sqliteExprDelete($$);}
725*c5c4113dSnw141292 
726*c5c4113dSnw141292 exprlist(A) ::= exprlist(X) COMMA expritem(Y).
727*c5c4113dSnw141292    {A = sqliteExprListAppend(X,Y,0);}
728*c5c4113dSnw141292 exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
729*c5c4113dSnw141292 expritem(A) ::= expr(X).                {A = X;}
730*c5c4113dSnw141292 expritem(A) ::= .                       {A = 0;}
731*c5c4113dSnw141292 
732*c5c4113dSnw141292 ///////////////////////////// The CREATE INDEX command ///////////////////////
733*c5c4113dSnw141292 //
734*c5c4113dSnw141292 cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X)
735*c5c4113dSnw141292         ON nm(Y) dbnm(D) LP idxlist(Z) RP(E) onconf(R). {
736*c5c4113dSnw141292   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
737*c5c4113dSnw141292   if( U!=OE_None ) U = R;
738*c5c4113dSnw141292   if( U==OE_Default) U = OE_Abort;
739*c5c4113dSnw141292   sqliteCreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
740*c5c4113dSnw141292 }
741*c5c4113dSnw141292 
742*c5c4113dSnw141292 %type uniqueflag {int}
743*c5c4113dSnw141292 uniqueflag(A) ::= UNIQUE.  { A = OE_Abort; }
744*c5c4113dSnw141292 uniqueflag(A) ::= .        { A = OE_None; }
745*c5c4113dSnw141292 
746*c5c4113dSnw141292 %type idxlist {IdList*}
747*c5c4113dSnw141292 %destructor idxlist {sqliteIdListDelete($$);}
748*c5c4113dSnw141292 %type idxlist_opt {IdList*}
749*c5c4113dSnw141292 %destructor idxlist_opt {sqliteIdListDelete($$);}
750*c5c4113dSnw141292 %type idxitem {Token}
751*c5c4113dSnw141292 
752*c5c4113dSnw141292 idxlist_opt(A) ::= .                         {A = 0;}
753*c5c4113dSnw141292 idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
754*c5c4113dSnw141292 idxlist(A) ::= idxlist(X) COMMA idxitem(Y).  {A = sqliteIdListAppend(X,&Y);}
755*c5c4113dSnw141292 idxlist(A) ::= idxitem(Y).                   {A = sqliteIdListAppend(0,&Y);}
756*c5c4113dSnw141292 idxitem(A) ::= nm(X) sortorder.              {A = X;}
757*c5c4113dSnw141292 
758*c5c4113dSnw141292 ///////////////////////////// The DROP INDEX command /////////////////////////
759*c5c4113dSnw141292 //
760*c5c4113dSnw141292 
761*c5c4113dSnw141292 cmd ::= DROP INDEX nm(X) dbnm(Y).   {
762*c5c4113dSnw141292   sqliteDropIndex(pParse, sqliteSrcListAppend(0,&X,&Y));
763*c5c4113dSnw141292 }
764*c5c4113dSnw141292 
765*c5c4113dSnw141292 
766*c5c4113dSnw141292 ///////////////////////////// The COPY command ///////////////////////////////
767*c5c4113dSnw141292 //
768*c5c4113dSnw141292 cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y) USING DELIMITERS STRING(Z).
769*c5c4113dSnw141292     {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,&Z,R);}
770*c5c4113dSnw141292 cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y).
771*c5c4113dSnw141292     {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,0,R);}
772*c5c4113dSnw141292 
773*c5c4113dSnw141292 ///////////////////////////// The VACUUM command /////////////////////////////
774*c5c4113dSnw141292 //
775*c5c4113dSnw141292 cmd ::= VACUUM.                {sqliteVacuum(pParse,0);}
776*c5c4113dSnw141292 cmd ::= VACUUM nm(X).         {sqliteVacuum(pParse,&X);}
777*c5c4113dSnw141292 
778*c5c4113dSnw141292 ///////////////////////////// The PRAGMA command /////////////////////////////
779*c5c4113dSnw141292 //
780*c5c4113dSnw141292 cmd ::= PRAGMA ids(X) EQ nm(Y).         {sqlitePragma(pParse,&X,&Y,0);}
781*c5c4113dSnw141292 cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlitePragma(pParse,&X,&Y,0);}
782*c5c4113dSnw141292 cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlitePragma(pParse,&X,&Y,0);}
783*c5c4113dSnw141292 cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlitePragma(pParse,&X,&Y,1);}
784*c5c4113dSnw141292 cmd ::= PRAGMA ids(X) LP nm(Y) RP.      {sqlitePragma(pParse,&X,&Y,0);}
785*c5c4113dSnw141292 cmd ::= PRAGMA ids(X).                   {sqlitePragma(pParse,&X,&X,0);}
786*c5c4113dSnw141292 plus_num(A) ::= plus_opt number(X).   {A = X;}
787*c5c4113dSnw141292 minus_num(A) ::= MINUS number(X).     {A = X;}
788*c5c4113dSnw141292 number(A) ::= INTEGER(X).  {A = X;}
789*c5c4113dSnw141292 number(A) ::= FLOAT(X).    {A = X;}
790*c5c4113dSnw141292 plus_opt ::= PLUS.
791*c5c4113dSnw141292 plus_opt ::= .
792*c5c4113dSnw141292 
793*c5c4113dSnw141292 //////////////////////////// The CREATE TRIGGER command /////////////////////
794*c5c4113dSnw141292 
795*c5c4113dSnw141292 cmd ::= CREATE(A) trigger_decl BEGIN trigger_cmd_list(S) END(Z). {
796*c5c4113dSnw141292   Token all;
797*c5c4113dSnw141292   all.z = A.z;
798*c5c4113dSnw141292   all.n = (Z.z - A.z) + Z.n;
799*c5c4113dSnw141292   sqliteFinishTrigger(pParse, S, &all);
800*c5c4113dSnw141292 }
801*c5c4113dSnw141292 
802*c5c4113dSnw141292 trigger_decl ::= temp(T) TRIGGER nm(B) trigger_time(C) trigger_event(D)
803*c5c4113dSnw141292                  ON nm(E) dbnm(DB) foreach_clause(F) when_clause(G). {
804*c5c4113dSnw141292   SrcList *pTab = sqliteSrcListAppend(0, &E, &DB);
805*c5c4113dSnw141292   sqliteBeginTrigger(pParse, &B, C, D.a, D.b, pTab, F, G, T);
806*c5c4113dSnw141292 }
807*c5c4113dSnw141292 
808*c5c4113dSnw141292 %type trigger_time  {int}
809*c5c4113dSnw141292 trigger_time(A) ::= BEFORE.      { A = TK_BEFORE; }
810*c5c4113dSnw141292 trigger_time(A) ::= AFTER.       { A = TK_AFTER;  }
811*c5c4113dSnw141292 trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
812*c5c4113dSnw141292 trigger_time(A) ::= .            { A = TK_BEFORE; }
813*c5c4113dSnw141292 
814*c5c4113dSnw141292 %type trigger_event {struct TrigEvent}
815*c5c4113dSnw141292 %destructor trigger_event {sqliteIdListDelete($$.b);}
816*c5c4113dSnw141292 trigger_event(A) ::= DELETE. { A.a = TK_DELETE; A.b = 0; }
817*c5c4113dSnw141292 trigger_event(A) ::= INSERT. { A.a = TK_INSERT; A.b = 0; }
818*c5c4113dSnw141292 trigger_event(A) ::= UPDATE. { A.a = TK_UPDATE; A.b = 0;}
819*c5c4113dSnw141292 trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X; }
820*c5c4113dSnw141292 
821*c5c4113dSnw141292 %type foreach_clause {int}
822*c5c4113dSnw141292 foreach_clause(A) ::= .                   { A = TK_ROW; }
823*c5c4113dSnw141292 foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
824*c5c4113dSnw141292 foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
825*c5c4113dSnw141292 
826*c5c4113dSnw141292 %type when_clause {Expr *}
827*c5c4113dSnw141292 when_clause(A) ::= .             { A = 0; }
828*c5c4113dSnw141292 when_clause(A) ::= WHEN expr(X). { A = X; }
829*c5c4113dSnw141292 
830*c5c4113dSnw141292 %type trigger_cmd_list {TriggerStep *}
831*c5c4113dSnw141292 %destructor trigger_cmd_list {sqliteDeleteTriggerStep($$);}
832*c5c4113dSnw141292 trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
833*c5c4113dSnw141292   X->pNext = Y;
834*c5c4113dSnw141292   A = X;
835*c5c4113dSnw141292 }
836*c5c4113dSnw141292 trigger_cmd_list(A) ::= . { A = 0; }
837*c5c4113dSnw141292 
838*c5c4113dSnw141292 %type trigger_cmd {TriggerStep *}
839*c5c4113dSnw141292 %destructor trigger_cmd {sqliteDeleteTriggerStep($$);}
840*c5c4113dSnw141292 // UPDATE
841*c5c4113dSnw141292 trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).
842*c5c4113dSnw141292                { A = sqliteTriggerUpdateStep(&X, Y, Z, R); }
843*c5c4113dSnw141292 
844*c5c4113dSnw141292 // INSERT
845*c5c4113dSnw141292 trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F)
846*c5c4113dSnw141292   VALUES LP itemlist(Y) RP.
847*c5c4113dSnw141292 {A = sqliteTriggerInsertStep(&X, F, Y, 0, R);}
848*c5c4113dSnw141292 
849*c5c4113dSnw141292 trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S).
850*c5c4113dSnw141292                {A = sqliteTriggerInsertStep(&X, F, 0, S, R);}
851*c5c4113dSnw141292 
852*c5c4113dSnw141292 // DELETE
853*c5c4113dSnw141292 trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y).
854*c5c4113dSnw141292                {A = sqliteTriggerDeleteStep(&X, Y);}
855*c5c4113dSnw141292 
856*c5c4113dSnw141292 // SELECT
857*c5c4113dSnw141292 trigger_cmd(A) ::= select(X).  {A = sqliteTriggerSelectStep(X); }
858*c5c4113dSnw141292 
859*c5c4113dSnw141292 // The special RAISE expression that may occur in trigger programs
860*c5c4113dSnw141292 expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
861*c5c4113dSnw141292   A = sqliteExpr(TK_RAISE, 0, 0, 0);
862*c5c4113dSnw141292   A->iColumn = OE_Ignore;
863*c5c4113dSnw141292   sqliteExprSpan(A, &X, &Y);
864*c5c4113dSnw141292 }
865*c5c4113dSnw141292 expr(A) ::= RAISE(X) LP ROLLBACK COMMA nm(Z) RP(Y).  {
866*c5c4113dSnw141292   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
867*c5c4113dSnw141292   A->iColumn = OE_Rollback;
868*c5c4113dSnw141292   sqliteExprSpan(A, &X, &Y);
869*c5c4113dSnw141292 }
870*c5c4113dSnw141292 expr(A) ::= RAISE(X) LP ABORT COMMA nm(Z) RP(Y).  {
871*c5c4113dSnw141292   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
872*c5c4113dSnw141292   A->iColumn = OE_Abort;
873*c5c4113dSnw141292   sqliteExprSpan(A, &X, &Y);
874*c5c4113dSnw141292 }
875*c5c4113dSnw141292 expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y).  {
876*c5c4113dSnw141292   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
877*c5c4113dSnw141292   A->iColumn = OE_Fail;
878*c5c4113dSnw141292   sqliteExprSpan(A, &X, &Y);
879*c5c4113dSnw141292 }
880*c5c4113dSnw141292 
881*c5c4113dSnw141292 ////////////////////////  DROP TRIGGER statement //////////////////////////////
882*c5c4113dSnw141292 cmd ::= DROP TRIGGER nm(X) dbnm(D). {
883*c5c4113dSnw141292   sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D));
884*c5c4113dSnw141292 }
885*c5c4113dSnw141292 
886*c5c4113dSnw141292 //////////////////////// ATTACH DATABASE file AS name /////////////////////////
887*c5c4113dSnw141292 cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
888*c5c4113dSnw141292   sqliteAttach(pParse, &F, &D, &K);
889*c5c4113dSnw141292 }
890*c5c4113dSnw141292 %type key_opt {Token}
891*c5c4113dSnw141292 key_opt(A) ::= USING ids(X).  { A = X; }
892*c5c4113dSnw141292 key_opt(A) ::= .              { A.z = 0; A.n = 0; }
893*c5c4113dSnw141292 
894*c5c4113dSnw141292 database_kw_opt ::= DATABASE.
895*c5c4113dSnw141292 database_kw_opt ::= .
896*c5c4113dSnw141292 
897*c5c4113dSnw141292 //////////////////////// DETACH DATABASE name /////////////////////////////////
898*c5c4113dSnw141292 cmd ::= DETACH database_kw_opt nm(D). {
899*c5c4113dSnw141292   sqliteDetach(pParse, &D);
900*c5c4113dSnw141292 }
901