Index: third_party/sqlite/src/src/resolve.c |
diff --git a/third_party/sqlite/src/src/resolve.c b/third_party/sqlite/src/src/resolve.c |
index 068e3355680ca050fc9f8fb2ef58a14d42918e1e..bb6646256a0fc4a0d50b5dc131aa5ef7fa288365 100644 |
--- a/third_party/sqlite/src/src/resolve.c |
+++ b/third_party/sqlite/src/src/resolve.c |
@@ -28,7 +28,7 @@ |
** is a helper function - a callback for the tree walker. |
*/ |
static int incrAggDepth(Walker *pWalker, Expr *pExpr){ |
- if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i; |
+ if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; |
return WRC_Continue; |
} |
static void incrAggFunctionDepth(Expr *pExpr, int N){ |
@@ -36,7 +36,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ |
Walker w; |
memset(&w, 0, sizeof(w)); |
w.xExprCallback = incrAggDepth; |
- w.u.i = N; |
+ w.u.n = N; |
sqlite3WalkExpr(&w, pExpr); |
} |
} |
@@ -45,30 +45,6 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ |
** Turn the pExpr expression into an alias for the iCol-th column of the |
** result set in pEList. |
** |
-** If the result set column is a simple column reference, then this routine |
-** makes an exact copy. But for any other kind of expression, this |
-** routine make a copy of the result set column as the argument to the |
-** TK_AS operator. The TK_AS operator causes the expression to be |
-** evaluated just once and then reused for each alias. |
-** |
-** The reason for suppressing the TK_AS term when the expression is a simple |
-** column reference is so that the column reference will be recognized as |
-** usable by indices within the WHERE clause processing logic. |
-** |
-** The TK_AS operator is inhibited if zType[0]=='G'. This means |
-** that in a GROUP BY clause, the expression is evaluated twice. Hence: |
-** |
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x |
-** |
-** Is equivalent to: |
-** |
-** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5 |
-** |
-** The result of random()%5 in the GROUP BY clause is probably different |
-** from the result in the result-set. On the other hand Standard SQL does |
-** not allow the GROUP BY clause to contain references to result-set columns. |
-** So this should never come up in well-formed queries. |
-** |
** If the reference is followed by a COLLATE operator, then make sure |
** the COLLATE operator is preserved. For example: |
** |
@@ -79,7 +55,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ |
** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; |
** |
** The nSubquery parameter specifies how many levels of subquery the |
-** alias is removed from the original expression. The usually value is |
+** alias is removed from the original expression. The usual value is |
** zero but it might be more if the alias is contained within a subquery |
** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION |
** structures must be increased by the nSubquery amount. |
@@ -99,23 +75,14 @@ static void resolveAlias( |
assert( iCol>=0 && iCol<pEList->nExpr ); |
pOrig = pEList->a[iCol].pExpr; |
assert( pOrig!=0 ); |
- assert( pOrig->flags & EP_Resolved ); |
db = pParse->db; |
pDup = sqlite3ExprDup(db, pOrig, 0); |
if( pDup==0 ) return; |
- if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){ |
- incrAggFunctionDepth(pDup, nSubquery); |
- pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); |
- if( pDup==0 ) return; |
- ExprSetProperty(pDup, EP_Skip); |
- if( pEList->a[iCol].u.x.iAlias==0 ){ |
- pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); |
- } |
- pDup->iTable = pEList->a[iCol].u.x.iAlias; |
- } |
+ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); |
if( pExpr->op==TK_COLLATE ){ |
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); |
} |
+ ExprSetProperty(pDup, EP_Alias); |
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This |
** prevents ExprDelete() from deleting the Expr structure itself, |
@@ -247,9 +214,10 @@ static int lookupName( |
testcase( pNC->ncFlags & NC_PartIdx ); |
testcase( pNC->ncFlags & NC_IsCheck ); |
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ |
- /* Silently ignore database qualifiers inside CHECK constraints and partial |
- ** indices. Do not raise errors because that might break legacy and |
- ** because it does not hurt anything to just ignore the database name. */ |
+ /* Silently ignore database qualifiers inside CHECK constraints and |
+ ** partial indices. Do not raise errors because that might break |
+ ** legacy and because it does not hurt anything to just ignore the |
+ ** database name. */ |
zDb = 0; |
}else{ |
for(i=0; i<db->nDb; i++){ |
@@ -306,7 +274,7 @@ static int lookupName( |
** USING clause, then skip this match. |
*/ |
if( cnt==1 ){ |
- if( pItem->jointype & JT_NATURAL ) continue; |
+ if( pItem->fg.jointype & JT_NATURAL ) continue; |
if( nameInUsingClause(pItem->pUsing, zCol) ) continue; |
} |
cnt++; |
@@ -320,8 +288,9 @@ static int lookupName( |
if( pMatch ){ |
pExpr->iTable = pMatch->iCursor; |
pExpr->pTab = pMatch->pTab; |
- assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */ |
- if( (pMatch->jointype & JT_LEFT)!=0 ){ |
+ /* RIGHT JOIN not (yet) supported */ |
+ assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); |
+ if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ |
ExprSetProperty(pExpr, EP_CanBeNull); |
} |
pSchema = pExpr->pTab->pSchema; |
@@ -357,9 +326,8 @@ static int lookupName( |
break; |
} |
} |
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ |
+ if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ |
/* IMP: R-51414-32910 */ |
- /* IMP: R-44911-55124 */ |
iCol = -1; |
} |
if( iCol<pTab->nCol ){ |
@@ -386,10 +354,15 @@ static int lookupName( |
/* |
** Perhaps the name is a reference to the ROWID |
*/ |
- if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol) |
- && HasRowid(pMatch->pTab) ){ |
+ if( cnt==0 |
+ && cntTab==1 |
+ && pMatch |
+ && (pNC->ncFlags & NC_IdxExpr)==0 |
+ && sqlite3IsRowid(zCol) |
+ && VisibleRowid(pMatch->pTab) |
+ ){ |
cnt = 1; |
- pExpr->iColumn = -1; /* IMP: R-44911-55124 */ |
+ pExpr->iColumn = -1; |
pExpr->affinity = SQLITE_AFF_INTEGER; |
} |
@@ -406,9 +379,9 @@ static int lookupName( |
** resolved by the time the WHERE clause is resolved. |
** |
** The ability to use an output result-set column in the WHERE, GROUP BY, |
- ** or HAVING clauses, or as part of a larger expression in the ORDRE BY |
+ ** or HAVING clauses, or as part of a larger expression in the ORDER BY |
** clause is not standard SQL. This is a (goofy) SQLite extension, that |
- ** is supported for backwards compatibility only. TO DO: Issue a warning |
+ ** is supported for backwards compatibility only. Hence, we issue a warning |
** on sqlite3_log() whenever the capability is used. |
*/ |
if( (pEList = pNC->pEList)!=0 |
@@ -505,7 +478,7 @@ static int lookupName( |
lookupname_end: |
if( cnt==1 ){ |
assert( pNC!=0 ); |
- if( pExpr->op!=TK_AS ){ |
+ if( !ExprHasProperty(pExpr, EP_Alias) ){ |
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); |
} |
/* Increment the nRef value on all name contexts from TopNC up to |
@@ -546,36 +519,25 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ |
} |
/* |
-** Report an error that an expression is not valid for a partial index WHERE |
-** clause. |
+** Report an error that an expression is not valid for some set of |
+** pNC->ncFlags values determined by validMask. |
*/ |
-static void notValidPartIdxWhere( |
+static void notValid( |
Parse *pParse, /* Leave error message here */ |
NameContext *pNC, /* The name context */ |
- const char *zMsg /* Type of error */ |
+ const char *zMsg, /* Type of error */ |
+ int validMask /* Set of contexts for which prohibited */ |
){ |
- if( (pNC->ncFlags & NC_PartIdx)!=0 ){ |
- sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses", |
- zMsg); |
- } |
-} |
- |
+ assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 ); |
+ if( (pNC->ncFlags & validMask)!=0 ){ |
+ const char *zIn = "partial index WHERE clauses"; |
+ if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; |
#ifndef SQLITE_OMIT_CHECK |
-/* |
-** Report an error that an expression is not valid for a CHECK constraint. |
-*/ |
-static void notValidCheckConstraint( |
- Parse *pParse, /* Leave error message here */ |
- NameContext *pNC, /* The name context */ |
- const char *zMsg /* Type of error */ |
-){ |
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){ |
- sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg); |
+ else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; |
+#endif |
+ sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); |
} |
} |
-#else |
-# define notValidCheckConstraint(P,N,M) |
-#endif |
/* |
** Expression p should encode a floating point value between 1.0 and 0.0. |
@@ -588,7 +550,7 @@ static int exprProbability(Expr *p){ |
sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); |
assert( r>=0.0 ); |
if( r>1.0 ) return -1; |
- return (int)(r*1000.0); |
+ return (int)(r*134217728.0); |
} |
/* |
@@ -641,7 +603,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
pExpr->affinity = SQLITE_AFF_INTEGER; |
break; |
} |
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */ |
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) |
+ && !defined(SQLITE_OMIT_SUBQUERY) */ |
/* A lone identifier is the name of a column. |
*/ |
@@ -659,6 +622,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
Expr *pRight; |
/* if( pSrcList==0 ) break; */ |
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); |
+ /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/ |
pRight = pExpr->pRight; |
if( pRight->op==TK_ID ){ |
zDb = 0; |
@@ -688,7 +653,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
u8 enc = ENC(pParse->db); /* The database encoding */ |
assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); |
- notValidPartIdxWhere(pParse, pNC, "functions"); |
+ notValid(pParse, pNC, "functions", NC_PartIdx); |
zId = pExpr->u.zToken; |
nId = sqlite3Strlen30(zId); |
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); |
@@ -706,21 +671,22 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
if( n==2 ){ |
pExpr->iTable = exprProbability(pList->a[1].pExpr); |
if( pExpr->iTable<0 ){ |
- sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a " |
- "constant between 0.0 and 1.0"); |
+ sqlite3ErrorMsg(pParse, |
+ "second argument to likelihood() must be a " |
+ "constant between 0.0 and 1.0"); |
pNC->nErr++; |
} |
}else{ |
- /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to |
- ** likelihood(X, 0.0625). |
- ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for |
- ** likelihood(X,0.0625). |
- ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for |
- ** likelihood(X,0.9375). |
- ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to |
- ** likelihood(X,0.9375). */ |
+ /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is |
+ ** equivalent to likelihood(X, 0.0625). |
+ ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is |
+ ** short-hand for likelihood(X,0.0625). |
+ ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand |
+ ** for likelihood(X,0.9375). |
+ ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent |
+ ** to likelihood(X,0.9375). */ |
/* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ |
- pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938; |
+ pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; |
} |
} |
#ifndef SQLITE_OMIT_AUTHORIZATION |
@@ -735,7 +701,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
return WRC_Prune; |
} |
#endif |
- if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); |
+ if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ |
+ /* For the purposes of the EP_ConstFunc flag, date and time |
+ ** functions and other functions that change slowly are considered |
+ ** constant because they are constant for the duration of one query */ |
+ ExprSetProperty(pExpr,EP_ConstFunc); |
+ } |
+ if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ |
+ /* Date/time functions that use 'now', and other functions like |
+ ** sqlite_version() that might change over time cannot be used |
+ ** in an index. */ |
+ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr); |
+ } |
} |
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ |
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); |
@@ -781,8 +758,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
testcase( pExpr->op==TK_IN ); |
if( ExprHasProperty(pExpr, EP_xIsSelect) ){ |
int nRef = pNC->nRef; |
- notValidCheckConstraint(pParse, pNC, "subqueries"); |
- notValidPartIdxWhere(pParse, pNC, "subqueries"); |
+ notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr); |
sqlite3WalkSelect(pWalker, pExpr->x.pSelect); |
assert( pNC->nRef>=nRef ); |
if( nRef!=pNC->nRef ){ |
@@ -792,8 +768,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ |
break; |
} |
case TK_VARIABLE: { |
- notValidCheckConstraint(pParse, pNC, "parameters"); |
- notValidPartIdxWhere(pParse, pNC, "parameters"); |
+ notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr); |
break; |
} |
} |
@@ -987,9 +962,11 @@ static int resolveCompoundOrderBy( |
if( pItem->pExpr==pE ){ |
pItem->pExpr = pNew; |
}else{ |
- assert( pItem->pExpr->op==TK_COLLATE ); |
- assert( pItem->pExpr->pLeft==pE ); |
- pItem->pExpr->pLeft = pNew; |
+ Expr *pParent = pItem->pExpr; |
+ assert( pParent->op==TK_COLLATE ); |
+ while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; |
+ assert( pParent->pLeft==pE ); |
+ pParent->pLeft = pNew; |
} |
sqlite3ExprDelete(db, pE); |
pItem->u.x.iOrderByCol = (u16)iCol; |
@@ -1046,7 +1023,8 @@ int sqlite3ResolveOrderGroupBy( |
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); |
return 1; |
} |
- resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0); |
+ resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, |
+ zType,0); |
} |
} |
return 0; |
@@ -1134,7 +1112,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
int isCompound; /* True if p is a compound select */ |
int nCompound; /* Number of compound terms processed so far */ |
Parse *pParse; /* Parsing context */ |
- ExprList *pEList; /* Result set expression list */ |
int i; /* Loop counter */ |
ExprList *pGroupBy; /* The GROUP BY clause */ |
Select *pLeftmost; /* Left-most of SELECT of a compound */ |
@@ -1179,6 +1156,20 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
sqlite3ResolveExprNames(&sNC, p->pOffset) ){ |
return WRC_Abort; |
} |
+ |
+ /* If the SF_Converted flags is set, then this Select object was |
+ ** was created by the convertCompoundSelectToSubquery() function. |
+ ** In this case the ORDER BY clause (p->pOrderBy) should be resolved |
+ ** as if it were part of the sub-query, not the parent. This block |
+ ** moves the pOrderBy down to the sub-query. It will be moved back |
+ ** after the names have been resolved. */ |
+ if( p->selFlags & SF_Converted ){ |
+ Select *pSub = p->pSrc->a[0].pSelect; |
+ assert( p->pSrc->nSrc==1 && p->pOrderBy ); |
+ assert( pSub->pPrior && pSub->pOrderBy==0 ); |
+ pSub->pOrderBy = p->pOrderBy; |
+ p->pOrderBy = 0; |
+ } |
/* Recursively resolve names in all subqueries |
*/ |
@@ -1193,7 +1184,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
** parent contexts. After resolving references to expressions in |
** pItem->pSelect, check if this value has changed. If so, then |
** SELECT statement pItem->pSelect must be correlated. Set the |
- ** pItem->isCorrelated flag if this is the case. */ |
+ ** pItem->fg.isCorrelated flag if this is the case. */ |
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; |
if( pItem->zName ) pParse->zAuthContext = pItem->zName; |
@@ -1202,8 +1193,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
if( pParse->nErr || db->mallocFailed ) return WRC_Abort; |
for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; |
- assert( pItem->isCorrelated==0 && nRef<=0 ); |
- pItem->isCorrelated = (nRef!=0); |
+ assert( pItem->fg.isCorrelated==0 && nRef<=0 ); |
+ pItem->fg.isCorrelated = (nRef!=0); |
} |
} |
@@ -1215,14 +1206,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
sNC.pNext = pOuterNC; |
/* Resolve names in the result set. */ |
- pEList = p->pEList; |
- assert( pEList!=0 ); |
- for(i=0; i<pEList->nExpr; i++){ |
- Expr *pX = pEList->a[i].pExpr; |
- if( sqlite3ResolveExprNames(&sNC, pX) ){ |
- return WRC_Abort; |
- } |
- } |
+ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; |
/* If there are no aggregate functions in the result-set, and no GROUP BY |
** expression, do not allow aggregates in any of the other expressions. |
@@ -1255,18 +1239,46 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; |
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; |
+ /* Resolve names in table-valued-function arguments */ |
+ for(i=0; i<p->pSrc->nSrc; i++){ |
+ struct SrcList_item *pItem = &p->pSrc->a[i]; |
+ if( pItem->fg.isTabFunc |
+ && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) |
+ ){ |
+ return WRC_Abort; |
+ } |
+ } |
+ |
/* The ORDER BY and GROUP BY clauses may not refer to terms in |
** outer queries |
*/ |
sNC.pNext = 0; |
sNC.ncFlags |= NC_AllowAgg; |
+ /* If this is a converted compound query, move the ORDER BY clause from |
+ ** the sub-query back to the parent query. At this point each term |
+ ** within the ORDER BY clause has been transformed to an integer value. |
+ ** These integers will be replaced by copies of the corresponding result |
+ ** set expressions by the call to resolveOrderGroupBy() below. */ |
+ if( p->selFlags & SF_Converted ){ |
+ Select *pSub = p->pSrc->a[0].pSelect; |
+ p->pOrderBy = pSub->pOrderBy; |
+ pSub->pOrderBy = 0; |
+ } |
+ |
/* Process the ORDER BY clause for singleton SELECT statements. |
** The ORDER BY clause for compounds SELECT statements is handled |
** below, after all of the result-sets for all of the elements of |
** the compound have been resolved. |
+ ** |
+ ** If there is an ORDER BY clause on a term of a compound-select other |
+ ** than the right-most term, then that is a syntax error. But the error |
+ ** is not detected until much later, and so we need to go ahead and |
+ ** resolve those symbols on the incorrect ORDER BY for consistency. |
*/ |
- if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){ |
+ if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ |
+ && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") |
+ ){ |
return WRC_Abort; |
} |
if( db->mallocFailed ){ |
@@ -1291,6 +1303,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ |
} |
} |
+ /* If this is part of a compound SELECT, check that it has the right |
+ ** number of expressions in the select list. */ |
+ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ |
+ sqlite3SelectWrongNumTermsError(pParse, p->pNext); |
+ return WRC_Abort; |
+ } |
+ |
/* Advance to the next term of the compound |
*/ |
p = p->pPrior; |
@@ -1393,6 +1412,23 @@ int sqlite3ResolveExprNames( |
return ExprHasProperty(pExpr, EP_Error); |
} |
+/* |
+** Resolve all names for all expression in an expression list. This is |
+** just like sqlite3ResolveExprNames() except that it works for an expression |
+** list rather than a single expression. |
+*/ |
+int sqlite3ResolveExprListNames( |
+ NameContext *pNC, /* Namespace to resolve expressions in. */ |
+ ExprList *pList /* The expression list to be analyzed. */ |
+){ |
+ int i; |
+ if( pList ){ |
+ for(i=0; i<pList->nExpr; i++){ |
+ if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; |
+ } |
+ } |
+ return WRC_Continue; |
+} |
/* |
** Resolve all names in all expressions of a SELECT and in all |
@@ -1436,15 +1472,14 @@ void sqlite3ResolveSelectNames( |
void sqlite3ResolveSelfReference( |
Parse *pParse, /* Parsing context */ |
Table *pTab, /* The table being referenced */ |
- int type, /* NC_IsCheck or NC_PartIdx */ |
+ int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ |
Expr *pExpr, /* Expression to resolve. May be NULL. */ |
ExprList *pList /* Expression list to resolve. May be NUL. */ |
){ |
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ |
NameContext sNC; /* Name context for pParse->pNewTable */ |
- int i; /* Loop counter */ |
- assert( type==NC_IsCheck || type==NC_PartIdx ); |
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr ); |
memset(&sNC, 0, sizeof(sNC)); |
memset(&sSrc, 0, sizeof(sSrc)); |
sSrc.nSrc = 1; |
@@ -1455,11 +1490,5 @@ void sqlite3ResolveSelfReference( |
sNC.pSrcList = &sSrc; |
sNC.ncFlags = type; |
if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; |
- if( pList ){ |
- for(i=0; i<pList->nExpr; i++){ |
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ |
- return; |
- } |
- } |
- } |
+ if( pList ) sqlite3ResolveExprListNames(&sNC, pList); |
} |