-C Disable\sthe\squery\sflattener\sfor\saggregate\ssubqueries\sif\sthe\sparent\squery\nuses\sother\ssubqueries\sin\sits\sresult\sset\sor\sWHERE\sclause\sor\sORDER\sBY\sclause.\nPreliminary\sfix\sfor\sticket\s[2f7170d73bf9abf8].\s\sHowever\sit\sstill\scontains\na\sdefect\ssimilar\sto\sthe\sCOLLATE\sproblem\sof\s[ca0d20b6cddd].
-D 2015-02-09T15:21:36.228
+C Propagate\sthe\sCOLLATE\soperator\supward\sthrough\sfunction\scalls.\nInitial\sfix\sfor\sticket\s[ca0d20b6cdddec5e8].
+D 2015-02-09T16:09:34.923
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 6b9e7677829aa94b9f30949656e27312aefb9a46
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/complete.c 198a0066ba60ab06fc00fba1998d870a4d575463
F src/ctime.c 98f89724adc891a1a4c655bee04e33e716e05887
F src/date.c e4d50b3283696836ec1036b695ead9a19e37a5ac
-F src/delete.c bd1a91ddd247ce13004075251e0b7fe2bf9925ef
-F src/expr.c 3fbe5a2a0be67b337b4947adde81694b4d48a84d
+F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e
+F src/expr.c f40082f5d31a76ea53302e202899a4959555b009
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c e0444b61bed271a76840cbe6182df93a9baa3f12
F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77
-F src/parse.y d6507371513e94c03e61f7ec097d7b7e90a66665
+F src/parse.y 0f8e7d60f0ab3cb53d270adef69259ac307d83a8
F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
-F src/select.c 15490b9da27a688a9fa09f943ebf4e6c749dc33b
+F src/select.c e46cef4c224549b439384c88fc7f57ba064dad54
F src/shell.c 82c25508dac802b32198af6f5256ca1597c6a1af
F src/sqlite.h.in 54678c21401909f72b221344dd560d285a1ba5eb
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
-F src/sqliteInt.h b7b14a15f2c60e15f99145e9f5a90f5280e98582
+F src/sqliteInt.h 57a405ae6d2ed10fff52de376d18f21e04d96609
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6
F test/collate6.test 8be65a182abaac8011a622131486dafb8076e907
F test/collate7.test 8ec29d98f3ee4ccebce6e16ce3863fb6b8c7b868
-F test/collate8.test df26649cfcbddf109c04122b340301616d3a88f6
+F test/collate8.test cd9b3d3f999b8520ffaa7cc1647061fc5bab1334
F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 4ef7ceced2b0000d21f7f8014384c04a0e4661d3
-R b512281a09e1b31cff93e7ca5bacbcdc
-T *branch * tkt-2f7170d7
-T *sym-tkt-2f7170d7 *
-T -sym-trunk *
+P 0b7d65e3fda676d193347cb782854c28a48252af
+R 0fcf0b67c1cdaee9bbc7c2fe09760751
U drh
-Z f683ca0757ba5ade9ef6c768a943d35e
+Z d2e1dd3a2a5ed2929029c668f1fd20a5
-0b7d65e3fda676d193347cb782854c28a48252af
\ No newline at end of file
+c053448a55f9d030e8ffe88cf4fc14ada7f6ec19
\ No newline at end of file
pInClause->x.pSelect = pSelect;
pInClause->flags |= EP_xIsSelect;
- sqlite3ExprSetHeight(pParse, pInClause);
+ sqlite3ExprSetHeightAndFlags(pParse, pInClause);
return pInClause;
/* something went wrong. clean up anything allocated. */
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;
** 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;
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;
}
** 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);
}
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 */
/*
}
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- sqlite3ExprSetHeight(pParse, pNew);
+ sqlite3ExprSetHeightAndFlags(pParse, pNew);
return pNew;
}
}
/*
-** 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;
}
/*
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( 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);
}
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);
}
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);
}
if( p ){
p->x.pSelect = Y;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
- sqlite3ExprSetHeight(pParse, p);
+ sqlite3ExprSetHeightAndFlags(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, Y);
}
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);
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) */
}
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);
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
# focus of this script is making sure collations pass through the
# unary + operator.
#
-# $Id: collate8.test,v 1.2 2008/08/25 12:14:09 drh Exp $
+# 2015-02-09: Added tests to make sure COLLATE passes through function
+# calls. Ticket [ca0d20b6cdddec5e81b8d66f89c46a5583b5f6f6].
+#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {abc}
+# Make sure the COLLATE operator perculates up through function calls
+# and other Expr structures that use the Expr.x.pList field.
+#
+do_execsql_test collate8-3.1 {
+ SELECT 'abc'==('ABC'||'') COLLATE nocase;
+ SELECT 'abc'==('ABC'||'' COLLATE nocase);
+ SELECT 'abc'==('ABC'||('' COLLATE nocase));
+ SELECT 'abc'==('ABC'||upper('' COLLATE nocase));
+} {1 1 1 1}
+do_execsql_test collate8-3.2 {
+ SELECT 'abc'==('ABC'||max('' COLLATE nocase,'' COLLATE binary));
+} {1}
+
+# The COLLATE binary is on the left and so takes precedence
+do_execsql_test collate8-3.3 {
+ SELECT 'abc'==('ABC'||max('' COLLATE binary,'' COLLATE nocase));
+} {0}
+
+do_execsql_test collate8-3.4 {
+ SELECT 'abc'==('ABC'||CASE WHEN 1-1=2 THEN '' COLLATE nocase
+ ELSE '' COLLATE binary END);
+ SELECT 'abc'==('ABC'||CASE WHEN 1+1=2 THEN '' COLLATE nocase
+ ELSE '' COLLATE binary END);
+} {1 1}
+do_execsql_test collate8-3.5 {
+ SELECT 'abc'==('ABC'||CASE WHEN 1=2 THEN '' COLLATE binary
+ ELSE '' COLLATE nocase END);
+} {0}
+
+
finish_test