Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45a10b2

Browse files
committed
Add some sanity checks to CREATE CAST ... WITHOUT FUNCTION. Disallow
composite, enum and array types, as those are surely not binary-compatible with anything else because of the embedded OIDs. Inspired by bug report by Oleg Serov.
1 parent 12f87b2 commit 45a10b2

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

src/backend/commands/functioncmds.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
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
{
14711471
Oid sourcetypeid;
14721472
Oid targettypeid;
1473+
char sourcetyptype;
1474+
char targettyptype;
14731475
Oid funcid;
14741476
int nargs;
14751477
char castcontext;
@@ -1483,15 +1485,17 @@ CreateCast(CreateCastStmt *stmt)
14831485

14841486
sourcetypeid = typenameTypeId(NULL, stmt->sourcetype, NULL);
14851487
targettypeid = 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)
14891493
ereport(ERROR,
14901494
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
14911495
errmsg("source data type %s is a pseudo-type",
14921496
TypeNameToString(stmt->sourcetype))));
14931497

1494-
if (get_typtype(targettypeid) == TYPTYPE_PSEUDO)
1498+
if (targettyptype == TYPTYPE_PSEUDO)
14951499
ereport(ERROR,
14961500
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
14971501
errmsg("target data type %s is a pseudo-type",
@@ -1615,6 +1619,33 @@ CreateCast(CreateCastStmt *stmt)
16151619
ereport(ERROR,
16161620
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
16171621
errmsg("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
/*

0 commit comments

Comments
 (0)