1010 *
1111 *
1212 * IDENTIFICATION
13- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.108 2009/02/24 01:38:09 tgl Exp $
13+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.109 2009/03/04 11:53:53 heikki Exp $
1414 *
1515 * DESCRIPTION
1616 * These routines take the parse tree and pick out the
@@ -1470,6 +1470,8 @@ CreateCast(CreateCastStmt *stmt)
14701470{
14711471Oid sourcetypeid ;
14721472Oid targettypeid ;
1473+ char sourcetyptype ;
1474+ char targettyptype ;
14731475Oid funcid ;
14741476int nargs ;
14751477char castcontext ;
@@ -1483,15 +1485,17 @@ CreateCast(CreateCastStmt *stmt)
14831485
14841486sourcetypeid = typenameTypeId (NULL ,stmt -> sourcetype ,NULL );
14851487targettypeid = typenameTypeId (NULL ,stmt -> targettype ,NULL );
1488+ sourcetyptype = get_typtype (sourcetypeid );
1489+ targettyptype = get_typtype (targettypeid );
14861490
14871491/* No pseudo-types allowed */
1488- if (get_typtype ( sourcetypeid ) == TYPTYPE_PSEUDO )
1492+ if (sourcetyptype == TYPTYPE_PSEUDO )
14891493ereport (ERROR ,
14901494(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
14911495errmsg ("source data type %s is a pseudo-type" ,
14921496TypeNameToString (stmt -> sourcetype ))));
14931497
1494- if (get_typtype ( targettypeid ) == TYPTYPE_PSEUDO )
1498+ if (targettyptype == TYPTYPE_PSEUDO )
14951499ereport (ERROR ,
14961500(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
14971501errmsg ("target data type %s is a pseudo-type" ,
@@ -1615,6 +1619,33 @@ CreateCast(CreateCastStmt *stmt)
16151619ereport (ERROR ,
16161620(errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
16171621errmsg ("source and target data types are not physically compatible" )));
1622+
1623+ /*
1624+ * We know that composite, enum and array types are never binary-
1625+ * compatible with each other. They all have OIDs embedded in them.
1626+ *
1627+ * Theoretically you could build a user-defined base type that is
1628+ * binary-compatible with a composite, enum, or array type. But we
1629+ * disallow that too, as in practice such a cast is surely a mistake.
1630+ * You can always work around that by writing a cast function.
1631+ */
1632+ if (sourcetyptype == TYPTYPE_COMPOSITE ||
1633+ targettyptype == TYPTYPE_COMPOSITE )
1634+ ereport (ERROR ,
1635+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
1636+ errmsg ("composite data types are not binary-compatible" )));
1637+
1638+ if (sourcetyptype == TYPTYPE_ENUM ||
1639+ targettyptype == TYPTYPE_ENUM )
1640+ ereport (ERROR ,
1641+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
1642+ errmsg ("enum data types are not binary-compatible" )));
1643+
1644+ if (OidIsValid (get_element_type (sourcetypeid ))||
1645+ OidIsValid (get_element_type (targettypeid )))
1646+ ereport (ERROR ,
1647+ (errcode (ERRCODE_INVALID_OBJECT_DEFINITION ),
1648+ errmsg ("array data types are not binary-compatible" )));
16181649}
16191650
16201651/*