Index: third_party/sqlite/src/src/parse.y |
diff --git a/third_party/sqlite/src/src/parse.y b/third_party/sqlite/src/src/parse.y |
index 39af6c0ce6cbd54f22bc5911af73a6638f65a83d..92abd5ce58118d115980839ddd8e2397ac940db5 100644 |
--- a/third_party/sqlite/src/src/parse.y |
+++ b/third_party/sqlite/src/src/parse.y |
@@ -13,8 +13,6 @@ |
** using the lemon parser generator to generate C code that runs |
** the parser. Lemon will also generate a header file containing |
** numeric codes for all of the tokens. |
-** |
-** @(#) $Id: parse.y,v 1.286 2009/08/10 03:57:58 shane Exp $ |
*/ |
// All token codes are small integers with #defines that begin with "TK_" |
@@ -196,9 +194,9 @@ id(A) ::= INDEXED(X). {A = X;} |
// This obviates the need for the "id" nonterminal. |
// |
%fallback ID |
- ABORT AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW CONFLICT |
- DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR |
- IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH PLAN |
+ ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW |
+ CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR |
+ IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN |
QUERY KEY OF OFFSET PRAGMA RAISE RELEASE REPLACE RESTRICT ROW ROLLBACK |
SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL |
%ifdef SQLITE_OMIT_COMPOUND_SELECT |
@@ -230,7 +228,7 @@ id(A) ::= INDEXED(X). {A = X;} |
%left STAR SLASH REM. |
%left CONCAT. |
%left COLLATE. |
-%right UMINUS UPLUS BITNOT. |
+%right BITNOT. |
// And "ids" is an identifer-or-string. |
// |
@@ -314,20 +312,21 @@ autoinc(X) ::= AUTOINCR. {X = 1;} |
// check fails. |
// |
%type refargs {int} |
-refargs(A) ::= . { A = OE_Restrict * 0x010101; } |
+refargs(A) ::= . { A = OE_None*0x0101; /* EV: R-19803-45884 */} |
refargs(A) ::= refargs(X) refarg(Y). { A = (X & ~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; } |
-refarg(A) ::= ON INSERT refact(X). { A.value = X<<16; A.mask = 0xff0000; } |
%type refact {int} |
-refact(A) ::= SET NULL. { A = OE_SetNull; } |
-refact(A) ::= SET DEFAULT. { A = OE_SetDflt; } |
-refact(A) ::= CASCADE. { A = OE_Cascade; } |
-refact(A) ::= RESTRICT. { A = OE_Restrict; } |
+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(X). {A = X;} |
+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;} |
@@ -781,7 +780,7 @@ expr(A) ::= VARIABLE(X). { |
spanSet(&A, &X, &X); |
} |
expr(A) ::= expr(E) COLLATE ids(C). { |
- A.pExpr = sqlite3ExprSetColl(pParse, E.pExpr, &C); |
+ A.pExpr = sqlite3ExprSetCollByToken(pParse, E.pExpr, &C); |
A.zStart = E.zStart; |
A.zEnd = &C.z[C.n]; |
} |
@@ -849,23 +848,27 @@ likeop(A) ::= LIKE_KW(X). {A.eOperator = X; A.not = 0;} |
likeop(A) ::= NOT LIKE_KW(X). {A.eOperator = X; A.not = 1;} |
likeop(A) ::= MATCH(X). {A.eOperator = X; A.not = 0;} |
likeop(A) ::= NOT MATCH(X). {A.eOperator = X; A.not = 1;} |
-%type escape {ExprSpan} |
-%destructor escape {sqlite3ExprDelete(pParse->db, $$.pExpr);} |
-escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} |
-escape(X) ::= . [ESCAPE] {memset(&X,0,sizeof(X));} |
-expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] { |
+expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] { |
ExprList *pList; |
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); |
pList = sqlite3ExprListAppend(pParse,pList, X.pExpr); |
- if( E.pExpr ){ |
- pList = sqlite3ExprListAppend(pParse,pList, E.pExpr); |
- } |
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); |
if( OP.not ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); |
A.zStart = X.zStart; |
A.zEnd = Y.zEnd; |
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; |
} |
+expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { |
+ ExprList *pList; |
+ pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); |
+ pList = sqlite3ExprListAppend(pParse,pList, X.pExpr); |
+ pList = sqlite3ExprListAppend(pParse,pList, E.pExpr); |
+ A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); |
+ if( OP.not ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); |
+ A.zStart = X.zStart; |
+ A.zEnd = E.zEnd; |
+ if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; |
+} |
%include { |
/* Construct an expression node for a unary postfix operator |
@@ -884,10 +887,35 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] { |
} |
expr(A) ::= expr(X) ISNULL|NOTNULL(E). {spanUnaryPostfix(&A,pParse,@E,&X,&E);} |
-expr(A) ::= expr(X) IS NULL(E). {spanUnaryPostfix(&A,pParse,TK_ISNULL,&X,&E);} |
expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);} |
-expr(A) ::= expr(X) IS NOT NULL(E). |
- {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);} |
+ |
+%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( db->mallocFailed==0 && pY->op==TK_NULL ){ |
+ 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(X) IS expr(Y). { |
+ spanBinaryExpr(&A,pParse,TK_IS,&X,&Y); |
+ binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL); |
+} |
+expr(A) ::= expr(X) IS NOT expr(Y). { |
+ spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y); |
+ binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL); |
+} |
%include { |
/* Construct an expression node for a unary prefix operator |
@@ -909,9 +937,9 @@ expr(A) ::= expr(X) IS NOT NULL(E). |
expr(A) ::= NOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} |
expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);} |
-expr(A) ::= MINUS(B) expr(X). [UMINUS] |
+expr(A) ::= MINUS(B) expr(X). [BITNOT] |
{spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);} |
-expr(A) ::= PLUS(B) expr(X). [UPLUS] |
+expr(A) ::= PLUS(B) expr(X). [BITNOT] |
{spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);} |
%type between_op {int} |
@@ -935,14 +963,27 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { |
in_op(A) ::= IN. {A = 0;} |
in_op(A) ::= NOT IN. {A = 1;} |
expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] { |
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0); |
- if( A.pExpr ){ |
- A.pExpr->x.pList = Y; |
- sqlite3ExprSetHeight(pParse, A.pExpr); |
+ 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. |
+ */ |
+ A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]); |
+ sqlite3ExprDelete(pParse->db, X.pExpr); |
}else{ |
- sqlite3ExprListDelete(pParse->db, Y); |
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0); |
+ if( A.pExpr ){ |
+ A.pExpr->x.pList = Y; |
+ sqlite3ExprSetHeight(pParse, A.pExpr); |
+ }else{ |
+ sqlite3ExprListDelete(pParse->db, Y); |
+ } |
+ if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); |
} |
- if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); |
A.zStart = X.zStart; |
A.zEnd = &E.z[E.n]; |
} |
@@ -1067,7 +1108,7 @@ idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z). { |
Expr *p = 0; |
if( C.n>0 ){ |
p = sqlite3Expr(pParse->db, TK_COLUMN, 0); |
- sqlite3ExprSetColl(pParse, p, &C); |
+ sqlite3ExprSetCollByToken(pParse, p, &C); |
} |
A = sqlite3ExprListAppend(pParse,X, p); |
sqlite3ExprListSetName(pParse,A,&Y,1); |
@@ -1078,7 +1119,7 @@ idxlist(A) ::= nm(Y) collate(C) sortorder(Z). { |
Expr *p = 0; |
if( C.n>0 ){ |
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); |
- sqlite3ExprSetColl(pParse, p, &C); |
+ sqlite3ExprSetCollByToken(pParse, p, &C); |
} |
A = sqlite3ExprListAppend(pParse,0, p); |
sqlite3ExprListSetName(pParse, A, &Y, 1); |