Propagate the COLLATE operator upward through function calls.
Initial fix for ticket [ca0d20b6cdddec5e8].

FossilOrigin-Name: c053448a55f9d030e8ffe88cf4fc14ada7f6ec19
diff --git a/src/delete.c b/src/delete.c
index 011fb80..ef6aace 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -189,7 +189,7 @@
 
   pInClause->x.pSelect = pSelect;
   pInClause->flags |= EP_xIsSelect;
-  sqlite3ExprSetHeight(pParse, pInClause);
+  sqlite3ExprSetHeightAndFlags(pParse, pInClause);
   return pInClause;
 
   /* something went wrong. clean up anything allocated. */
diff --git a/src/expr.c b/src/expr.c
index 2def950..496c7a3 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -146,10 +146,20 @@
       break;
     }
     if( p->flags & EP_Collate ){
-      if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
+      if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
         p = p->pLeft;
       }else{
-        p = p->pRight;
+        Expr *pNext  = p->pRight;
+        if( p->x.pList!=0 && !ExprHasProperty(p, EP_xIsSelect) ){
+          int i;
+          for(i=0; i<p->x.pList->nExpr; i++){
+            if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
+              pNext = p->x.pList->a[i].pExpr;
+              break;
+            }
+          }
+        }
+        p = pNext;
       }
     }else{
       break;
@@ -355,6 +365,9 @@
 ** Expr.pSelect member has a height of 1. Any other expression
 ** has a height equal to the maximum height of any other 
 ** referenced Expr plus one.
+**
+** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
+** if appropriate.
 */
 static void exprSetHeight(Expr *p){
   int nHeight = 0;
@@ -362,8 +375,9 @@
   heightOfExpr(p->pRight, &nHeight);
   if( ExprHasProperty(p, EP_xIsSelect) ){
     heightOfSelect(p->x.pSelect, &nHeight);
-  }else{
+  }else if( p->x.pList ){
     heightOfExprList(p->x.pList, &nHeight);
+    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
   }
   p->nHeight = nHeight + 1;
 }
@@ -372,8 +386,11 @@
 ** Set the Expr.nHeight variable using the exprSetHeight() function. If
 ** the height is greater than the maximum allowed expression depth,
 ** leave an error in pParse.
+**
+** Also propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags. 
 */
-void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
+void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
   exprSetHeight(p);
   sqlite3ExprCheckHeight(pParse, p->nHeight);
 }
@@ -387,8 +404,17 @@
   heightOfSelect(p, &nHeight);
   return nHeight;
 }
-#else
-  #define exprSetHeight(y)
+#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
+/*
+** Propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags. 
+*/
+void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
+  if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
+    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
+  }
+}
+#define exprSetHeight(y)
 #endif /* SQLITE_MAX_EXPR_DEPTH>0 */
 
 /*
@@ -594,7 +620,7 @@
   }
   pNew->x.pList = pList;
   assert( !ExprHasProperty(pNew, EP_xIsSelect) );
-  sqlite3ExprSetHeight(pParse, pNew);
+  sqlite3ExprSetHeightAndFlags(pParse, pNew);
   return pNew;
 }
 
@@ -1210,16 +1236,18 @@
 }
 
 /*
-** Return TRUE if any expression in ExprList has any of the EP_*
-** properties given by "m"
+** Return the bitwise-OR of all Expr.flags fields in the given
+** ExprList.
 */
-int sqlite3AnyExprListHasProperty(const ExprList *pList, u32 m){
+u32 sqlite3ExprListFlags(const ExprList *pList){
   int i;
-  if( pList==0 ) return 0;
-  for(i=0; i<pList->nExpr; i++){
-    if( ExprHasProperty(pList->a[i].pExpr, m) ) return 1;
+  u32 m = 0;
+  if( pList ){
+    for(i=0; i<pList->nExpr; i++){
+       m |= pList->a[i].pExpr->flags;
+    }
   }
-  return 0;
+  return m;
 }
 
 /*
diff --git a/src/parse.y b/src/parse.y
index 6730312..78e79cd 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -1078,7 +1078,7 @@
       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);
       }
@@ -1092,7 +1092,7 @@
     if( A.pExpr ){
       A.pExpr->x.pSelect = X;
       ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeight(pParse, A.pExpr);
+      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
     }else{
       sqlite3SelectDelete(pParse->db, X);
     }
@@ -1104,7 +1104,7 @@
     if( A.pExpr ){
       A.pExpr->x.pSelect = Y;
       ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeight(pParse, A.pExpr);
+      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
     }else{
       sqlite3SelectDelete(pParse->db, Y);
     }
@@ -1118,7 +1118,7 @@
     if( A.pExpr ){
       A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
       ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeight(pParse, A.pExpr);
+      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
     }else{
       sqlite3SrcListDelete(pParse->db, pSrc);
     }
@@ -1131,7 +1131,7 @@
     if( p ){
       p->x.pSelect = Y;
       ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
-      sqlite3ExprSetHeight(pParse, p);
+      sqlite3ExprSetHeightAndFlags(pParse, p);
     }else{
       sqlite3SelectDelete(pParse->db, Y);
     }
@@ -1145,7 +1145,7 @@
   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);
diff --git a/src/select.c b/src/select.c
index 2c4c9e4..91b3d43 100644
--- a/src/select.c
+++ b/src/select.c
@@ -3338,8 +3338,8 @@
     if( isAgg ) return 0;                                /* Restriction (1)   */
     if( pSrc->nSrc>1 ) return 0;                         /* Restriction (2a)  */
     if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
-     || sqlite3AnyExprListHasProperty(p->pEList,EP_Subquery)
-     || sqlite3AnyExprListHasProperty(p->pOrderBy,EP_Subquery)
+     || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
+     || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
     ){
       return 0;                                          /* Restriction (2b)  */
     }
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e07ee4a..3f9a3a7 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3159,7 +3159,7 @@
 void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
 void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
 void sqlite3ExprListDelete(sqlite3*, ExprList*);
-int sqlite3AnyExprListHasProperty(const ExprList*,u32);
+u32 sqlite3ExprListFlags(const ExprList*);
 int sqlite3Init(sqlite3*, char**);
 int sqlite3InitCallback(void*, int, char**, char**);
 void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -3743,12 +3743,11 @@
 int sqlite3MemJournalSize(void);
 int sqlite3IsMemJournal(sqlite3_file *);
 
+void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
 #if SQLITE_MAX_EXPR_DEPTH>0
-  void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
   int sqlite3SelectExprHeight(Select *);
   int sqlite3ExprCheckHeight(Parse*, int);
 #else
-  #define sqlite3ExprSetHeight(x,y)
   #define sqlite3SelectExprHeight(x) 0
   #define sqlite3ExprCheckHeight(x,y)
 #endif