Skip to content

Commit 40b3e2c

Browse files
committed
Split out CreateCast into src/backend/catalog/pg_cast.c
This catalog-handling code was previously together with the rest of CastCreate() in src/backend/commands/functioncmds.c. A future patch will need a way to add casts internally, so this will be useful to have separate. Also, move the nearby get_cast_oid() function from functioncmds.c to lsyscache.c, which seems a more natural place for it. Author: Paul Jungwirth, minor edits by Álvaro Discussion: https://postgr.es/m/20200309210003.GA19992@alvherre.pgsql
1 parent 0a42a2e commit 40b3e2c

File tree

8 files changed

+164
-98
lines changed

8 files changed

+164
-98
lines changed

src/backend/catalog/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ OBJS = \
2525
objectaddress.o \
2626
partition.o \
2727
pg_aggregate.o \
28+
pg_cast.o \
2829
pg_collation.o \
2930
pg_constraint.o \
3031
pg_conversion.o \

src/backend/catalog/pg_cast.c

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* pg_cast.c
4+
* routines to support manipulation of the pg_cast relation
5+
*
6+
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
*
10+
* IDENTIFICATION
11+
* src/backend/catalog/pg_cast.c
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
15+
#include "postgres.h"
16+
17+
#include "access/htup_details.h"
18+
#include "access/table.h"
19+
#include "catalog/catalog.h"
20+
#include "catalog/dependency.h"
21+
#include "catalog/indexing.h"
22+
#include "catalog/objectaccess.h"
23+
#include "catalog/pg_cast.h"
24+
#include "catalog/pg_proc.h"
25+
#include "catalog/pg_type.h"
26+
#include "utils/builtins.h"
27+
#include "utils/rel.h"
28+
#include "utils/syscache.h"
29+
30+
/*
31+
* ----------------------------------------------------------------
32+
* CastCreate
33+
*
34+
* Forms and inserts catalog tuples for a new cast being created.
35+
* Caller must have already checked privileges, and done consistency
36+
* checks on the given datatypes and cast function (if applicable).
37+
*
38+
* 'behavior' indicates the types of the dependencies that the new
39+
* cast will have on its input and output types and the cast function.
40+
* ----------------------------------------------------------------
41+
*/
42+
ObjectAddress
43+
CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext,
44+
char castmethod, DependencyType behavior)
45+
{
46+
Relation relation;
47+
HeapTuple tuple;
48+
Oid castid;
49+
Datum values[Natts_pg_cast];
50+
bool nulls[Natts_pg_cast];
51+
ObjectAddress myself,
52+
referenced;
53+
54+
relation = table_open(CastRelationId, RowExclusiveLock);
55+
56+
/*
57+
* Check for duplicate. This is just to give a friendly error message,
58+
* the unique index would catch it anyway (so no need to sweat about race
59+
* conditions).
60+
*/
61+
tuple = SearchSysCache2(CASTSOURCETARGET,
62+
ObjectIdGetDatum(sourcetypeid),
63+
ObjectIdGetDatum(targettypeid));
64+
if (HeapTupleIsValid(tuple))
65+
ereport(ERROR,
66+
(errcode(ERRCODE_DUPLICATE_OBJECT),
67+
errmsg("cast from type %s to type %s already exists",
68+
format_type_be(sourcetypeid),
69+
format_type_be(targettypeid))));
70+
71+
/* ready to go */
72+
castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
73+
values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
74+
values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
75+
values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
76+
values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
77+
values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
78+
values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
79+
80+
MemSet(nulls, false, sizeof(nulls));
81+
82+
tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
83+
84+
CatalogTupleInsert(relation, tuple);
85+
86+
/* make dependency entries */
87+
myself.classId = CastRelationId;
88+
myself.objectId = castid;
89+
myself.objectSubId = 0;
90+
91+
/* dependency on source type */
92+
referenced.classId = TypeRelationId;
93+
referenced.objectId = sourcetypeid;
94+
referenced.objectSubId = 0;
95+
recordDependencyOn(&myself, &referenced, behavior);
96+
97+
/* dependency on target type */
98+
referenced.classId = TypeRelationId;
99+
referenced.objectId = targettypeid;
100+
referenced.objectSubId = 0;
101+
recordDependencyOn(&myself, &referenced, behavior);
102+
103+
/* dependency on function */
104+
if (OidIsValid(funcid))
105+
{
106+
referenced.classId = ProcedureRelationId;
107+
referenced.objectId = funcid;
108+
referenced.objectSubId = 0;
109+
recordDependencyOn(&myself, &referenced, behavior);
110+
}
111+
112+
/* dependency on extension */
113+
recordDependencyOnCurrentExtension(&myself, false);
114+
115+
/* Post creation hook for new cast */
116+
InvokeObjectPostCreateHook(CastRelationId, castid, 0);
117+
118+
heap_freetuple(tuple);
119+
120+
table_close(relation, RowExclusiveLock);
121+
122+
return myself;
123+
}

