aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attach.c2
-rw-r--r--src/expr.c54
-rw-r--r--src/parse.y5
-rw-r--r--src/resolve.c6
-rw-r--r--src/select.c4
-rw-r--r--src/sqliteInt.h53
-rw-r--r--src/walker.c2
7 files changed, 60 insertions, 66 deletions
diff --git a/src/attach.c b/src/attach.c
index 6d965ace6..805305dab 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -509,7 +509,7 @@ int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
diff --git a/src/expr.c b/src/expr.c
index 6587ee1f7..82623b14b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -596,7 +596,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
const char *z;
if( pExpr==0 ) return;
- assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
@@ -666,12 +666,12 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
+ /* The Expr.x union is never used at the same time as Expr.pRight */
+ assert( p->x.pList==0 || p->pRight==0 );
sqlite3ExprDelete(db, p->pLeft);
sqlite3ExprDelete(db, p->pRight);
- if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
- sqlite3DbFree(db, p->u.zToken);
- }
+ if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@@ -734,10 +734,10 @@ static int dupedExprStructSize(Expr *p, int flags){
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
}else{
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_FromJoin) );
- assert( (p->flags2 & EP2_MallocedToken)==0 );
- assert( (p->flags2 & EP2_Irreducible)==0 );
+ assert( !ExprHasProperty(p, EP_MemToken) );
+ assert( !ExprHasProperty(p, EP_Irreduce) );
if( p->pLeft || p->pRight || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
@@ -834,7 +834,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
@@ -854,7 +854,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
@@ -864,8 +864,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
- pNew->flags2 = 0;
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
@@ -1175,7 +1174,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* If pWalker->u.i is 3 then any term of the expression that comes from
** the ON or USING clauses of a join disqualifies the expression
** from being considered constant. */
- if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
+ if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
pWalker->u.i = 0;
return WRC_Abort;
}
@@ -1606,7 +1605,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
}else{
testcase( pParse->nQueryLoop>0 );
pParse->nQueryLoop = 0;
- if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
+ if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
eType = IN_INDEX_ROWID;
}
}
@@ -1675,7 +1674,7 @@ int sqlite3CodeSubselect(
** If all of the above are false, then we can run this code just once
** save the results, and reuse the same result on subsequent invocations.
*/
- if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
+ if( !ExprHasProperty(pExpr, EP_VarSelect) ){
testAddr = sqlite3CodeOnce(pParse);
}
@@ -2615,7 +2614,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
@@ -2846,9 +2845,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
** WHEN x=eN THEN rN ELSE y END
**
** X (if it exists) is in pExpr->pLeft.
- ** Y is in pExpr->pRight. The Y is also optional. If there is no
- ** ELSE clause and no other term matches, then the result of the
- ** exprssion is NULL.
+ ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is
+ ** odd. The Y is also optional. If the number of elements in x.pList
+ ** is even, then Y is omitted and the "otherwise" result is NULL.
** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
**
** The result of the expression is the Ri for the first matching Ei,
@@ -2869,7 +2868,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
- assert((pExpr->x.pList->nExpr % 2) == 0);
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
@@ -2891,7 +2889,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
** purposes and possibly overwritten. */
regFree1 = 0;
}
- for(i=0; i<nExpr; i=i+2){
+ for(i=0; i<nExpr-1; i=i+2){
sqlite3ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
@@ -2909,9 +2907,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
sqlite3ExprCachePop(pParse, 1);
sqlite3VdbeResolveLabel(v, nextCase);
}
- if( pExpr->pRight ){
+ if( (nExpr&1)!=0 ){
sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pRight, target);
+ sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
sqlite3ExprCachePop(pParse, 1);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -3155,7 +3153,7 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
@@ -3821,8 +3819,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
if( pA==0||pB==0 ){
return pB==pA ? 0 : 2;
}
- assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pA, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 2;
}
@@ -4036,7 +4034,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
@@ -4131,7 +4129,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
diff --git a/src/parse.y b/src/parse.y
index e9c8a1563..1e8d7f751 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -1081,12 +1081,13 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
- A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, Z, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
if( A.pExpr ){
- A.pExpr->x.pList = Y;
+ A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
sqlite3ExprSetHeight(pParse, A.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, Y);
+ sqlite3ExprDelete(pParse->db, Z);
}
A.zStart = C.z;
A.zEnd = &E.z[E.n];
diff --git a/src/resolve.c b/src/resolve.c
index 43a3870e2..54ce3adf5 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -129,7 +129,7 @@ static void resolveAlias(
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
- pExpr->flags2 |= EP2_MallocedToken;
+ pExpr->flags |= EP_MemToken;
}
sqlite3DbFree(db, pDup);
}
@@ -229,7 +229,7 @@ static int lookupName(
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
@@ -591,7 +591,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pParse = pNC->pParse;
assert( pParse==pWalker->pParse );
- if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
+ if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune;
ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
diff --git a/src/select.c b/src/select.c
index 6e409e73a..f0dbf8091 100644
--- a/src/select.c
+++ b/src/select.c
@@ -264,7 +264,7 @@ static void addWhereTerm(
pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
if( pEq && isOuterJoin ){
ExprSetProperty(pEq, EP_FromJoin);
- assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pEq);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
@@ -300,7 +300,7 @@ static void addWhereTerm(
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(p);
p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index f017229f7..758561362 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1722,7 +1722,7 @@ typedef int ynVar;
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
- u16 flags; /* Various flags. EP_* See below */
+ u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
int iValue; /* Non-negative integer value if EP_IntValue */
@@ -1736,8 +1736,8 @@ struct Expr {
Expr *pLeft; /* Left subnode */
Expr *pRight; /* Right subnode */
union {
- ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
- Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
+ ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
+ Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */
} x;
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
@@ -1755,7 +1755,6 @@ struct Expr {
** TK_VARIABLE: variable number (always >= 1). */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 flags2; /* Second set of flags. EP2_... */
u8 op2; /* TK_REGISTER: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
@@ -1766,28 +1765,24 @@ struct Expr {
/*
** The following are the meanings of bits in the Expr.flags field.
*/
-#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
-#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
-#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
-#define EP_Error 0x0008 /* Expression contains one or more errors */
-#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
-#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
-#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
-#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
-#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
-#define EP_FixedDest 0x0200 /* Result needed in a specific register */
-#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Hint 0x1000 /* Not used */
-#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
-#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
-
-/*
-** The following are the meanings of bits in the Expr.flags2 field.
-*/
-#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
+#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
+#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
+#define EP_Error 0x000008 /* Expression contains one or more errors */
+#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
+#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
+#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */
+#define EP_FixedDest 0x000200 /* Result needed in a specific register */
+#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
+#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
+#define EP_Hint 0x001000 /* Not used */
+#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
+#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP_Irreduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
/*
** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
@@ -1796,7 +1791,7 @@ struct Expr {
** so as not to burden production code.
*/
#ifdef SQLITE_DEBUG
-# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+# define ExprSetIrreducible(X) (X)->flags |= EP_Irreduce
#else
# define ExprSetIrreducible(X)
#endif
@@ -1805,8 +1800,8 @@ struct Expr {
** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
-#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
-#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P) (E)->flags|=(P)
#define ExprClearProperty(E,P) (E)->flags&=~(P)
diff --git a/src/walker.c b/src/walker.c
index e71ed2ac4..cde34ad78 100644
--- a/src/walker.c
+++ b/src/walker.c
@@ -43,7 +43,7 @@ int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
+ && !ExprHasProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){