%include {
/*
** 2001-09-15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains SQLite's SQL parser.
**
** The canonical source code to this file ("parse.y") is a Lemon grammar 
** file that specifies the input grammar and actions to take while parsing.
** That input file is processed by Lemon to generate a C-language 
** implementation of a parser for the given grammer.  You might be reading
** this comment as part of the translated C-code.  Edits should be made
** to the original parse.y sources.
*/
}

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
//
%token_type {Token}
%default_type {Token}

// An extra argument to the constructor for the parser, which is available
// to all actions.
%extra_context {Parse *pParse}

// This code runs whenever there is a syntax error
//
%syntax_error {
  UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
  if( TOKEN.z[0] ){
    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
  }else{
    sqlite3ErrorMsg(pParse, "incomplete input");
  }
}
%stack_overflow {
  sqlite3ErrorMsg(pParse, "parser stack overflow");
}

// The name of the generated procedure that implements the parser
// is as follows:
%name sqlite3Parser

// The following text is included near the beginning of the C source
// code file that implements the parser.
//
%include {
#include "sqliteInt.h"

/*
** Disable all error recovery processing in the parser push-down
** automaton.
*/
#define YYNOERRORRECOVERY 1

/*
** Make yytestcase() the same as testcase()
*/
#define yytestcase(X) testcase(X)

/*
** Indicate that sqlite3ParserFree() will never be called with a null
** pointer.
*/
#define YYPARSEFREENEVERNULL 1

/*
** In the amalgamation, the parse.c file generated by lemon and the
** tokenize.c file are concatenated.  In that case, sqlite3RunParser()
** has access to the the size of the yyParser object and so the parser
** engine can be allocated from stack.  In that case, only the
** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
** omitted.
*/
#ifdef SQLITE_AMALGAMATION
# define sqlite3Parser_ENGINEALWAYSONSTACK 1
#endif

/*
** Alternative datatype for the argument to the malloc() routine passed
** into sqlite3ParserAlloc().  The default is size_t.
*/
#define YYMALLOCARGTYPE  u64

/*
** An instance of the following structure describes the event of a
** TRIGGER.  "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD.  If the event is of the form
**
**      UPDATE ON (a,b,c)
**
** Then the "b" IdList records the list "a,b,c".
*/
struct TrigEvent { int a; IdList * b; };

struct FrameBound     { int eType; Expr *pExpr; };

/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
static void disableLookaside(Parse *pParse){
  sqlite3 *db = pParse->db;
  pParse->disableLookaside++;
  DisableLookaside;
}

#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \
 && defined(SQLITE_UDL_CAPABLE_PARSER)
/*
** Issue an error message if an ORDER BY or LIMIT clause occurs on an
** UPDATE or DELETE statement.
*/
static void updateDeleteLimitError(
  Parse *pParse,
  ExprList *pOrderBy,
  Expr *pLimit
){
  if( pOrderBy ){
    sqlite3ErrorMsg(pParse, "syntax error near \"ORDER BY\"");
  }else{
    sqlite3ErrorMsg(pParse, "syntax error near \"LIMIT\"");
  }
  sqlite3ExprListDelete(pParse->db, pOrderBy);
  sqlite3ExprDelete(pParse->db, pLimit);
}
#endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */

} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
ecmd ::= SEMI.
ecmd ::= cmdx SEMI.
%ifndef SQLITE_OMIT_EXPLAIN
ecmd ::= explain cmdx SEMI.       {NEVER-REDUCE}
explain ::= EXPLAIN.              { pParse->explain = 1; }
explain ::= EXPLAIN QUERY PLAN.   { pParse->explain = 2; }
%endif  SQLITE_OMIT_EXPLAIN
cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }

///////////////////// Begin and end transactions. ////////////////////////////
//

cmd ::= BEGIN transtype(Y) trans_opt.  {sqlite3BeginTransaction(pParse, Y);}
trans_opt ::= .
trans_opt ::= TRANSACTION.
trans_opt ::= TRANSACTION nm.
%type transtype {int}
transtype(A) ::= .             {A = TK_DEFERRED;}
transtype(A) ::= DEFERRED(X).  {A = @X; /*A-overwrites-X*/}
transtype(A) ::= IMMEDIATE(X). {A = @X; /*A-overwrites-X*/}
transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
cmd ::= COMMIT|END(X) trans_opt.   {sqlite3EndTransaction(pParse,@X);}
cmd ::= ROLLBACK(X) trans_opt.     {sqlite3EndTransaction(pParse,@X);}

savepoint_opt ::= SAVEPOINT.
savepoint_opt ::= .
cmd ::= SAVEPOINT nm(X). {
  sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &X);
}
cmd ::= RELEASE savepoint_opt nm(X). {
  sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &X);
}
cmd ::= ROLLBACK trans_opt TO savepoint_opt nm(X). {
  sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &X);
}

///////////////////// The CREATE TABLE statement ////////////////////////////
//
cmd ::= create_table create_table_args.
create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
   sqlite3StartTable(pParse,&Y,&Z,T,0,0,E);
}
createkw(A) ::= CREATE(A).  {disableLookaside(pParse);}

%type ifnotexists {int}
ifnotexists(A) ::= .              {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
%type temp {int}
%ifndef SQLITE_OMIT_TEMPDB
temp(A) ::= TEMP.  {A = pParse->db->init.busy==0;}
%endif  SQLITE_OMIT_TEMPDB
temp(A) ::= .      {A = 0;}
create_table_args ::= LP columnlist conslist_opt(X) RP(E) table_option_set(F). {
  sqlite3EndTable(pParse,&X,&E,F,0);
}
create_table_args ::= AS select(S). {
  sqlite3EndTable(pParse,0,0,0,S);
  sqlite3SelectDelete(pParse->db, S);
}
%type table_option_set {u32}
%type table_option {u32}
table_option_set(A) ::= .    {A = 0;}
table_option_set(A) ::= table_option(A).
table_option_set(A) ::= table_option_set(X) COMMA table_option(Y). {A = X|Y;}
table_option(A) ::= WITHOUT nm(X). {
  if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
    A = TF_WithoutRowid | TF_NoVisibleRowid;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
table_option(A) ::= nm(X). {
  if( X.n==6 && sqlite3_strnicmp(X.z,"strict",6)==0 ){
    A = TF_Strict;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}

// Declare some tokens early in order to influence their values, to 
// improve performance and reduce the executable size.  The goal here is
// to get the "jump" operations in ISNULL through ESCAPE to have numeric
// values that are early enough so that all jump operations are clustered
// at the beginning.
//
%token ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST.
%token CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL.
%token OR AND NOT IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%token GT LE LT GE ESCAPE.

// The following directive causes tokens ABORT, AFTER, ASC, etc. to
// fallback to ID if they will not parse as their original value.
// This obviates the need for the "id" nonterminal.
//
%fallback ID
  ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
  CONFLICT DATABASE DEFERRED DESC DETACH DO
  EACH END EXCLUSIVE EXPLAIN FAIL FOR
  IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
  QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
  ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
  NULLS FIRST LAST
%ifdef SQLITE_OMIT_COMPOUND_SELECT
  EXCEPT INTERSECT UNION
%endif SQLITE_OMIT_COMPOUND_SELECT
%ifndef SQLITE_OMIT_WINDOWFUNC
  CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
  EXCLUDE GROUPS OTHERS TIES
%endif SQLITE_OMIT_WINDOWFUNC
%ifndef SQLITE_OMIT_GENERATED_COLUMNS
  GENERATED ALWAYS
%endif
  MATERIALIZED
  REINDEX RENAME CTIME_KW IF
  .
%wildcard ANY.

// Define operator precedence early so that this is the first occurrence
// of the operator tokens in the grammer.  Keeping the operators together
// causes them to be assigned integer values that are close together,
// which keeps parser tables smaller.
//
// The token values assigned to these symbols is determined by the order
// in which lemon first sees them.  It must be the case that ISNULL/NOTNULL,
// NE/EQ, GT/LE, and GE/LT are separated by only a single value.  See
// the sqlite3ExprIfFalse() routine for additional information on this
// constraint.
//
%left OR.
%left AND.
%right NOT.
%left IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
%left GT LE LT GE.
%right ESCAPE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT PTR.
%left COLLATE.
%right BITNOT.
%nonassoc ON.

// An IDENTIFIER can be a generic identifier, or one of several
// keywords.  Any non-standard keyword can also be an identifier.
//
%token_class id  ID|INDEXED.


// And "ids" is an identifer-or-string.
//
%token_class ids  ID|STRING.

// The name of a column or table can be any of the following:
//
%type nm {Token}
nm(A) ::= id(A).
nm(A) ::= STRING(A).
nm(A) ::= JOIN_KW(A).

// A typetoken is really zero or more tokens that form a type name such
// as can be found after the column name in a CREATE TABLE statement.
// Multiple tokens are concatenated to form the value of the typetoken.
//
%type typetoken {Token}
typetoken(A) ::= .   {A.n = 0; A.z = 0;}
typetoken(A) ::= typename(A).
typetoken(A) ::= typename(A) LP signed RP(Y). {
  A.n = (int)(&Y.z[Y.n] - A.z);
}
typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
  A.n = (int)(&Y.z[Y.n] - A.z);
}
%type typename {Token}
typename(A) ::= ids(A).
typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
signed ::= plus_num.
signed ::= minus_num.

// The scanpt non-terminal takes a value which is a pointer to the
// input text just past the last token that has been shifted into
// the parser.  By surrounding some phrase in the grammar with two
// scanpt non-terminals, we can capture the input text for that phrase.
// For example:
//
//      something ::= .... scanpt(A) phrase scanpt(Z).
//
// The text that is parsed as "phrase" is a string starting at A
// and containing (int)(Z-A) characters.  There might be some extra
// whitespace on either end of the text, but that can be removed in
// post-processing, if needed.
//
%type scanpt {const char*}
scanpt(A) ::= . {
  assert( yyLookahead!=YYNOCODE );
  A = yyLookaheadToken.z;
}
scantok(A) ::= . {
  assert( yyLookahead!=YYNOCODE );
  A = yyLookaheadToken;
}

// "carglist" is a list of additional constraints that come after the
// column name and column type in a CREATE TABLE statement.
//
carglist ::= carglist ccons.
carglist ::= .
ccons ::= CONSTRAINT nm(X).           {pParse->constraintName = X;}
ccons ::= DEFAULT scantok(A) term(X).
                            {sqlite3AddDefaultValue(pParse,X,A.z,&A.z[A.n]);}
ccons ::= DEFAULT LP(A) expr(X) RP(Z).
                            {sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);}
ccons ::= DEFAULT PLUS(A) scantok(Z) term(X).
                            {sqlite3AddDefaultValue(pParse,X,A.z,&Z.z[Z.n]);}
ccons ::= DEFAULT MINUS(A) scantok(Z) term(X). {
  Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
  sqlite3AddDefaultValue(pParse,p,A.z,&Z.z[Z.n]);
}
ccons ::= DEFAULT scantok id(X).       {
  Expr *p = tokenExpr(pParse, TK_STRING, X);
  if( p ){
    sqlite3ExprIdToTrueFalse(p);
    testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
  }
    sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}

// In addition to the type name, we also care about the primary key and
// UNIQUE constraints.
//
ccons ::= NULL onconf.
ccons ::= NOT NULL onconf(R).    {sqlite3AddNotNull(pParse, R);}
ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
                                 {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R).      {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
                                   SQLITE_IDXTYPE_UNIQUE);}
