summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2013-04-26 19:48:24 +0000
committerTom Lane2013-04-26 19:48:53 +0000
commit41a2760f611d1b3c1e67f755baf0a052b5cec9af (patch)
tree49d241ef6bf8200782c22780ecb7fdeabca6b3c3 /src/test
parentb42ea7981ce1e7484951a22662937541066d8647 (diff)
Fix collation assignment for aggregates with ORDER BY.
ORDER BY expressions were being treated the same as regular aggregate arguments for purposes of collation determination, but really they should not affect the aggregate's collation at all; only collations of the aggregate's regular arguments should affect it. In many cases this mistake would lead to incorrectly throwing a "collation conflict" error; but in some cases the corrected code will silently assign a different collation to the aggregate than before, for example agg(foo ORDER BY bar COLLATE "x") which will now use foo's collation rather than "x" for the aggregate. Given this risk and the lack of field complaints about the issue, it doesn't seem prudent to back-patch. In passing, rearrange code in assign_collations_walker so that we don't need multiple copies of the standard logic for computing collation of a node with children. (Previously, CaseExpr duplicated the standard logic, and we would have needed a third copy for Aggref without this change.) Andrew Gierth and David Fetter
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/collate.out22
-rw-r--r--src/test/regress/sql/collate.sql6
2 files changed, 28 insertions, 0 deletions
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index 4ab9566cd10..91d574dbe4c 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -362,6 +362,28 @@ SELECT array_agg(b ORDER BY b) FROM collate_test2;
{ABD,Abc,abc,bbc}
(1 row)
+-- In aggregates, ORDER BY expressions don't affect aggregate's collation
+SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; -- fail
+ERROR: collation mismatch between explicit collations "C" and "POSIX"
+LINE 1: SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM col...
+ ^
+SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10;
+ array_agg
+-----------
+ {HIJ,hij}
+(1 row)
+
+SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10;
+ array_agg
+-----------
+ {2,1}
+(1 row)
+
+SELECT array_agg(a ORDER BY x||y) FROM collate_test10; -- fail
+ERROR: collation mismatch between implicit collations "C" and "POSIX"
+LINE 1: SELECT array_agg(a ORDER BY x||y) FROM collate_test10;
+ ^
+HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
a | b
---+-----
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index 3c960e7ed93..63ab590f3a4 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -128,6 +128,12 @@ SELECT min(b), max(b) FROM collate_test2;
SELECT array_agg(b ORDER BY b) FROM collate_test1;
SELECT array_agg(b ORDER BY b) FROM collate_test2;
+-- In aggregates, ORDER BY expressions don't affect aggregate's collation
+SELECT string_agg(x COLLATE "C", y COLLATE "POSIX") FROM collate_test10; -- fail
+SELECT array_agg(x COLLATE "C" ORDER BY y COLLATE "POSIX") FROM collate_test10;
+SELECT array_agg(a ORDER BY x COLLATE "C", y COLLATE "POSIX") FROM collate_test10;
+SELECT array_agg(a ORDER BY x||y) FROM collate_test10; -- fail
+
SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2;
SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2;
SELECT a, b FROM collate_test2 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test2 WHERE a > 1 ORDER BY 2;