]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Split out CreateCast into src/backend/catalog/pg_cast.c
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 10 Mar 2020 14:28:23 +0000 (11:28 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 10 Mar 2020 14:28:23 +0000 (11:28 -0300)
This catalog-handling code was previously together with the rest of
CastCreate() in src/backend/commands/functioncmds.c.  A future patch
will need a way to add casts internally, so this will be useful to have
separate.

Also, move the nearby get_cast_oid() function from functioncmds.c to
lsyscache.c, which seems a more natural place for it.

Author: Paul Jungwirth, minor edits by Álvaro
Discussion: https://postgr.es/m/20200309210003.GA19992@alvherre.pgsql

src/backend/catalog/Makefile
src/backend/catalog/pg_cast.c [new file with mode: 0644]
src/backend/commands/functioncmds.c
src/backend/commands/typecmds.c
src/backend/utils/cache/lsyscache.c
src/include/catalog/pg_cast.h
src/include/commands/defrem.h
src/include/utils/lsyscache.h

index f8f0b4841c3fe105dec7e6d36dcb096e7a90a7a7..9499bb33e566e56a5178458ec4a886c0abefcd2d 100644 (file)
@@ -25,6 +25,7 @@ OBJS = \
        objectaddress.o \
        partition.o \
        pg_aggregate.o \
+       pg_cast.o \
        pg_collation.o \
        pg_constraint.o \
        pg_conversion.o \
diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c
new file mode 100644 (file)
index 0000000..3854455
--- /dev/null
@@ -0,0 +1,123 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_cast.c
+ *       routines to support manipulation of the pg_cast relation
+ *
+ * Portions Copyright (c) 1996-2019, 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;
+
+       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);
+
+       /* make dependency entries */
+       myself.classId = CastRelationId;
+       myself.objectId = castid;
+       myself.objectSubId = 0;
+
+       /* dependency on source type */
+       referenced.classId = TypeRelationId;
+       referenced.objectId = sourcetypeid;
+       referenced.objectSubId = 0;
+       recordDependencyOn(&myself, &referenced, behavior);
+
+       /* dependency on target type */
+       referenced.classId = TypeRelationId;
+       referenced.objectId = targettypeid;
+       referenced.objectSubId = 0;
+       recordDependencyOn(&myself, &referenced, behavior);
+
+       /* dependency on function */
+       if (OidIsValid(funcid))
+       {
+               referenced.classId = ProcedureRelationId;
+               referenced.objectId = funcid;
+               referenced.objectSubId = 0;
+               recordDependencyOn(&myself, &referenced, behavior);
+       }
+
+       /* 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;
+}
index 43a23c69af30e42a9636720eb988c3cacdb09f8e..5eac55aaca196ebefe05b24d3006bbaa8314e16d 100644 (file)
@@ -1411,17 +1411,12 @@ CreateCast(CreateCastStmt *stmt)
        char            sourcetyptype;
        char            targettyptype;
        Oid                     funcid;
-       Oid                     castid;
        int                     nargs;
        char            castcontext;
        char            castmethod;
-       Relation        relation;
        HeapTuple       tuple;
-       Datum           values[Natts_pg_cast];
-       bool            nulls[Natts_pg_cast];
-       ObjectAddress myself,
-                               referenced;
        AclResult       aclresult;
+       ObjectAddress   myself;
 
        sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
        targettypeid = typenameTypeId(NULL, stmt->targettype);
@@ -1645,100 +1640,11 @@ CreateCast(CreateCastStmt *stmt)
                        break;
        }
 
-       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);
-
-       /* make dependency entries */
-       myself.classId = CastRelationId;
-       myself.objectId = castid;
-       myself.objectSubId = 0;
-
-       /* dependency on source type */
-       referenced.classId = TypeRelationId;
-       referenced.objectId = sourcetypeid;
-       referenced.objectSubId = 0;
-       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
-       /* dependency on target type */
-       referenced.classId = TypeRelationId;
-       referenced.objectId = targettypeid;
-       referenced.objectSubId = 0;
-       recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
-       /* dependency on function */
-       if (OidIsValid(funcid))
-       {
-               referenced.classId = ProcedureRelationId;
-               referenced.objectId = funcid;
-               referenced.objectSubId = 0;
-               recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-       }
-
-       /* dependency on extension */
-       recordDependencyOnCurrentExtension(&myself, false);
-
-       /* Post creation hook for new cast */
-       InvokeObjectPostCreateHook(CastRelationId, castid, 0);
-
-       heap_freetuple(tuple);
-
-       table_close(relation, RowExclusiveLock);
-
+       myself = CastCreate(sourcetypeid, targettypeid, funcid, castcontext,
+                                               castmethod, DEPENDENCY_NORMAL);
        return myself;
 }
 