ccons ::= CHECK LP(A) expr(X) RP(B).  {sqlite3AddCheckConstraint(pParse,X,A.z,B.z);}
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
                                 {sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D).    {sqlite3DeferForeignKey(pParse,D);}
ccons ::= COLLATE ids(C).        {sqlite3AddCollateType(pParse, &C);}
ccons ::= GENERATED ALWAYS AS generated.
ccons ::= AS generated.
generated ::= LP expr(E) RP.          {sqlite3AddGenerated(pParse,E,0);}
generated ::= LP expr(E) RP ID(TYPE). {sqlite3AddGenerated(pParse,E,&TYPE);}

// The optional AUTOINCREMENT keyword
%type autoinc {int}
autoinc(X) ::= .          {X = 0;}
autoinc(X) ::= AUTOINCR.  {X = 1;}

// The next group of rules parses the arguments to a REFERENCES clause
// that determine if the referential integrity checking is deferred or
// or immediate and which determine what action to take if a ref-integ
// check fails.
//
%type refargs {int}
refargs(A) ::= .                  { A = OE_None*0x0101; /* EV: R-19803-45884 */}
refargs(A) ::= refargs(A) refarg(Y). { A = (A & ~Y.mask) | Y.value; }
%type refarg {struct {int value; int mask;}}
refarg(A) ::= MATCH nm.              { A.value = 0;     A.mask = 0x000000; }
refarg(A) ::= ON INSERT refact.      { A.value = 0;     A.mask = 0x000000; }
refarg(A) ::= ON DELETE refact(X).   { A.value = X;     A.mask = 0x0000ff; }
refarg(A) ::= ON UPDATE refact(X).   { A.value = X<<8;  A.mask = 0x00ff00; }
%type refact {int}
refact(A) ::= SET NULL.              { A = OE_SetNull;  /* EV: R-33326-45252 */}
refact(A) ::= SET DEFAULT.           { A = OE_SetDflt;  /* EV: R-33326-45252 */}
refact(A) ::= CASCADE.               { A = OE_Cascade;  /* EV: R-33326-45252 */}
refact(A) ::= RESTRICT.              { A = OE_Restrict; /* EV: R-33326-45252 */}
refact(A) ::= NO ACTION.             { A = OE_None;     /* EV: R-33326-45252 */}
%type defer_subclause {int}
defer_subclause(A) ::= NOT DEFERRABLE init_deferred_pred_opt.     {A = 0;}
defer_subclause(A) ::= DEFERRABLE init_deferred_pred_opt(X).      {A = X;}
%type init_deferred_pred_opt {int}
init_deferred_pred_opt(A) ::= .                       {A = 0;}
init_deferred_pred_opt(A) ::= INITIALLY DEFERRED.     {A = 1;}
init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE.    {A = 0;}

conslist_opt(A) ::= .                         {A.n = 0; A.z = 0;}
conslist_opt(A) ::= COMMA(A) conslist.
conslist ::= conslist tconscomma tcons.
conslist ::= tcons.
tconscomma ::= COMMA.            {pParse->constraintName.n = 0;}
tconscomma ::= .
tcons ::= CONSTRAINT nm(X).      {pParse->constraintName = X;}
tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
                                 {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
                                       SQLITE_IDXTYPE_UNIQUE);}
tcons ::= CHECK LP(A) expr(E) RP(B) onconf.
                                 {sqlite3AddCheckConstraint(pParse,E,A.z,B.z);}
tcons ::= FOREIGN KEY LP eidlist(FA) RP
          REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite3DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}
defer_subclause_opt(A) ::= defer_subclause(A).

// The following is a non-standard extension that allows us to declare the
// default behavior when there is a constraint conflict.
//
%type onconf {int}
%type orconf {int}
%type resolvetype {int}
onconf(A) ::= .                              {A = OE_Default;}
onconf(A) ::= ON CONFLICT resolvetype(X).    {A = X;}
orconf(A) ::= .                              {A = OE_Default;}
orconf(A) ::= OR resolvetype(X).             {A = X;}
resolvetype(A) ::= raisetype(A).
resolvetype(A) ::= IGNORE.                   {A = OE_Ignore;}
resolvetype(A) ::= REPLACE.                  {A = OE_Replace;}

////////////////////////// The DROP TABLE /////////////////////////////////////
//
cmd ::= DROP TABLE ifexists(E) fullname(X). {
  sqlite3DropTable(pParse, X, 0, E);
}
%type ifexists {int}
ifexists(A) ::= IF EXISTS.   {A = 1;}
ifexists(A) ::= .            {A = 0;}

///////////////////// The CREATE VIEW statement /////////////////////////////
//
%ifndef SQLITE_OMIT_VIEW
cmd ::= createkw(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) eidlist_opt(C)
          AS select(S). {
  sqlite3CreateView(pParse, &X, &Y, &Z, C, S, T, E);
}
cmd ::= DROP VIEW ifexists(E) fullname(X). {
  sqlite3DropTable(pParse, X, 1, E);
}
%endif  SQLITE_OMIT_VIEW

//////////////////////// The SELECT statement /////////////////////////////////
//
cmd ::= select(X).  {
  SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
  sqlite3Select(pParse, X, &dest);
  sqlite3SelectDelete(pParse->db, X);
}

%type select {Select*}
%destructor select {sqlite3SelectDelete(pParse->db, $$);}
%type selectnowith {Select*}
%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}

%include {
  /*
  ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
  ** all elements in the list.  And make sure list length does not exceed
  ** SQLITE_LIMIT_COMPOUND_SELECT.
  */
  static void parserDoubleLinkSelect(Parse *pParse, Select *p){
    assert( p!=0 );
    if( p->pPrior ){
      Select *pNext = 0, *pLoop = p;
      int mxSelect, cnt = 1;
      while(1){
        pLoop->pNext = pNext;
        pLoop->selFlags |= SF_Compound;
        pNext = pLoop;
        pLoop = pLoop->pPrior;
        if( pLoop==0 ) break;
        cnt++;        
        if( pLoop->pOrderBy || pLoop->pLimit ){
          sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
             pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT",
             sqlite3SelectOpName(pNext->op));
          break;
        }
      }
      if( (p->selFlags & SF_MultiValue)==0 && 
        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
        cnt>mxSelect
      ){
        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
      }
    }
  }

  /* Attach a With object describing the WITH clause to a Select
  ** object describing the query for which the WITH clause is a prefix.
  */
  static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){
    if( pSelect ){
      pSelect->pWith = pWith;
      parserDoubleLinkSelect(pParse, pSelect);
    }else{
      sqlite3WithDelete(pParse->db, pWith);
    }
    return pSelect;
  }
}

%ifndef SQLITE_OMIT_CTE
select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);}
select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X).
                                              {A = attachWithToSelect(pParse,X,W);}
%endif /* SQLITE_OMIT_CTE */
select(A) ::= selectnowith(X). {
  Select *p = X;
  if( p ){
    parserDoubleLinkSelect(pParse, p);
  }
  A = p; /*A-overwrites-X*/
}

selectnowith(A) ::= oneselect(A).
%ifndef SQLITE_OMIT_COMPOUND_SELECT
selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z).  {
  Select *pRhs = Z;
  Select *pLhs = A;
  if( pRhs && pRhs->pPrior ){
    SrcList *pFrom;
    Token x;
    x.n = 0;
    parserDoubleLinkSelect(pParse, pRhs);
    pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0);
    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
  }
  if( pRhs ){
    pRhs->op = (u8)Y;
    pRhs->pPrior = pLhs;
    if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
    pRhs->selFlags &= ~SF_MultiValue;
    if( Y!=TK_ALL ) pParse->hasCompound = 1;
  }else{
    sqlite3SelectDelete(pParse->db, pLhs);
  }
  A = pRhs;
}
%type multiselect_op {int}
multiselect_op(A) ::= UNION(OP).             {A = @OP; /*A-overwrites-OP*/}
multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP; /*A-overwrites-OP*/}
%endif SQLITE_OMIT_COMPOUND_SELECT

oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
                 groupby_opt(P) having_opt(Q) 
                 orderby_opt(Z) limit_opt(L). {
  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);
}
%ifndef SQLITE_OMIT_WINDOWFUNC
oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
                 groupby_opt(P) having_opt(Q) window_clause(R)
                 orderby_opt(Z) limit_opt(L). {
  A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L);
  if( A ){
    A->pWinDefn = R;
  }else{
    sqlite3WindowListDelete(pParse->db, R);
  }
}
%endif


oneselect(A) ::= values(A).

%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
  A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0);
}
values(A) ::= values(A) COMMA LP nexprlist(Y) RP. {
  Select *pRight, *pLeft = A;
  pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0);
  if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
  if( pRight ){
    pRight->op = TK_ALL;
    pRight->pPrior = pLeft;
    A = pRight;
  }else{
    A = pLeft;
  }
}

// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
//
%type distinct {int}
distinct(A) ::= DISTINCT.   {A = SF_Distinct;}
distinct(A) ::= ALL.        {A = SF_All;}
distinct(A) ::= .           {A = 0;}

// selcollist is a list of expressions that are to become the return
// values of the SELECT statement.  The "*" in statements like
// "SELECT * FROM ..." is encoded as a special expression with an
// opcode of TK_ASTERISK.
//
%type selcollist {ExprList*}
%destructor selcollist {sqlite3ExprListDelete(pParse->db, $$);}
%type sclp {ExprList*}
%destructor sclp {sqlite3ExprListDelete(pParse->db, $$);}
sclp(A) ::= selcollist(A) COMMA.
sclp(A) ::= .                                {A = 0;}
selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y).     {
   A = sqlite3ExprListAppend(pParse, A, X);
   if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
   sqlite3ExprListSetSpan(pParse,A,B,Z);
}
selcollist(A) ::= sclp(A) scanpt STAR. {
  Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
  A = sqlite3ExprListAppend(pParse, A, p);
}
selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. {
  Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
  Expr *pLeft = tokenExpr(pParse, TK_ID, X);
  Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
  A = sqlite3ExprListAppend(pParse,A, pDot);
}

// An option "AS <id>" phrase that can follow one of the expressions that
// define the result set, or one of the tables in the FROM clause.
//
%type as {Token}
as(X) ::= AS nm(Y).    {X = Y;}
as(X) ::= ids(X).
as(X) ::= .            {X.n = 0; X.z = 0;}


%type seltablist {SrcList*}
%destructor seltablist {sqlite3SrcListDelete(pParse->db, $$);}
%type stl_prefix {SrcList*}
%destructor stl_prefix {sqlite3SrcListDelete(pParse->db, $$);}
%type from {SrcList*}
%destructor from {sqlite3SrcListDelete(pParse->db, $$);}

// A complete FROM clause.
//
from(A) ::= .                {A = 0;}
from(A) ::= FROM seltablist(X). {
  A = X;
  sqlite3SrcListShiftJoinType(pParse,A);
}

// "seltablist" is a "Select Table List" - the content of the FROM clause
// in a SELECT statement.  "stl_prefix" is a prefix of this list.
//
stl_prefix(A) ::= seltablist(A) joinop(Y).    {
   if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y;
}
stl_prefix(A) ::= .                           {A = 0;}
seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) on_using(N). {
  A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N);
}
seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_by(I) on_using(N). {
  A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N);
  sqlite3SrcListIndexedBy(pParse, A, &I);
}
seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N). {
  A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N);
  sqlite3SrcListFuncArgs(pParse, A, E);
}
%ifndef SQLITE_OMIT_SUBQUERY
  seltablist(A) ::= stl_prefix(A) LP select(S) RP as(Z) on_using(N). {
    A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,&N);
  }
  seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP as(Z) on_using(N). {
    if( A==0 && Z.n==0 && N.pOn==0 && N.pUsing==0 ){
      A = F;
    }else if( F->nSrc==1 ){
      A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,&N);
      if( A ){
        SrcItem *pNew = &A->a[A->nSrc-1];
        SrcItem *pOld = F->a;
        pNew->zName = pOld->zName;
        pNew->zDatabase = pOld->zDatabase;
        pNew->pSelect = pOld->pSelect;
        if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
          pNew->fg.isNestedFrom = 1;
        }
        if( pOld->fg.isTabFunc ){
          pNew->u1.pFuncArg = pOld->u1.pFuncArg;
          pOld->u1.pFuncArg = 0;
          pOld->fg.isTabFunc = 0;
          pNew->fg.isTabFunc = 1;
        }
        pOld->zName = pOld->zDatabase = 0;
        pOld->pSelect = 0;
      }
      sqlite3SrcListDelete(pParse->db, F);
    }else{
      Select *pSubquery;
      sqlite3SrcListShiftJoinType(pParse,F);
      pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0);
      A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,&N);
    }
  }
%endif  SQLITE_OMIT_SUBQUERY

%type dbnm {Token}
dbnm(A) ::= .          {A.z=0; A.n=0;}
dbnm(A) ::= DOT nm(X). {A = X;}

%type fullname {SrcList*}
%destructor fullname {sqlite3SrcListDelete(pParse->db, $$);}
fullname(A) ::= nm(X).  {
  A = sqlite3SrcListAppend(pParse,0,&X,0);
  if( IN_RENAME_OBJECT && A ) sqlite3RenameTokenMap(pParse, A->a[0].zName, &X);
}
fullname(A) ::= nm(X) DOT nm(Y). {
  A = sqlite3SrcListAppend(pParse,0,&X,&Y);
  if( IN_RENAME_OBJECT && A ) sqlite3RenameTokenMap(pParse, A->a[0].zName, &Y);
}

%type xfullname {SrcList*}
%destructor xfullname {sqlite3SrcListDelete(pParse->db, $$);}
xfullname(A) ::= nm(X).  
   {A = sqlite3SrcListAppend(pParse,0,&X,0); /*A-overwrites-X*/}
xfullname(A) ::= nm(X) DOT nm(Y).  
   {A = sqlite3SrcListAppend(pParse,0,&X,&Y); /*A-overwrites-X*/}
