aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_collate.c24
-rw-r--r--src/test/regress/expected/collate.linux.utf8.out5
-rw-r--r--src/test/regress/expected/collate.out5
-rw-r--r--src/test/regress/sql/collate.linux.utf8.sql1
-rw-r--r--src/test/regress/sql/collate.sql1
5 files changed, 36 insertions, 0 deletions
diff --git a/src/backend/parser/parse_collate.c b/src/backend/parser/parse_collate.c
index 0b77e3ea2b7..8860679ccb9 100644
--- a/src/backend/parser/parse_collate.c
+++ b/src/backend/parser/parse_collate.c
@@ -533,6 +533,30 @@ assign_collations_walker(Node *node, assign_collations_context *context)
collation = loccontext.collation;
strength = loccontext.strength;
location = loccontext.location;
+
+ /*
+ * Throw error if the collation is indeterminate for a TargetEntry
+ * that is a sort/group target. We prefer to do this now, instead
+ * of leaving the comparison functions to fail at runtime, because
+ * we can give a syntax error pointer to help locate the problem.
+ * There are some cases where there might not be a failure, for
+ * example if the planner chooses to use hash aggregation instead
+ * of sorting for grouping; but it seems better to predictably
+ * throw an error. (Compare transformSetOperationTree, which will
+ * throw error for indeterminate collation of set-op columns,
+ * even though the planner might be able to implement the set-op
+ * without sorting.)
+ */
+ if (strength == COLLATE_CONFLICT &&
+ ((TargetEntry *) node)->ressortgroupref != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_COLLATION_MISMATCH),
+ errmsg("collation mismatch between implicit collations \"%s\" and \"%s\"",
+ get_collation_name(loccontext.collation),
+ get_collation_name(loccontext.collation2)),
+ errhint("You can choose the collation by applying the COLLATE clause to one or both expressions."),
+ parser_errposition(context->pstate,
+ loccontext.location2)));
break;
case T_RangeTblRef:
case T_JoinExpr:
diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out
index f967998be63..0ed0b36da79 100644
--- a/src/test/regress/expected/collate.linux.utf8.out
+++ b/src/test/regress/expected/collate.linux.utf8.out
@@ -637,6 +637,11 @@ select x || y from collate_test10; -- ok, because || is not collation aware
HIJHIJ
(2 rows)
+select x, y from collate_test10 order by x || y; -- not so ok
+ERROR: collation mismatch between implicit collations "en_US.utf8" and "tr_TR.utf8"
+LINE 1: select x, y from collate_test10 order by x || y;
+ ^
+HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
-- collation mismatch between recursive and non-recursive term
WITH RECURSIVE foo(x) AS
(SELECT x FROM (VALUES('a' COLLATE "en_US"),('b')) t(x)
diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out
index bd25955c5e4..4536cf21015 100644
--- a/src/test/regress/expected/collate.out
+++ b/src/test/regress/expected/collate.out
@@ -443,6 +443,11 @@ select x || y from collate_test10; -- ok, because || is not collation aware
HIJHIJ
(2 rows)
+select x, y from collate_test10 order by x || y; -- not so ok
+ERROR: collation mismatch between implicit collations "C" and "POSIX"
+LINE 1: select x, y from collate_test10 order by x || y;
+ ^
+HINT: You can choose the collation by applying the COLLATE clause to one or both expressions.
-- collation mismatch between recursive and non-recursive term
WITH RECURSIVE foo(x) AS
(SELECT x FROM (VALUES('a' COLLATE "C"),('b')) t(x)
diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql
index 62e66811b64..f5c5d802b29 100644
--- a/src/test/regress/sql/collate.linux.utf8.sql
+++ b/src/test/regress/sql/collate.linux.utf8.sql
@@ -193,6 +193,7 @@ CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM
-- ideally this would be a parse-time error, but for now it must be run-time:
select x < y from collate_test10; -- fail
select x || y from collate_test10; -- ok, because || is not collation aware
+select x, y from collate_test10 order by x || y; -- not so ok
-- collation mismatch between recursive and non-recursive term
WITH RECURSIVE foo(x) AS
diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql
index a3926a9e79e..c7e26d8577b 100644
--- a/src/test/regress/sql/collate.sql
+++ b/src/test/regress/sql/collate.sql
@@ -145,6 +145,7 @@ CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM
-- ideally this would be a parse-time error, but for now it must be run-time:
select x < y from collate_test10; -- fail
select x || y from collate_test10; -- ok, because || is not collation aware
+select x, y from collate_test10 order by x || y; -- not so ok
-- collation mismatch between recursive and non-recursive term
WITH RECURSIVE foo(x) AS