1 /*-------------------------------------------------------------------------
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
11 * src/backend/catalog/pg_cast.c
13 *-------------------------------------------------------------------------
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 * ----------------------------------------------------------------
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 * ----------------------------------------------------------------
43 CastCreate(Oid sourcetypeid
, Oid targettypeid
, Oid funcid
, char castcontext
,
44 char castmethod
, DependencyType behavior
)
49 Datum values
[Natts_pg_cast
];
50 bool nulls
[Natts_pg_cast
];
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
61 tuple
= SearchSysCache2(CASTSOURCETARGET
,
62 ObjectIdGetDatum(sourcetypeid
),
63 ObjectIdGetDatum(targettypeid
));
64 if (HeapTupleIsValid(tuple
))
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
))));
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
);