xfullname(A) ::= nm(X) DOT nm(Y) AS nm(Z).  {
   A = sqlite3SrcListAppend(pParse,0,&X,&Y); /*A-overwrites-X*/
   if( A ) A->a[0].zAlias = sqlite3NameFromToken(pParse->db, &Z);
}
xfullname(A) ::= nm(X) AS nm(Z). {  
   A = sqlite3SrcListAppend(pParse,0,&X,0); /*A-overwrites-X*/
   if( A ) A->a[0].zAlias = sqlite3NameFromToken(pParse->db, &Z);
}

%type joinop {int}
joinop(X) ::= COMMA|JOIN.              { X = JT_INNER; }
joinop(X) ::= JOIN_KW(A) JOIN.
                  {X = sqlite3JoinType(pParse,&A,0,0);  /*X-overwrites-A*/}
joinop(X) ::= JOIN_KW(A) nm(B) JOIN.
                  {X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/}
joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
                  {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/}

// There is a parsing abiguity in an upsert statement that uses a
// SELECT on the RHS of a the INSERT:
//
//      INSERT INTO tab SELECT * FROM aaa JOIN bbb ON CONFLICT ...
//                                        here ----^^
//
// When the ON token is encountered, the parser does not know if it is
// the beginning of an ON CONFLICT clause, or the beginning of an ON
// clause associated with the JOIN.  The conflict is resolved in favor
// of the JOIN.  If an ON CONFLICT clause is intended, insert a dummy
// WHERE clause in between, like this:
//
//      INSERT INTO tab SELECT * FROM aaa JOIN bbb WHERE true ON CONFLICT ...
//
// The [AND] and [OR] precedence marks in the rules for on_using cause the
// ON in this context to always be interpreted as belonging to the JOIN.
//
%type on_using {OnOrUsing}
//%destructor on_using {sqlite3ClearOnOrUsing(pParse->db, &$$);}
on_using(N) ::= ON expr(E).            {N.pOn = E; N.pUsing = 0;}
on_using(N) ::= USING LP idlist(L) RP. {N.pOn = 0; N.pUsing = L;}
on_using(N) ::= .                 [OR] {N.pOn = 0; N.pUsing = 0;}

// Note that this block abuses the Token type just a little. If there is
// no "INDEXED BY" clause, the returned token is empty (z==0 && n==0). If
// there is an INDEXED BY clause, then the token is populated as per normal,
// with z pointing to the token data and n containing the number of bytes
// in the token.
//
// If there is a "NOT INDEXED" clause, then (z==0 && n==1), which is 
// normally illegal. The sqlite3SrcListIndexedBy() function 
// recognizes and interprets this as a special case.
//
%type indexed_opt {Token}
%type indexed_by  {Token}
indexed_opt(A) ::= .                 {A.z=0; A.n=0;}
indexed_opt(A) ::= indexed_by(A).
indexed_by(A)  ::= INDEXED BY nm(X). {A = X;}
indexed_by(A)  ::= NOT INDEXED.      {A.z=0; A.n=1;}

%type orderby_opt {ExprList*}
%destructor orderby_opt {sqlite3ExprListDelete(pParse->db, $$);}

// the sortlist non-terminal stores a list of expression where each
// expression is optionally followed by ASC or DESC to indicate the
// sort order.
//
%type sortlist {ExprList*}
%destructor sortlist {sqlite3ExprListDelete(pParse->db, $$);}

orderby_opt(A) ::= .                          {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). {
  A = sqlite3ExprListAppend(pParse,A,Y);
  sqlite3ExprListSetSortOrder(A,Z,X);
}
sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). {
  A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/
  sqlite3ExprListSetSortOrder(A,Z,X);
}

%type sortorder {int}

sortorder(A) ::= ASC.           {A = SQLITE_SO_ASC;}
sortorder(A) ::= DESC.          {A = SQLITE_SO_DESC;}
sortorder(A) ::= .              {A = SQLITE_SO_UNDEFINED;}

%type nulls {int}
nulls(A) ::= NULLS FIRST.       {A = SQLITE_SO_ASC;}
nulls(A) ::= NULLS LAST.        {A = SQLITE_SO_DESC;}
nulls(A) ::= .                  {A = SQLITE_SO_UNDEFINED;}

%type groupby_opt {ExprList*}
%destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
groupby_opt(A) ::= .                      {A = 0;}
groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}

%type having_opt {Expr*}
%destructor having_opt {sqlite3ExprDelete(pParse->db, $$);}
having_opt(A) ::= .                {A = 0;}
having_opt(A) ::= HAVING expr(X).  {A = X;}

%type limit_opt {Expr*}

// The destructor for limit_opt will never fire in the current grammar.
// The limit_opt non-terminal only occurs at the end of a single production
// rule for SELECT statements.  As soon as the rule that create the 
// limit_opt non-terminal reduces, the SELECT statement rule will also
// reduce.  So there is never a limit_opt non-terminal on the stack 
// except as a transient.  So there is never anything to destroy.
//
//%destructor limit_opt {sqlite3ExprDelete(pParse->db, $$);}
limit_opt(A) ::= .       {A = 0;}
limit_opt(A) ::= LIMIT expr(X).
                         {A = sqlite3PExpr(pParse,TK_LIMIT,X,0);}
limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y). 
                         {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);}
limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). 
                         {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);}

/////////////////////////// The DELETE statement /////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W)
        orderby_opt(O) limit_opt(L). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3DeleteFrom(pParse,X,W,O,L);
}
%else
cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3DeleteFrom(pParse,X,W,0,0);
}
%endif

%type where_opt {Expr*}
%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
%type where_opt_ret {Expr*}
%destructor where_opt_ret {sqlite3ExprDelete(pParse->db, $$);}

where_opt(A) ::= .                    {A = 0;}
where_opt(A) ::= WHERE expr(X).       {A = X;}
where_opt_ret(A) ::= .                                      {A = 0;}
where_opt_ret(A) ::= WHERE expr(X).                         {A = X;}
where_opt_ret(A) ::= RETURNING selcollist(X).               
       {sqlite3AddReturning(pParse,X); A = 0;}
where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y).
       {sqlite3AddReturning(pParse,Y); A = X;}

////////////////////////// The UPDATE command ////////////////////////////////
//
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt_ret(W) orderby_opt(O) limit_opt(L).  {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  if( F ){
    SrcList *pFromClause = F;
    if( pFromClause->nSrc>1 ){
      Select *pSubquery;
      Token as;
      pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
      as.n = 0;
      as.z = 0;
      pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
    }
    X = sqlite3SrcListAppendList(pParse, X, pFromClause);
  }
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
#ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( O || L ){
    updateDeleteLimitError(pParse,O,L);
    O = 0;
    L = 0;
  }
#endif
  sqlite3Update(pParse,X,Y,W,R,O,L,0);
}
%else
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
        where_opt_ret(W). {
  sqlite3SrcListIndexedBy(pParse, X, &I);
  sqlite3ExprListCheckLength(pParse,Y,"set list"); 
  if( F ){
    SrcList *pFromClause = F;
    if( pFromClause->nSrc>1 ){
      Select *pSubquery;
      Token as;
      pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
      as.n = 0;
      as.z = 0;
      pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
    }
    X = sqlite3SrcListAppendList(pParse, X, pFromClause);
  }
  sqlite3Update(pParse,X,Y,W,R,0,0,0);
}
%endif



%type setlist {ExprList*}
%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}

setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
  A = sqlite3ExprListAppend(pParse, A, Y);
  sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= setlist(A) COMMA LP idlist(X) RP EQ expr(Y). {
  A = sqlite3ExprListAppendVector(pParse, A, X, Y);
}
setlist(A) ::= nm(X) EQ expr(Y). {
  A = sqlite3ExprListAppend(pParse, 0, Y);
  sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= LP idlist(X) RP EQ expr(Y). {
  A = sqlite3ExprListAppendVector(pParse, 0, X, Y);
}

////////////////////////// The INSERT command /////////////////////////////////
//
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S)
        upsert(U). {
  sqlite3Insert(pParse, X, S, F, R, U);
}
cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES returning.
{
  sqlite3Insert(pParse, X, 0, F, R, 0);
}

%type upsert {Upsert*}

