xref: /illumos-gate/usr/src/lib/libsqlite/src/parse.y (revision 1da57d55)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate ** 2001 September 15
37c478bd9Sstevel@tonic-gate **
47c478bd9Sstevel@tonic-gate ** The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate ** a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate **
77c478bd9Sstevel@tonic-gate **    May you do good and not evil.
87c478bd9Sstevel@tonic-gate **    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate **    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate **
117c478bd9Sstevel@tonic-gate *************************************************************************
127c478bd9Sstevel@tonic-gate ** This file contains SQLite's grammar for SQL.  Process this file
137c478bd9Sstevel@tonic-gate ** using the lemon parser generator to generate C code that runs
147c478bd9Sstevel@tonic-gate ** the parser.  Lemon will also generate a header file containing
157c478bd9Sstevel@tonic-gate ** numeric codes for all of the tokens.
167c478bd9Sstevel@tonic-gate **
177c478bd9Sstevel@tonic-gate ** @(#) $Id: parse.y,v 1.112 2004/02/22 18:40:57 drh Exp $
187c478bd9Sstevel@tonic-gate */
197c478bd9Sstevel@tonic-gate %token_prefix TK_
207c478bd9Sstevel@tonic-gate %token_type {Token}
217c478bd9Sstevel@tonic-gate %default_type {Token}
227c478bd9Sstevel@tonic-gate %extra_argument {Parse *pParse}
237c478bd9Sstevel@tonic-gate %syntax_error {
247c478bd9Sstevel@tonic-gate   if( pParse->zErrMsg==0 ){
257c478bd9Sstevel@tonic-gate     if( TOKEN.z[0] ){
267c478bd9Sstevel@tonic-gate       sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
277c478bd9Sstevel@tonic-gate     }else{
287c478bd9Sstevel@tonic-gate       sqliteErrorMsg(pParse, "incomplete SQL statement");
297c478bd9Sstevel@tonic-gate     }
307c478bd9Sstevel@tonic-gate   }
317c478bd9Sstevel@tonic-gate }
327c478bd9Sstevel@tonic-gate %name sqliteParser
337c478bd9Sstevel@tonic-gate %include {
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include "sqliteInt.h"
367c478bd9Sstevel@tonic-gate #include "parse.h"
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate ** An instance of this structure holds information about the
407c478bd9Sstevel@tonic-gate ** LIMIT clause of a SELECT statement.
417c478bd9Sstevel@tonic-gate */
427c478bd9Sstevel@tonic-gate struct LimitVal {
437c478bd9Sstevel@tonic-gate   int limit;    /* The LIMIT value.  -1 if there is no limit */
447c478bd9Sstevel@tonic-gate   int offset;   /* The OFFSET.  0 if there is none */
457c478bd9Sstevel@tonic-gate };
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate ** An instance of the following structure describes the event of a
497c478bd9Sstevel@tonic-gate ** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
507c478bd9Sstevel@tonic-gate ** TK_DELETE, or TK_INSTEAD.  If the event is of the form
517c478bd9Sstevel@tonic-gate **
527c478bd9Sstevel@tonic-gate **      UPDATE ON (a,b,c)
537c478bd9Sstevel@tonic-gate **
547c478bd9Sstevel@tonic-gate ** Then the "b" IdList records the list "a,b,c".
557c478bd9Sstevel@tonic-gate */
567c478bd9Sstevel@tonic-gate struct TrigEvent { int a; IdList * b; };
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate } // end %include
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate // These are extra tokens used by the lexer but never seen by the
617c478bd9Sstevel@tonic-gate // parser.  We put them in a rule so that the parser generator will
627c478bd9Sstevel@tonic-gate // add them to the parse.h output file.
637c478bd9Sstevel@tonic-gate //
647c478bd9Sstevel@tonic-gate %nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
657c478bd9Sstevel@tonic-gate           COLUMN AGG_FUNCTION.
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate // Input is a single SQL command
687c478bd9Sstevel@tonic-gate input ::= cmdlist.
697c478bd9Sstevel@tonic-gate cmdlist ::= cmdlist ecmd.
707c478bd9Sstevel@tonic-gate cmdlist ::= ecmd.
717c478bd9Sstevel@tonic-gate ecmd ::= explain cmdx SEMI.
727c478bd9Sstevel@tonic-gate ecmd ::= SEMI.
737c478bd9Sstevel@tonic-gate cmdx ::= cmd.           { sqliteExec(pParse); }
747c478bd9Sstevel@tonic-gate explain ::= EXPLAIN.    { sqliteBeginParse(pParse, 1); }
757c478bd9Sstevel@tonic-gate explain ::= .           { sqliteBeginParse(pParse, 0); }
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate ///////////////////// Begin and end transactions. ////////////////////////////
787c478bd9Sstevel@tonic-gate //
797c478bd9Sstevel@tonic-gate 
onconf(R)807c478bd9Sstevel@tonic-gate cmd ::= BEGIN trans_opt onconf(R).  {sqliteBeginTransaction(pParse,R);}
817c478bd9Sstevel@tonic-gate trans_opt ::= .
827c478bd9Sstevel@tonic-gate trans_opt ::= TRANSACTION.
837c478bd9Sstevel@tonic-gate trans_opt ::= TRANSACTION nm.
847c478bd9Sstevel@tonic-gate cmd ::= COMMIT trans_opt.      {sqliteCommitTransaction(pParse);}
857c478bd9Sstevel@tonic-gate cmd ::= END trans_opt.         {sqliteCommitTransaction(pParse);}
867c478bd9Sstevel@tonic-gate cmd ::= ROLLBACK trans_opt.    {sqliteRollbackTransaction(pParse);}
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate ///////////////////// The CREATE TABLE statement ////////////////////////////
897c478bd9Sstevel@tonic-gate //
907c478bd9Sstevel@tonic-gate cmd ::= create_table create_table_args.
CREATE(X)917c478bd9Sstevel@tonic-gate create_table ::= CREATE(X) temp(T) TABLE nm(Y). {
927c478bd9Sstevel@tonic-gate    sqliteStartTable(pParse,&X,&Y,T,0);
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate %type temp {int}
temp(A)957c478bd9Sstevel@tonic-gate temp(A) ::= TEMP.  {A = 1;}
temp(A)967c478bd9Sstevel@tonic-gate temp(A) ::= .      {A = 0;}
RP(X)977c478bd9Sstevel@tonic-gate create_table_args ::= LP columnlist conslist_opt RP(X). {
987c478bd9Sstevel@tonic-gate   sqliteEndTable(pParse,&X,0);
997c478bd9Sstevel@tonic-gate }
select(S)1007c478bd9Sstevel@tonic-gate create_table_args ::= AS select(S). {
1017c478bd9Sstevel@tonic-gate   sqliteEndTable(pParse,0,S);
1027c478bd9Sstevel@tonic-gate   sqliteSelectDelete(S);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate columnlist ::= columnlist COMMA column.
1057c478bd9Sstevel@tonic-gate columnlist ::= column.
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate // About the only information used for a column is the name of the
1087c478bd9Sstevel@tonic-gate // column.  The type is always just "text".  But the code will accept
1097c478bd9Sstevel@tonic-gate // an elaborate typename.  Perhaps someday we'll do something with it.
1107c478bd9Sstevel@tonic-gate //
111*1da57d55SToomas Soome column ::= columnid type carglist.
nm(X)1127c478bd9Sstevel@tonic-gate columnid ::= nm(X).                {sqliteAddColumn(pParse,&X);}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate // An IDENTIFIER can be a generic identifier, or one of several
1157c478bd9Sstevel@tonic-gate // keywords.  Any non-standard keyword can also be an identifier.
1167c478bd9Sstevel@tonic-gate //
1177c478bd9Sstevel@tonic-gate %type id {Token}
id(A)1187c478bd9Sstevel@tonic-gate id(A) ::= ID(X).         {A = X;}
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate // The following directive causes tokens ABORT, AFTER, ASC, etc. to
1217c478bd9Sstevel@tonic-gate // fallback to ID if they will not parse as their original value.
1227c478bd9Sstevel@tonic-gate // This obviates the need for the "id" nonterminal.
1237c478bd9Sstevel@tonic-gate //
1247c478bd9Sstevel@tonic-gate %fallback ID
1257c478bd9Sstevel@tonic-gate   ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT
1267c478bd9Sstevel@tonic-gate   COPY DATABASE DEFERRED DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR
1277c478bd9Sstevel@tonic-gate   GLOB IGNORE IMMEDIATE INITIALLY INSTEAD LIKE MATCH KEY
1287c478bd9Sstevel@tonic-gate   OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
1297c478bd9Sstevel@tonic-gate   TEMP TRIGGER VACUUM VIEW.
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate // Define operator precedence early so that this is the first occurance
1327c478bd9Sstevel@tonic-gate // of the operator tokens in the grammer.  Keeping the operators together
1337c478bd9Sstevel@tonic-gate // causes them to be assigned integer values that are close together,
1347c478bd9Sstevel@tonic-gate // which keeps parser tables smaller.
1357c478bd9Sstevel@tonic-gate //
1367c478bd9Sstevel@tonic-gate %left OR.
1377c478bd9Sstevel@tonic-gate %left AND.
1387c478bd9Sstevel@tonic-gate %right NOT.
1397c478bd9Sstevel@tonic-gate %left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
1407c478bd9Sstevel@tonic-gate %left GT GE LT LE.
1417c478bd9Sstevel@tonic-gate %left BITAND BITOR LSHIFT RSHIFT.
1427c478bd9Sstevel@tonic-gate %left PLUS MINUS.
1437c478bd9Sstevel@tonic-gate %left STAR SLASH REM.
1447c478bd9Sstevel@tonic-gate %left CONCAT.
1457c478bd9Sstevel@tonic-gate %right UMINUS UPLUS BITNOT.
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate // And "ids" is an identifer-or-string.
1487c478bd9Sstevel@tonic-gate //
1497c478bd9Sstevel@tonic-gate %type ids {Token}
ids(A)1507c478bd9Sstevel@tonic-gate ids(A) ::= ID(X).        {A = X;}
ids(A)1517c478bd9Sstevel@tonic-gate ids(A) ::= STRING(X).    {A = X;}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate // The name of a column or table can be any of the following:
1547c478bd9Sstevel@tonic-gate //
1557c478bd9Sstevel@tonic-gate %type nm {Token}
nm(A)1567c478bd9Sstevel@tonic-gate nm(A) ::= ID(X).         {A = X;}
nm(A)1577c478bd9Sstevel@tonic-gate nm(A) ::= STRING(X).     {A = X;}
nm(A)1587c478bd9Sstevel@tonic-gate nm(A) ::= JOIN_KW(X).    {A = X;}
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate type ::= .
typename(X)1617c478bd9Sstevel@tonic-gate type ::= typename(X).                    {sqliteAddColumnType(pParse,&X,&X);}
typename(X)1627c478bd9Sstevel@tonic-gate type ::= typename(X) LP signed RP(Y).    {sqliteAddColumnType(pParse,&X,&Y);}
typename(X)1637c478bd9Sstevel@tonic-gate type ::= typename(X) LP signed COMMA signed RP(Y).
1647c478bd9Sstevel@tonic-gate                                          {sqliteAddColumnType(pParse,&X,&Y);}
1657c478bd9Sstevel@tonic-gate %type typename {Token}
typename(A)1667c478bd9Sstevel@tonic-gate typename(A) ::= ids(X).           {A = X;}
typename(A)1677c478bd9Sstevel@tonic-gate typename(A) ::= typename(X) ids.  {A = X;}
1687c478bd9Sstevel@tonic-gate %type signed {int}
INTEGER(X)1697c478bd9Sstevel@tonic-gate signed(A) ::= INTEGER(X).         { A = atoi(X.z); }
INTEGER(X)1707c478bd9Sstevel@tonic-gate signed(A) ::= PLUS INTEGER(X).    { A = atoi(X.z); }
INTEGER(X)1717c478bd9Sstevel@tonic-gate signed(A) ::= MINUS INTEGER(X).   { A = -atoi(X.z); }
1727c478bd9Sstevel@tonic-gate carglist ::= carglist carg.
1737c478bd9Sstevel@tonic-gate carglist ::= .
1747c478bd9Sstevel@tonic-gate carg ::= CONSTRAINT nm ccons.
1757c478bd9Sstevel@tonic-gate carg ::= ccons.
STRING(X)1767c478bd9Sstevel@tonic-gate carg ::= DEFAULT STRING(X).          {sqliteAddDefaultValue(pParse,&X,0);}
ID(X)1777c478bd9Sstevel@tonic-gate carg ::= DEFAULT ID(X).              {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)1787c478bd9Sstevel@tonic-gate carg ::= DEFAULT INTEGER(X).         {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)1797c478bd9Sstevel@tonic-gate carg ::= DEFAULT PLUS INTEGER(X).    {sqliteAddDefaultValue(pParse,&X,0);}
INTEGER(X)1807c478bd9Sstevel@tonic-gate carg ::= DEFAULT MINUS INTEGER(X).   {sqliteAddDefaultValue(pParse,&X,1);}
FLOAT(X)1817c478bd9Sstevel@tonic-gate carg ::= DEFAULT FLOAT(X).           {sqliteAddDefaultValue(pParse,&X,0);}
FLOAT(X)1827c478bd9Sstevel@tonic-gate carg ::= DEFAULT PLUS FLOAT(X).      {sqliteAddDefaultValue(pParse,&X,0);}
FLOAT(X)1837c478bd9Sstevel@tonic-gate carg ::= DEFAULT MINUS FLOAT(X).     {sqliteAddDefaultValue(pParse,&X,1);}
184*1da57d55SToomas Soome carg ::= DEFAULT NULL.
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate // In addition to the type name, we also care about the primary key and
1877c478bd9Sstevel@tonic-gate // UNIQUE constraints.
1887c478bd9Sstevel@tonic-gate //
1897c478bd9Sstevel@tonic-gate ccons ::= NULL onconf.
onconf(R)1907c478bd9Sstevel@tonic-gate ccons ::= NOT NULL onconf(R).               {sqliteAddNotNull(pParse, R);}
onconf(R)1917c478bd9Sstevel@tonic-gate ccons ::= PRIMARY KEY sortorder onconf(R).  {sqliteAddPrimaryKey(pParse,0,R);}
onconf(R)1927c478bd9Sstevel@tonic-gate ccons ::= UNIQUE onconf(R).           {sqliteCreateIndex(pParse,0,0,0,R,0,0);}
1937c478bd9Sstevel@tonic-gate ccons ::= CHECK LP expr RP onconf.
nm(T)1947c478bd9Sstevel@tonic-gate ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
1957c478bd9Sstevel@tonic-gate                                 {sqliteCreateForeignKey(pParse,0,&T,TA,R);}
defer_subclause(D)1967c478bd9Sstevel@tonic-gate ccons ::= defer_subclause(D).   {sqliteDeferForeignKey(pParse,D);}
id(C)1977c478bd9Sstevel@tonic-gate ccons ::= COLLATE id(C).  {
1987c478bd9Sstevel@tonic-gate    sqliteAddCollateType(pParse, sqliteCollateType(C.z, C.n));
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate // The next group of rules parses the arguments to a REFERENCES clause
2027c478bd9Sstevel@tonic-gate // that determine if the referential integrity checking is deferred or
2037c478bd9Sstevel@tonic-gate // or immediate and which determine what action to take if a ref-integ
2047c478bd9Sstevel@tonic-gate // check fails.
2057c478bd9Sstevel@tonic-gate //
2067c478bd9Sstevel@tonic-gate %type refargs {int}
refargs(A)2077c478bd9Sstevel@tonic-gate refargs(A) ::= .                     { A = OE_Restrict * 0x010101; }
refargs(A)2087c478bd9Sstevel@tonic-gate refargs(A) ::= refargs(X) refarg(Y). { A = (X & Y.mask) | Y.value; }
2097c478bd9Sstevel@tonic-gate %type refarg {struct {int value; int mask;}}
2107c478bd9Sstevel@tonic-gate refarg(A) ::= MATCH nm.              { A.value = 0;     A.mask = 0x000000; }
2117c478bd9Sstevel@tonic-gate refarg(A) ::= ON DELETE refact(X).   { A.value = X;     A.mask = 0x0000ff; }
2127c478bd9Sstevel@tonic-gate refarg(A) ::= ON UPDATE refact(X).   { A.value = X<<8;  A.mask = 0x00ff00; }
2137c478bd9Sstevel@tonic-gate refarg(A) ::= ON INSERT refact(X).   { A.value = X<<16; A.mask = 0xff0000; }
2147c478bd9Sstevel@tonic-gate %type refact {int}
2157c478bd9Sstevel@tonic-gate refact(A) ::= SET NULL.              { A = OE_SetNull; }
2167c478bd9Sstevel@tonic-gate refact(A) ::= SET DEFAULT.           { A = OE_SetDflt; }
2177c478bd9Sstevel@tonic-gate refact(A) ::= CASCADE.               { A = OE_Cascade; }
2187c478bd9Sstevel@tonic-gate refact(A) ::= RESTRICT.              { A = OE_Restrict; }
2197c478bd9Sstevel@tonic-gate %type defer_subclause {int}
2207c478bd9Sstevel@tonic-gate defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt(X).  {A = X;}
2217c478bd9Sstevel@tonic-gate defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
2227c478bd9Sstevel@tonic-gate %type init_deferred_pred_opt {int}
2237c478bd9Sstevel@tonic-gate init_deferred_pred_opt(A) ::= .                       {A = 0;}
2247c478bd9Sstevel@tonic-gate init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
2257c478bd9Sstevel@tonic-gate init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate // For the time being, the only constraint we care about is the primary
2287c478bd9Sstevel@tonic-gate // key and UNIQUE.  Both create indices.
2297c478bd9Sstevel@tonic-gate //
2307c478bd9Sstevel@tonic-gate conslist_opt ::= .
2317c478bd9Sstevel@tonic-gate conslist_opt ::= COMMA conslist.
2327c478bd9Sstevel@tonic-gate conslist ::= conslist COMMA tcons.
2337c478bd9Sstevel@tonic-gate conslist ::= conslist tcons.
2347c478bd9Sstevel@tonic-gate conslist ::= tcons.
2357c478bd9Sstevel@tonic-gate tcons ::= CONSTRAINT nm.
2367c478bd9Sstevel@tonic-gate tcons ::= PRIMARY KEY LP idxlist(X) RP onconf(R).
2377c478bd9Sstevel@tonic-gate                                              {sqliteAddPrimaryKey(pParse,X,R);}
2387c478bd9Sstevel@tonic-gate tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
2397c478bd9Sstevel@tonic-gate                                        {sqliteCreateIndex(pParse,0,0,X,R,0,0);}
2407c478bd9Sstevel@tonic-gate tcons ::= CHECK expr onconf.
2417c478bd9Sstevel@tonic-gate tcons ::= FOREIGN KEY LP idxlist(FA) RP
2427c478bd9Sstevel@tonic-gate           REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
2437c478bd9Sstevel@tonic-gate     sqliteCreateForeignKey(pParse, FA, &T, TA, R);
2447c478bd9Sstevel@tonic-gate     sqliteDeferForeignKey(pParse, D);
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate %type defer_subclause_opt {int}
2477c478bd9Sstevel@tonic-gate defer_subclause_opt(A) ::= .                    {A = 0;}
2487c478bd9Sstevel@tonic-gate defer_subclause_opt(A) ::= defer_subclause(X).  {A = X;}
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate // The following is a non-standard extension that allows us to declare the
2517c478bd9Sstevel@tonic-gate // default behavior when there is a constraint conflict.
2527c478bd9Sstevel@tonic-gate //
2537c478bd9Sstevel@tonic-gate %type onconf {int}
2547c478bd9Sstevel@tonic-gate %type orconf {int}
2557c478bd9Sstevel@tonic-gate %type resolvetype {int}
2567c478bd9Sstevel@tonic-gate onconf(A) ::= .                              { A = OE_Default; }
2577c478bd9Sstevel@tonic-gate onconf(A) ::= ON CONFLICT resolvetype(X).    { A = X; }
2587c478bd9Sstevel@tonic-gate orconf(A) ::= .                              { A = OE_Default; }
2597c478bd9Sstevel@tonic-gate orconf(A) ::= OR resolvetype(X).             { A = X; }
2607c478bd9Sstevel@tonic-gate resolvetype(A) ::= ROLLBACK.                 { A = OE_Rollback; }
2617c478bd9Sstevel@tonic-gate resolvetype(A) ::= ABORT.                    { A = OE_Abort; }
2627c478bd9Sstevel@tonic-gate resolvetype(A) ::= FAIL.                     { A = OE_Fail; }
2637c478bd9Sstevel@tonic-gate resolvetype(A) ::= IGNORE.                   { A = OE_Ignore; }
2647c478bd9Sstevel@tonic-gate resolvetype(A) ::= REPLACE.                  { A = OE_Replace; }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate ////////////////////////// The DROP TABLE /////////////////////////////////////
2677c478bd9Sstevel@tonic-gate //
2687c478bd9Sstevel@tonic-gate cmd ::= DROP TABLE nm(X).          {sqliteDropTable(pParse,&X,0);}
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate ///////////////////// The CREATE VIEW statement /////////////////////////////
2717c478bd9Sstevel@tonic-gate //
2727c478bd9Sstevel@tonic-gate cmd ::= CREATE(X) temp(T) VIEW nm(Y) AS select(S). {
2737c478bd9Sstevel@tonic-gate   sqliteCreateView(pParse, &X, &Y, S, T);
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate cmd ::= DROP VIEW nm(X). {
2767c478bd9Sstevel@tonic-gate   sqliteDropTable(pParse, &X, 1);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate //////////////////////// The SELECT statement /////////////////////////////////
2807c478bd9Sstevel@tonic-gate //
2817c478bd9Sstevel@tonic-gate cmd ::= select(X).  {
2827c478bd9Sstevel@tonic-gate   sqliteSelect(pParse, X, SRT_Callback, 0, 0, 0, 0);
2837c478bd9Sstevel@tonic-gate   sqliteSelectDelete(X);
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate %type select {Select*}
2877c478bd9Sstevel@tonic-gate %destructor select {sqliteSelectDelete($$);}
2887c478bd9Sstevel@tonic-gate %type oneselect {Select*}
2897c478bd9Sstevel@tonic-gate %destructor oneselect {sqliteSelectDelete($$);}
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate select(A) ::= oneselect(X).                      {A = X;}
2927c478bd9Sstevel@tonic-gate select(A) ::= select(X) multiselect_op(Y) oneselect(Z).  {
2937c478bd9Sstevel@tonic-gate   if( Z ){
2947c478bd9Sstevel@tonic-gate     Z->op = Y;
2957c478bd9Sstevel@tonic-gate     Z->pPrior = X;
2967c478bd9Sstevel@tonic-gate   }
2977c478bd9Sstevel@tonic-gate   A = Z;
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate %type multiselect_op {int}
3007c478bd9Sstevel@tonic-gate multiselect_op(A) ::= UNION.      {A = TK_UNION;}
3017c478bd9Sstevel@tonic-gate multiselect_op(A) ::= UNION ALL.  {A = TK_ALL;}
3027c478bd9Sstevel@tonic-gate multiselect_op(A) ::= INTERSECT.  {A = TK_INTERSECT;}
3037c478bd9Sstevel@tonic-gate multiselect_op(A) ::= EXCEPT.     {A = TK_EXCEPT;}
3047c478bd9Sstevel@tonic-gate oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
3057c478bd9Sstevel@tonic-gate                  groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
3067c478bd9Sstevel@tonic-gate   A = sqliteSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate // The "distinct" nonterminal is true (1) if the DISTINCT keyword is
3107c478bd9Sstevel@tonic-gate // present and false (0) if it is not.
3117c478bd9Sstevel@tonic-gate //
3127c478bd9Sstevel@tonic-gate %type distinct {int}
3137c478bd9Sstevel@tonic-gate distinct(A) ::= DISTINCT.   {A = 1;}
3147c478bd9Sstevel@tonic-gate distinct(A) ::= ALL.        {A = 0;}
3157c478bd9Sstevel@tonic-gate distinct(A) ::= .           {A = 0;}
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate // selcollist is a list of expressions that are to become the return
3187c478bd9Sstevel@tonic-gate // values of the SELECT statement.  The "*" in statements like
3197c478bd9Sstevel@tonic-gate // "SELECT * FROM ..." is encoded as a special expression with an
3207c478bd9Sstevel@tonic-gate // opcode of TK_ALL.
3217c478bd9Sstevel@tonic-gate //
3227c478bd9Sstevel@tonic-gate %type selcollist {ExprList*}
3237c478bd9Sstevel@tonic-gate %destructor selcollist {sqliteExprListDelete($$);}
3247c478bd9Sstevel@tonic-gate %type sclp {ExprList*}
3257c478bd9Sstevel@tonic-gate %destructor sclp {sqliteExprListDelete($$);}
3267c478bd9Sstevel@tonic-gate sclp(A) ::= selcollist(X) COMMA.             {A = X;}
3277c478bd9Sstevel@tonic-gate sclp(A) ::= .                                {A = 0;}
3287c478bd9Sstevel@tonic-gate selcollist(A) ::= sclp(P) expr(X) as(Y).     {
3297c478bd9Sstevel@tonic-gate    A = sqliteExprListAppend(P,X,Y.n?&Y:0);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate selcollist(A) ::= sclp(P) STAR. {
3327c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(P, sqliteExpr(TK_ALL, 0, 0, 0), 0);
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate selcollist(A) ::= sclp(P) nm(X) DOT STAR. {
3357c478bd9Sstevel@tonic-gate   Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
3367c478bd9Sstevel@tonic-gate   Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &X);
3377c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(P, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
3387c478bd9Sstevel@tonic-gate }
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate // An option "AS <id>" phrase that can follow one of the expressions that
3417c478bd9Sstevel@tonic-gate // define the result set, or one of the tables in the FROM clause.
3427c478bd9Sstevel@tonic-gate //
3437c478bd9Sstevel@tonic-gate %type as {Token}
3447c478bd9Sstevel@tonic-gate as(X) ::= AS nm(Y).    { X = Y; }
3457c478bd9Sstevel@tonic-gate as(X) ::= ids(Y).      { X = Y; }
3467c478bd9Sstevel@tonic-gate as(X) ::= .            { X.n = 0; }
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate %type seltablist {SrcList*}
3507c478bd9Sstevel@tonic-gate %destructor seltablist {sqliteSrcListDelete($$);}
3517c478bd9Sstevel@tonic-gate %type stl_prefix {SrcList*}
3527c478bd9Sstevel@tonic-gate %destructor stl_prefix {sqliteSrcListDelete($$);}
3537c478bd9Sstevel@tonic-gate %type from {SrcList*}
3547c478bd9Sstevel@tonic-gate %destructor from {sqliteSrcListDelete($$);}
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate // A complete FROM clause.
3577c478bd9Sstevel@tonic-gate //
3587c478bd9Sstevel@tonic-gate from(A) ::= .                                 {A = sqliteMalloc(sizeof(*A));}
3597c478bd9Sstevel@tonic-gate from(A) ::= FROM seltablist(X).               {A = X;}
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate // "seltablist" is a "Select Table List" - the content of the FROM clause
3627c478bd9Sstevel@tonic-gate // in a SELECT statement.  "stl_prefix" is a prefix of this list.
3637c478bd9Sstevel@tonic-gate //
3647c478bd9Sstevel@tonic-gate stl_prefix(A) ::= seltablist(X) joinop(Y).    {
3657c478bd9Sstevel@tonic-gate    A = X;
3667c478bd9Sstevel@tonic-gate    if( A && A->nSrc>0 ) A->a[A->nSrc-1].jointype = Y;
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate stl_prefix(A) ::= .                           {A = 0;}
3697c478bd9Sstevel@tonic-gate seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). {
3707c478bd9Sstevel@tonic-gate   A = sqliteSrcListAppend(X,&Y,&D);
3717c478bd9Sstevel@tonic-gate   if( Z.n ) sqliteSrcListAddAlias(A,&Z);
3727c478bd9Sstevel@tonic-gate   if( N ){
3737c478bd9Sstevel@tonic-gate     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
3747c478bd9Sstevel@tonic-gate     else { sqliteExprDelete(N); }
3757c478bd9Sstevel@tonic-gate   }
3767c478bd9Sstevel@tonic-gate   if( U ){
3777c478bd9Sstevel@tonic-gate     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
3787c478bd9Sstevel@tonic-gate     else { sqliteIdListDelete(U); }
3797c478bd9Sstevel@tonic-gate   }
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate seltablist(A) ::= stl_prefix(X) LP seltablist_paren(S) RP
3827c478bd9Sstevel@tonic-gate                   as(Z) on_opt(N) using_opt(U). {
3837c478bd9Sstevel@tonic-gate   A = sqliteSrcListAppend(X,0,0);
3847c478bd9Sstevel@tonic-gate   A->a[A->nSrc-1].pSelect = S;
3857c478bd9Sstevel@tonic-gate   if( Z.n ) sqliteSrcListAddAlias(A,&Z);
3867c478bd9Sstevel@tonic-gate   if( N ){
3877c478bd9Sstevel@tonic-gate     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pOn = N; }
3887c478bd9Sstevel@tonic-gate     else { sqliteExprDelete(N); }
3897c478bd9Sstevel@tonic-gate   }
3907c478bd9Sstevel@tonic-gate   if( U ){
3917c478bd9Sstevel@tonic-gate     if( A && A->nSrc>1 ){ A->a[A->nSrc-2].pUsing = U; }
3927c478bd9Sstevel@tonic-gate     else { sqliteIdListDelete(U); }
3937c478bd9Sstevel@tonic-gate   }
3947c478bd9Sstevel@tonic-gate }
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate // A seltablist_paren nonterminal represents anything in a FROM that
3977c478bd9Sstevel@tonic-gate // is contained inside parentheses.  This can be either a subquery or
3987c478bd9Sstevel@tonic-gate // a grouping of table and subqueries.
3997c478bd9Sstevel@tonic-gate //
4007c478bd9Sstevel@tonic-gate %type seltablist_paren {Select*}
4017c478bd9Sstevel@tonic-gate %destructor seltablist_paren {sqliteSelectDelete($$);}
4027c478bd9Sstevel@tonic-gate seltablist_paren(A) ::= select(S).      {A = S;}
4037c478bd9Sstevel@tonic-gate seltablist_paren(A) ::= seltablist(F).  {
4047c478bd9Sstevel@tonic-gate    A = sqliteSelectNew(0,F,0,0,0,0,0,-1,0);
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate %type dbnm {Token}
4087c478bd9Sstevel@tonic-gate dbnm(A) ::= .          {A.z=0; A.n=0;}
4097c478bd9Sstevel@tonic-gate dbnm(A) ::= DOT nm(X). {A = X;}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate %type joinop {int}
4127c478bd9Sstevel@tonic-gate %type joinop2 {int}
4137c478bd9Sstevel@tonic-gate joinop(X) ::= COMMA.                   { X = JT_INNER; }
4147c478bd9Sstevel@tonic-gate joinop(X) ::= JOIN.                    { X = JT_INNER; }
4157c478bd9Sstevel@tonic-gate joinop(X) ::= JOIN_KW(A) JOIN.         { X = sqliteJoinType(pParse,&A,0,0); }
4167c478bd9Sstevel@tonic-gate joinop(X) ::= JOIN_KW(A) nm(B) JOIN.   { X = sqliteJoinType(pParse,&A,&B,0); }
4177c478bd9Sstevel@tonic-gate joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
4187c478bd9Sstevel@tonic-gate                                        { X = sqliteJoinType(pParse,&A,&B,&C); }
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate %type on_opt {Expr*}
4217c478bd9Sstevel@tonic-gate %destructor on_opt {sqliteExprDelete($$);}
4227c478bd9Sstevel@tonic-gate on_opt(N) ::= ON expr(E).   {N = E;}
4237c478bd9Sstevel@tonic-gate on_opt(N) ::= .             {N = 0;}
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate %type using_opt {IdList*}
4267c478bd9Sstevel@tonic-gate %destructor using_opt {sqliteIdListDelete($$);}
4277c478bd9Sstevel@tonic-gate using_opt(U) ::= USING LP idxlist(L) RP.  {U = L;}
4287c478bd9Sstevel@tonic-gate using_opt(U) ::= .                        {U = 0;}
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate %type orderby_opt {ExprList*}
4327c478bd9Sstevel@tonic-gate %destructor orderby_opt {sqliteExprListDelete($$);}
4337c478bd9Sstevel@tonic-gate %type sortlist {ExprList*}
4347c478bd9Sstevel@tonic-gate %destructor sortlist {sqliteExprListDelete($$);}
4357c478bd9Sstevel@tonic-gate %type sortitem {Expr*}
4367c478bd9Sstevel@tonic-gate %destructor sortitem {sqliteExprDelete($$);}
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate orderby_opt(A) ::= .                          {A = 0;}
4397c478bd9Sstevel@tonic-gate orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
4407c478bd9Sstevel@tonic-gate sortlist(A) ::= sortlist(X) COMMA sortitem(Y) collate(C) sortorder(Z). {
4417c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(X,Y,0);
4427c478bd9Sstevel@tonic-gate   if( A ) A->a[A->nExpr-1].sortOrder = C+Z;
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate sortlist(A) ::= sortitem(Y) collate(C) sortorder(Z). {
4457c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(0,Y,0);
4467c478bd9Sstevel@tonic-gate   if( A ) A->a[0].sortOrder = C+Z;
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate sortitem(A) ::= expr(X).   {A = X;}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate %type sortorder {int}
4517c478bd9Sstevel@tonic-gate %type collate {int}
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
4547c478bd9Sstevel@tonic-gate sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
4557c478bd9Sstevel@tonic-gate sortorder(A) ::= .              {A = SQLITE_SO_ASC;}
4567c478bd9Sstevel@tonic-gate collate(C) ::= .                {C = SQLITE_SO_UNK;}
4577c478bd9Sstevel@tonic-gate collate(C) ::= COLLATE id(X).   {C = sqliteCollateType(X.z, X.n);}
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate %type groupby_opt {ExprList*}
4607c478bd9Sstevel@tonic-gate %destructor groupby_opt {sqliteExprListDelete($$);}
4617c478bd9Sstevel@tonic-gate groupby_opt(A) ::= .                      {A = 0;}
4627c478bd9Sstevel@tonic-gate groupby_opt(A) ::= GROUP BY exprlist(X).  {A = X;}
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate %type having_opt {Expr*}
4657c478bd9Sstevel@tonic-gate %destructor having_opt {sqliteExprDelete($$);}
4667c478bd9Sstevel@tonic-gate having_opt(A) ::= .                {A = 0;}
4677c478bd9Sstevel@tonic-gate having_opt(A) ::= HAVING expr(X).  {A = X;}
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate %type limit_opt {struct LimitVal}
4707c478bd9Sstevel@tonic-gate limit_opt(A) ::= .                     {A.limit = -1; A.offset = 0;}
4717c478bd9Sstevel@tonic-gate limit_opt(A) ::= LIMIT signed(X).      {A.limit = X; A.offset = 0;}
472*1da57d55SToomas Soome limit_opt(A) ::= LIMIT signed(X) OFFSET signed(Y).
4737c478bd9Sstevel@tonic-gate                                        {A.limit = X; A.offset = Y;}
474*1da57d55SToomas Soome limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y).
4757c478bd9Sstevel@tonic-gate                                        {A.limit = Y; A.offset = X;}
4767c478bd9Sstevel@tonic-gate 
4777c478bd9Sstevel@tonic-gate /////////////////////////// The DELETE statement /////////////////////////////
4787c478bd9Sstevel@tonic-gate //
4797c478bd9Sstevel@tonic-gate cmd ::= DELETE FROM nm(X) dbnm(D) where_opt(Y). {
4807c478bd9Sstevel@tonic-gate    sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&X,&D), Y);
4817c478bd9Sstevel@tonic-gate }
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate %type where_opt {Expr*}
4847c478bd9Sstevel@tonic-gate %destructor where_opt {sqliteExprDelete($$);}
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate where_opt(A) ::= .                    {A = 0;}
4877c478bd9Sstevel@tonic-gate where_opt(A) ::= WHERE expr(X).       {A = X;}
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate %type setlist {ExprList*}
4907c478bd9Sstevel@tonic-gate %destructor setlist {sqliteExprListDelete($$);}
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate ////////////////////////// The UPDATE command ////////////////////////////////
4937c478bd9Sstevel@tonic-gate //
4947c478bd9Sstevel@tonic-gate cmd ::= UPDATE orconf(R) nm(X) dbnm(D) SET setlist(Y) where_opt(Z).
4957c478bd9Sstevel@tonic-gate     {sqliteUpdate(pParse,sqliteSrcListAppend(0,&X,&D),Y,Z,R);}
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y).
4987c478bd9Sstevel@tonic-gate     {A = sqliteExprListAppend(Z,Y,&X);}
4997c478bd9Sstevel@tonic-gate setlist(A) ::= nm(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate ////////////////////////// The INSERT command /////////////////////////////////
5027c478bd9Sstevel@tonic-gate //
503*1da57d55SToomas Soome cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F)
5047c478bd9Sstevel@tonic-gate         VALUES LP itemlist(Y) RP.
5057c478bd9Sstevel@tonic-gate             {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), Y, 0, F, R);}
5067c478bd9Sstevel@tonic-gate cmd ::= insert_cmd(R) INTO nm(X) dbnm(D) inscollist_opt(F) select(S).
5077c478bd9Sstevel@tonic-gate             {sqliteInsert(pParse, sqliteSrcListAppend(0,&X,&D), 0, S, F, R);}
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate %type insert_cmd {int}
5107c478bd9Sstevel@tonic-gate insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
5117c478bd9Sstevel@tonic-gate insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate %type itemlist {ExprList*}
5157c478bd9Sstevel@tonic-gate %destructor itemlist {sqliteExprListDelete($$);}
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate itemlist(A) ::= itemlist(X) COMMA expr(Y).  {A = sqliteExprListAppend(X,Y,0);}
5187c478bd9Sstevel@tonic-gate itemlist(A) ::= expr(X).                    {A = sqliteExprListAppend(0,X,0);}
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate %type inscollist_opt {IdList*}
5217c478bd9Sstevel@tonic-gate %destructor inscollist_opt {sqliteIdListDelete($$);}
5227c478bd9Sstevel@tonic-gate %type inscollist {IdList*}
5237c478bd9Sstevel@tonic-gate %destructor inscollist {sqliteIdListDelete($$);}
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate inscollist_opt(A) ::= .                       {A = 0;}
5267c478bd9Sstevel@tonic-gate inscollist_opt(A) ::= LP inscollist(X) RP.    {A = X;}
5277c478bd9Sstevel@tonic-gate inscollist(A) ::= inscollist(X) COMMA nm(Y).  {A = sqliteIdListAppend(X,&Y);}
5287c478bd9Sstevel@tonic-gate inscollist(A) ::= nm(Y).                      {A = sqliteIdListAppend(0,&Y);}
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate /////////////////////////// Expression Processing /////////////////////////////
5317c478bd9Sstevel@tonic-gate //
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate %type expr {Expr*}
5347c478bd9Sstevel@tonic-gate %destructor expr {sqliteExprDelete($$);}
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate expr(A) ::= LP(B) expr(X) RP(E). {A = X; sqliteExprSpan(A,&B,&E); }
5377c478bd9Sstevel@tonic-gate expr(A) ::= NULL(X).             {A = sqliteExpr(TK_NULL, 0, 0, &X);}
5387c478bd9Sstevel@tonic-gate expr(A) ::= ID(X).               {A = sqliteExpr(TK_ID, 0, 0, &X);}
5397c478bd9Sstevel@tonic-gate expr(A) ::= JOIN_KW(X).          {A = sqliteExpr(TK_ID, 0, 0, &X);}
5407c478bd9Sstevel@tonic-gate expr(A) ::= nm(X) DOT nm(Y). {
5417c478bd9Sstevel@tonic-gate   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
5427c478bd9Sstevel@tonic-gate   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
5437c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_DOT, temp1, temp2, 0);
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
5467c478bd9Sstevel@tonic-gate   Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
5477c478bd9Sstevel@tonic-gate   Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
5487c478bd9Sstevel@tonic-gate   Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &Z);
5497c478bd9Sstevel@tonic-gate   Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
5507c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_DOT, temp1, temp4, 0);
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
5537c478bd9Sstevel@tonic-gate expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
5547c478bd9Sstevel@tonic-gate expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
5557c478bd9Sstevel@tonic-gate expr(A) ::= VARIABLE(X).     {
5567c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_VARIABLE, 0, 0, &X);
5577c478bd9Sstevel@tonic-gate   if( A ) A->iTable = ++pParse->nVar;
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
5607c478bd9Sstevel@tonic-gate   A = sqliteExprFunction(Y, &X);
5617c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X,&E);
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate expr(A) ::= ID(X) LP STAR RP(E). {
5647c478bd9Sstevel@tonic-gate   A = sqliteExprFunction(0, &X);
5657c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X,&E);
5667c478bd9Sstevel@tonic-gate }
5677c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) AND expr(Y).   {A = sqliteExpr(TK_AND, X, Y, 0);}
5687c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
5697c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
5707c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
5717c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
5727c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
5737c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NE expr(Y).    {A = sqliteExpr(TK_NE, X, Y, 0);}
5747c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) EQ expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
5757c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
5767c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) BITOR expr(Y).  {A = sqliteExpr(TK_BITOR, X, Y, 0);}
5777c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
5787c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
5797c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
5807c478bd9Sstevel@tonic-gate   ExprList *pList = sqliteExprListAppend(0, Y, 0);
5817c478bd9Sstevel@tonic-gate   pList = sqliteExprListAppend(pList, X, 0);
5827c478bd9Sstevel@tonic-gate   A = sqliteExprFunction(pList, 0);
5837c478bd9Sstevel@tonic-gate   if( A ) A->op = OP;
5847c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &X->span, &Y->span);
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
5877c478bd9Sstevel@tonic-gate   ExprList *pList = sqliteExprListAppend(0, Y, 0);
5887c478bd9Sstevel@tonic-gate   pList = sqliteExprListAppend(pList, X, 0);
5897c478bd9Sstevel@tonic-gate   A = sqliteExprFunction(pList, 0);
5907c478bd9Sstevel@tonic-gate   if( A ) A->op = OP;
5917c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, A, 0, 0);
5927c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&Y->span);
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate %type likeop {int}
5957c478bd9Sstevel@tonic-gate likeop(A) ::= LIKE. {A = TK_LIKE;}
5967c478bd9Sstevel@tonic-gate likeop(A) ::= GLOB. {A = TK_GLOB;}
5977c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
5987c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
5997c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
6007c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
6017c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) REM expr(Y).   {A = sqliteExpr(TK_REM, X, Y, 0);}
6027c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) CONCAT expr(Y). {A = sqliteExpr(TK_CONCAT, X, Y, 0);}
6037c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) ISNULL(E). {
6047c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_ISNULL, X, 0, 0);
6057c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) IS NULL(E). {
6087c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_ISNULL, X, 0, 0);
6097c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOTNULL(E). {
6127c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
6137c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOT NULL(E). {
6167c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
6177c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) IS NOT NULL(E). {
6207c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOTNULL, X, 0, 0);
6217c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6227c478bd9Sstevel@tonic-gate }
6237c478bd9Sstevel@tonic-gate expr(A) ::= NOT(B) expr(X). {
6247c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, X, 0, 0);
6257c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&B,&X->span);
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate expr(A) ::= BITNOT(B) expr(X). {
6287c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_BITNOT, X, 0, 0);
6297c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&B,&X->span);
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate expr(A) ::= MINUS(B) expr(X). [UMINUS] {
6327c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_UMINUS, X, 0, 0);
6337c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&B,&X->span);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate expr(A) ::= PLUS(B) expr(X). [UPLUS] {
6367c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_UPLUS, X, 0, 0);
6377c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&B,&X->span);
6387c478bd9Sstevel@tonic-gate }
6397c478bd9Sstevel@tonic-gate expr(A) ::= LP(B) select(X) RP(E). {
6407c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_SELECT, 0, 0, 0);
6417c478bd9Sstevel@tonic-gate   if( A ) A->pSelect = X;
6427c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&B,&E);
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
6457c478bd9Sstevel@tonic-gate   ExprList *pList = sqliteExprListAppend(0, X, 0);
6467c478bd9Sstevel@tonic-gate   pList = sqliteExprListAppend(pList, Y, 0);
6477c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_BETWEEN, W, 0, 0);
6487c478bd9Sstevel@tonic-gate   if( A ) A->pList = pList;
6497c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&W->span,&Y->span);
6507c478bd9Sstevel@tonic-gate }
6517c478bd9Sstevel@tonic-gate expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
6527c478bd9Sstevel@tonic-gate   ExprList *pList = sqliteExprListAppend(0, X, 0);
6537c478bd9Sstevel@tonic-gate   pList = sqliteExprListAppend(pList, Y, 0);
6547c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_BETWEEN, W, 0, 0);
6557c478bd9Sstevel@tonic-gate   if( A ) A->pList = pList;
6567c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, A, 0, 0);
6577c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&W->span,&Y->span);
6587c478bd9Sstevel@tonic-gate }
6597c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) IN LP exprlist(Y) RP(E).  {
6607c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6617c478bd9Sstevel@tonic-gate   if( A ) A->pList = Y;
6627c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) IN LP select(Y) RP(E).  {
6657c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6667c478bd9Sstevel@tonic-gate   if( A ) A->pSelect = Y;
6677c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E).  {
6707c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6717c478bd9Sstevel@tonic-gate   if( A ) A->pList = Y;
6727c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, A, 0, 0);
6737c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6747c478bd9Sstevel@tonic-gate }
6757c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
6767c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6777c478bd9Sstevel@tonic-gate   if( A ) A->pSelect = Y;
6787c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, A, 0, 0);
6797c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,&E);
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) IN nm(Y) dbnm(D). {
6827c478bd9Sstevel@tonic-gate   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
6837c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6847c478bd9Sstevel@tonic-gate   if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
6857c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,D.z?&D:&Y);
6867c478bd9Sstevel@tonic-gate }
6877c478bd9Sstevel@tonic-gate expr(A) ::= expr(X) NOT IN nm(Y) dbnm(D). {
6887c478bd9Sstevel@tonic-gate   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
6897c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_IN, X, 0, 0);
6907c478bd9Sstevel@tonic-gate   if( A ) A->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
6917c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_NOT, A, 0, 0);
6927c478bd9Sstevel@tonic-gate   sqliteExprSpan(A,&X->span,D.z?&D:&Y);
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate /* CASE expressions */
6977c478bd9Sstevel@tonic-gate expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
6987c478bd9Sstevel@tonic-gate   A = sqliteExpr(TK_CASE, X, Z, 0);
6997c478bd9Sstevel@tonic-gate   if( A ) A->pList = Y;
7007c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &C, &E);
7017c478bd9Sstevel@tonic-gate }
7027c478bd9Sstevel@tonic-gate %type case_exprlist {ExprList*}
7037c478bd9Sstevel@tonic-gate %destructor case_exprlist {sqliteExprListDelete($$);}
7047c478bd9Sstevel@tonic-gate case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
7057c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(X, Y, 0);
7067c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(A, Z, 0);
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
7097c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(0, Y, 0);
7107c478bd9Sstevel@tonic-gate   A = sqliteExprListAppend(A, Z, 0);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate %type case_else {Expr*}
7137c478bd9Sstevel@tonic-gate case_else(A) ::=  ELSE expr(X).         {A = X;}
714*1da57d55SToomas Soome case_else(A) ::=  .                     {A = 0;}
7157c478bd9Sstevel@tonic-gate %type case_operand {Expr*}
716*1da57d55SToomas Soome case_operand(A) ::= expr(X).            {A = X;}
717*1da57d55SToomas Soome case_operand(A) ::= .                   {A = 0;}
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate %type exprlist {ExprList*}
7207c478bd9Sstevel@tonic-gate %destructor exprlist {sqliteExprListDelete($$);}
7217c478bd9Sstevel@tonic-gate %type expritem {Expr*}
7227c478bd9Sstevel@tonic-gate %destructor expritem {sqliteExprDelete($$);}
7237c478bd9Sstevel@tonic-gate 
724*1da57d55SToomas Soome exprlist(A) ::= exprlist(X) COMMA expritem(Y).
7257c478bd9Sstevel@tonic-gate    {A = sqliteExprListAppend(X,Y,0);}
7267c478bd9Sstevel@tonic-gate exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
7277c478bd9Sstevel@tonic-gate expritem(A) ::= expr(X).                {A = X;}
7287c478bd9Sstevel@tonic-gate expritem(A) ::= .                       {A = 0;}
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate ///////////////////////////// The CREATE INDEX command ///////////////////////
7317c478bd9Sstevel@tonic-gate //
7327c478bd9Sstevel@tonic-gate cmd ::= CREATE(S) uniqueflag(U) INDEX nm(X)
7337c478bd9Sstevel@tonic-gate         ON nm(Y) dbnm(D) LP idxlist(Z) RP(E) onconf(R). {
7347c478bd9Sstevel@tonic-gate   SrcList *pSrc = sqliteSrcListAppend(0, &Y, &D);
7357c478bd9Sstevel@tonic-gate   if( U!=OE_None ) U = R;
7367c478bd9Sstevel@tonic-gate   if( U==OE_Default) U = OE_Abort;
7377c478bd9Sstevel@tonic-gate   sqliteCreateIndex(pParse, &X, pSrc, Z, U, &S, &E);
7387c478bd9Sstevel@tonic-gate }
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate %type uniqueflag {int}
7417c478bd9Sstevel@tonic-gate uniqueflag(A) ::= UNIQUE.  { A = OE_Abort; }
7427c478bd9Sstevel@tonic-gate uniqueflag(A) ::= .        { A = OE_None; }
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate %type idxlist {IdList*}
7457c478bd9Sstevel@tonic-gate %destructor idxlist {sqliteIdListDelete($$);}
7467c478bd9Sstevel@tonic-gate %type idxlist_opt {IdList*}
7477c478bd9Sstevel@tonic-gate %destructor idxlist_opt {sqliteIdListDelete($$);}
7487c478bd9Sstevel@tonic-gate %type idxitem {Token}
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate idxlist_opt(A) ::= .                         {A = 0;}
7517c478bd9Sstevel@tonic-gate idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
7527c478bd9Sstevel@tonic-gate idxlist(A) ::= idxlist(X) COMMA idxitem(Y).  {A = sqliteIdListAppend(X,&Y);}
7537c478bd9Sstevel@tonic-gate idxlist(A) ::= idxitem(Y).                   {A = sqliteIdListAppend(0,&Y);}
7547c478bd9Sstevel@tonic-gate idxitem(A) ::= nm(X) sortorder.              {A = X;}
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate ///////////////////////////// The DROP INDEX command /////////////////////////
7577c478bd9Sstevel@tonic-gate //
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate cmd ::= DROP INDEX nm(X) dbnm(Y).   {
7607c478bd9Sstevel@tonic-gate   sqliteDropIndex(pParse, sqliteSrcListAppend(0,&X,&Y));
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate ///////////////////////////// The COPY command ///////////////////////////////
7657c478bd9Sstevel@tonic-gate //
7667c478bd9Sstevel@tonic-gate cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y) USING DELIMITERS STRING(Z).
7677c478bd9Sstevel@tonic-gate     {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,&Z,R);}
7687c478bd9Sstevel@tonic-gate cmd ::= COPY orconf(R) nm(X) dbnm(D) FROM nm(Y).
7697c478bd9Sstevel@tonic-gate     {sqliteCopy(pParse,sqliteSrcListAppend(0,&X,&D),&Y,0,R);}
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate ///////////////////////////// The VACUUM command /////////////////////////////
7727c478bd9Sstevel@tonic-gate //
7737c478bd9Sstevel@tonic-gate cmd ::= VACUUM.                {sqliteVacuum(pParse,0);}
7747c478bd9Sstevel@tonic-gate cmd ::= VACUUM nm(X).         {sqliteVacuum(pParse,&X);}
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate ///////////////////////////// The PRAGMA command /////////////////////////////
7777c478bd9Sstevel@tonic-gate //
7787c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X) EQ nm(Y).         {sqlitePragma(pParse,&X,&Y,0);}
7797c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X) EQ ON(Y).          {sqlitePragma(pParse,&X,&Y,0);}
7807c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X) EQ plus_num(Y).    {sqlitePragma(pParse,&X,&Y,0);}
7817c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X) EQ minus_num(Y).   {sqlitePragma(pParse,&X,&Y,1);}
7827c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X) LP nm(Y) RP.      {sqlitePragma(pParse,&X,&Y,0);}
7837c478bd9Sstevel@tonic-gate cmd ::= PRAGMA ids(X).                   {sqlitePragma(pParse,&X,&X,0);}
7847c478bd9Sstevel@tonic-gate plus_num(A) ::= plus_opt number(X).   {A = X;}
7857c478bd9Sstevel@tonic-gate minus_num(A) ::= MINUS number(X).     {A = X;}
7867c478bd9Sstevel@tonic-gate number(A) ::= INTEGER(X).  {A = X;}
7877c478bd9Sstevel@tonic-gate number(A) ::= FLOAT(X).    {A = X;}
7887c478bd9Sstevel@tonic-gate plus_opt ::= PLUS.
7897c478bd9Sstevel@tonic-gate plus_opt ::= .
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate //////////////////////////// The CREATE TRIGGER command /////////////////////
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate cmd ::= CREATE(A) trigger_decl BEGIN trigger_cmd_list(S) END(Z). {
7947c478bd9Sstevel@tonic-gate   Token all;
7957c478bd9Sstevel@tonic-gate   all.z = A.z;
7967c478bd9Sstevel@tonic-gate   all.n = (Z.z - A.z) + Z.n;
7977c478bd9Sstevel@tonic-gate   sqliteFinishTrigger(pParse, S, &all);
7987c478bd9Sstevel@tonic-gate }
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate trigger_decl ::= temp(T) TRIGGER nm(B) trigger_time(C) trigger_event(D)
8017c478bd9Sstevel@tonic-gate                  ON nm(E) dbnm(DB) foreach_clause(F) when_clause(G). {
8027c478bd9Sstevel@tonic-gate   SrcList *pTab = sqliteSrcListAppend(0, &E, &DB);
8037c478bd9Sstevel@tonic-gate   sqliteBeginTrigger(pParse, &B, C, D.a, D.b, pTab, F, G, T);
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate %type trigger_time  {int}
8077c478bd9Sstevel@tonic-gate trigger_time(A) ::= BEFORE.      { A = TK_BEFORE; }
8087c478bd9Sstevel@tonic-gate trigger_time(A) ::= AFTER.       { A = TK_AFTER;  }
8097c478bd9Sstevel@tonic-gate trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
8107c478bd9Sstevel@tonic-gate trigger_time(A) ::= .            { A = TK_BEFORE; }
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate %type trigger_event {struct TrigEvent}
8137c478bd9Sstevel@tonic-gate %destructor trigger_event {sqliteIdListDelete($$.b);}
8147c478bd9Sstevel@tonic-gate trigger_event(A) ::= DELETE. { A.a = TK_DELETE; A.b = 0; }
8157c478bd9Sstevel@tonic-gate trigger_event(A) ::= INSERT. { A.a = TK_INSERT; A.b = 0; }
8167c478bd9Sstevel@tonic-gate trigger_event(A) ::= UPDATE. { A.a = TK_UPDATE; A.b = 0;}
8177c478bd9Sstevel@tonic-gate trigger_event(A) ::= UPDATE OF inscollist(X). {A.a = TK_UPDATE; A.b = X; }
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate %type foreach_clause {int}
8207c478bd9Sstevel@tonic-gate foreach_clause(A) ::= .                   { A = TK_ROW; }
8217c478bd9Sstevel@tonic-gate foreach_clause(A) ::= FOR EACH ROW.       { A = TK_ROW; }
8227c478bd9Sstevel@tonic-gate foreach_clause(A) ::= FOR EACH STATEMENT. { A = TK_STATEMENT; }
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate %type when_clause {Expr *}
8257c478bd9Sstevel@tonic-gate when_clause(A) ::= .             { A = 0; }
8267c478bd9Sstevel@tonic-gate when_clause(A) ::= WHEN expr(X). { A = X; }
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate %type trigger_cmd_list {TriggerStep *}
8297c478bd9Sstevel@tonic-gate %destructor trigger_cmd_list {sqliteDeleteTriggerStep($$);}
8307c478bd9Sstevel@tonic-gate trigger_cmd_list(A) ::= trigger_cmd(X) SEMI trigger_cmd_list(Y). {
8317c478bd9Sstevel@tonic-gate   X->pNext = Y;
8327c478bd9Sstevel@tonic-gate   A = X;
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate trigger_cmd_list(A) ::= . { A = 0; }
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate %type trigger_cmd {TriggerStep *}
8377c478bd9Sstevel@tonic-gate %destructor trigger_cmd {sqliteDeleteTriggerStep($$);}
838*1da57d55SToomas Soome // UPDATE
839*1da57d55SToomas Soome trigger_cmd(A) ::= UPDATE orconf(R) nm(X) SET setlist(Y) where_opt(Z).
8407c478bd9Sstevel@tonic-gate                { A = sqliteTriggerUpdateStep(&X, Y, Z, R); }
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate // INSERT
843*1da57d55SToomas Soome trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F)
844*1da57d55SToomas Soome   VALUES LP itemlist(Y) RP.
8457c478bd9Sstevel@tonic-gate {A = sqliteTriggerInsertStep(&X, F, Y, 0, R);}
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate trigger_cmd(A) ::= insert_cmd(R) INTO nm(X) inscollist_opt(F) select(S).
8487c478bd9Sstevel@tonic-gate                {A = sqliteTriggerInsertStep(&X, F, 0, S, R);}
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate // DELETE
8517c478bd9Sstevel@tonic-gate trigger_cmd(A) ::= DELETE FROM nm(X) where_opt(Y).
8527c478bd9Sstevel@tonic-gate                {A = sqliteTriggerDeleteStep(&X, Y);}
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate // SELECT
8557c478bd9Sstevel@tonic-gate trigger_cmd(A) ::= select(X).  {A = sqliteTriggerSelectStep(X); }
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate // The special RAISE expression that may occur in trigger programs
8587c478bd9Sstevel@tonic-gate expr(A) ::= RAISE(X) LP IGNORE RP(Y).  {
859*1da57d55SToomas Soome   A = sqliteExpr(TK_RAISE, 0, 0, 0);
8607c478bd9Sstevel@tonic-gate   A->iColumn = OE_Ignore;
8617c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &X, &Y);
8627c478bd9Sstevel@tonic-gate }
8637c478bd9Sstevel@tonic-gate expr(A) ::= RAISE(X) LP ROLLBACK COMMA nm(Z) RP(Y).  {
864*1da57d55SToomas Soome   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
8657c478bd9Sstevel@tonic-gate   A->iColumn = OE_Rollback;
8667c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &X, &Y);
8677c478bd9Sstevel@tonic-gate }
8687c478bd9Sstevel@tonic-gate expr(A) ::= RAISE(X) LP ABORT COMMA nm(Z) RP(Y).  {
869*1da57d55SToomas Soome   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
8707c478bd9Sstevel@tonic-gate   A->iColumn = OE_Abort;
8717c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &X, &Y);
8727c478bd9Sstevel@tonic-gate }
8737c478bd9Sstevel@tonic-gate expr(A) ::= RAISE(X) LP FAIL COMMA nm(Z) RP(Y).  {
874*1da57d55SToomas Soome   A = sqliteExpr(TK_RAISE, 0, 0, &Z);
8757c478bd9Sstevel@tonic-gate   A->iColumn = OE_Fail;
8767c478bd9Sstevel@tonic-gate   sqliteExprSpan(A, &X, &Y);
8777c478bd9Sstevel@tonic-gate }
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate ////////////////////////  DROP TRIGGER statement //////////////////////////////
8807c478bd9Sstevel@tonic-gate cmd ::= DROP TRIGGER nm(X) dbnm(D). {
8817c478bd9Sstevel@tonic-gate   sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&X,&D));
8827c478bd9Sstevel@tonic-gate }
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate //////////////////////// ATTACH DATABASE file AS name /////////////////////////
8857c478bd9Sstevel@tonic-gate cmd ::= ATTACH database_kw_opt ids(F) AS nm(D) key_opt(K). {
8867c478bd9Sstevel@tonic-gate   sqliteAttach(pParse, &F, &D, &K);
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate %type key_opt {Token}
8897c478bd9Sstevel@tonic-gate key_opt(A) ::= USING ids(X).  { A = X; }
8907c478bd9Sstevel@tonic-gate key_opt(A) ::= .              { A.z = 0; A.n = 0; }
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate database_kw_opt ::= DATABASE.
8937c478bd9Sstevel@tonic-gate database_kw_opt ::= .
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate //////////////////////// DETACH DATABASE name /////////////////////////////////
8967c478bd9Sstevel@tonic-gate cmd ::= DETACH database_kw_opt nm(D). {
8977c478bd9Sstevel@tonic-gate   sqliteDetach(pParse, &D);
8987c478bd9Sstevel@tonic-gate }
899