OSDN Git Service

A better fix for the "ARRAY[...]::domain" problem. The previous patch worked,
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 13 Nov 2009 19:48:20 +0000 (19:48 +0000)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 13 Nov 2009 19:48:20 +0000 (19:48 +0000)
but the transformed ArrayExpr claimed to have a return type of "domain",
even though the domain constraint was only checked by the enclosing
CoerceToDomain node. With this fix, the ArrayExpr is correctly labeled with
the base type of the domain. Per gripe by Tom Lane.

src/backend/parser/parse_expr.c

index 8e0172d..8513102 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.249 2009/11/13 16:09:10 heikki Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.250 2009/11/13 19:48:20 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -164,32 +164,23 @@ transformExpr(ParseState *pstate, Node *expr)
                                        elementType = get_element_type(targetType);
                                        if (OidIsValid(elementType))
                                        {
-                                               result = transformArrayExpr(pstate,
-                                                                                                       (A_ArrayExpr *) tc->arg,
-                                                                                                       targetType,
-                                                                                                       elementType,
-                                                                                                       targetTypmod);
-
                                                /*
-                                                * If the target array type is a domain, we still need
-                                                * to check the domain constraint. (coerce_to_domain
-                                                * is a no-op if targetType is not a domain)
+                                                * tranformArrayExpr doesn't know how to check domain
+                                                * constraints, so ask it to return the base type
+                                                * instead. transformTypeCast below will cast it to
+                                                * the domain. In the usual case that the target is
+                                                * not a domain, transformTypeCast is a no-op.
                                                 */
-                                               result = coerce_to_domain(result,
-                                                                                                 InvalidOid,
-                                                                                                 -1,
-                                                                                                 targetType,
-                                                                                                 COERCE_IMPLICIT_CAST,
-                                                                                                 tc->location,
-                                                                                                 false,
-                                                                                                 true);
-                                               break;
+                                               targetType = getBaseTypeAndTypmod(targetType,
+                                                                                                                &targetTypmod);
+                                                       
+                                               tc = copyObject(tc);
+                                               tc->arg = transformArrayExpr(pstate,
+                                                                                                        (A_ArrayExpr *) tc->arg,
+                                                                                                        targetType,
+                                                                                                        elementType,
+                                                                                                        targetTypmod);
                                        }
-
-                                       /*
-                                        * Corner case: ARRAY[] cast to a non-array type. Fall
-                                        * through to do it the standard way.
-                                        */
                                }
 
                                result = transformTypeCast(pstate, tc);
@@ -324,6 +315,7 @@ transformExpr(ParseState *pstate, Node *expr)
                case T_ArrayCoerceExpr:
                case T_ConvertRowtypeExpr:
                case T_CaseTestExpr:
+               case T_ArrayExpr:
                case T_CoerceToDomain:
                case T_CoerceToDomainValue:
                case T_SetToDefault: