8000 Split out CreateCast into src/backend/catalog/pg_cast.c · postgrespro/postgres@40b3e2c · GitHub
[go: up one dir, main page]

Skip to content
  • Commit 40b3e2c

    Browse files
    committed
    Split out CreateCast into src/backend/catalog/pg_cast.c
    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
    1 parent 0a42a2e commit 40b3e2c

    File tree

    8 files changed

    +164
    -98
    lines changed

    8 files changed

    +164
    -98
    lines changed

    src/backend/catalog/Makefile

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -25,6 +25,7 @@ OBJS = \
    2525
    objectaddress.o \
    2626
    partition.o \
    2727
    pg_aggregate.o \
    28+
    pg_cast.o \
    2829
    pg_collation.o \
    2930
    pg_constraint.o \
    3031
    pg_conversion.o \

    src/backend/catalog/pg_cast.c

    Lines changed: 123 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -0,0 +1,123 @@
    1+
    /*-------------------------------------------------------------------------
    2+
    *
    3+
    * pg_cast.c
    4+
    * routines to support manipulation of the pg_cast relation
    5+
    *
    6+
    * Portions Copyright (c) 1996-2019, 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+
    * '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+
    * ----------------------------------------------------------------
    41+
    */
    42+
    ObjectAddress
    43+
    CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext,
    44+
    char castmethod, DependencyType behavior)
    45+
    {
    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;
    53+
    54+
    relation = table_open(CastRelationId, RowExclusiveLock);
    55+
    56+
    /*
    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).
    60+
    */
    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))));
    70+
    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);
    79+
    80+
    MemSet(nulls, false, sizeof(nulls));
    81+
    82+
    tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
    83+
    84+
    CatalogTupleInsert(relation, tuple);
    85+
    86+
    /* make dependency entries */
    87+
    myself.classId = CastRelationId;
    88+
    myself.objectId = castid;
    89+
    myself.objectSubId = 0;
    90+
    91+
    /* dependency on source type */
    92+
    referenced.classId = TypeRelationId;
    93+
    referenced.objectId = sourcetypeid;
    94+
    referenced.objectSubId = 0;
    95+
    recordDependencyOn(&myself, &referenced, behavior);
    96+
    97+
    /* dependency on target type */
    98+
    referenced.classId = TypeRelationId;
    99+
    referenced.objectId = targettypeid;
    100+
    referenced.objectSubId = 0;
    101+
    recordDependencyOn(&myself, &referenced, behavior);
    102+
    103+
    /* dependency on function */
    104+
    if (OidIsValid(funcid))
    105+
    {
    106+
    referenced.classId = ProcedureRelationId;
    107+
    referenced.objectId = funcid;
    108+
    referenced.objectSubId = 0;
    109+
    recordDependencyOn(&myself, &referenced, behavior);
    110+
    }
    111+
    112+
    /* dependency on extension */
    113+
    recordDependencyOnCurrentExtension(&myself, false);
    114+
    115+
    /* Post creation hook for new cast */
    116+
    InvokeObjectPostCreateHook(CastRelationId, castid, 0);
    117+
    118+
    heap_freetuple(tuple);
    119+
    120+
    table_close(relation, RowExclusiveLock);
    121+
    122+
    return myself;
    123+
    }

    src/backend/commands/functioncmds.c

    Lines changed: 3 additions & 97 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1411,17 +1411,12 @@ CreateCast(CreateCastStmt *stmt)
    14111411
    char sourcetyptype;
    14121412
    char targettyptype;
    14131413
    Oid funcid;
    1414-
    Oid castid;
    14151414
    int nargs;
    14161415
    char castcontext;
    14171416
    char castmethod;
    1418-
    Relation relation;
    14191417
    HeapTuple tuple;
    1420-
    Datum values[Natts_pg_cast];
    1421-
    bool nulls[Natts_pg_cast];
    1422-
    ObjectAddress myself,
    1423-
    referenced;
    14241418
    AclResult aclresult;
    1419+
    ObjectAddress myself;
    14251420

    14261421
    sourcetypeid = typenameTypeId(NULL, stmt->sourcetype);
    14271422
    targettypeid = typenameTypeId(NULL, stmt->targettype);
    @@ -1645,100 +1640,11 @@ CreateCast(CreateCastStmt *stmt)
    16451640
    break;
    16461641
    }
    16471642

    1648-
    relation = table_open(CastRelationId, RowExclusiveLock);
    1649-
    1650-
    /*
    1651-
    * Check for duplicate. This is just to give a friendly error message,
    1652-
    * the unique index would catch it anyway (so no need to sweat about race
    1653-
    * conditions).
    1654-
    */
    1655-
    tuple = SearchSysCache2(CASTSOURCETARGET,
    1656-
    ObjectIdGetDatum(sourcetypeid),
    1657-
    ObjectIdGetDatum(targettypeid));
    1658-
    if (HeapTupleIsValid(tuple))
    1659-
    ereport(ERROR,
    1660-
    (errcode(ERRCODE_DUPLICATE_OBJECT),
    1661-
    errmsg("cast from type %s to type %s already exists",
    1662-
    format_type_be(sourcetypeid),
    1663-
    format_type_be(targettypeid))));
    1664-
    1665-
    /* ready to go */
    1666-
    castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
    1667-
    values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
    1668-
    values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
    1669-
    values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
    1670-
    values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
    1671-
    values[Anum_pg_cast_castcontext - 1] = CharGetDatum(castcontext);
    1672-
    values[Anum_pg_cast_castmethod - 1] = CharGetDatum(castmethod);
    1673-
    1674-
    MemSet(nulls, false, sizeof(nulls));
    1675-
    1676-
    tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
    1677-
    1678-
    CatalogTupleInsert(relation, tuple);
    1679-
    1680-
    /* make dependency entries */
    1681-
    myself.classId = CastRelationId;
    1682-
    myself.objectId = castid;
    1683-
    myself.objectSubId = 0;
    1684-
    1685-
    /* dependency on source type */
    1686-
    referenced.classId = TypeRelationId;
    1687-
    referenced.objectId = sourcetypeid;
    1688-
    referenced.objectSubId = 0;
    1689-
    recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    1690-
    1691-
    /* dependency on target type */
    1692-
    referenced.classId = TypeRelationId;
    1693-
    referenced.objectId = targettypeid;
    1694-
    referenced.objectSubId = 0;
    1695-
    recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    1696-
    1697-
    /* dependency on function */
    1698-
    if (OidIsValid(funcid))
    1699-
    {
    1700-
    referenced.classId = ProcedureRelationId;
    1701-
    referenced.objectId = funcid;
    1702-
    referenced.objectSubId = 0;
    1703-
    recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    1704-
    }
    1705-
    1706-
    /* dependency on extension */
    1707-
    recordDependencyOnCurrentExtension(&myself, false);
    1708-
    1709-
    /* Post creation hook for new cast */
    1710-
    InvokeObjectPostCreateHook(CastRelationId, castid, 0);
    1711-
    1712-
    heap_freetuple(tuple);
    1713-
    1714-
    table_close(relation, RowExclusiveLock);
    1715-
    1643+
    myself = CastCreate(sourcetypeid, targettypeid, funcid, castcontext,
    1644+
    castmethod, DEPENDENCY_NORMAL);
    17161645
    return myself;
    17171646
    }
    17181647

    1719-
    /*
    1720-
    * get_cast_oid - given two type OIDs, look up a cast OID
    1721-
    *
    1722-
    * If missing_ok is false, throw an error if the cast is not found. If
    1723-
    * true, just return InvalidOid.
    1724-
    */
    1725-
    Oid
    1726-
    get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
    1727-
    {
    1728-
    Oid oid;
    1729-
    1730-
    oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
    1731-
    ObjectIdGetDatum(sourcetypeid),
    1732-
    ObjectIdGetDatum(targettypeid));
    1733-
    if (!OidIsValid(oid) && !missing_ok)
    1734-
    ereport(ERROR,
    1735-
    (errcode(ERRCODE_UNDEFINED_OBJECT),
    1736-
    errmsg("cast from type %s to type %s does not exist",
    1737-
    format_type_be(sourcetypeid),
    1738-
    format_type_be(targettypeid))));
    1739-
    return oid;
    1740-
    }
    1741-
    17421648
    void
    17431649
    DropCastById(Oid castOid)
    17441650
    {

    src/backend/commands/typecmds.c

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -42,6 +42,7 @@
    4242
    #include "catalog/objectaccess.h"
    4343
    #include "catalog/pg_am.h"
    4444
    #include "catalog/pg_authid.h"
    45+
    #include "catalog/pg_cast.h"
    4546
    #include "catalog/pg_collation.h"
    4647
    #include "catalog/pg_constraint.h"
    4748
    #include "catalog/pg_depend.h"

    src/backend/utils/cache/lsyscache.c

    Lines changed: 26 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -23,6 +23,7 @@
    2323
    #include "catalog/pg_am.h"
    2424
    #include "catalog/pg_amop.h"
    2525
    #include "catalog/pg_amproc.h"
    26+
    #include "catalog/pg_cast.h"
    2627
    #include "catalog/pg_collation.h"
    2728
    #include "catalog/pg_constraint.h"
    2829
    #include "catalog/pg_language.h"
    @@ -908,6 +909,31 @@ get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
    908909
    ReleaseSysCache(tp);
    909910
    }
    910911

    912+
    /* ---------- PG_CAST CACHE ---------- */
    913+
    914+
    /*
    915+
    * get_cast_oid - given two type OIDs, look up a cast OID
    916+
    *
    917+
    * If missing_ok is false, throw an error if the cast is not found. If
    918+
    * true, just return InvalidOid.
    919+
    */
    920+
    Oid
    921+
    get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok)
    922+
    {
    923+
    Oid oid;
    924+
    925+
    oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid,
    926+
    ObjectIdGetDatum(sourcetypeid),
    927+
    ObjectIdGetDatum(targettypeid));
    928+
    if (!OidIsValid(oid) && !missing_ok)
    929+
    ereport(ERROR,
    930+
    (errcode(ERRCODE_UNDEFINED_OBJECT),
    931+
    errmsg("cast from type %s to type %s does not exist",
    932+
    format_type_be(sourcetypeid),
    933+
    format_type_be(targettypeid))));
    934+
    return oid;
    935+
    }
    936+
    911937
    /* ---------- COLLATION CACHE ---------- */
    912938

    913939
    /*

    src/include/catalog/pg_cast.h

    Lines changed: 9 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -20,6 +20,7 @@
    2020
    #ifndef PG_CAST_H
    2121
    #define PG_CAST_H
    2222

    23+
    #include "catalog/dependency.h"
    2324
    #include "catalog/genbki.h"
    2425
    #include "catalog/pg_cast_d.h"
    2526

    @@ -87,4 +88,12 @@ typedef enum CoercionMethod
    8788

    8889
    #endif /* EXPOSE_TO_CLIENT_CODE */
    8990

    91+
    92+
    extern ObjectAddress CastCreate(Oid sourcetypeid,
    93+
    Oid targettypeid,
    94+
    Oid funcid,
    95+
    char castcontext,
    96+
    char castmethod,
    97+
    DependencyType behavior);
    98+
    9099
    #endif /* PG_CAST_H */

    src/include/commands/defrem.h

    Lines changed: 0 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -64,7 +64,6 @@ extern void IsThereFunctionInNamespace(const char *proname, int pronargs,
    6464
    extern void ExecuteDoStmt(DoStmt *stmt, bool atomic);
    6565
    extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest);
    6666
    extern TupleDesc CallStmtResultDesc(CallStmt *stmt);
    67-
    extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
    6867
    extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok);
    6968
    extern void interpret_function_parameter_list(ParseState *pstate,
    7069
    List *parameters,

    src/include/utils/lsyscache.h

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -90,6 +90,7 @@ extern char get_attgenerated(Oid relid, AttrNumber attnum);
    9090
    extern Oid get_atttype(Oid relid, AttrNumber attnum);
    9191
    extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum,
    9292
    Oid *typid, int32 *typmod, Oid *collid);
    93+
    extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
    9394
    extern char *get_collation_name(Oid colloid);
    9495
    extern bool get_collation_isdeterministic(Oid colloid);
    9596
    extern char *get_constraint_name(Oid conoid);

    0 commit comments

    Comments
     (0)
    0