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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 123 additions & 0 deletions
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

Lines changed: 3 additions & 97 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 26 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy