LCOV - code coverage report
Current view: top level - src/backend/catalog - pg_cast.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 34 37 91.9 %
Date: 2024-04-23 10:11:02 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_cast.c
       4             :  *    routines to support manipulation of the pg_cast relation
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/catalog/pg_cast.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      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"
      29             : 
      30             : /*
      31             :  * ----------------------------------------------------------------
      32             :  *      CastCreate
      33             :  *
      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).
      37             :  *
      38             :  * Since we allow binary coercibility of the datatypes to the cast
      39             :  * function's input and result, there could be one or two WITHOUT FUNCTION
      40             :  * casts that this one depends on.  We don't record that explicitly
      41             :  * in pg_cast, but we still need to make dependencies on those casts.
      42             :  *
      43             :  * 'behavior' indicates the types of the dependencies that the new
      44             :  * cast will have on its input and output types, the cast function,
      45             :  * and the other casts if any.
      46             :  * ----------------------------------------------------------------
      47             :  */
      48             : ObjectAddress
      49         406 : CastCreate(Oid sourcetypeid, Oid targettypeid,
      50             :            Oid funcid, Oid incastid, Oid outcastid,
      51             :            char castcontext, char castmethod, DependencyType behavior)
      52             : {
      53             :     Relation    relation;
      54             :     HeapTuple   tuple;
      55             :     Oid         castid;
      56             :     Datum       values[Natts_pg_cast];
      57         406 :     bool        nulls[Natts_pg_cast] = {0};
      58             :     ObjectAddress myself,
      59             :                 referenced;
      60             :     ObjectAddresses *addrs;
      61             : 
      62         406 :     relation = table_open(CastRelationId, RowExclusiveLock);
      63             : 
      64             :     /*
      65             :      * Check for duplicate.  This is just to give a friendly error message,
      66             :      * the unique index would catch it anyway (so no need to sweat about race
      67             :      * conditions).
      68             :      */
      69         406 :     tuple = SearchSysCache2(CASTSOURCETARGET,
      70             :                             ObjectIdGetDatum(sourcetypeid),
      71             :                             ObjectIdGetDatum(targettypeid));
      72         406 :     if (HeapTupleIsValid(tuple))
      73           0 :         ereport(ERROR,
      74             :                 (errcode(ERRCODE_DUPLICATE_OBJECT),
      75             :                  errmsg("cast from type %s to type %s already exists",
      76             :                         format_type_be(sourcetypeid),
      77             :                         format_type_be(targettypeid))));
      78             : 
      79             :     /* ready to go */
      80         406 :     castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
      81         406 :     values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
      82         406 :     values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
      83         406 :     values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
      84         406 :     values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
      85         406 :     values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
      86         406 :     values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
      87             : 
      88         406 :     tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
      89             : 
      90         406 :     CatalogTupleInsert(relation, tuple);
      91             : 
      92         406 :     addrs = new_object_addresses();
      93             : 
      94             :     /* make dependency entries */
      95         406 :     ObjectAddressSet(myself, CastRelationId, castid);
      96             : 
      97             :     /* dependency on source type */
      98         406 :     ObjectAddressSet(referenced, TypeRelationId, sourcetypeid);
      99         406 :     add_exact_object_address(&referenced, addrs);
     100             : 
     101             :     /* dependency on target type */
     102         406 :     ObjectAddressSet(referenced, TypeRelationId, targettypeid);
     103         406 :     add_exact_object_address(&referenced, addrs);
     104             : 
     105             :     /* dependency on function */
     106         406 :     if (OidIsValid(funcid))
     107             :     {
     108         238 :         ObjectAddressSet(referenced, ProcedureRelationId, funcid);
     109         238 :         add_exact_object_address(&referenced, addrs);
     110             :     }
     111             : 
     112             :     /* dependencies on casts required for function */
     113         406 :     if (OidIsValid(incastid))
     114             :     {
     115           0 :         ObjectAddressSet(referenced, CastRelationId, incastid);
     116           0 :         add_exact_object_address(&referenced, addrs);
     117             :     }
     118         406 :     if (OidIsValid(outcastid))
     119             :     {
     120           8 :         ObjectAddressSet(referenced, CastRelationId, outcastid);
     121           8 :         add_exact_object_address(&referenced, addrs);
     122             :     }
     123             : 
     124         406 :     record_object_address_dependencies(&myself, addrs, behavior);
     125         406 :     free_object_addresses(addrs);
     126             : 
     127             :     /* dependency on extension */
     128         406 :     recordDependencyOnCurrentExtension(&myself, false);
     129             : 
     130             :     /* Post creation hook for new cast */
     131         406 :     InvokeObjectPostCreateHook(CastRelationId, castid, 0);
     132             : 
     133         406 :     heap_freetuple(tuple);
     134             : 
     135         406 :     table_close(relation, RowExclusiveLock);
     136             : 
     137         406 :     return myself;
     138             : }

Generated by: LCOV version 1.14