aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_coerce.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_coerce.c')
-rw-r--r--src/backend/parser/parse_coerce.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index d5310f27db1..aa4a21126d3 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -95,6 +95,7 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
* *must* know that to avoid possibly calling hide_coercion_node on
* something that wasn't generated by coerce_type. Note that if there are
* multiple stacked CollateExprs, we just discard all but the topmost.
+ * Also, if the target type isn't collatable, we discard the CollateExpr.
*/
origexpr = expr;
while (expr && IsA(expr, CollateExpr))
@@ -114,7 +115,7 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype,
ccontext, cformat, location,
(result != expr && !IsA(result, Const)));
- if (expr != origexpr)
+ if (expr != origexpr && type_is_collatable(targettype))
{
/* Reinstall top CollateExpr */
CollateExpr *coll = (CollateExpr *) origexpr;
@@ -388,20 +389,26 @@ coerce_type(ParseState *pstate, Node *node,
{
/*
* If we have a COLLATE clause, we have to push the coercion
- * underneath the COLLATE. This is really ugly, but there is little
- * choice because the above hacks on Consts and Params wouldn't happen
+ * underneath the COLLATE; or discard the COLLATE if the target type
+ * isn't collatable. This is really ugly, but there is little choice
+ * because the above hacks on Consts and Params wouldn't happen
* otherwise. This kluge has consequences in coerce_to_target_type.
*/
CollateExpr *coll = (CollateExpr *) node;
- CollateExpr *newcoll = makeNode(CollateExpr);
- newcoll->arg = (Expr *)
- coerce_type(pstate, (Node *) coll->arg,
- inputTypeId, targetTypeId, targetTypeMod,
- ccontext, cformat, location);
- newcoll->collOid = coll->collOid;
- newcoll->location = coll->location;
- return (Node *) newcoll;
+ result = coerce_type(pstate, (Node *) coll->arg,
+ inputTypeId, targetTypeId, targetTypeMod,
+ ccontext, cformat, location);
+ if (type_is_collatable(targetTypeId))
+ {
+ CollateExpr *newcoll = makeNode(CollateExpr);
+
+ newcoll->arg = (Expr *) result;
+ newcoll->collOid = coll->collOid;
+ newcoll->location = coll->location;
+ result = (Node *) newcoll;
+ }
+ return result;
}
pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext,
&funcId);