mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-03 22:26:49 +02:00
6a68a233ce
Thinko in 40b3e2c201
.
Reported-by: "Wang, Shenhao" <wangsh.fnst@cn.fujitsu.com>
Discussion: https://postgr.es/m/ed98706b82694b57a8c0d339a10732aa@G08CNEXMBPEKD06.g08.fujitsu.local
122 lines
3.7 KiB
C
122 lines
3.7 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* pg_cast.c
|
|
* routines to support manipulation of the pg_cast relation
|
|
*
|
|
* Portions Copyright (c) 1996-2020, 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;
|
|
}
|