aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-08-21 12:00:03 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-08-21 12:00:03 -0400
commit86488cdf1249f86cff75c2446f670be49cb55055 (patch)
tree3aa9777c968b64232835571f6f86943d55e5b504 /src
parentc01743aa4866e13da2c54e44010abc6d5f986363 (diff)
downloadpostgresql-86488cdf1249f86cff75c2446f670be49cb55055.tar.gz
postgresql-86488cdf1249f86cff75c2446f670be49cb55055.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/functioncmds.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 6593fd7d811..d43b89d3efa 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1689,13 +1689,18 @@ CreateCast(CreateCastStmt *stmt)
errmsg("source and target data types are not physically compatible")));
/*
- * We know that composite, enum and array types are never binary-
- * compatible with each other. They all have OIDs embedded in them.
+ * We know that composite, array, range and enum types are never
+ * binary-compatible with each other. They all have OIDs embedded in
+ * them.
*
* Theoretically you could build a user-defined base type that is
- * binary-compatible with a composite, enum, or array type. But we
- * disallow that too, as in practice such a cast is surely a mistake.
- * You can always work around that by writing a cast function.
+ * binary-compatible with such a type. But we disallow it anyway, as
+ * in practice such a cast is surely a mistake. You can always work
+ * around that by writing a cast function.
+ *
+ * NOTE: if we ever have a kind of container type that doesn't need to
+ * be rejected for this reason, we'd likely need to recursively apply
+ * all of these same checks to the contained type(s).
*/
if (sourcetyptype == TYPTYPE_COMPOSITE ||
targettyptype == TYPTYPE_COMPOSITE)
@@ -1703,18 +1708,26 @@ CreateCast(CreateCastStmt *stmt)
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("composite data types are not binary-compatible")));
- if (sourcetyptype == TYPTYPE_ENUM ||
- targettyptype == TYPTYPE_ENUM)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
- errmsg("enum data types are not binary-compatible")));
-
if (OidIsValid(get_element_type(sourcetypeid)) ||
OidIsValid(get_element_type(targettypeid)))
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("array data types are not binary-compatible")));
+ if (sourcetyptype == TYPTYPE_RANGE ||
+ targettyptype == TYPTYPE_RANGE ||
+ sourcetyptype == TYPTYPE_MULTIRANGE ||
+ targettyptype == TYPTYPE_MULTIRANGE)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("range data types are not binary-compatible")));
+
+ if (sourcetyptype == TYPTYPE_ENUM ||
+ targettyptype == TYPTYPE_ENUM)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("enum data types are not binary-compatible")));
+
/*
* We also disallow creating binary-compatibility casts involving
* domains. Casting from a domain to its base type is already