* *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))
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;
{
/*
* 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);
"C"
(1 row)
+-- old bug with not dropping COLLATE when coercing to non-collatable type
+CREATE VIEW collate_on_int AS
+SELECT c1+1 AS c1p FROM
+ (SELECT ('4' COLLATE "C")::INT AS c1) ss;
+\d+ collate_on_int
+ View "collate_tests.collate_on_int"
+ Column | Type | Collation | Nullable | Default | Storage | Description
+--------+---------+-----------+----------+---------+---------+-------------
+ c1p | integer | | | | plain |
+View definition:
+ SELECT ss.c1 + 1 AS c1p
+ FROM ( SELECT 4 AS c1) ss;
+
--
-- Clean up. Many of these table names will be re-used if the user is
-- trying to run any platform-specific collation tests later, so we
--
\set VERBOSITY terse
DROP SCHEMA collate_tests CASCADE;
-NOTICE: drop cascades to 17 other objects
+NOTICE: drop cascades to 18 other objects