Make nbtree split REDO locking match original execution.
[pgsql.git] / src / backend / catalog / pg_cast.c
blob5ea2b82b083477777c2a82b8d1a4588e4530f92e
1 /*-------------------------------------------------------------------------
3 * pg_cast.c
4 * routines to support manipulation of the pg_cast relation
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * src/backend/catalog/pg_cast.c
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
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"
31 * ----------------------------------------------------------------
32 * CastCreate
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).
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 * ----------------------------------------------------------------
42 ObjectAddress
43 CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext,
44 char castmethod, DependencyType behavior)
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;
54 relation = table_open(CastRelationId, RowExclusiveLock);
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).
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))));
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);
80 MemSet(nulls, false, sizeof(nulls));
82 tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
84 CatalogTupleInsert(relation, tuple);
86 /* make dependency entries */
87 myself.classId = CastRelationId;
88 myself.objectId = castid;
89 myself.objectSubId = 0;
91 /* dependency on source type */
92 referenced.classId = TypeRelationId;
93 referenced.objectId = sourcetypeid;
94 referenced.objectSubId = 0;
95 recordDependencyOn(&myself, &referenced, behavior);
97 /* dependency on target type */
98 referenced.classId = TypeRelationId;
99 referenced.objectId = targettypeid;
100 referenced.objectSubId = 0;
101 recordDependencyOn(&myself, &referenced, behavior);
103 /* dependency on function */
104 if (OidIsValid(funcid))
106 referenced.classId = ProcedureRelationId;
107 referenced.objectId = funcid;
108 referenced.objectSubId = 0;
109 recordDependencyOn(&myself, &referenced, behavior);
112 /* dependency on extension */
113 recordDependencyOnCurrentExtension(&myself, false);
115 /* Post creation hook for new cast */
116 InvokeObjectPostCreateHook(CastRelationId, castid, 0);
118 heap_freetuple(tuple);
120 table_close(relation, RowExclusiveLock);
122 return myself;