aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/Makefile1
-rw-r--r--src/backend/catalog/pg_cast.c123
-rw-r--r--src/backend/commands/functioncmds.c100
-rw-r--r--src/backend/commands/typecmds.c1
-rw-r--r--src/backend/utils/cache/lsyscache.c26
5 files changed, 154 insertions, 97 deletions
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index f8f0b4841c3..9499bb33e56 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -25,6 +25,7 @@ OBJS = \
objectaddress.o \
partition.o \
pg_aggregate.o \
+ pg_cast.o \
pg_collation.o \
pg_constraint.o \
pg_conversion.o \
diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c
new file mode 100644
index 00000000000..38544556371
--- /dev/null
+++ b/src/backend/catalog/pg_cast.c
@@ -0,0 +1,123 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_cast.c
+ * routines to support manipulation of the pg_cast relation
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/catalog/pg_cast.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/htup_details.h"
+#include "access/table.h"
+#include "catalog/catalog.h"
+#include "catalog/dependency.h"
+#include "catalog/indexing.h"
+#include "catalog/objectaccess.h"
+#include "catalog/pg_cast.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_type.h"
+#include "utils/builtins.h"
+#include "utils/rel.h"
+#include "utils/syscache.h"
+
+/*
+ * ----------------------------------------------------------------
+ * CastCreate
+ *
+ * Forms and inserts catalog tuples for a new cast being created.
+ * Caller must have already checked privileges, and done consistency
+ * checks on the given datatypes and cast function (if applicable).
+ *
+ * 'behavior' indicates the types of the dependencies that the new
+ * cast will have on its input and output types and the cast function.
+ * ----------------------------------------------------------------
+ */
+ObjectAddress
+CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext,
+ char castmethod, DependencyType behavior)
+{
+ Relation relation;
+ HeapTuple tuple;
+ Oid castid;
+ Datum values[Natts_pg_cast];
+ bool nulls[Natts_pg_cast];
+ ObjectAddress myself,
+ referenced;
+
+ relation = table_open(CastRelationId, RowExclusiveLock);
+
+ /*
+ * Check for duplicate. This is just to give a friendly error message,
+ * the unique index would catch it anyway (so no need to sweat about race
+ * conditions).
+ */
+ tuple = SearchSysCache2(CASTSOURCETARGET,
+ ObjectIdGetDatum(sourcetypeid),
+ ObjectIdGetDatum(targettypeid));
+ if (HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("cast from type %s to type %s already exists",
+ format_type_be(sourcetypeid),
+ format_type_be(targettypeid))));
+
+ /* ready to go */
+ castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
+ values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
+ values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
+ values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
+ values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
+ values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
+ values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
+
+ MemSet(nulls, false, sizeof(nulls));
+
+ tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
+
+ CatalogTupleInsert(relation, tuple);
+
+ /* make dependency entries */
+ myself.classId = CastRelationId;
+ myself.objectId = castid;
+ myself.objectSubId = 0;
+
+ /* dependency on source type */
+ referenced.classId = TypeRelationId;
+ referenced.objectId = sourcetypeid;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, behavior);
+
+ /* dependency on target type */
+ referenced.classId = TypeRelationId;
+ referenced.objectId = targettypeid;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, behavior);
+
+ /* dependency on function */
+ if (OidIsValid(funcid))
+ {
+ referenced.classId = ProcedureRelationId;
+ referenced.objectId = funcid;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, behavior);
+ }
+
+ /* dependency on extension */
+ recordDependencyOnCurrentExtension(&myself, false);
+
+ /* Post creation hook for new cast */
+ InvokeObjectPostCreateHook(CastRelationId, castid, 0);
+
+ heap_freetuple(tuple);
+
+ table_close(relation, RowExclusiveLock);
+
+ return myself;
+}
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 43a23c69af3..5eac55aaca1 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1411,17 +1411,12 @@ CreateCast(CreateCastStmt *stmt)
char sourcetyptype;
char targettyptype;
Oid funcid;
- Oid castid;
int nargs;
char castcontext;
char castmethod;
- Relation relation;
HeapTuple tuple;
- Datum values[Natts_pg_cast];
- bool nulls[Natts_pg_cast];
- ObjectAddress myself,
- referenced;
AclResult aclresult;
+ ObjectAddress myself;
sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
targettypeid = typenameTypeId(NULL, stmt->targettype);
@@ -1645,100 +1640,11 @@ CreateCast(CreateCastStmt *stmt)
break;
}
- relation = table_open(CastRelationId, RowExclusiveLock);
-
- /*
- * Check for duplicate. This is just to give a friendly error message,
- * the unique index would catch it anyway (so no need to sweat about race
- * conditions).
- */
- tuple = SearchSysCache2(CASTSOURCETARGET,
- ObjectIdGetDatum(sourcetypeid),
- ObjectIdGetDatum(targettypeid));
- if (HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("cast from type %s to type %s already exists",
- format_type_be(sourcetypeid),
- format_type_be(targettypeid))));
-
- /* ready to go */
- castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
- values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
- values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
- values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
- values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
- values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
- values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
-
- MemSet(nulls, false, sizeof(nulls));
-
- tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
-
- CatalogTupleInsert(relation, tuple);
-
- /* make dependency entries */
- myself.classId = CastRelationId;
- myself.objectId = castid;
- myself.objectSubId = 0;
-
- /* dependency on source type */
- referenced.classId = TypeRelationId;
- referenced.objectId = sourcetypeid;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
- /* dependency on target type */
- referenced.classId = TypeRelationId;
- referenced.objectId = targettypeid;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
- /* dependency on function */
- if (OidIsValid(funcid))
- {
- referenced.classId = ProcedureRelationId;
- referenced.objectId = funcid;
- referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
- }
-
- /* dependency on extension */
- recordDependencyOnCurrentExtension(&myself, false);
-
- /* Post creation hook for new cast */
- InvokeObjectPostCreateHook(CastRelationId, castid, 0);
-
- heap_freetuple(tuple);
-
- table_close(relation, RowExclusiveLock);
-
+ myself = CastCreate(sourcetypeid, targettypeid, funcid, castcontext,
+ castmethod, DEPENDENCY_NORMAL);
return myself;
}
-/*
- * get_cast_oid - given two type OIDs, look up a cast OID
- *
- * If missing_ok is false, throw an error if the cast is not found. If
- * true, just return InvalidOid.
- */
-Oid
-get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
-{
- Oid oid;
-
- oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
- ObjectIdGetDatum(sourcetypeid),
- ObjectIdGetDatum(targettypeid));
- if (!OidIsValid(oid) && !missing_ok)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("cast from type %s to type %s does not exist",
- format_type_be(sourcetypeid),
- format_type_be(targettypeid))));
- return oid;
-}
-
void
DropCastById(Oid castOid)
{
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index b088ca848d3..8891b1d5645 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -42,6 +42,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_am.h"
#include "catalog/pg_authid.h"
+#include "catalog/pg_cast.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 400e7689fe2..6b24369de8f 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -23,6 +23,7 @@
#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
+#include "catalog/pg_cast.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_language.h"
@@ -908,6 +909,31 @@ get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
ReleaseSysCache(tp);
}
+/* ---------- PG_CAST CACHE ---------- */
+
+/*
+ * get_cast_oid - given two type OIDs, look up a cast OID
+ *
+ * If missing_ok is false, throw an error if the cast is not found. If
+ * true, just return InvalidOid.
+ */
+Oid
+get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
+{
+ Oid oid;
+
+ oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
+ ObjectIdGetDatum(sourcetypeid),
+ ObjectIdGetDatum(targettypeid));
+ if (!OidIsValid(oid) && !missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("cast from type %s to type %s does not exist",
+ format_type_be(sourcetypeid),
+ format_type_be(targettypeid))));
+ return oid;
+}
+
/* ---------- COLLATION CACHE ---------- */
/*