diff options
Diffstat (limited to 'src/backend/catalog/pg_cast.c')
-rw-r--r-- | src/backend/catalog/pg_cast.c | 121 |
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; +} |