aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_collate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_collate.c')
-rw-r--r--src/backend/parser/parse_collate.c24
1 files changed, 24 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: