diff options
Diffstat (limited to 'src/backend/parser/parse_coerce.c')
-rw-r--r-- | src/backend/parser/parse_coerce.c | 29 |
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); |