src/backend/commands/functioncmds.c

+3-97
Original file line numberDiff line numberDiff line change
@@ -1411,17 +1411,12 @@ CreateCast(CreateCastStmt *stmt)
14111411
char sourcetyptype;
14121412
char targettyptype;
14131413
Oid funcid;
1414-
Oid castid;
14151414
int nargs;
14161415
char castcontext;
14171416
char castmethod;
1418-
Relation relation;
14191417
HeapTuple tuple;
1420-
Datum values[Natts_pg_cast];
1421-
bool nulls[Natts_pg_cast];
1422-
ObjectAddress myself,
1423-
referenced;
14241418
AclResult aclresult;
1419+
ObjectAddress myself;
14251420

14261421
sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
14271422
targettypeid = typenameTypeId(NULL, stmt->targettype);
@@ -1645,100 +1640,11 @@ CreateCast(CreateCastStmt *stmt)
16451640
break;
16461641
}
16471642

1648-
relation = table_open(CastRelationId, RowExclusiveLock);
1649-
1650-
/*
1651-
* Check for duplicate. This is just to give a friendly error message,
1652-
* the unique index would catch it anyway (so no need to sweat about race
1653-
* conditions).
1654-
*/
1655-
tuple = SearchSysCache2(CASTSOURCETARGET,
1656-
ObjectIdGetDatum(sourcetypeid),
1657-
ObjectIdGetDatum(targettypeid));
1658-
if (HeapTupleIsValid(tuple))
1659-
ereport(ERROR,
1660-
(errcode(ERRCODE_DUPLICATE_OBJECT),
1661-
errmsg("cast from type %s to type %s already exists",
1662-
format_type_be(sourcetypeid),
1663-
format_type_be(targettypeid))));
1664-
1665-
/* ready to go */
1666-
castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
1667-
values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
1668-
values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
1669-
values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
1670-
values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
1671-
values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
1672-
values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
1673-
1674-
MemSet(nulls, false, sizeof(nulls));
1675-
1676-
tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
1677-
1678-
CatalogTupleInsert(relation, tuple);
1679-
1680-
/* make dependency entries */
1681-
myself.classId = CastRelationId;
1682-
myself.objectId = castid;
1683-
myself.objectSubId = 0;
1684-
1685-
/* dependency on source type */
1686-
referenced.classId = TypeRelationId;
1687-
referenced.objectId = sourcetypeid;
1688-
referenced.objectSubId = 0;
1689-
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1690-
1691-
/* dependency on target type */
1692-
referenced.classId = TypeRelationId;
1693-
referenced.objectId = targettypeid;
1694-
referenced.objectSubId = 0;
1695-
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1696-
1697-
/* dependency on function */
1698-
if (OidIsValid(funcid))
1699-
{
1700-
referenced.classId = ProcedureRelationId;
1701-
referenced.objectId = funcid;
1702-
referenced.objectSubId = 0;
1703-
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
1704-
}
1705-
1706-
/* dependency on extension */
1707-
recordDependencyOnCurrentExtension(&myself, false);
1708-
1709-
/* Post creation hook for new cast */
1710-
InvokeObjectPostCreateHook(CastRelationId, castid, 0);
1711-
1712-
heap_freetuple(tuple);
1713-
1714-
table_close(relation, RowExclusiveLock);
1715-
1643+
myself = CastCreate(sourcetypeid, targettypeid, funcid, castcontext,
1644+
castmethod, DEPENDENCY_NORMAL);
17161645
return myself;
17171646
}
17181647