// Because upsert only occurs at the tip end of the INSERT rule for cmd,
// there is never a case where the value of the upsert pointer will not
// be destroyed by the cmd action.  So comment-out the destructor to
// avoid unreachable code.
//%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);}
upsert(A) ::= . { A = 0; }
upsert(A) ::= RETURNING selcollist(X).  { A = 0; sqlite3AddReturning(pParse,X); }
upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW)
              DO UPDATE SET setlist(Z) where_opt(W) upsert(N).
              { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W,N);}
upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N).
              { A = sqlite3UpsertNew(pParse->db,T,TW,0,0,N); }
upsert(A) ::= ON CONFLICT DO NOTHING returning.
              { A = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W) returning.
              { A = sqlite3UpsertNew(pParse->db,0,0,Z,W,0);}

returning ::= RETURNING selcollist(X).  {sqlite3AddReturning(pParse,X);}
returning ::= .

%type insert_cmd {int}
insert_cmd(A) ::= INSERT orconf(R).   {A = R;}
insert_cmd(A) ::= REPLACE.            {A = OE_Replace;}

%type idlist_opt {IdList*}
%destructor idlist_opt {sqlite3IdListDelete(pParse->db, $$);}
%type idlist {IdList*}
%destructor idlist {sqlite3IdListDelete(pParse->db, $$);}

idlist_opt(A) ::= .                       {A = 0;}
idlist_opt(A) ::= LP idlist(X) RP.    {A = X;}
idlist(A) ::= idlist(A) COMMA nm(Y).
    {A = sqlite3IdListAppend(pParse,A,&Y);}
idlist(A) ::= nm(Y).
    {A = sqlite3IdListAppend(pParse,0,&Y); /*A-overwrites-Y*/}

/////////////////////////// Expression Processing /////////////////////////////
//

%type expr {Expr*}
%destructor expr {sqlite3ExprDelete(pParse->db, $$);}
%type term {Expr*}
%destructor term {sqlite3ExprDelete(pParse->db, $$);}

%include {

  /* Construct a new Expr object from a single token */
  static Expr *tokenExpr(Parse *pParse, int op, Token t){
    Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
    if( p ){
      /* memset(p, 0, sizeof(Expr)); */
      p->op = (u8)op;
      p->affExpr = 0;
      p->flags = EP_Leaf;
      ExprClearVVAProperties(p);
      /* p->iAgg = -1; // Not required */
      p->pLeft = p->pRight = 0;
      p->pAggInfo = 0;
      memset(&p->x, 0, sizeof(p->x));
      memset(&p->y, 0, sizeof(p->y));
      p->op2 = 0;
      p->iTable = 0;
      p->iColumn = 0;
      p->u.zToken = (char*)&p[1];
      memcpy(p->u.zToken, t.z, t.n);
      p->u.zToken[t.n] = 0;
      p->w.iOfst = (int)(t.z - pParse->zTail);
      if( sqlite3Isquote(p->u.zToken[0]) ){
        sqlite3DequoteExpr(p);
      }
#if SQLITE_MAX_EXPR_DEPTH>0
      p->nHeight = 1;
#endif  
      if( IN_RENAME_OBJECT ){
        return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t);
      }
    }
    return p;
  }

}

expr(A) ::= term(A).
expr(A) ::= LP expr(X) RP. {A = X;}
expr(A) ::= id(X).          {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
expr(A) ::= JOIN_KW(X).     {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
expr(A) ::= nm(X) DOT nm(Y). {
  Expr *temp1 = tokenExpr(pParse,TK_ID,X);
  Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
  A = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
  Expr *temp1 = tokenExpr(pParse,TK_ID,X);
  Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
  Expr *temp3 = tokenExpr(pParse,TK_ID,Z);
  Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
  if( IN_RENAME_OBJECT ){
    sqlite3RenameTokenRemap(pParse, 0, temp1);
  }
  A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
term(A) ::= STRING(X).          {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
term(A) ::= INTEGER(X). {
  A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
  if( A ) A->w.iOfst = (int)(X.z - pParse->zTail);
}
expr(A) ::= VARIABLE(X).     {
  if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
    u32 n = X.n;
    A = tokenExpr(pParse, TK_VARIABLE, X);
    sqlite3ExprAssignVarNumber(pParse, A, n);
  }else{
    /* When doing a nested parse, one can include terms in an expression
    ** that look like this:   #1 #2 ...  These terms refer to registers
    ** in the virtual machine.  #N is the N-th register. */
    Token t = X; /*A-overwrites-X*/
    assert( t.n>=2 );
    if( pParse->nested==0 ){
      sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
      A = 0;
    }else{
      A = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
      if( A ) sqlite3GetInt32(&t.z[1], &A->iTable);
    }
  }
}
expr(A) ::= expr(A) COLLATE ids(C). {
  A = sqlite3ExprAddCollateToken(pParse, A, &C, 1);
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. {
  A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
  sqlite3ExprAttachSubtrees(pParse->db, A, E, 0);
}
%endif  SQLITE_OMIT_CAST


expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP. {
  A = sqlite3ExprFunction(pParse, Y, &X, D);
}
expr(A) ::= id(X) LP STAR RP. {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
}

%ifndef SQLITE_OMIT_WINDOWFUNC
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP filter_over(Z). {
  A = sqlite3ExprFunction(pParse, Y, &X, D);
  sqlite3WindowAttach(pParse, A, Z);
}
expr(A) ::= id(X) LP STAR RP filter_over(Z). {
  A = sqlite3ExprFunction(pParse, 0, &X, 0);
  sqlite3WindowAttach(pParse, A, Z);
}
%endif

term(A) ::= CTIME_KW(OP). {
  A = sqlite3ExprFunction(pParse, 0, &OP, 0);
}

expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
  ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
  A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  if( A ){
    A->x.pList = pList;
    if( ALWAYS(pList->nExpr) ){
      A->flags |= pList->a[0].pExpr->flags & EP_Propagate;
    }
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  }
}

expr(A) ::= expr(A) AND expr(Y).        {A=sqlite3ExprAnd(pParse,A,Y);}
expr(A) ::= expr(A) OR(OP) expr(Y).     {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) EQ|NE(OP) expr(Y).  {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
                                        {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) CONCAT(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
%type likeop {Token}
likeop(A) ::= LIKE_KW|MATCH(A).
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
expr(A) ::= expr(A) likeop(OP) expr(Y).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  A = sqlite3ExprFunction(pParse, pList, &OP, 0);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}
expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E).  [LIKE_KW]  {
  ExprList *pList;
  int bNot = OP.n & 0x80000000;
  OP.n &= 0x7fffffff;
  pList = sqlite3ExprListAppend(pParse,0, Y);
  pList = sqlite3ExprListAppend(pParse,pList, A);
  pList = sqlite3ExprListAppend(pParse,pList, E);
  A = sqlite3ExprFunction(pParse, pList, &OP, 0);
  if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  if( A ) A->flags |= EP_InfixFunc;
}

expr(A) ::= expr(A) ISNULL|NOTNULL(E).   {A = sqlite3PExpr(pParse,@E,A,0);}
expr(A) ::= expr(A) NOT NULL.    {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);}

%include {
  /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
  ** unary TK_ISNULL or TK_NOTNULL expression. */
  static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
    sqlite3 *db = pParse->db;
    if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){
      pA->op = (u8)op;
      sqlite3ExprDelete(db, pA->pRight);
      pA->pRight = 0;
    }
  }
}

//    expr1 IS expr2
//    expr1 IS NOT expr2
//
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL.  If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
// 
expr(A) ::= expr(A) IS expr(Y).     {
  A = sqlite3PExpr(pParse,TK_IS,A,Y);
  binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL);
}
expr(A) ::= expr(A) IS NOT expr(Y). {
  A = sqlite3PExpr(pParse,TK_ISNOT,A,Y);
  binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL);
}
expr(A) ::= expr(A) IS NOT DISTINCT FROM expr(Y).     {
  A = sqlite3PExpr(pParse,TK_IS,A,Y);
  binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL);
}
expr(A) ::= expr(A) IS DISTINCT FROM expr(Y). {
  A = sqlite3PExpr(pParse,TK_ISNOT,A,Y);
  binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL);
}

expr(A) ::= NOT(B) expr(X).  
              {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/}
expr(A) ::= BITNOT(B) expr(X).
              {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/}
expr(A) ::= PLUS|MINUS(B) expr(X). [BITNOT] {
  A = sqlite3PExpr(pParse, @B==TK_PLUS ? TK_UPLUS : TK_UMINUS, X, 0);
  /*A-overwrites-B*/
}

expr(A) ::= expr(B) PTR(C) expr(D). {
  ExprList *pList = sqlite3ExprListAppend(pParse, 0, B);
  pList = sqlite3ExprListAppend(pParse, pList, D);
  A = sqlite3ExprFunction(pParse, pList, &C, 0);
}

%type between_op {int}
between_op(A) ::= BETWEEN.     {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
  ExprList *pList = sqlite3ExprListAppend(pParse,0, X);
  pList = sqlite3ExprListAppend(pParse,pList, Y);
  A = sqlite3PExpr(pParse, TK_BETWEEN, A, 0);
  if( A ){
    A->x.pList = pList;
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  } 
  if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}
%ifndef SQLITE_OMIT_SUBQUERY
  %type in_op {int}
  in_op(A) ::= IN.      {A = 0;}
  in_op(A) ::= NOT IN.  {A = 1;}
  expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP. [IN] {
    if( Y==0 ){
      /* Expressions of the form
      **
      **      expr1 IN ()
      **      expr1 NOT IN ()
      **
      ** simplify to constants 0 (false) and 1 (true), respectively,
      ** regardless of the value of expr1.
      */
      sqlite3ExprUnmapAndDelete(pParse, A);
      A = sqlite3Expr(pParse->db, TK_STRING, N ? "true" : "false");
      if( A ) sqlite3ExprIdToTrueFalse(A);
    }else{
      Expr *pRHS = Y->a[0].pExpr;
      if( Y->nExpr==1 && sqlite3ExprIsConstant(pRHS) && A->op!=TK_VECTOR ){
        Y->a[0].pExpr = 0;
        sqlite3ExprListDelete(pParse->db, Y);
        pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
        A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
      }else{
        A = sqlite3PExpr(pParse, TK_IN, A, 0);
        if( A==0 ){
          sqlite3ExprListDelete(pParse->db, Y);
        }else if( A->pLeft->op==TK_VECTOR ){
          int nExpr = A->pLeft->x.pList->nExpr;
          Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, Y);
          if( pSelectRHS ){
            parserDoubleLinkSelect(pParse, pSelectRHS);
            sqlite3PExprAddSelect(pParse, A, pSelectRHS);
          }
        }else{
          A->x.pList = Y;
          sqlite3ExprSetHeightAndFlags(pParse, A);
        }
      }
      if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
    }
  }
  expr(A) ::= LP select(X) RP. {
    A = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
    sqlite3PExprAddSelect(pParse, A, X);
  }
  expr(A) ::= expr(A) in_op(N) LP select(Y) RP.  [IN] {
    A = sqlite3PExpr(pParse, TK_IN, A, 0);
    sqlite3PExprAddSelect(pParse, A, Y);
    if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  }
  expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
    SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&Y,&Z);
    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
    if( E )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E);
    A = sqlite3PExpr(pParse, TK_IN, A, 0);
    sqlite3PExprAddSelect(pParse, A, pSelect);
    if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
  }
  expr(A) ::= EXISTS LP select(Y) RP. {
    Expr *p;
    p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
    sqlite3PExprAddSelect(pParse, p, Y);
  }
%endif SQLITE_OMIT_SUBQUERY

/* CASE expressions */
expr(A) ::= CASE case_operand(X) case_exprlist(Y) case_else(Z) END. {
  A = sqlite3PExpr(pParse, TK_CASE, X, 0);
  if( A ){
    A->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
    sqlite3ExprSetHeightAndFlags(pParse, A);
  }else{
    sqlite3ExprListDelete(pParse->db, Y);
    sqlite3ExprDelete(pParse->db, Z);
  }
}
%type case_exprlist {ExprList*}
%destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
case_exprlist(A) ::= case_exprlist(A) WHEN expr(Y) THEN expr(Z). {
  A = sqlite3ExprListAppend(pParse,A, Y);
  A = sqlite3ExprListAppend(pParse,A, Z);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
  A = sqlite3ExprListAppend(pParse,0, Y);
  A = sqlite3ExprListAppend(pParse,A, Z);
}
%type case_else {Expr*}
%destructor case_else {sqlite3ExprDelete(pParse->db, $$);}
case_else(A) ::=  ELSE expr(X).         {A = X;}
case_else(A) ::=  .                     {A = 0;} 
%type case_operand {Expr*}
%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
case_operand(A) ::= expr(X).            {A = X; /*A-overwrites-X*/} 
case_operand(A) ::= .                   {A = 0;} 

%type exprlist {ExprList*}
%destructor exprlist {sqlite3ExprListDelete(pParse->db, $$);}
%type nexprlist {ExprList*}
%destructor nexprlist {sqlite3ExprListDelete(pParse->db, $$);}

exprlist(A) ::= nexprlist(A).
exprlist(A) ::= .                            {A = 0;}
nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
    {A = sqlite3ExprListAppend(pParse,A,Y);}
nexprlist(A) ::= expr(Y).
    {A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/}

%ifndef SQLITE_OMIT_SUBQUERY
/* A paren_exprlist is an optional expression list contained inside
** of parenthesis */
%type paren_exprlist {ExprList*}
%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
paren_exprlist(A) ::= .   {A = 0;}
paren_exprlist(A) ::= LP exprlist(X) RP.  {A = X;}
%endif SQLITE_OMIT_SUBQUERY


///////////////////////////// The CREATE INDEX command ///////////////////////
//
cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
        ON nm(Y) LP sortlist(Z) RP where_opt(W). {
  sqlite3CreateIndex(pParse, &X, &D, 
                     sqlite3SrcListAppend(pParse,0,&Y,0), Z, U,
                      &S, W, SQLITE_SO_ASC, NE, SQLITE_IDXTYPE_APPDEF);
  if( IN_RENAME_OBJECT && pParse->pNewIndex ){
    sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &Y);
  }
}

%type uniqueflag {int}
uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
uniqueflag(A) ::= .        {A = OE_None;}


// The eidlist non-terminal (Expression Id List) generates an ExprList
// from a list of identifiers.  The identifier names are in ExprList.a[].zName.
// This list is stored in an ExprList rather than an IdList so that it
// can be easily sent to sqlite3ColumnsExprList().
//
// eidlist is grouped with CREATE INDEX because it used to be the non-terminal
// used for the arguments to an index.  That is just an historical accident.
//
// IMPORTANT COMPATIBILITY NOTE:  Some prior versions of SQLite accepted
// COLLATE clauses and ASC or DESC keywords on ID lists in inappropriate
// places - places that might have been stored in the sqlite_schema table.
// Those extra features were ignored.  But because they might be in some
// (busted) old databases, we need to continue parsing them when loading
// historical schemas.
//
%type eidlist {ExprList*}
%destructor eidlist {sqlite3ExprListDelete(pParse->db, $$);}
%type eidlist_opt {ExprList*}
%destructor eidlist_opt {sqlite3ExprListDelete(pParse->db, $$);}

%include {
  /* Add a single new term to an ExprList that is used to store a
  ** list of identifiers.  Report an error if the ID list contains
  ** a COLLATE clause or an ASC or DESC keyword, except ignore the
  ** error while parsing a legacy schema.
  */
  static ExprList *parserAddExprIdListTerm(
    Parse *pParse,
    ExprList *pPrior,
    Token *pIdToken,
    int hasCollate,
    int sortOrder
  ){
    ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0);
    if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED)
        && pParse->db->init.busy==0
    ){
      sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"",
                         pIdToken->n, pIdToken->z);
    }
    sqlite3ExprListSetName(pParse, p, pIdToken, 1);
    return p;
  }
} // end %include

eidlist_opt(A) ::= .                         {A = 0;}
eidlist_opt(A) ::= LP eidlist(X) RP.         {A = X;}
eidlist(A) ::= eidlist(A) COMMA nm(Y) collate(C) sortorder(Z).  {
  A = parserAddExprIdListTerm(pParse, A, &Y, C, Z);
}
eidlist(A) ::= nm(Y) collate(C) sortorder(Z). {
  A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z); /*A-overwrites-Y*/
}

%type collate {int}
collate(C) ::= .              {C = 0;}
collate(C) ::= COLLATE ids.   {C = 1;}


///////////////////////////// The DROP INDEX command /////////////////////////
//
cmd ::= DROP INDEX ifexists(E) fullname(X).   {sqlite3DropIndex(pParse, X, E);}

///////////////////////////// The VACUUM command /////////////////////////////
//
%if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH
%type vinto {Expr*}
%destructor vinto {sqlite3ExprDelete(pParse->db, $$);}
cmd ::= VACUUM vinto(Y).                {sqlite3Vacuum(pParse,0,Y);}
cmd ::= VACUUM nm(X) vinto(Y).          {sqlite3Vacuum(pParse,&X,Y);}
vinto(A) ::= INTO expr(X).              {A = X;}
vinto(A) ::= .                          {A = 0;}
%endif

