*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.198 2010/02/26 02:00:50 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.198.4.1 2010/07/18 19:37:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "commands/defrem.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
+#include "optimizer/clauses.h"
#include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/analyze.h"
foreach(tl, *tlist)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
+ Node *texpr;
- if (equal(expr, tle->expr))
+ /*
+ * Ignore any implicit cast on the existing tlist expression.
+ *
+ * This essentially allows the ORDER/GROUP/etc item to adopt the same
+ * datatype previously selected for a textually-equivalent tlist item.
+ * There can't be any implicit cast at top level in an ordinary SELECT
+ * tlist at this stage, but the case does arise with ORDER BY in an
+ * aggregate function.
+ */
+ texpr = strip_implicit_coercions((Node *) tle->expr);
+
+ if (equal(expr, texpr))
return tle;
}
(1 row)
+-- check some implicit casting cases, as per bug #5564
+select string_agg(distinct f1 order by f1) from varchar_tbl; -- ok
+ string_agg
+------------
+ aababcd
+(1 row)
+
+select string_agg(distinct f1::text order by f1) from varchar_tbl; -- not ok
+ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
+LINE 1: select string_agg(distinct f1::text order by f1) from varcha...
+ ^
+select string_agg(distinct f1 order by f1::text) from varchar_tbl; -- not ok
+ERROR: in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list
+LINE 1: select string_agg(distinct f1 order by f1::text) from varcha...
+ ^
+select string_agg(distinct f1::text order by f1::text) from varchar_tbl; -- ok
+ string_agg
+------------
+ aababcd
+(1 row)
+
select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a);
select string_agg(a,',') from (values(null),(null),('bbbb'),('cccc')) g(a);
select string_agg(a,',') from (values(null),(null)) g(a);
+
+-- check some implicit casting cases, as per bug #5564
+select string_agg(distinct f1 order by f1) from varchar_tbl; -- ok
+select string_agg(distinct f1::text order by f1) from varchar_tbl; -- not ok
+select string_agg(distinct f1 order by f1::text) from varchar_tbl; -- not ok
+select string_agg(distinct f1::text order by f1::text) from varchar_tbl; -- ok