1719-
/*
1720-
* get_cast_oid - given two type OIDs, look up a cast OID
1721-
*
1722-
* If missing_ok is false, throw an error if the cast is not found. If
1723-
* true, just return InvalidOid.
1724-
*/
1725-
Oid
1726-
get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
1727-
{
1728-
Oid oid;
1729-
1730-
oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
1731-
ObjectIdGetDatum(sourcetypeid),
1732-
ObjectIdGetDatum(targettypeid));
1733-
if (!OidIsValid(oid) && !missing_ok)
1734-
ereport(ERROR,
1735-
(errcode(ERRCODE_UNDEFINED_OBJECT),
1736-
errmsg("cast from type %s to type %s does not exist",
1737-
format_type_be(sourcetypeid),
1738-
format_type_be(targettypeid))));
1739-
return oid;
1740-
}
1741-
17421648
void
17431649
DropCastById(Oid castOid)
17441650
{

src/backend/commands/typecmds.c

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "catalog/objectaccess.h"
4343
#include "catalog/pg_am.h"
4444
#include "catalog/pg_authid.h"
45+
#include "catalog/pg_cast.h"
4546
#include "catalog/pg_collation.h"
4647
#include "catalog/pg_constraint.h"
4748
#include "catalog/pg_depend.h"

src/backend/utils/cache/lsyscache.c

+26
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "catalog/pg_am.h"
2424
#include "catalog/pg_amop.h"
2525
#include "catalog/pg_amproc.h"
26+
#include "catalog/pg_cast.h"
2627
#include "catalog/pg_collation.h"
2728
#include "catalog/pg_constraint.h"
2829
#include "catalog/pg_language.h"
@@ -908,6 +909,31 @@ get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
908909
ReleaseSysCache(tp);
909910
}
910911

912+
/* ---------- PG_CAST CACHE ---------- */
913+
914+
/*
915+
* get_cast_oid - given two type OIDs, look up a cast OID
916+
*
917+
* If missing_ok is false, throw an error if the cast is not found. If
918+
* true, just return InvalidOid.
919+
*/
920+
Oid
921+
get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
922+
{
923+
Oid oid;
924+
925+
oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
926+
ObjectIdGetDatum(sourcetypeid),
927+
ObjectIdGetDatum(targettypeid));
928+
if (!OidIsValid(oid) && !missing_ok)
929+
ereport(ERROR,
930+
(errcode(ERRCODE_UNDEFINED_OBJECT),
931+
errmsg("cast from type %s to type %s does not exist",
932+
format_type_be(sourcetypeid),
933+
format_type_be(targettypeid))));
934+
return oid;
935+
}
936+
911937
/* ---------- COLLATION CACHE ---------- */
912938

913939
/*

src/include/catalog/pg_cast.h

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#ifndef PG_CAST_H
2121
#define PG_CAST_H
2222

23+
#include "catalog/dependency.h"
2324
#include "catalog/genbki.h"
2425
#include "catalog/pg_cast_d.h"
2526

@@ -87,4 +88,12 @@ typedef enum CoercionMethod
8788

8889
#endif /* EXPOSE_TO_CLIENT_CODE */
8990

91+
92+
extern ObjectAddress CastCreate(Oid sourcetypeid,
93+
Oid targettypeid,
94+
Oid funcid,
95+
char castcontext,
96+
char castmethod,
97+
DependencyType behavior);
98+
9099
#endif /* PG_CAST_H */

src/include/commands/defrem.h

-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
6464
extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
6565
extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest);
6666
extern TupleDesc CallStmtResultDesc(CallStmt *stmt);
67-
extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
6867
extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok);
6968
extern void interpret_function_parameter_list(ParseState *pstate,
7069
List *parameters,

src/include/utils/lsyscache.h

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ extern char get_attgenerated(Oid relid, AttrNumber attnum);
9090
extern Oid get_atttype(Oid relid, AttrNumber attnum);
9191
extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
9292
Oid *typid, int32 *typmod, Oid *collid);
93+
extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
9394
extern char *get_collation_name(Oid colloid);
9495
extern bool get_collation_isdeterministic(Oid colloid);
9596
extern char *get_constraint_name(Oid conoid);

0 commit comments

Comments
 (0)