///////////////////////////// The PRAGMA command /////////////////////////////
//
%ifndef SQLITE_OMIT_PRAGMA
cmd ::= PRAGMA nm(X) dbnm(Z).                {sqlite3Pragma(pParse,&X,&Z,0,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ nmnum(Y).    {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) LP nmnum(Y) RP. {sqlite3Pragma(pParse,&X,&Z,&Y,0);}
cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y). 
                                             {sqlite3Pragma(pParse,&X,&Z,&Y,1);}
cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
                                             {sqlite3Pragma(pParse,&X,&Z,&Y,1);}

nmnum(A) ::= plus_num(A).
nmnum(A) ::= nm(A).
nmnum(A) ::= ON(A).
nmnum(A) ::= DELETE(A).
nmnum(A) ::= DEFAULT(A).
%endif SQLITE_OMIT_PRAGMA
%token_class number INTEGER|FLOAT.
plus_num(A) ::= PLUS number(X).       {A = X;}
plus_num(A) ::= number(A).
minus_num(A) ::= MINUS number(X).     {A = X;}
//////////////////////////// The CREATE TRIGGER command /////////////////////

%ifndef SQLITE_OMIT_TRIGGER

cmd ::= createkw trigger_decl(A) BEGIN trigger_cmd_list(S) END(Z). {
  Token all;
  all.z = A.z;
  all.n = (int)(Z.z - A.z) + Z.n;
  sqlite3FinishTrigger(pParse, S, &all);
}

trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z) 
                    trigger_time(C) trigger_event(D)
                    ON fullname(E) foreach_clause when_clause(G). {
  sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR);
  A = (Z.n==0?B:Z); /*A-overwrites-T*/
}

%type trigger_time {int}
trigger_time(A) ::= BEFORE|AFTER(X).  { A = @X; /*A-overwrites-X*/ }
trigger_time(A) ::= INSTEAD OF.  { A = TK_INSTEAD;}
trigger_time(A) ::= .            { A = TK_BEFORE; }

%type trigger_event {struct TrigEvent}
%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
trigger_event(A) ::= DELETE|INSERT(X).   {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
trigger_event(A) ::= UPDATE(X).          {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
trigger_event(A) ::= UPDATE OF idlist(X).{A.a = TK_UPDATE; A.b = X;}

foreach_clause ::= .
foreach_clause ::= FOR EACH ROW.

%type when_clause {Expr*}
%destructor when_clause {sqlite3ExprDelete(pParse->db, $$);}
when_clause(A) ::= .             { A = 0; }
when_clause(A) ::= WHEN expr(X). { A = X; }

%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);}
trigger_cmd_list(A) ::= trigger_cmd_list(A) trigger_cmd(X) SEMI. {
  assert( A!=0 );
  A->pLast->pNext = X;
  A->pLast = X;
}
trigger_cmd_list(A) ::= trigger_cmd(A) SEMI. { 
  assert( A!=0 );
  A->pLast = A;
}

// Disallow qualified table names on INSERT, UPDATE, and DELETE statements
// within a trigger.  The table to INSERT, UPDATE, or DELETE is always in 
// the same database as the table that the trigger fires on.
//
%type trnm {Token}
trnm(A) ::= nm(A).
trnm(A) ::= nm DOT nm(X). {
  A = X;
  sqlite3ErrorMsg(pParse, 
        "qualified table names are not allowed on INSERT, UPDATE, and DELETE "
        "statements within triggers");
}

// Disallow the INDEX BY and NOT INDEXED clauses on UPDATE and DELETE
// statements within triggers.  We make a specific error message for this
// since it is an exception to the default grammar rules.
//
tridxby ::= .
tridxby ::= INDEXED BY nm. {
  sqlite3ErrorMsg(pParse,
        "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
tridxby ::= NOT INDEXED. {
  sqlite3ErrorMsg(pParse,
        "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}



%type trigger_cmd {TriggerStep*}
%destructor trigger_cmd {sqlite3DeleteTriggerStep(pParse->db, $$);}
// UPDATE 
trigger_cmd(A) ::=
   UPDATE(B) orconf(R) trnm(X) tridxby SET setlist(Y) from(F) where_opt(Z) scanpt(E).  
   {A = sqlite3TriggerUpdateStep(pParse, &X, F, Y, Z, R, B.z, E);}

// INSERT
trigger_cmd(A) ::= scanpt(B) insert_cmd(R) INTO
                      trnm(X) idlist_opt(F) select(S) upsert(U) scanpt(Z). {
   A = sqlite3TriggerInsertStep(pParse,&X,F,S,R,U,B,Z);/*A-overwrites-R*/
}
// DELETE
trigger_cmd(A) ::= DELETE(B) FROM trnm(X) tridxby where_opt(Y) scanpt(E).
   {A = sqlite3TriggerDeleteStep(pParse, &X, Y, B.z, E);}

// SELECT
trigger_cmd(A) ::= scanpt(B) select(X) scanpt(E).
   {A = sqlite3TriggerSelectStep(pParse->db, X, B, E); /*A-overwrites-X*/}

// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE LP IGNORE RP.  {
  A = sqlite3PExpr(pParse, TK_RAISE, 0, 0); 
  if( A ){
    A->affExpr = OE_Ignore;
  }
}
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP.  {
  A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
  if( A ) {
    A->affExpr = (char)T;
  }
}
%endif  !SQLITE_OMIT_TRIGGER

%type raisetype {int}
raisetype(A) ::= ROLLBACK.  {A = OE_Rollback;}
raisetype(A) ::= ABORT.     {A = OE_Abort;}
raisetype(A) ::= FAIL.      {A = OE_Fail;}


////////////////////////  DROP TRIGGER statement //////////////////////////////
%ifndef SQLITE_OMIT_TRIGGER
cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). {
  sqlite3DropTrigger(pParse,X,NOERR);
}
%endif  !SQLITE_OMIT_TRIGGER

//////////////////////// ATTACH DATABASE file AS name /////////////////////////
%ifndef SQLITE_OMIT_ATTACH
cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
  sqlite3Attach(pParse, F, D, K);
}
cmd ::= DETACH database_kw_opt expr(D). {
  sqlite3Detach(pParse, D);
}

%type key_opt {Expr*}
%destructor key_opt {sqlite3ExprDelete(pParse->db, $$);}
key_opt(A) ::= .                     { A = 0; }
key_opt(A) ::= KEY expr(X).          { A = X; }

database_kw_opt ::= DATABASE.
database_kw_opt ::= .
%endif SQLITE_OMIT_ATTACH

////////////////////////// REINDEX collation //////////////////////////////////
%ifndef SQLITE_OMIT_REINDEX
cmd ::= REINDEX.                {sqlite3Reindex(pParse, 0, 0);}
cmd ::= REINDEX nm(X) dbnm(Y).  {sqlite3Reindex(pParse, &X, &Y);}
%endif  SQLITE_OMIT_REINDEX

/////////////////////////////////// ANALYZE ///////////////////////////////////
%ifndef SQLITE_OMIT_ANALYZE
cmd ::= ANALYZE.                {sqlite3Analyze(pParse, 0, 0);}
cmd ::= ANALYZE nm(X) dbnm(Y).  {sqlite3Analyze(pParse, &X, &Y);}
%endif

//////////////////////// ALTER TABLE table ... ////////////////////////////////
%ifndef SQLITE_OMIT_ALTERTABLE 
%ifndef SQLITE_OMIT_VIRTUALTABLE
cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
  sqlite3AlterRenameTable(pParse,X,&Z);
}
cmd ::= ALTER TABLE add_column_fullname
        ADD kwcolumn_opt columnname(Y) carglist. {
  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &Y);
}
cmd ::= ALTER TABLE fullname(X) DROP kwcolumn_opt nm(Y). {
  sqlite3AlterDropColumn(pParse, X, &Y);
}

add_column_fullname ::= fullname(X). {
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, X);
}
cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). {
  sqlite3AlterRenameColumn(pParse, X, &Y, &Z);
}

kwcolumn_opt ::= .
kwcolumn_opt ::= COLUMNKW.

%endif SQLITE_OMIT_VIRTUALTABLE
%endif SQLITE_OMIT_ALTERTABLE

