Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 86488cd

Browse files
committed
Disallow creating binary-coercible casts involving range types.
For a long time we have forbidden binary-coercible casts to or from composite and array types, because such a cast cannot work correctly: the type OID embedded in the value would need to change, but it won't in a binary coercion. That reasoning applies equally to range types, but we overlooked installing a similar restriction here when we invented range types. Do so now. Given the lack of field complaints, we won't change this in stable branches, but it seems not too late for v17. Per discussion of a problem noted by Peter Eisentraut. Discussion: https://postgr.es/m/076968e1-0852-40a9-bc0b-117cd3f0e43c@eisentraut.org
1 parent c01743a commit 86488cd

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

src/backend/commands/functioncmds.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,32 +1689,45 @@ CreateCast(CreateCastStmt *stmt)
16891689
errmsg("source and target data types are not physically compatible")));
16901690

16911691
/*
1692-
* We know that composite, enum and array types are never binary-
1693-
* compatible with each other. They all have OIDs embedded in them.
1692+
* We know that composite, array, range and enum types are never
1693+
* binary-compatible with each other. They all have OIDs embedded in
1694+
* them.
16941695
*
16951696
* Theoretically you could build a user-defined base type that is
1696-
* binary-compatible with a composite, enum, or array type. But we
1697-
* disallow that too, as in practice such a cast is surely a mistake.
1698-
* You can always work around that by writing a cast function.
1697+
* binary-compatible with such a type. But we disallow it anyway, as
1698+
* in practice such a cast is surely a mistake. You can always work
1699+
* around that by writing a cast function.
1700+
*
1701+
* NOTE: if we ever have a kind of container type that doesn't need to
1702+
* be rejected for this reason, we'd likely need to recursively apply
1703+
* all of these same checks to the contained type(s).
16991704
*/
17001705
if (sourcetyptype == TYPTYPE_COMPOSITE ||
17011706
targettyptype == TYPTYPE_COMPOSITE)
17021707
ereport(ERROR,
17031708
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
17041709
errmsg("composite data types are not binary-compatible")));
17051710

1706-
if (sourcetyptype == TYPTYPE_ENUM ||
1707-
targettyptype == TYPTYPE_ENUM)
1708-
ereport(ERROR,
1709-
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1710-
errmsg("enum data types are not binary-compatible")));
1711-
17121711
if (OidIsValid(get_element_type(sourcetypeid)) ||
17131712
OidIsValid(get_element_type(targettypeid)))
17141713
ereport(ERROR,
17151714
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
17161715
errmsg("array data types are not binary-compatible")));
17171716

1717+
if (sourcetyptype == TYPTYPE_RANGE ||
1718+
targettyptype == TYPTYPE_RANGE ||
1719+
sourcetyptype == TYPTYPE_MULTIRANGE ||
1720+
targettyptype == TYPTYPE_MULTIRANGE)
1721+
ereport(ERROR,
1722+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1723+
errmsg("range data types are not binary-compatible")));
1724+
1725+
if (sourcetyptype == TYPTYPE_ENUM ||
1726+
targettyptype == TYPTYPE_ENUM)
1727+
ereport(ERROR,
1728+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1729+
errmsg("enum data types are not binary-compatible")));
1730+
17181731
/*
17191732
* We also disallow creating binary-compatibility casts involving
17201733
* domains. Casting from a domain to its base type is already

0 commit comments

Comments
 (0)