summaryrefslogtreecommitdiffstats
path: root/src/backend/catalog/pg_cast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/pg_cast.c')
-rw-r--r--src/backend/catalog/pg_cast.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c
new file mode 100644
index 0000000..4857f64
--- /dev/null
+++ b/src/backend/catalog/pg_cast.c
@@ -0,0 +1,121 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_cast.c
+ * routines to support manipulation of the pg_cast relation
+ *
+ * Portions Copyright (c) 1996-2022, 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;
+ ObjectAddresses *addrs;
+
+ 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);
+
+ addrs = new_object_addresses();
+
+ /* make dependency entries */
+ ObjectAddressSet(myself, CastRelationId, castid);
+
+ /* dependency on source type */
+ ObjectAddressSet(referenced, TypeRelationId, sourcetypeid);
+ add_exact_object_address(&referenced, addrs);
+
+ /* dependency on target type */
+ ObjectAddressSet(referenced, TypeRelationId, targettypeid);
+ add_exact_object_address(&referenced, addrs);
+
+ /* dependency on function */
+ if (OidIsValid(funcid))
+ {
+ ObjectAddressSet(referenced, ProcedureRelationId, funcid);
+ add_exact_object_address(&referenced, addrs);
+ }
+
+ record_object_address_dependencies(&myself, addrs, behavior);
+ free_object_addresses(addrs);
+
+ /* 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;
+}