//////////////////////// CREATE VIRTUAL TABLE ... /////////////////////////////
%ifndef SQLITE_OMIT_VIRTUALTABLE
cmd ::= create_vtab.                       {sqlite3VtabFinishParse(pParse,0);}
cmd ::= create_vtab LP vtabarglist RP(X).  {sqlite3VtabFinishParse(pParse,&X);}
create_vtab ::= createkw VIRTUAL TABLE ifnotexists(E)
                nm(X) dbnm(Y) USING nm(Z). {
    sqlite3VtabBeginParse(pParse, &X, &Y, &Z, E);
}
vtabarglist ::= vtabarg.
vtabarglist ::= vtabarglist COMMA vtabarg.
vtabarg ::= .                       {sqlite3VtabArgInit(pParse);}
vtabarg ::= vtabarg vtabargtoken.
vtabargtoken ::= ANY(X).            {sqlite3VtabArgExtend(pParse,&X);}
vtabargtoken ::= lp anylist RP(X).  {sqlite3VtabArgExtend(pParse,&X);}
lp ::= LP(X).                       {sqlite3VtabArgExtend(pParse,&X);}
anylist ::= .
anylist ::= anylist LP anylist RP.
anylist ::= anylist ANY.
%endif  SQLITE_OMIT_VIRTUALTABLE


//////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
%type wqlist {With*}
%destructor wqlist {sqlite3WithDelete(pParse->db, $$);}
%type wqitem {Cte*}
// %destructor wqitem {sqlite3CteDelete(pParse->db, $$);} // not reachable

with ::= .
%ifndef SQLITE_OMIT_CTE
with ::= WITH wqlist(W).              { sqlite3WithPush(pParse, W, 1); }
with ::= WITH RECURSIVE wqlist(W).    { sqlite3WithPush(pParse, W, 1); }

%type wqas {u8}
wqas(A)   ::= AS.                  {A = M10d_Any;}
wqas(A)   ::= AS MATERIALIZED.     {A = M10d_Yes;}
wqas(A)   ::= AS NOT MATERIALIZED. {A = M10d_No;}
wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. {
  A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/
}
wqlist(A) ::= wqitem(X). {
  A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/
}
wqlist(A) ::= wqlist(A) COMMA wqitem(X). {
  A = sqlite3WithAdd(pParse, A, X);
}
%endif  SQLITE_OMIT_CTE

//////////////////////// WINDOW FUNCTION EXPRESSIONS /////////////////////////
// These must be at the end of this file. Specifically, the rules that
// introduce tokens WINDOW, OVER and FILTER must appear last. This causes 
// the integer values assigned to these tokens to be larger than all other 
// tokens that may be output by the tokenizer except TK_SPACE and TK_ILLEGAL.
//
%ifndef SQLITE_OMIT_WINDOWFUNC
%type windowdefn_list {Window*}
%destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);}
windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
  assert( Z!=0 );
  sqlite3WindowChain(pParse, Z, Y);
  Z->pNextWin = Y;
  A = Z;
}

%type windowdefn {Window*}
%destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
windowdefn(A) ::= nm(X) AS LP window(Y) RP. {
  if( ALWAYS(Y) ){
    Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
  }
  A = Y;
}

%type window {Window*}
%destructor window {sqlite3WindowDelete(pParse->db, $$);}

%type frame_opt {Window*}
%destructor frame_opt {sqlite3WindowDelete(pParse->db, $$);}

%type part_opt {ExprList*}
%destructor part_opt {sqlite3ExprListDelete(pParse->db, $$);}

%type filter_clause {Expr*}
%destructor filter_clause {sqlite3ExprDelete(pParse->db, $$);}

%type over_clause {Window*}
%destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}

%type filter_over {Window*}
%destructor filter_over {sqlite3WindowDelete(pParse->db, $$);}

%type range_or_rows {int}

%type frame_bound {struct FrameBound}
%destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
%type frame_bound_s {struct FrameBound}
%destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
%type frame_bound_e {struct FrameBound}
%destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);}

window(A) ::= PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
  A = sqlite3WindowAssemble(pParse, Z, X, Y, 0);
}
window(A) ::= nm(W) PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
  A = sqlite3WindowAssemble(pParse, Z, X, Y, &W);
}
window(A) ::= ORDER BY sortlist(Y) frame_opt(Z). {
  A = sqlite3WindowAssemble(pParse, Z, 0, Y, 0);
}
window(A) ::= nm(W) ORDER BY sortlist(Y) frame_opt(Z). {
  A = sqlite3WindowAssemble(pParse, Z, 0, Y, &W);
}
window(A) ::= frame_opt(Z). {
  A = Z;
}
window(A) ::= nm(W) frame_opt(Z). {
  A = sqlite3WindowAssemble(pParse, Z, 0, 0, &W);
}

frame_opt(A) ::= .                             { 
  A = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y) frame_exclude_opt(Z). { 
  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0, Z);
}
frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND
                          frame_bound_e(Z) frame_exclude_opt(W). { 
  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr, W);
}

range_or_rows(A) ::= RANGE|ROWS|GROUPS(X).   {A = @X; /*A-overwrites-X*/}

frame_bound_s(A) ::= frame_bound(X).         {A = X;}
frame_bound_s(A) ::= UNBOUNDED(X) PRECEDING. {A.eType = @X; A.pExpr = 0;}
frame_bound_e(A) ::= frame_bound(X).         {A = X;}
frame_bound_e(A) ::= UNBOUNDED(X) FOLLOWING. {A.eType = @X; A.pExpr = 0;}

frame_bound(A) ::= expr(X) PRECEDING|FOLLOWING(Y).
                                             {A.eType = @Y; A.pExpr = X;}
frame_bound(A) ::= CURRENT(X) ROW.           {A.eType = @X; A.pExpr = 0;}

%type frame_exclude_opt {u8}
frame_exclude_opt(A) ::= . {A = 0;}
frame_exclude_opt(A) ::= EXCLUDE frame_exclude(X). {A = X;}

%type frame_exclude {u8}
frame_exclude(A) ::= NO(X) OTHERS.   {A = @X; /*A-overwrites-X*/}
frame_exclude(A) ::= CURRENT(X) ROW. {A = @X; /*A-overwrites-X*/}
frame_exclude(A) ::= GROUP|TIES(X).  {A = @X; /*A-overwrites-X*/}


%type window_clause {Window*}
%destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }

filter_over(A) ::= filter_clause(F) over_clause(O). {
  if( O ){
    O->pFilter = F;
  }else{
    sqlite3ExprDelete(pParse->db, F);
  }
  A = O;
}
filter_over(A) ::= over_clause(O). {
  A = O;
}
filter_over(A) ::= filter_clause(F). {
  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( A ){
    A->eFrmType = TK_FILTER;
    A->pFilter = F;
  }else{
    sqlite3ExprDelete(pParse->db, F);
  }
}

over_clause(A) ::= OVER LP window(Z) RP. {
  A = Z;
  assert( A!=0 );
}
over_clause(A) ::= OVER nm(Z). {
  A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( A ){
    A->zName = sqlite3DbStrNDup(pParse->db, Z.z, Z.n);
  }
}

filter_clause(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
%endif /* SQLITE_OMIT_WINDOWFUNC */

/*
** The code generator needs some extra TK_ token values for tokens that
** are synthesized and do not actually appear in the grammar:
*/
%token
  COLUMN          /* Reference to a table column */
  AGG_FUNCTION    /* An aggregate function */
  AGG_COLUMN      /* An aggregated column */
  TRUEFALSE       /* True or false keyword */
  ISNOT           /* Combination of IS and NOT */
  FUNCTION        /* A function invocation */
  UMINUS          /* Unary minus */
  UPLUS           /* Unary plus */
  TRUTH           /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
  REGISTER        /* Reference to a VDBE register */
  VECTOR          /* Vector */
  SELECT_COLUMN   /* Choose a single column from a multi-column SELECT */
  IF_NULL_ROW     /* the if-null-row operator */
  ASTERISK        /* The "*" in count(*) and similar */
  SPAN            /* The span operator */
  ERROR           /* An expression containing an error */
.
/* There must be no more than 255 tokens defined above.  If this grammar
** is extended with new rules and tokens, they must either be so few in
** number that TK_SPAN is no more than 255, or else the new tokens must
** appear after this line.
*/
%include {
#if TK_SPAN>255
# error too many tokens in the grammar
#endif
}

/*
** The TK_SPACE and TK_ILLEGAL tokens must be the last two tokens.  The
** parser depends on this.  Those tokens are not used in any grammar rule.
** They are only used by the tokenizer.  Declare them last so that they
** are guaranteed to be the last two tokens
*/
%token SPACE ILLEGAL.