-/*
- * get_cast_oid - given two type OIDs, look up a cast OID
- *
- * If missing_ok is false, throw an error if the cast is not found.  If
- * true, just return InvalidOid.
- */
-Oid
-get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
-{
-       Oid                     oid;
-
-       oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
-                                                 ObjectIdGetDatum(sourcetypeid),
-                                                 ObjectIdGetDatum(targettypeid));
-       if (!OidIsValid(oid) && !missing_ok)
-               ereport(ERROR,
-                               (errcode(ERRCODE_UNDEFINED_OBJECT),
-                                errmsg("cast from type %s to type %s does not exist",
-                                               format_type_be(sourcetypeid),
-                                               format_type_be(targettypeid))));
-       return oid;
-}
-
 void
 DropCastById(Oid castOid)
 {
index b088ca848d38c0988aca9d9cb43a6c8e68f73a76..8891b1d56458ff2173c2abebb236de9e4a0547b4 100644 (file)
@@ -42,6 +42,7 @@
 #include "catalog/objectaccess.h"
 #include "catalog/pg_am.h"
 #include "catalog/pg_authid.h"
+#include "catalog/pg_cast.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_depend.h"
index 400e7689fe27916cc6ac4715746b1443644b1ed9..6b24369de8ff9b02740ad13dd5a4927c3c1f8ba3 100644 (file)
@@ -23,6 +23,7 @@
 #include "catalog/pg_am.h"
 #include "catalog/pg_amop.h"
 #include "catalog/pg_amproc.h"
+#include "catalog/pg_cast.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_language.h"
@@ -908,6 +909,31 @@ get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
        ReleaseSysCache(tp);
 }
 
+/*                             ---------- PG_CAST CACHE ----------                                      */
+
+/*
+ * get_cast_oid - given two type OIDs, look up a cast OID
+ *
+ * If missing_ok is false, throw an error if the cast is not found.  If
+ * true, just return InvalidOid.
+ */
+Oid
+get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
+{
+       Oid                     oid;
+
+       oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
+                                                 ObjectIdGetDatum(sourcetypeid),
+                                                 ObjectIdGetDatum(targettypeid));
+       if (!OidIsValid(oid) && !missing_ok)
+               ereport(ERROR,
+                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                errmsg("cast from type %s to type %s does not exist",
+                                               format_type_be(sourcetypeid),
+                                               format_type_be(targettypeid))));
+       return oid;
+}
+
 /*                             ---------- COLLATION CACHE ----------                                    */
 
 /*
index 1b81b52df6b54fa854d2b6bd6be75831b9bdcd8c..2620ff40f05cbf7a75403a890233935a1809db0b 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef PG_CAST_H
 #define PG_CAST_H
 
+#include "catalog/dependency.h"
 #include "catalog/genbki.h"
 #include "catalog/pg_cast_d.h"
 
@@ -87,4 +88,12 @@ typedef enum CoercionMethod
 
 #endif                                                 /* EXPOSE_TO_CLIENT_CODE */
 
+
+extern ObjectAddress CastCreate(Oid sourcetypeid,
+                                                               Oid targettypeid,
+                                                               Oid funcid,
+                                                               char castcontext,
+                                                               char castmethod,
+                                                               DependencyType behavior);
+
 #endif                                                 /* PG_CAST_H */
index 08ca6ac31e8d328db1d7f04e31bae9b25b074b60..c77c9a6ed5aea648e092a6ada88edcc0b0c208bb 100644 (file)
@@ -64,7 +64,6 @@ extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
 extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
 extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest);
 extern TupleDesc CallStmtResultDesc(CallStmt *stmt);
-extern Oid     get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 extern Oid     get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok);
 extern void interpret_function_parameter_list(ParseState *pstate,
                                                                                          List *parameters,
index 131d10eab07698b499eb18f972ef15b97791979f..6e93590befcd044aaf9d0b698ff93947c839d055 100644 (file)
@@ -90,6 +90,7 @@ extern char get_attgenerated(Oid relid, AttrNumber attnum);
 extern Oid     get_atttype(Oid relid, AttrNumber attnum);
 extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
                                                                  Oid *typid, int32 *typmod, Oid *collid);
+extern Oid     get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
 extern char *get_collation_name(Oid colloid);
 extern bool get_collation_isdeterministic(Oid colloid);
 extern char *get_constraint_name(Oid conoid);