| Index: third_party/sqlite/sqlite-src-3100200/src/parse.y
|
| diff --git a/third_party/sqlite/src/src/parse.y b/third_party/sqlite/sqlite-src-3100200/src/parse.y
|
| similarity index 88%
|
| copy from third_party/sqlite/src/src/parse.y
|
| copy to third_party/sqlite/sqlite-src-3100200/src/parse.y
|
| index d888cff92d7f7d9e19916235d769ae2e9ad38541..6ac2be21f25b88bb11b898810ee97ad0584bc8b9 100644
|
| --- a/third_party/sqlite/src/src/parse.y
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/parse.y
|
| @@ -61,6 +61,18 @@
|
| #define yytestcase(X) testcase(X)
|
|
|
| /*
|
| +** Indicate that sqlite3ParserFree() will never be called with a null
|
| +** pointer.
|
| +*/
|
| +#define YYPARSEFREENEVERNULL 1
|
| +
|
| +/*
|
| +** Alternative datatype for the argument to the malloc() routine passed
|
| +** into sqlite3ParserAlloc(). The default is size_t.
|
| +*/
|
| +#define YYMALLOCARGTYPE u64
|
| +
|
| +/*
|
| ** An instance of this structure holds information about the
|
| ** LIMIT clause of a SELECT statement.
|
| */
|
| @@ -162,11 +174,11 @@ create_table_args ::= AS select(S). {
|
| sqlite3EndTable(pParse,0,0,0,S);
|
| sqlite3SelectDelete(pParse->db, S);
|
| }
|
| -%type table_options {u8}
|
| +%type table_options {int}
|
| table_options(A) ::= . {A = 0;}
|
| table_options(A) ::= WITHOUT nm(X). {
|
| if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
|
| - A = TF_WithoutRowid;
|
| + A = TF_WithoutRowid | TF_NoVisibleRowid;
|
| }else{
|
| A = 0;
|
| sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
|
| @@ -301,7 +313,7 @@ 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);}
|
| ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);}
|
| -ccons ::= REFERENCES nm(T) idxlist_opt(TA) refargs(R).
|
| +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);}
|
| @@ -345,14 +357,14 @@ conslist ::= tcons.
|
| tconscomma ::= COMMA. {pParse->constraintName.n = 0;}
|
| tconscomma ::= .
|
| tcons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
|
| -tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
|
| +tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
|
| {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
|
| -tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
|
| +tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
|
| {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
|
| tcons ::= CHECK LP expr(E) RP onconf.
|
| {sqlite3AddCheckConstraint(pParse,E.pExpr);}
|
| -tcons ::= FOREIGN KEY LP idxlist(FA) RP
|
| - REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
|
| +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);
|
| }
|
| @@ -364,12 +376,12 @@ defer_subclause_opt(A) ::= defer_subclause(X). {A = X;}
|
| // default behavior when there is a constraint conflict.
|
| //
|
| %type onconf {int}
|
| -%type orconf {u8}
|
| +%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 = (u8)X;}
|
| +orconf(A) ::= OR resolvetype(X). {A = X;}
|
| resolvetype(A) ::= raisetype(X). {A = X;}
|
| resolvetype(A) ::= IGNORE. {A = OE_Ignore;}
|
| resolvetype(A) ::= REPLACE. {A = OE_Replace;}
|
| @@ -386,8 +398,9 @@ ifexists(A) ::= . {A = 0;}
|
| ///////////////////// The CREATE VIEW statement /////////////////////////////
|
| //
|
| %ifndef SQLITE_OMIT_VIEW
|
| -cmd ::= createkw(X) temp(T) VIEW ifnotexists(E) nm(Y) dbnm(Z) AS select(S). {
|
| - sqlite3CreateView(pParse, &X, &Y, &Z, S, T, E);
|
| +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);
|
| @@ -409,22 +422,35 @@ cmd ::= select(X). {
|
| %type oneselect {Select*}
|
| %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
|
|
|
| -select(A) ::= with(W) selectnowith(X). {
|
| - Select *p = X, *pNext, *pLoop;
|
| - if( p ){
|
| - int cnt = 0, mxSelect;
|
| - p->pWith = W;
|
| +%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){
|
| if( p->pPrior ){
|
| - pNext = 0;
|
| + Select *pNext = 0, *pLoop;
|
| + int mxSelect, cnt = 0;
|
| for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
|
| pLoop->pNext = pNext;
|
| pLoop->selFlags |= SF_Compound;
|
| }
|
| - mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
|
| - if( mxSelect && cnt>mxSelect ){
|
| + 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");
|
| }
|
| }
|
| + }
|
| +}
|
| +
|
| +select(A) ::= with(W) selectnowith(X). {
|
| + Select *p = X;
|
| + if( p ){
|
| + p->pWith = W;
|
| + parserDoubleLinkSelect(pParse, p);
|
| }else{
|
| sqlite3WithDelete(pParse->db, W);
|
| }
|
| @@ -435,19 +461,23 @@ selectnowith(A) ::= oneselect(X). {A = X;}
|
| %ifndef SQLITE_OMIT_COMPOUND_SELECT
|
| selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
|
| Select *pRhs = Z;
|
| + Select *pLhs = X;
|
| if( pRhs && pRhs->pPrior ){
|
| SrcList *pFrom;
|
| Token x;
|
| x.n = 0;
|
| + parserDoubleLinkSelect(pParse, pRhs);
|
| pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
|
| pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
|
| }
|
| if( pRhs ){
|
| pRhs->op = (u8)Y;
|
| - pRhs->pPrior = X;
|
| + 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, X);
|
| + sqlite3SelectDelete(pParse->db, pLhs);
|
| }
|
| A = pRhs;
|
| }
|
| @@ -492,28 +522,31 @@ values(A) ::= VALUES LP nexprlist(X) RP. {
|
| A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
|
| }
|
| values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
|
| - Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
|
| + Select *pRight, *pLeft = X;
|
| + pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
|
| + if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
|
| if( pRight ){
|
| pRight->op = TK_ALL;
|
| - pRight->pPrior = X;
|
| + pLeft = X;
|
| + pRight->pPrior = pLeft;
|
| A = pRight;
|
| }else{
|
| - A = X;
|
| + A = pLeft;
|
| }
|
| }
|
|
|
| // The "distinct" nonterminal is true (1) if the DISTINCT keyword is
|
| // present and false (0) if it is not.
|
| //
|
| -%type distinct {u16}
|
| +%type distinct {int}
|
| distinct(A) ::= DISTINCT. {A = SF_Distinct;}
|
| -distinct(A) ::= ALL. {A = 0;}
|
| +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_ALL.
|
| +// opcode of TK_ASTERISK.
|
| //
|
| %type selcollist {ExprList*}
|
| %destructor selcollist {sqlite3ExprListDelete(pParse->db, $$);}
|
| @@ -527,11 +560,11 @@ selcollist(A) ::= sclp(P) expr(X) as(Y). {
|
| sqlite3ExprListSetSpan(pParse,A,&X);
|
| }
|
| selcollist(A) ::= sclp(P) STAR. {
|
| - Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
|
| + Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
|
| A = sqlite3ExprListAppend(pParse, P, p);
|
| }
|
| selcollist(A) ::= sclp(P) nm(X) DOT STAR(Y). {
|
| - Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &Y);
|
| + Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y);
|
| Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
|
| Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
|
| A = sqlite3ExprListAppend(pParse,P, pDot);
|
| @@ -566,7 +599,7 @@ from(A) ::= FROM seltablist(X). {
|
| //
|
| stl_prefix(A) ::= seltablist(X) joinop(Y). {
|
| A = X;
|
| - if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].jointype = (u8)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(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
|
| @@ -574,6 +607,11 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
|
| A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
|
| sqlite3SrcListIndexedBy(pParse, A, &I);
|
| }
|
| +seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
|
| + on_opt(N) using_opt(U). {
|
| + A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
|
| + sqlite3SrcListFuncArgs(pParse, A, E);
|
| +}
|
| %ifndef SQLITE_OMIT_SUBQUERY
|
| seltablist(A) ::= stl_prefix(X) LP select(S) RP
|
| as(Z) on_opt(N) using_opt(U). {
|
| @@ -613,7 +651,6 @@ dbnm(A) ::= DOT nm(X). {A = X;}
|
| fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);}
|
|
|
| %type joinop {int}
|
| -%type joinop2 {int}
|
| joinop(X) ::= COMMA|JOIN. { X = JT_INNER; }
|
| joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); }
|
| joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); }
|
| @@ -648,6 +685,11 @@ using_opt(U) ::= . {U = 0;}
|
|
|
| %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, $$);}
|
|
|
| @@ -655,18 +697,18 @@ orderby_opt(A) ::= . {A = 0;}
|
| orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
|
| sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
|
| A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
|
| - if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
| + sqlite3ExprListSetSortOrder(A,Z);
|
| }
|
| sortlist(A) ::= expr(Y) sortorder(Z). {
|
| A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
|
| - if( A && ALWAYS(A->a) ) A->a[0].sortOrder = (u8)Z;
|
| + sqlite3ExprListSetSortOrder(A,Z);
|
| }
|
|
|
| %type sortorder {int}
|
|
|
| sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;}
|
| sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;}
|
| -sortorder(A) ::= . {A = SQLITE_SO_ASC;}
|
| +sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;}
|
|
|
| %type groupby_opt {ExprList*}
|
| %destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
| @@ -759,27 +801,27 @@ setlist(A) ::= nm(X) EQ expr(Y). {
|
|
|
| ////////////////////////// The INSERT command /////////////////////////////////
|
| //
|
| -cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S). {
|
| +cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) select(S). {
|
| sqlite3WithPush(pParse, W, 1);
|
| sqlite3Insert(pParse, X, S, F, R);
|
| }
|
| -cmd ::= with(W) insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
|
| +cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) DEFAULT VALUES.
|
| {
|
| sqlite3WithPush(pParse, W, 1);
|
| sqlite3Insert(pParse, X, 0, F, R);
|
| }
|
|
|
| -%type insert_cmd {u8}
|
| +%type insert_cmd {int}
|
| insert_cmd(A) ::= INSERT orconf(R). {A = R;}
|
| insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
|
|
|
| -%type inscollist_opt {IdList*}
|
| -%destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);}
|
| +%type idlist_opt {IdList*}
|
| +%destructor idlist_opt {sqlite3IdListDelete(pParse->db, $$);}
|
| %type idlist {IdList*}
|
| %destructor idlist {sqlite3IdListDelete(pParse->db, $$);}
|
|
|
| -inscollist_opt(A) ::= . {A = 0;}
|
| -inscollist_opt(A) ::= LP idlist(X) RP. {A = X;}
|
| +idlist_opt(A) ::= . {A = 0;}
|
| +idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
|
| idlist(A) ::= idlist(X) COMMA nm(Y).
|
| {A = sqlite3IdListAppend(pParse->db,X,&Y);}
|
| idlist(A) ::= nm(Y).
|
| @@ -870,7 +912,7 @@ expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
|
| }
|
| A.pExpr = sqlite3ExprFunction(pParse, Y, &X);
|
| spanSet(&A,&X,&E);
|
| - if( D && A.pExpr ){
|
| + if( D==SF_Distinct && A.pExpr ){
|
| A.pExpr->flags |= EP_Distinct;
|
| }
|
| }
|
| @@ -898,6 +940,13 @@ term(A) ::= CTIME_KW(OP). {
|
| pOut->zStart = pLeft->zStart;
|
| pOut->zEnd = pRight->zEnd;
|
| }
|
| +
|
| + /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
|
| + ** outside of *ppExpr.
|
| + */
|
| + static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
|
| + if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
|
| + }
|
| }
|
|
|
| expr(A) ::= expr(X) AND(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
|
| @@ -920,7 +969,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] {
|
| pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
|
| pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
|
| A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
|
| - if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, OP.bNot, &A.pExpr);
|
| A.zStart = X.zStart;
|
| A.zEnd = Y.zEnd;
|
| if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
|
| @@ -931,7 +980,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
|
| pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
|
| pList = sqlite3ExprListAppend(pParse,pList, E.pExpr);
|
| A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
|
| - if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, OP.bNot, &A.pExpr);
|
| A.zStart = X.zStart;
|
| A.zEnd = E.zEnd;
|
| if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
|
| @@ -1021,7 +1070,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| }else{
|
| sqlite3ExprListDelete(pParse->db, pList);
|
| }
|
| - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, N, &A.pExpr);
|
| A.zStart = W.zStart;
|
| A.zEnd = Y.zEnd;
|
| }
|
| @@ -1072,11 +1121,11 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
| if( A.pExpr ){
|
| A.pExpr->x.pList = Y;
|
| - sqlite3ExprSetHeight(pParse, A.pExpr);
|
| + sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
| }else{
|
| sqlite3ExprListDelete(pParse->db, Y);
|
| }
|
| - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, N, &A.pExpr);
|
| }
|
| A.zStart = X.zStart;
|
| A.zEnd = &E.z[E.n];
|
| @@ -1085,8 +1134,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
|
| if( A.pExpr ){
|
| A.pExpr->x.pSelect = X;
|
| - ExprSetProperty(A.pExpr, EP_xIsSelect);
|
| - sqlite3ExprSetHeight(pParse, A.pExpr);
|
| + ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
| + sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
| }else{
|
| sqlite3SelectDelete(pParse->db, X);
|
| }
|
| @@ -1097,12 +1146,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
| if( A.pExpr ){
|
| A.pExpr->x.pSelect = Y;
|
| - ExprSetProperty(A.pExpr, EP_xIsSelect);
|
| - sqlite3ExprSetHeight(pParse, A.pExpr);
|
| + ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
| + sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
| }else{
|
| sqlite3SelectDelete(pParse->db, Y);
|
| }
|
| - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, N, &A.pExpr);
|
| A.zStart = X.zStart;
|
| A.zEnd = &E.z[E.n];
|
| }
|
| @@ -1111,12 +1160,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
|
| if( A.pExpr ){
|
| A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
|
| - ExprSetProperty(A.pExpr, EP_xIsSelect);
|
| - sqlite3ExprSetHeight(pParse, A.pExpr);
|
| + ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
|
| + sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
| }else{
|
| sqlite3SrcListDelete(pParse->db, pSrc);
|
| }
|
| - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
|
| + exprNot(pParse, N, &A.pExpr);
|
| A.zStart = X.zStart;
|
| A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
|
| }
|
| @@ -1124,8 +1173,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
|
| Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
|
| if( p ){
|
| p->x.pSelect = Y;
|
| - ExprSetProperty(p, EP_xIsSelect);
|
| - sqlite3ExprSetHeight(pParse, p);
|
| + ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
|
| + sqlite3ExprSetHeightAndFlags(pParse, p);
|
| }else{
|
| sqlite3SelectDelete(pParse->db, Y);
|
| }
|
| @@ -1139,7 +1188,7 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
|
| A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
|
| if( A.pExpr ){
|
| A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
|
| - sqlite3ExprSetHeight(pParse, A.pExpr);
|
| + sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
|
| }else{
|
| sqlite3ExprListDelete(pParse->db, Y);
|
| sqlite3ExprDelete(pParse->db, Z);
|
| @@ -1182,7 +1231,7 @@ nexprlist(A) ::= expr(Y).
|
| ///////////////////////////// The CREATE INDEX command ///////////////////////
|
| //
|
| cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
|
| - ON nm(Y) LP idxlist(Z) RP where_opt(W). {
|
| + ON nm(Y) LP sortlist(Z) RP where_opt(W). {
|
| sqlite3CreateIndex(pParse, &X, &D,
|
| sqlite3SrcListAppend(pParse->db,0,&Y,0), Z, U,
|
| &S, W, SQLITE_SO_ASC, NE);
|
| @@ -1192,31 +1241,64 @@ cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X) dbnm(D)
|
| uniqueflag(A) ::= UNIQUE. {A = OE_Abort;}
|
| uniqueflag(A) ::= . {A = OE_None;}
|
|
|
| -%type idxlist {ExprList*}
|
| -%destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
|
| -%type idxlist_opt {ExprList*}
|
| -%destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}
|
|
|
| -idxlist_opt(A) ::= . {A = 0;}
|
| -idxlist_opt(A) ::= LP idxlist(X) RP. {A = X;}
|
| -idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
| - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
| - A = sqlite3ExprListAppend(pParse,X, p);
|
| - sqlite3ExprListSetName(pParse,A,&Y,1);
|
| - sqlite3ExprListCheckLength(pParse, A, "index");
|
| - if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
| +// 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_master schema.
|
| +// 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(X) COMMA nm(Y) collate(C) sortorder(Z). {
|
| + A = parserAddExprIdListTerm(pParse, X, &Y, C, Z);
|
| }
|
| -idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
| - Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &C, 1);
|
| - A = sqlite3ExprListAppend(pParse,0, p);
|
| - sqlite3ExprListSetName(pParse, A, &Y, 1);
|
| - sqlite3ExprListCheckLength(pParse, A, "index");
|
| - if( A ) A->a[A->nExpr-1].sortOrder = (u8)Z;
|
| +eidlist(A) ::= nm(Y) collate(C) sortorder(Z). {
|
| + A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z);
|
| }
|
|
|
| -%type collate {Token}
|
| -collate(C) ::= . {C.z = 0; C.n = 0;}
|
| -collate(C) ::= COLLATE ids(X). {C = X;}
|
| +%type collate {int}
|
| +collate(C) ::= . {C = 0;}
|
| +collate(C) ::= COLLATE ids. {C = 1;}
|
|
|
|
|
| ///////////////////////////// The DROP INDEX command /////////////////////////
|
| @@ -1344,7 +1426,7 @@ trigger_cmd(A) ::=
|
| { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
|
|
|
| // INSERT
|
| -trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) inscollist_opt(F) select(S).
|
| +trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S).
|
| {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);}
|
|
|
| // DELETE
|
| @@ -1464,10 +1546,10 @@ with(A) ::= . {A = 0;}
|
| with(A) ::= WITH wqlist(W). { A = W; }
|
| with(A) ::= WITH RECURSIVE wqlist(W). { A = W; }
|
|
|
| -wqlist(A) ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. {
|
| +wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
|
| A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
|
| }
|
| -wqlist(A) ::= wqlist(W) COMMA nm(X) idxlist_opt(Y) AS LP select(Z) RP. {
|
| +wqlist(A) ::= wqlist(W) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
|
| A = sqlite3WithAdd(pParse, W, &X, Y, Z);
|
| }
|
| %endif SQLITE_OMIT_CTE
|
|
|