Re: Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10)); - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10));
Date
Msg-id 2936041.1618246783@sss.pgh.pa.us
Whole thread Raw
In response to Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10));  (Yulin PEI <ypeiae@connect.ust.hk>)
Responses 回复: Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10));  (Yulin PEI <ypeiae@connect.ust.hk>)
回复: Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10));  (Yulin PEI <ypeiae@connect.ust.hk>)
回复: Core dump happens when execute sql CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE "C")::INT FROM generate_series(1, 10));  (Yulin PEI <ypeiae@connect.ust.hk>)
List pgsql-hackers
Yulin PEI <ypeiae@connect.ust.hk> writes:
>     I found it could cause a crash when executing sql statement: `CREATE VIEW v1(c1) AS (SELECT ('4' COLLATE
"C")::INTFROM generate_series(1, 10)); ` in postgres 13.2 release. 

Nice catch.  I don't think the code in DefineVirtualRelation is wrong:
exprCollation shouldn't report any collation for an expression of a
non-collatable type.  Rather the problem is with an old kluge in
coerce_type(), which will push a type coercion underneath a CollateExpr
... without any mind for the possibility that the coercion result isn't
collatable.  So the right fix is more or less the attached.

            regards, tom lane

diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index d5310f27db..228ee8e7d6 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;
@@ -384,7 +385,7 @@ coerce_type(ParseState *pstate, Node *node,
         if (result)
             return result;
     }
-    if (IsA(node, CollateExpr))
+    if (IsA(node, CollateExpr) && type_is_collatable(targetTypeId))
     {
         /*
          * If we have a COLLATE clause, we have to push the coercion

pgsql-hackers by date:

Previous
From: Ranier Vilela
Date:
Subject: Re: Uninitialized scalar variable (UNINIT) (src/backend/statistics/extended_stats.c)
Next
From: Tomas Vondra
Date:
Subject: Re: Uninitialized scalar variable (UNINIT) (src/backend/statistics/extended_stats.c)