LCOV - differential code coverage report
Current view: top level - src/backend/catalog - pg_type.c (source / functions) Coverage Total Hit LBC UIC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 93.6 % 281 263 1 17 2 135 8 118 16 136 8
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 7 7 7 7
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 93.6 % 281 263 1 17 2 135 8 118 16 136
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 14 7 7 7

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * pg_type.c
                                  4                 :  *    routines to support manipulation of the pg_type relation
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/catalog/pg_type.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include "access/htup_details.h"
                                 18                 : #include "access/table.h"
                                 19                 : #include "access/xact.h"
                                 20                 : #include "catalog/binary_upgrade.h"
                                 21                 : #include "catalog/catalog.h"
                                 22                 : #include "catalog/dependency.h"
                                 23                 : #include "catalog/indexing.h"
                                 24                 : #include "catalog/objectaccess.h"
                                 25                 : #include "catalog/pg_collation.h"
                                 26                 : #include "catalog/pg_namespace.h"
                                 27                 : #include "catalog/pg_proc.h"
                                 28                 : #include "catalog/pg_type.h"
                                 29                 : #include "commands/defrem.h"
                                 30                 : #include "commands/typecmds.h"
                                 31                 : #include "mb/pg_wchar.h"
                                 32                 : #include "miscadmin.h"
                                 33                 : #include "parser/scansup.h"
                                 34                 : #include "utils/acl.h"
                                 35                 : #include "utils/builtins.h"
                                 36                 : #include "utils/fmgroids.h"
                                 37                 : #include "utils/lsyscache.h"
                                 38                 : #include "utils/rel.h"
                                 39                 : #include "utils/syscache.h"
                                 40                 : 
                                 41                 : /* Potentially set by pg_upgrade_support functions */
                                 42                 : Oid         binary_upgrade_next_pg_type_oid = InvalidOid;
                                 43                 : 
                                 44                 : /* ----------------------------------------------------------------
                                 45                 :  *      TypeShellMake
                                 46                 :  *
                                 47                 :  *      This procedure inserts a "shell" tuple into the pg_type relation.
                                 48                 :  *      The type tuple inserted has valid but dummy values, and its
                                 49                 :  *      "typisdefined" field is false indicating it's not really defined.
                                 50                 :  *
                                 51                 :  *      This is used so that a tuple exists in the catalogs.  The I/O
                                 52                 :  *      functions for the type will link to this tuple.  When the full
                                 53                 :  *      CREATE TYPE command is issued, the bogus values will be replaced
                                 54                 :  *      with correct ones, and "typisdefined" will be set to true.
                                 55                 :  * ----------------------------------------------------------------
 9770 scrappy                    56 ECB             :  */
                                 57                 : ObjectAddress
 5157 tgl                        58 GIC         107 : TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
                                 59                 : {
                                 60                 :     Relation    pg_type_desc;
                                 61                 :     TupleDesc   tupDesc;
                                 62                 :     int         i;
                                 63                 :     HeapTuple   tup;
                                 64                 :     Datum       values[Natts_pg_type];
                                 65                 :     bool        nulls[Natts_pg_type];
                                 66                 :     Oid         typoid;
                                 67                 :     NameData    name;
 2959 alvherre                   68 ECB             :     ObjectAddress address;
                                 69                 : 
 7681 tgl                        70 GIC         107 :     Assert(PointerIsValid(typeName));
                                 71                 : 
                                 72                 :     /*
 7681 tgl                        73 ECB             :      * open pg_type
                                 74                 :      */
 1539 andres                     75 GIC         107 :     pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
 7681 tgl                        76             107 :     tupDesc = pg_type_desc->rd_att;
                                 77                 : 
                                 78                 :     /*
 8053 bruce                      79 ECB             :      * initialize our *nulls and *values arrays
                                 80                 :      */
 9345 bruce                      81 CBC        3531 :     for (i = 0; i < Natts_pg_type; ++i)
 9345 bruce                      82 ECB             :     {
 5271 tgl                        83 GIC        3424 :         nulls[i] = false;
 2118                            84            3424 :         values[i] = (Datum) NULL;   /* redundant, but safe */
                                 85                 :     }
                                 86                 : 
                                 87                 :     /*
                                 88                 :      * initialize *values with the type name and dummy values
                                 89                 :      *
                                 90                 :      * The representational details are the same as int4 ... it doesn't really
                                 91                 :      * matter what they are so long as they are consistent.  Also note that we
                                 92                 :      * give it typtype = TYPTYPE_PSEUDO as extra insurance that it won't be
 6031 bruce                      93 ECB             :      * mistaken for a usable type.
 9345                            94                 :      */
 9139 scrappy                    95 CBC         107 :     namestrcpy(&name, typeName);
 4315 tgl                        96             107 :     values[Anum_pg_type_typname - 1] = NameGetDatum(&name);
                                 97             107 :     values[Anum_pg_type_typnamespace - 1] = ObjectIdGetDatum(typeNamespace);
                                 98             107 :     values[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(ownerId);
 3940 peter_e                    99             107 :     values[Anum_pg_type_typlen - 1] = Int16GetDatum(sizeof(int32));
 4315 tgl                       100             107 :     values[Anum_pg_type_typbyval - 1] = BoolGetDatum(true);
                                101             107 :     values[Anum_pg_type_typtype - 1] = CharGetDatum(TYPTYPE_PSEUDO);
                                102             107 :     values[Anum_pg_type_typcategory - 1] = CharGetDatum(TYPCATEGORY_PSEUDOTYPE);
                                103             107 :     values[Anum_pg_type_typispreferred - 1] = BoolGetDatum(false);
                                104             107 :     values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(false);
                                105             107 :     values[Anum_pg_type_typdelim - 1] = CharGetDatum(DEFAULT_TYPDELIM);
                                106             107 :     values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(InvalidOid);
  851                           107             107 :     values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(InvalidOid);
 4315                           108             107 :     values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(InvalidOid);
                                109             107 :     values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(InvalidOid);
                                110             107 :     values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(F_SHELL_IN);
                                111             107 :     values[Anum_pg_type_typoutput - 1] = ObjectIdGetDatum(F_SHELL_OUT);
                                112             107 :     values[Anum_pg_type_typreceive - 1] = ObjectIdGetDatum(InvalidOid);
                                113             107 :     values[Anum_pg_type_typsend - 1] = ObjectIdGetDatum(InvalidOid);
                                114             107 :     values[Anum_pg_type_typmodin - 1] = ObjectIdGetDatum(InvalidOid);
                                115             107 :     values[Anum_pg_type_typmodout - 1] = ObjectIdGetDatum(InvalidOid);
                                116             107 :     values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(InvalidOid);
 1131                           117             107 :     values[Anum_pg_type_typalign - 1] = CharGetDatum(TYPALIGN_INT);
                                118             107 :     values[Anum_pg_type_typstorage - 1] = CharGetDatum(TYPSTORAGE_PLAIN);
 4315                           119             107 :     values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(false);
                                120             107 :     values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(InvalidOid);
                                121             107 :     values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(-1);
                                122             107 :     values[Anum_pg_type_typndims - 1] = Int32GetDatum(0);
                                123             107 :     values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid);
                                124             107 :     nulls[Anum_pg_type_typdefaultbin - 1] = true;
 4315 tgl                       125 GIC         107 :     nulls[Anum_pg_type_typdefault - 1] = true;
 4128 peter_e                   126             107 :     nulls[Anum_pg_type_typacl - 1] = true;
 9345 bruce                     127 ECB             : 
                                128                 :     /* Use binary-upgrade override for pg_type.oid? */
 3149 bruce                     129 CBC         107 :     if (IsBinaryUpgrade)
 4854 bruce                     130 EUB             :     {
 3149 bruce                     131 GIC           8 :         if (!OidIsValid(binary_upgrade_next_pg_type_oid))
 3149 bruce                     132 UIC           0 :             ereport(ERROR,
                                133                 :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 2118 tgl                       134 ECB             :                      errmsg("pg_type OID value not set when in binary upgrade mode")));
 3149 bruce                     135                 : 
 1601 andres                    136 GIC           8 :         typoid = binary_upgrade_next_pg_type_oid;
 4854 bruce                     137               8 :         binary_upgrade_next_pg_type_oid = InvalidOid;
                                138                 :     }
 1601 andres                    139 ECB             :     else
                                140                 :     {
 1601 andres                    141 GIC          99 :         typoid = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId,
                                142                 :                                     Anum_pg_type_oid);
 1601 andres                    143 ECB             :     }
                                144                 : 
 1601 andres                    145 GIC         107 :     values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typoid);
                                146                 : 
                                147                 :     /*
 1601 andres                    148 ECB             :      * create a new type tuple
                                149                 :      */
 1601 andres                    150 GIC         107 :     tup = heap_form_tuple(tupDesc, values, nulls);
                                151                 : 
                                152                 :     /*
 8053 bruce                     153 ECB             :      * insert the tuple in the relation and get the tuple's oid.
                                154                 :      */
 1601 andres                    155 GIC         107 :     CatalogTupleInsert(pg_type_desc, tup);
                                156                 : 
                                157                 :     /*
 7396 tgl                       158 ECB             :      * Create dependencies.  We can/must skip this in bootstrap mode.
                                159                 :      */
 7396 tgl                       160 GIC         107 :     if (!IsBootstrapProcessingMode())
 1129                           161             107 :         GenerateTypeDependencies(tup,
                                162                 :                                  pg_type_desc,
                                163                 :                                  NULL,
                                164                 :                                  NULL,
                                165                 :                                  0,
                                166                 :                                  false,
                                167                 :                                  false,
                                168                 :                                  true,  /* make extension dependency */
                                169                 :                                  false);
 7396 tgl                       170 ECB             : 
                                171                 :     /* Post creation hook for new shell type */
 3686 rhaas                     172 CBC         107 :     InvokeObjectPostCreateHook(TypeRelationId, typoid, 0);
                                173                 : 
 2959 alvherre                  174 GIC         107 :     ObjectAddressSet(address, TypeRelationId, typoid);
                                175                 : 
                                176                 :     /*
 7681 tgl                       177 ECB             :      * clean up and return the type-oid
 9345 bruce                     178                 :      */
 8515 JanWieck                  179 GIC         107 :     heap_freetuple(tup);
 1539 andres                    180 CBC         107 :     table_close(pg_type_desc, RowExclusiveLock);
                                181                 : 
 2959 alvherre                  182 GIC         107 :     return address;
                                183                 : }
                                184                 : 
                                185                 : /* ----------------------------------------------------------------
                                186                 :  *      TypeCreate
                                187                 :  *
                                188                 :  *      This does all the necessary work needed to define a new type.
                                189                 :  *
                                190                 :  *      Returns the ObjectAddress assigned to the new type.
                                191                 :  *      If newTypeOid is zero (the normal case), a new OID is created;
                                192                 :  *      otherwise we use exactly that OID.
                                193                 :  * ----------------------------------------------------------------
 9770 scrappy                   194 ECB             :  */
                                195                 : ObjectAddress
 5812 tgl                       196 GIC      166616 : TypeCreate(Oid newTypeOid,
                                197                 :            const char *typeName,
                                198                 :            Oid typeNamespace,
                                199                 :            Oid relationOid,     /* only for relation rowtypes */
                                200                 :            char relationKind,   /* ditto */
                                201                 :            Oid ownerId,
                                202                 :            int16 internalSize,
                                203                 :            char typeType,
                                204                 :            char typeCategory,
                                205                 :            bool typePreferred,
                                206                 :            char typDelim,
                                207                 :            Oid inputProcedure,
                                208                 :            Oid outputProcedure,
                                209                 :            Oid receiveProcedure,
                                210                 :            Oid sendProcedure,
                                211                 :            Oid typmodinProcedure,
                                212                 :            Oid typmodoutProcedure,
                                213                 :            Oid analyzeProcedure,
                                214                 :            Oid subscriptProcedure,
                                215                 :            Oid elementType,
                                216                 :            bool isImplicitArray,
                                217                 :            Oid arrayType,
                                218                 :            Oid baseType,
                                219                 :            const char *defaultTypeValue,    /* human-readable rep */
                                220                 :            char *defaultTypeBin,    /* cooked rep */
                                221                 :            bool passedByValue,
                                222                 :            char alignment,
                                223                 :            char storage,
                                224                 :            int32 typeMod,
                                225                 :            int32 typNDims,      /* Array dimensions for baseType */
                                226                 :            bool typeNotNull,
                                227                 :            Oid typeCollation)
                                228                 : {
                                229                 :     Relation    pg_type_desc;
 9344 bruce                     230 ECB             :     Oid         typeObjectId;
                                231                 :     bool        isDependentType;
 7396 tgl                       232 GIC      166616 :     bool        rebuildDeps = false;
                                233                 :     Acl        *typacl;
                                234                 :     HeapTuple   tup;
                                235                 :     bool        nulls[Natts_pg_type];
                                236                 :     bool        replaces[Natts_pg_type];
                                237                 :     Datum       values[Natts_pg_type];
                                238                 :     NameData    name;
                                239                 :     int         i;
                                240                 :     ObjectAddress address;
                                241                 : 
                                242                 :     /*
                                243                 :      * We assume that the caller validated the arguments individually, but did
                                244                 :      * not check for bad combinations.
                                245                 :      *
                                246                 :      * Validate size specifications: either positive (fixed-length) or -1
 5362 tgl                       247 ECB             :      * (varlena) or -2 (cstring).
                                248                 :      */
 7533 tgl                       249 GIC      166616 :     if (!(internalSize > 0 ||
 7533 tgl                       250 EUB             :           internalSize == -1 ||
                                251                 :           internalSize == -2))
 7202 tgl                       252 UIC           0 :         ereport(ERROR,
                                253                 :                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                254                 :                  errmsg("invalid type internal size %d",
 7202 tgl                       255 ECB             :                         internalSize)));
                                256                 : 
 5362 tgl                       257 GIC      166616 :     if (passedByValue)
                                258                 :     {
                                259                 :         /*
                                260                 :          * Pass-by-value types must have a fixed length that is one of the
                                261                 :          * values supported by fetch_att() and store_att_byval(); and the
                                262                 :          * alignment had better agree, too.  All this code must match
 5362 tgl                       263 ECB             :          * access/tupmacs.h!
                                264                 :          */
 5362 tgl                       265 CBC         991 :         if (internalSize == (int16) sizeof(char))
 5362 tgl                       266 EUB             :         {
 1131 tgl                       267 GIC           6 :             if (alignment != TYPALIGN_CHAR)
 5362 tgl                       268 UIC           0 :                 ereport(ERROR,
                                269                 :                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                270                 :                          errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
 5362 tgl                       271 ECB             :                                 alignment, internalSize)));
                                272                 :         }
 5362 tgl                       273 CBC         985 :         else if (internalSize == (int16) sizeof(int16))
 5362 tgl                       274 EUB             :         {
 1131 tgl                       275 GIC           2 :             if (alignment != TYPALIGN_SHORT)
 5362 tgl                       276 UIC           0 :                 ereport(ERROR,
                                277                 :                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                278                 :                          errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
 5362 tgl                       279 ECB             :                                 alignment, internalSize)));
                                280                 :         }
 5362 tgl                       281 CBC         983 :         else if (internalSize == (int16) sizeof(int32))
 5362 tgl                       282 EUB             :         {
 1131 tgl                       283 GIC         656 :             if (alignment != TYPALIGN_INT)
 5362 tgl                       284 UIC           0 :                 ereport(ERROR,
                                285                 :                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                286                 :                          errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
                                287                 :                                 alignment, internalSize)));
 5362 tgl                       288 ECB             :         }
                                289                 : #if SIZEOF_DATUM == 8
 5362 tgl                       290 CBC         327 :         else if (internalSize == (int16) sizeof(Datum))
 5362 tgl                       291 EUB             :         {
 1131 tgl                       292 GIC         327 :             if (alignment != TYPALIGN_DOUBLE)
 5362 tgl                       293 UIC           0 :                 ereport(ERROR,
                                294                 :                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                295                 :                          errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
                                296                 :                                 alignment, internalSize)));
                                297                 :         }
 5362 tgl                       298 EUB             : #endif
                                299                 :         else
 5362 tgl                       300 UIC           0 :             ereport(ERROR,
                                301                 :                     (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                302                 :                      errmsg("internal size %d is invalid for passed-by-value type",
                                303                 :                             internalSize)));
                                304                 :     }
                                305                 :     else
 5362 tgl                       306 ECB             :     {
                                307                 :         /* varlena types must have int align or better */
 1131 tgl                       308 GBC      165625 :         if (internalSize == -1 &&
 1131 tgl                       309 GIC      162517 :             !(alignment == TYPALIGN_INT || alignment == TYPALIGN_DOUBLE))
 5362 tgl                       310 UIC           0 :             ereport(ERROR,
                                311                 :                     (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                312                 :                      errmsg("alignment \"%c\" is invalid for variable-length type",
 2118 tgl                       313 ECB             :                             alignment)));
 5362 tgl                       314 EUB             :         /* cstring must have char alignment */
 1131 tgl                       315 GIC      165625 :         if (internalSize == -2 && !(alignment == TYPALIGN_CHAR))
 5362 tgl                       316 UIC           0 :             ereport(ERROR,
                                317                 :                     (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                318                 :                      errmsg("alignment \"%c\" is invalid for variable-length type",
                                319                 :                             alignment)));
                                320                 :     }
 7885 tgl                       321 ECB             : 
 7533 tgl                       322 EUB             :     /* Only varlena types can be toasted */
 1131 tgl                       323 GIC      166616 :     if (storage != TYPSTORAGE_PLAIN && internalSize != -1)
 7202 tgl                       324 UIC           0 :         ereport(ERROR,
                                325                 :                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                                326                 :                  errmsg("fixed-size types must have storage PLAIN")));
                                327                 : 
                                328                 :     /*
                                329                 :      * This is a dependent type if it's an implicitly-created array type, or
                                330                 :      * if it's a relation rowtype that's not a composite type.  For such types
                                331                 :      * we'll leave the ACL empty, and we'll skip creating some dependency
                                332                 :      * records because there will be a dependency already through the
                                333                 :      * depended-on type or relation.  (Caution: this is closely intertwined
 1612 tgl                       334 ECB             :      * with some behavior in GenerateTypeDependencies.)
                                335                 :      */
 1612 tgl                       336 GIC      247640 :     isDependentType = isImplicitArray ||
                                337           81024 :         (OidIsValid(relationOid) && relationKind != RELKIND_COMPOSITE_TYPE);
                                338                 : 
                                339                 :     /*
 5271 tgl                       340 ECB             :      * initialize arrays needed for heap_form_tuple or heap_modify_tuple
                                341                 :      */
 9345 bruce                     342 CBC     5498328 :     for (i = 0; i < Natts_pg_type; ++i)
 9345 bruce                     343 ECB             :     {
 5271 tgl                       344 CBC     5331712 :         nulls[i] = false;
 5271 tgl                       345 GIC     5331712 :         replaces[i] = true;
 7885                           346         5331712 :         values[i] = (Datum) 0;
                                347                 :     }
                                348                 : 
                                349                 :     /*
 4315 tgl                       350 ECB             :      * insert data values
 9345 bruce                     351                 :      */
 8986 bruce                     352 CBC      166616 :     namestrcpy(&name, typeName);
 4315 tgl                       353          166616 :     values[Anum_pg_type_typname - 1] = NameGetDatum(&name);
                                354          166616 :     values[Anum_pg_type_typnamespace - 1] = ObjectIdGetDatum(typeNamespace);
                                355          166616 :     values[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(ownerId);
                                356          166616 :     values[Anum_pg_type_typlen - 1] = Int16GetDatum(internalSize);
                                357          166616 :     values[Anum_pg_type_typbyval - 1] = BoolGetDatum(passedByValue);
                                358          166616 :     values[Anum_pg_type_typtype - 1] = CharGetDatum(typeType);
                                359          166616 :     values[Anum_pg_type_typcategory - 1] = CharGetDatum(typeCategory);
                                360          166616 :     values[Anum_pg_type_typispreferred - 1] = BoolGetDatum(typePreferred);
                                361          166616 :     values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(true);
                                362          166616 :     values[Anum_pg_type_typdelim - 1] = CharGetDatum(typDelim);
                                363          166616 :     values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(relationOid);
  851                           364          166616 :     values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(subscriptProcedure);
 4315                           365          166616 :     values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(elementType);
                                366          166616 :     values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(arrayType);
                                367          166616 :     values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(inputProcedure);
                                368          166616 :     values[Anum_pg_type_typoutput - 1] = ObjectIdGetDatum(outputProcedure);
                                369          166616 :     values[Anum_pg_type_typreceive - 1] = ObjectIdGetDatum(receiveProcedure);
                                370          166616 :     values[Anum_pg_type_typsend - 1] = ObjectIdGetDatum(sendProcedure);
                                371          166616 :     values[Anum_pg_type_typmodin - 1] = ObjectIdGetDatum(typmodinProcedure);
                                372          166616 :     values[Anum_pg_type_typmodout - 1] = ObjectIdGetDatum(typmodoutProcedure);
                                373          166616 :     values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(analyzeProcedure);
                                374          166616 :     values[Anum_pg_type_typalign - 1] = CharGetDatum(alignment);
                                375          166616 :     values[Anum_pg_type_typstorage - 1] = CharGetDatum(storage);
                                376          166616 :     values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(typeNotNull);
                                377          166616 :     values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(baseType);
                                378          166616 :     values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(typeMod);
 4315 tgl                       379 GIC      166616 :     values[Anum_pg_type_typndims - 1] = Int32GetDatum(typNDims);
                                380          166616 :     values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(typeCollation);
                                381                 : 
                                382                 :     /*
                                383                 :      * initialize the default binary value for this type.  Check for nulls of
 6385 bruce                     384 ECB             :      * course.
 7691                           385                 :      */
 7691 bruce                     386 GIC      166616 :     if (defaultTypeBin)
 4315 tgl                       387 CBC         324 :         values[Anum_pg_type_typdefaultbin - 1] = CStringGetTextDatum(defaultTypeBin);
                                388                 :     else
 4315 tgl                       389 GIC      166292 :         nulls[Anum_pg_type_typdefaultbin - 1] = true;
                                390                 : 
                                391                 :     /*
 8053 bruce                     392 ECB             :      * initialize the default value for this type.
 9345                           393                 :      */
 7885 tgl                       394 GIC      166616 :     if (defaultTypeValue)
 4315 tgl                       395 CBC         333 :         values[Anum_pg_type_typdefault - 1] = CStringGetTextDatum(defaultTypeValue);
                                396                 :     else
 4315 tgl                       397 GIC      166283 :         nulls[Anum_pg_type_typdefault - 1] = true;
                                398                 : 
                                399                 :     /*
 1612 tgl                       400 ECB             :      * Initialize the type's ACL, too.  But dependent types don't get one.
                                401                 :      */
 1612 tgl                       402 GIC      166616 :     if (isDependentType)
 1612 tgl                       403 CBC      164018 :         typacl = NULL;
                                404                 :     else
                                405            2598 :         typacl = get_user_default_acl(OBJECT_TYPE, ownerId,
 1612 tgl                       406 ECB             :                                       typeNamespace);
 4128 peter_e                   407 GIC      166616 :     if (typacl != NULL)
 4128 peter_e                   408 CBC           3 :         values[Anum_pg_type_typacl - 1] = PointerGetDatum(typacl);
                                409                 :     else
 4128 peter_e                   410 GIC      166613 :         nulls[Anum_pg_type_typacl - 1] = true;
                                411                 : 
                                412                 :     /*
                                413                 :      * open pg_type and prepare to insert or update a row.
                                414                 :      *
                                415                 :      * NOTE: updating will not work correctly in bootstrap mode; but we don't
 7681 tgl                       416 ECB             :      * expect to be overwriting any shell types in bootstrap mode.
                                417                 :      */
 1539 andres                    418 CBC      166616 :     pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
                                419                 : 
 4802 rhaas                     420 GIC      166616 :     tup = SearchSysCacheCopy2(TYPENAMENSP,
 4802 rhaas                     421 ECB             :                               CStringGetDatum(typeName),
                                422                 :                               ObjectIdGetDatum(typeNamespace));
 9345 bruce                     423 CBC      166616 :     if (HeapTupleIsValid(tup))
                                424                 :     {
 1601 andres                    425 GIC          95 :         Form_pg_type typform = (Form_pg_type) GETSTRUCT(tup);
                                426                 : 
                                427                 :         /*
                                428                 :          * check that the type is not already defined.  It may exist as a
 6449 tgl                       429 ECB             :          * shell type, however.
 7681 tgl                       430 EUB             :          */
 1601 andres                    431 GIC          95 :         if (typform->typisdefined)
 7202 tgl                       432 UIC           0 :             ereport(ERROR,
                                433                 :                     (errcode(ERRCODE_DUPLICATE_OBJECT),
                                434                 :                      errmsg("type \"%s\" already exists", typeName)));
                                435                 : 
                                436                 :         /*
 6249 tgl                       437 ECB             :          * shell type must have been created by same owner
 6249 tgl                       438 EUB             :          */
 1601 andres                    439 GIC          95 :         if (typform->typowner != ownerId)
 1954 peter_e                   440 UIC           0 :             aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TYPE, typeName);
 6249 tgl                       441 ECB             : 
 5812 tgl                       442 EUB             :         /* trouble if caller wanted to force the OID */
 5812 tgl                       443 GIC          95 :         if (OidIsValid(newTypeOid))
 5812 tgl                       444 LBC           0 :             elog(ERROR, "cannot assign new OID to existing shell type");
                                445                 : 
 1601 andres                    446 GIC          95 :         replaces[Anum_pg_type_oid - 1] = false;
                                447                 : 
                                448                 :         /*
 6249 tgl                       449 ECB             :          * Okay to update existing shell type tuple
                                450                 :          */
 5271 tgl                       451 GIC          95 :         tup = heap_modify_tuple(tup,
                                452                 :                                 RelationGetDescr(pg_type_desc),
                                453                 :                                 values,
                                454                 :                                 nulls,
 5050 bruce                     455 ECB             :                                 replaces);
                                456                 : 
 2259 alvherre                  457 CBC          95 :         CatalogTupleUpdate(pg_type_desc, &tup->t_self, tup);
                                458                 : 
 1601 andres                    459              95 :         typeObjectId = typform->oid;
                                460                 : 
 7396 tgl                       461 GIC          95 :         rebuildDeps = true;     /* get rid of shell type's dependencies */
                                462                 :     }
                                463                 :     else
 9345 bruce                     464 ECB             :     {
 4854                           465                 :         /* Force the OID if requested by caller */
 5812 tgl                       466 GIC      166521 :         if (OidIsValid(newTypeOid))
 1601 andres                    467 CBC       84892 :             typeObjectId = newTypeOid;
                                468                 :         /* Use binary-upgrade override for pg_type.oid, if supplied. */
 3149 bruce                     469           81629 :         else if (IsBinaryUpgrade)
 4854 bruce                     470 EUB             :         {
 3149 bruce                     471 GIC         705 :             if (!OidIsValid(binary_upgrade_next_pg_type_oid))
 3149 bruce                     472 UIC           0 :                 ereport(ERROR,
                                473                 :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 3149 bruce                     474 ECB             :                          errmsg("pg_type OID value not set when in binary upgrade mode")));
                                475                 : 
 1601 andres                    476 GIC         705 :             typeObjectId = binary_upgrade_next_pg_type_oid;
 4854 bruce                     477             705 :             binary_upgrade_next_pg_type_oid = InvalidOid;
                                478                 :         }
 1601 andres                    479 ECB             :         else
                                480                 :         {
 1601 andres                    481 GIC       80924 :             typeObjectId = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId,
                                482                 :                                               Anum_pg_type_oid);
 1601 andres                    483 ECB             :         }
                                484                 : 
 1601 andres                    485 CBC      166521 :         values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typeObjectId);
                                486                 : 
 1601 andres                    487 GIC      166521 :         tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
 1601 andres                    488 ECB             :                               values, nulls);
                                489                 : 
 1601 andres                    490 GIC      166521 :         CatalogTupleInsert(pg_type_desc, tup);
                                491                 :     }
                                492                 : 
                                493                 :     /*
 7570 tgl                       494 ECB             :      * Create dependencies.  We can/must skip this in bootstrap mode.
 7576                           495                 :      */
 7570 tgl                       496 GIC      166616 :     if (!IsBootstrapProcessingMode())
 1129                           497          130340 :         GenerateTypeDependencies(tup,
 1129 tgl                       498 ECB             :                                  pg_type_desc,
                                499                 :                                  (defaultTypeBin ?
 7396 tgl                       500 GIC         324 :                                   stringToNode(defaultTypeBin) :
                                501                 :                                   NULL),
                                502                 :                                  typacl,
                                503                 :                                  relationKind,
                                504                 :                                  isImplicitArray,
                                505                 :                                  isDependentType,
                                506                 :                                  true,  /* make extension dependency */
                                507                 :                                  rebuildDeps);
 7429 bruce                     508 ECB             : 
                                509                 :     /* Post creation hook for new type */
 3686 rhaas                     510 CBC      166615 :     InvokeObjectPostCreateHook(TypeRelationId, typeObjectId, 0);
                                511                 : 
 2959 alvherre                  512 GIC      166615 :     ObjectAddressSet(address, TypeRelationId, typeObjectId);
                                513                 : 
                                514                 :     /*
 7429 bruce                     515 ECB             :      * finish up
                                516                 :      */
 1539 andres                    517 CBC      166615 :     table_close(pg_type_desc, RowExclusiveLock);
                                518                 : 
 2959 alvherre                  519 GIC      166615 :     return address;
                                520                 : }
                                521                 : 
                                522                 : /*
                                523                 :  * GenerateTypeDependencies: build the dependencies needed for a type
                                524                 :  *
                                525                 :  * Most of what this function needs to know about the type is passed as the
                                526                 :  * new pg_type row, typeTuple.  We make callers pass the pg_type Relation
                                527                 :  * as well, so that we have easy access to a tuple descriptor for the row.
                                528                 :  *
                                529                 :  * While this is able to extract the defaultExpr and typacl from the tuple,
                                530                 :  * doing so is relatively expensive, and callers may have those values at
                                531                 :  * hand already.  Pass those if handy, otherwise pass NULL.  (typacl is really
                                532                 :  * "Acl *", but we declare it "void *" to avoid including acl.h in pg_type.h.)
                                533                 :  *
                                534                 :  * relationKind and isImplicitArray are likewise somewhat expensive to deduce
                                535                 :  * from the tuple, so we make callers pass those (they're not optional).
                                536                 :  *
                                537                 :  * isDependentType is true if this is an implicit array or relation rowtype;
                                538                 :  * that means it doesn't need its own dependencies on owner etc.
                                539                 :  *
                                540                 :  * We make an extension-membership dependency if we're in an extension
                                541                 :  * script and makeExtensionDep is true (and isDependentType isn't true).
                                542                 :  * makeExtensionDep should be true when creating a new type or replacing a
                                543                 :  * shell type, but not for ALTER TYPE on an existing type.  Passing false
                                544                 :  * causes the type's extension membership to be left alone.
                                545                 :  *
                                546                 :  * rebuild should be true if this is a pre-existing type.  We will remove
                                547                 :  * existing dependencies and rebuild them from scratch.  This is needed for
                                548                 :  * ALTER TYPE, and also when replacing a shell type.  We don't remove any
                                549                 :  * existing extension dependency, though; hence, if makeExtensionDep is also
                                550                 :  * true and we're in an extension script, an error will occur unless the
                                551                 :  * type already belongs to the current extension.  That's the behavior we
                                552                 :  * want when replacing a shell type, which is the only case where both flags
                                553                 :  * are true.
 7396 tgl                       554 ECB             :  */
                                555                 : void
 1129 tgl                       556 GIC      130163 : GenerateTypeDependencies(HeapTuple typeTuple,
                                557                 :                          Relation typeCatalog,
                                558                 :                          Node *defaultExpr,
                                559                 :                          void *typacl,
                                560                 :                          char relationKind, /* only for relation rowtypes */
                                561                 :                          bool isImplicitArray,
                                562                 :                          bool isDependentType,
                                563                 :                          bool makeExtensionDep,
 7429 bruce                     564 ECB             :                          bool rebuild)
                                565                 : {
 1129 tgl                       566 GIC      130163 :     Form_pg_type typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
                                567          130163 :     Oid         typeObjectId = typeForm->oid;
                                568                 :     Datum       datum;
                                569                 :     bool        isNull;
                                570                 :     ObjectAddress myself,
                                571                 :                 referenced;
                                572                 :     ObjectAddresses *addrs_normal;
 7429 bruce                     573 ECB             : 
                                574                 :     /* Extract defaultExpr if caller didn't pass it */
 1129 tgl                       575 CBC      130163 :     if (defaultExpr == NULL)
                                576                 :     {
                                577          129835 :         datum = heap_getattr(typeTuple, Anum_pg_type_typdefaultbin,
 1129 tgl                       578 EUB             :                              RelationGetDescr(typeCatalog), &isNull);
 1129 tgl                       579 GIC      129835 :         if (!isNull)
 1129 tgl                       580 UIC           0 :             defaultExpr = stringToNode(TextDatumGetCString(datum));
 1129 tgl                       581 ECB             :     }
                                582                 :     /* Extract typacl if caller didn't pass it */
 1129 tgl                       583 CBC      130163 :     if (typacl == NULL)
                                584                 :     {
                                585          130160 :         datum = heap_getattr(typeTuple, Anum_pg_type_typacl,
 1129 tgl                       586 EUB             :                              RelationGetDescr(typeCatalog), &isNull);
 1129 tgl                       587 GIC      130160 :         if (!isNull)
 1129 tgl                       588 UIC           0 :             typacl = DatumGetAclPCopy(datum);
                                589                 :     }
 1129 tgl                       590 ECB             : 
                                591                 :     /* If rebuild, first flush old dependencies, except extension deps */
 7429 bruce                     592 CBC      130163 :     if (rebuild)
 6485 tgl                       593 ECB             :     {
 4443 tgl                       594 GIC         135 :         deleteDependencyRecordsFor(TypeRelationId, typeObjectId, true);
 5190                           595             135 :         deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId, 0);
 6485 tgl                       596 ECB             :     }
                                597                 : 
 1014 michael                   598 GIC      130163 :     ObjectAddressSet(myself, TypeRelationId, typeObjectId);
                                599                 : 
                                600                 :     /*
                                601                 :      * Make dependencies on namespace, owner, ACL, extension.
                                602                 :      *
                                603                 :      * Skip these for a dependent type, since it will have such dependencies
                                604                 :      * indirectly through its depended-on type or relation.
                                605                 :      */
  946 michael                   606 ECB             : 
                                607                 :     /* placeholder for all normal dependencies */
  946 michael                   608 CBC      130163 :     addrs_normal = new_object_addresses();
                                609                 : 
 1612 tgl                       610          130163 :     if (!isDependentType)
                                611                 :     {
 1014 michael                   612            2742 :         ObjectAddressSet(referenced, NamespaceRelationId,
                                613                 :                          typeForm->typnamespace);
 7429 bruce                     614            2742 :         recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
                                615                 : 
 1612 tgl                       616 GIC        2742 :         recordDependencyOnOwner(TypeRelationId, typeObjectId,
 1612 tgl                       617 ECB             :                                 typeForm->typowner);
                                618                 : 
 1612 tgl                       619 GIC        2742 :         recordDependencyOnNewAcl(TypeRelationId, typeObjectId, 0,
 1612 tgl                       620 ECB             :                                  typeForm->typowner, typacl);
 7429 bruce                     621                 : 
  600 tgl                       622 GIC        2742 :         if (makeExtensionDep)
                                623            2705 :             recordDependencyOnCurrentExtension(&myself, rebuild);
                                624                 :     }
 4278 tgl                       625 ECB             : 
                                626                 :     /* Normal dependencies on the I/O and support functions */
 1612 tgl                       627 CBC      130162 :     if (OidIsValid(typeForm->typinput))
 7396 tgl                       628 ECB             :     {
 1014 michael                   629 GIC      130162 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typinput);
  946                           630          130162 :         add_exact_object_address(&referenced, addrs_normal);
 7396 tgl                       631 ECB             :     }
                                632                 : 
 1612 tgl                       633 CBC      130162 :     if (OidIsValid(typeForm->typoutput))
 7396 tgl                       634 ECB             :     {
 1014 michael                   635 GIC      130162 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typoutput);
  946                           636          130162 :         add_exact_object_address(&referenced, addrs_normal);
 7396 tgl                       637 ECB             :     }
                                638                 : 
 1612 tgl                       639 CBC      130162 :     if (OidIsValid(typeForm->typreceive))
 7276 tgl                       640 ECB             :     {
 1014 michael                   641 GIC      129967 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typreceive);
  946                           642          129967 :         add_exact_object_address(&referenced, addrs_normal);
 7276 tgl                       643 ECB             :     }
                                644                 : 
 1612 tgl                       645 CBC      130162 :     if (OidIsValid(typeForm->typsend))
 7276 tgl                       646 ECB             :     {
 1014 michael                   647 GIC      129961 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsend);
  946                           648          129961 :         add_exact_object_address(&referenced, addrs_normal);
 7276 tgl                       649 ECB             :     }
                                650                 : 
 1612 tgl                       651 CBC      130162 :     if (OidIsValid(typeForm->typmodin))
 5944 tgl                       652 ECB             :     {
 1014 michael                   653 GIC          14 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodin);
  946                           654              14 :         add_exact_object_address(&referenced, addrs_normal);
 5944 tgl                       655 ECB             :     }
                                656                 : 
 1612 tgl                       657 CBC      130162 :     if (OidIsValid(typeForm->typmodout))
 5944 tgl                       658 ECB             :     {
 1014 michael                   659 GIC          14 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodout);
  946                           660              14 :         add_exact_object_address(&referenced, addrs_normal);
 5944 tgl                       661 ECB             :     }
                                662                 : 
 1612 tgl                       663 CBC      130162 :     if (OidIsValid(typeForm->typanalyze))
 6996 tgl                       664 ECB             :     {
 1014 michael                   665 GIC       65213 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typanalyze);
  946                           666           65213 :         add_exact_object_address(&referenced, addrs_normal);
  946 michael                   667 ECB             :     }
                                668                 : 
  851 tgl                       669 CBC      130162 :     if (OidIsValid(typeForm->typsubscript))
  851 tgl                       670 ECB             :     {
  851 tgl                       671 GIC       65020 :         ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsubscript);
                                672           65020 :         add_exact_object_address(&referenced, addrs_normal);
                                673                 :     }
  851 tgl                       674 ECB             : 
                                675                 :     /* Normal dependency from a domain to its base type. */
  946 michael                   676 CBC      130162 :     if (OidIsValid(typeForm->typbasetype))
  946 michael                   677 ECB             :     {
  946 michael                   678 GIC        1863 :         ObjectAddressSet(referenced, TypeRelationId, typeForm->typbasetype);
                                679            1863 :         add_exact_object_address(&referenced, addrs_normal);
                                680                 :     }
                                681                 : 
                                682                 :     /*
                                683                 :      * Normal dependency from a domain to its collation.  We know the default
  946 michael                   684 ECB             :      * collation is pinned, so don't bother recording it.
                                685                 :      */
  946 michael                   686 GIC      130162 :     if (OidIsValid(typeForm->typcollation) &&
  946 michael                   687 CBC        2000 :         typeForm->typcollation != DEFAULT_COLLATION_OID)
  946 michael                   688 ECB             :     {
  946 michael                   689 GIC        1850 :         ObjectAddressSet(referenced, CollationRelationId, typeForm->typcollation);
                                690            1850 :         add_exact_object_address(&referenced, addrs_normal);
 6996 tgl                       691 ECB             :     }
                                692                 : 
  946 michael                   693 GIC      130162 :     record_object_address_dependencies(&myself, addrs_normal, DEPENDENCY_NORMAL);
                                694          130162 :     free_object_addresses(addrs_normal);
  946 michael                   695 ECB             : 
                                696                 :     /* Normal dependency on the default expression. */
  946 michael                   697 GIC      130162 :     if (defaultExpr)
                                698             328 :         recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
                                699                 : 
                                700                 :     /*
                                701                 :      * If the type is a rowtype for a relation, mark it as internally
                                702                 :      * dependent on the relation, *unless* it is a stand-alone composite type
                                703                 :      * relation. For the latter case, we have to reverse the dependency.
                                704                 :      *
                                705                 :      * In the former case, this allows the type to be auto-dropped when the
                                706                 :      * relation is, and not otherwise. And in the latter, of course we get the
 6385 bruce                     707 ECB             :      * opposite effect.
                                708                 :      */
 1612 tgl                       709 CBC      130162 :     if (OidIsValid(typeForm->typrelid))
                                710                 :     {
 1014 michael                   711           62724 :         ObjectAddressSet(referenced, RelationRelationId, typeForm->typrelid);
 7429 bruce                     712 ECB             : 
 7429 bruce                     713 GIC       62724 :         if (relationKind != RELKIND_COMPOSITE_TYPE)
 7429 bruce                     714 CBC       62415 :             recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
                                715                 :         else
 7429 bruce                     716 GIC         309 :             recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
                                717                 :     }
                                718                 : 
                                719                 :     /*
                                720                 :      * If the type is an implicitly-created array type, mark it as internally
                                721                 :      * dependent on the element type.  Otherwise, if it has an element type,
 5812 tgl                       722 ECB             :      * the dependency is a normal one.
                                723                 :      */
 1612 tgl                       724 CBC      130162 :     if (OidIsValid(typeForm->typelem))
 7429 bruce                     725 ECB             :     {
 1014 michael                   726 GIC       65010 :         ObjectAddressSet(referenced, TypeRelationId, typeForm->typelem);
 5812 tgl                       727           65010 :         recordDependencyOn(&myself, &referenced,
 2118 tgl                       728 ECB             :                            isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL);
                                729                 :     }
 9770 scrappy                   730 GIC      130162 : }
                                731                 : 
                                732                 : /*
                                733                 :  * RenameTypeInternal
                                734                 :  *      This renames a type, as well as any associated array type.
                                735                 :  *
                                736                 :  * Caller must have already checked privileges.
                                737                 :  *
                                738                 :  * Currently this is used for renaming table rowtypes and for
                                739                 :  * ALTER TYPE RENAME TO command.
 9770 scrappy                   740 ECB             :  */
                                741                 : void
 5499 tgl                       742 GIC         164 : RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
                                743                 : {
                                744                 :     Relation    pg_type_desc;
                                745                 :     HeapTuple   tuple;
                                746                 :     Form_pg_type typ;
                                747                 :     Oid         arrayOid;
 2144 tgl                       748 ECB             :     Oid         oldTypeOid;
                                749                 : 
 1539 andres                    750 CBC         164 :     pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
 9345 bruce                     751 ECB             : 
 4802 rhaas                     752 GBC         164 :     tuple = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid));
 8179 tgl                       753 CBC         164 :     if (!HeapTupleIsValid(tuple))
 5811 tgl                       754 UIC           0 :         elog(ERROR, "cache lookup failed for type %u", typeOid);
 5811 tgl                       755 GIC         164 :     typ = (Form_pg_type) GETSTRUCT(tuple);
 5811 tgl                       756 ECB             : 
                                757                 :     /* We are not supposed to be changing schemas here */
 5811 tgl                       758 CBC         164 :     Assert(typeNamespace == typ->typnamespace);
                                759                 : 
 5811 tgl                       760 GIC         164 :     arrayOid = typ->typarray;
 5811 tgl                       761 ECB             : 
                                762                 :     /* Check for a conflicting type name. */
 1601 andres                    763 GIC         164 :     oldTypeOid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
                                764                 :                                  CStringGetDatum(newTypeName),
                                765                 :                                  ObjectIdGetDatum(typeNamespace));
                                766                 : 
                                767                 :     /*
                                768                 :      * If there is one, see if it's an autogenerated array type, and if so
                                769                 :      * rename it out of the way.  (But we must skip that for a shell type
                                770                 :      * because moveArrayTypeName will do the wrong thing in that case.)
                                771                 :      * Otherwise, we can at least give a more friendly error than unique-index
 2144 tgl                       772 ECB             :      * violation.
                                773                 :      */
 2144 tgl                       774 CBC         164 :     if (OidIsValid(oldTypeOid))
 2144 tgl                       775 ECB             :     {
 2144 tgl                       776 GIC          12 :         if (get_typisdefined(oldTypeOid) &&
                                777               6 :             moveArrayTypeName(oldTypeOid, newTypeName, typeNamespace))
 2144 tgl                       778 EUB             :              /* successfully dodged the problem */ ;
                                779                 :         else
 2144 tgl                       780 UIC           0 :             ereport(ERROR,
                                781                 :                     (errcode(ERRCODE_DUPLICATE_OBJECT),
                                782                 :                      errmsg("type \"%s\" already exists", newTypeName)));
                                783                 :     }
 8986 bruce                     784 ECB             : 
                                785                 :     /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
 5811 tgl                       786 CBC         164 :     namestrcpy(&(typ->typname), newTypeName);
                                787                 : 
 2259 alvherre                  788             164 :     CatalogTupleUpdate(pg_type_desc, &tuple->t_self, tuple);
                                789                 : 
 3675 rhaas                     790             164 :     InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0);
 3675 rhaas                     791 ECB             : 
 8179 tgl                       792 GIC         164 :     heap_freetuple(tuple);
 1539 andres                    793             164 :     table_close(pg_type_desc, RowExclusiveLock);
                                794                 : 
                                795                 :     /*
                                796                 :      * If the type has an array type, recurse to handle that.  But we don't
                                797                 :      * need to do anything more if we already renamed that array type above
 2144 tgl                       798 ECB             :      * (which would happen when, eg, renaming "foo" to "_foo").
                                799                 :      */
 2144 tgl                       800 CBC         164 :     if (OidIsValid(arrayOid) && arrayOid != oldTypeOid)
                                801                 :     {
 5624 bruce                     802              74 :         char       *arrname = makeArrayTypeName(newTypeName, typeNamespace);
 5811 tgl                       803 ECB             : 
 5499 tgl                       804 GIC          74 :         RenameTypeInternal(arrayOid, arrname, typeNamespace);
 5811 tgl                       805 CBC          74 :         pfree(arrname);
                                806                 :     }
 9770 scrappy                   807 GIC         164 : }
                                808                 : 
                                809                 : 
                                810                 : /*
                                811                 :  * makeArrayTypeName
                                812                 :  *    - given a base type name, make an array type name for it
                                813                 :  *
                                814                 :  * the caller is responsible for pfreeing the result
 9770 scrappy                   815 ECB             :  */
                                816                 : char *
 5812 tgl                       817 GIC       83390 : makeArrayTypeName(const char *typeName, Oid typeNamespace)
 9770 scrappy                   818 ECB             : {
                                819                 :     char       *arr_name;
  257 tgl                       820 GNC       83390 :     int         pass = 0;
                                821                 :     char        suffix[NAMEDATALEN];
                                822                 : 
                                823                 :     /*
                                824                 :      * Per ancient Postgres tradition, array type names are made by prepending
                                825                 :      * an underscore to the base type name.  Much client code knows that
                                826                 :      * convention, so don't muck with it.  However, the tradition is less
                                827                 :      * clear about what to do in the corner cases where the resulting name is
                                828                 :      * too long or conflicts with an existing name.  Our current rules are (1)
                                829                 :      * truncate the base name on the right as needed, and (2) if there is a
                                830                 :      * conflict, append another underscore and some digits chosen to make it
                                831                 :      * unique.  This is similar to what ChooseRelationName() does.
                                832                 :      *
                                833                 :      * The actual name generation can be farmed out to makeObjectName() by
                                834                 :      * giving it an empty first name component.
                                835                 :      */
                                836                 : 
                                837                 :     /* First, try with no numeric suffix */
                                838           83390 :     arr_name = makeObjectName("", typeName, NULL);
                                839                 : 
                                840                 :     for (;;)
                                841                 :     {
                                842           83400 :         if (!SearchSysCacheExists2(TYPENAMENSP,
                                843                 :                                    CStringGetDatum(arr_name),
                                844                 :                                    ObjectIdGetDatum(typeNamespace)))
                                845           83390 :             break;
                                846                 : 
                                847                 :         /* That attempt conflicted.  Prepare a new name with some digits. */
                                848              10 :         pfree(arr_name);
                                849              10 :         snprintf(suffix, sizeof(suffix), "%d", ++pass);
                                850              10 :         arr_name = makeObjectName("", typeName, suffix);
                                851                 :     }
                                852                 : 
                                853           83390 :     return arr_name;
                                854                 : }
                                855                 : 
                                856                 : 
                                857                 : /*
                                858                 :  * moveArrayTypeName
                                859                 :  *    - try to reassign an array type name that the user wants to use.
                                860                 :  *
 5811 tgl                       861 ECB             :  * The given type name has been discovered to already exist (with the given
                                862                 :  * OID).  If it is an autogenerated array type, change the array type's name
                                863                 :  * to not conflict.  This allows the user to create type "foo" followed by
                                864                 :  * type "_foo" without problems.  (Of course, there are race conditions if
                                865                 :  * two backends try to create similarly-named types concurrently, but the
                                866                 :  * worst that can happen is an unnecessary failure --- anything we do here
                                867                 :  * will be rolled back if the type creation fails due to conflicting names.)
                                868                 :  *
                                869                 :  * Note that this must be called *before* calling makeArrayTypeName to
                                870                 :  * determine the new type's own array type name; else the latter will
                                871                 :  * certainly pick the same name.
                                872                 :  *
 2062 peter_e                   873                 :  * Returns true if successfully moved the type, false if not.
                                874                 :  *
                                875                 :  * We also return true if the given type is a shell type.  In this case
 5811 tgl                       876                 :  * the type has not been renamed out of the way, but nonetheless it can
                                877                 :  * be expected that TypeCreate will succeed.  This behavior is convenient
                                878                 :  * for most callers --- those that need to distinguish the shell-type case
                                879                 :  * must do their own typisdefined test.
                                880                 :  */
                                881                 : bool
 5811 tgl                       882 GIC          20 : moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
                                883                 : {
                                884                 :     Oid         elemOid;
                                885                 :     char       *newname;
                                886                 : 
                                887                 :     /* We need do nothing if it's a shell type. */
                                888              20 :     if (!get_typisdefined(typeOid))
                                889               1 :         return true;
                                890                 : 
                                891                 :     /* Can't change it if it's not an autogenerated array type. */
                                892              19 :     elemOid = get_element_type(typeOid);
                                893              32 :     if (!OidIsValid(elemOid) ||
                                894              13 :         get_array_type(elemOid) != typeOid)
                                895               6 :         return false;
                                896                 : 
                                897                 :     /*
                                898                 :      * OK, use makeArrayTypeName to pick an unused modification of the name.
                                899                 :      * Note that since makeArrayTypeName is an iterative process, this will
                                900                 :      * produce a name that it might have produced the first time, had the
                                901                 :      * conflicting type we are about to create already existed.
                                902                 :      */
                                903              13 :     newname = makeArrayTypeName(typeName, typeNamespace);
                                904                 : 
 5811 tgl                       905 ECB             :     /* Apply the rename */
 5499 tgl                       906 GIC          13 :     RenameTypeInternal(typeOid, newname, typeNamespace);
                                907                 : 
                                908                 :     /*
                                909                 :      * We must bump the command counter so that any subsequent use of
                                910                 :      * makeArrayTypeName sees what we just did and doesn't pick the same name.
 5811 tgl                       911 ECB             :      */
 5811 tgl                       912 CBC          13 :     CommandCounterIncrement();
                                913                 : 
 5811 tgl                       914 GIC          13 :     pfree(newname);
 5811 tgl                       915 ECB             : 
 5811 tgl                       916 CBC          13 :     return true;
 5811 tgl                       917 ECB             : }
  840 akorotkov                 918                 : 
                                919                 : 
                                920                 : /*
                                921                 :  * makeMultirangeTypeName
                                922                 :  *    - given a range type name, make a multirange type name for it
                                923                 :  *
                                924                 :  * caller is responsible for pfreeing the result
                                925                 :  */
                                926                 : char *
  840 akorotkov                 927 GIC          60 : makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
                                928                 : {
  840 akorotkov                 929 ECB             :     char       *buf;
                                930                 :     char       *rangestr;
                                931                 : 
                                932                 :     /*
                                933                 :      * If the range type name contains "range" then change that to
                                934                 :      * "multirange". Otherwise add "_multirange" to the end.
                                935                 :      */
  840 akorotkov                 936 GIC          60 :     rangestr = strstr(rangeTypeName, "range");
  840 akorotkov                 937 CBC          60 :     if (rangestr)
                                938                 :     {
                                939              51 :         char       *prefix = pnstrdup(rangeTypeName, rangestr - rangeTypeName);
                                940                 : 
  840 akorotkov                 941 GIC          51 :         buf = psprintf("%s%s%s", prefix, "multi", rangestr);
                                942                 :     }
                                943                 :     else
                                944               9 :         buf = psprintf("%s_multirange", pnstrdup(rangeTypeName, NAMEDATALEN - 12));
                                945                 : 
                                946                 :     /* clip it at NAMEDATALEN-1 bytes */
                                947              60 :     buf[pg_mbcliplen(buf, strlen(buf), NAMEDATALEN - 1)] = '\0';
                                948                 : 
                                949              60 :     if (SearchSysCacheExists2(TYPENAMENSP,
  840 akorotkov                 950 ECB             :                               CStringGetDatum(buf),
                                951                 :                               ObjectIdGetDatum(typeNamespace)))
  840 akorotkov                 952 GIC           6 :         ereport(ERROR,
                                953                 :                 (errcode(ERRCODE_DUPLICATE_OBJECT),
                                954                 :                  errmsg("type \"%s\" already exists", buf),
                                955                 :                  errdetail("Failed while creating a multirange type for type \"%s\".", rangeTypeName),
                                956                 :                  errhint("You can manually specify a multirange type name using the \"multirange_type_name\" attribute.")));
                                957                 : 
                                958              54 :     return pstrdup(buf);
  840 akorotkov                 959 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a