1
/*-------------------------------------------------------------------------
4
* routines to support manipulation of the pg_type relation
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/catalog/pg_type.c
13
*-------------------------------------------------------------------------
17
#include "access/heapam.h"
18
#include "access/xact.h"
19
#include "catalog/dependency.h"
20
#include "catalog/indexing.h"
21
#include "catalog/objectaccess.h"
22
#include "catalog/pg_collation.h"
23
#include "catalog/pg_namespace.h"
24
#include "catalog/pg_proc.h"
25
#include "catalog/pg_type.h"
26
#include "catalog/pg_type_fn.h"
27
#include "commands/typecmds.h"
28
#include "miscadmin.h"
29
#include "parser/scansup.h"
30
#include "utils/acl.h"
31
#include "utils/builtins.h"
32
#include "utils/fmgroids.h"
33
#include "utils/lsyscache.h"
34
#include "utils/rel.h"
35
#include "utils/syscache.h"
37
/* Potentially set by contrib/pg_upgrade_support functions */
38
Oid binary_upgrade_next_pg_type_oid = InvalidOid;
40
/* ----------------------------------------------------------------
43
* This procedure inserts a "shell" tuple into the pg_type relation.
44
* The type tuple inserted has valid but dummy values, and its
45
* "typisdefined" field is false indicating it's not really defined.
47
* This is used so that a tuple exists in the catalogs. The I/O
48
* functions for the type will link to this tuple. When the full
49
* CREATE TYPE command is issued, the bogus values will be replaced
50
* with correct ones, and "typisdefined" will be set to true.
51
* ----------------------------------------------------------------
54
TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
56
Relation pg_type_desc;
60
Datum values[Natts_pg_type];
61
bool nulls[Natts_pg_type];
65
Assert(PointerIsValid(typeName));
70
pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);
71
tupDesc = pg_type_desc->rd_att;
74
* initialize our *nulls and *values arrays
76
for (i = 0; i < Natts_pg_type; ++i)
79
values[i] = (Datum) NULL; /* redundant, but safe */
83
* initialize *values with the type name and dummy values
85
* The representational details are the same as int4 ... it doesn't really
86
* matter what they are so long as they are consistent. Also note that we
87
* give it typtype = TYPTYPE_PSEUDO as extra insurance that it won't be
88
* mistaken for a usable type.
91
namestrcpy(&name, typeName);
92
values[i++] = NameGetDatum(&name); /* typname */
93
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
94
values[i++] = ObjectIdGetDatum(ownerId); /* typowner */
95
values[i++] = Int16GetDatum(sizeof(int4)); /* typlen */
96
values[i++] = BoolGetDatum(true); /* typbyval */
97
values[i++] = CharGetDatum(TYPTYPE_PSEUDO); /* typtype */
98
values[i++] = CharGetDatum(TYPCATEGORY_PSEUDOTYPE); /* typcategory */
99
values[i++] = BoolGetDatum(false); /* typispreferred */
100
values[i++] = BoolGetDatum(false); /* typisdefined */
101
values[i++] = CharGetDatum(DEFAULT_TYPDELIM); /* typdelim */
102
values[i++] = ObjectIdGetDatum(InvalidOid); /* typrelid */
103
values[i++] = ObjectIdGetDatum(InvalidOid); /* typelem */
104
values[i++] = ObjectIdGetDatum(InvalidOid); /* typarray */
105
values[i++] = ObjectIdGetDatum(F_SHELL_IN); /* typinput */
106
values[i++] = ObjectIdGetDatum(F_SHELL_OUT); /* typoutput */
107
values[i++] = ObjectIdGetDatum(InvalidOid); /* typreceive */
108
values[i++] = ObjectIdGetDatum(InvalidOid); /* typsend */
109
values[i++] = ObjectIdGetDatum(InvalidOid); /* typmodin */
110
values[i++] = ObjectIdGetDatum(InvalidOid); /* typmodout */
111
values[i++] = ObjectIdGetDatum(InvalidOid); /* typanalyze */
112
values[i++] = CharGetDatum('i'); /* typalign */
113
values[i++] = CharGetDatum('p'); /* typstorage */
114
values[i++] = BoolGetDatum(false); /* typnotnull */
115
values[i++] = ObjectIdGetDatum(InvalidOid); /* typbasetype */
116
values[i++] = Int32GetDatum(-1); /* typtypmod */
117
values[i++] = Int32GetDatum(0); /* typndims */
118
values[i++] = ObjectIdGetDatum(InvalidOid); /* typcollation */
119
nulls[i++] = true; /* typdefaultbin */
120
nulls[i++] = true; /* typdefault */
123
* create a new type tuple
125
tup = heap_form_tuple(tupDesc, values, nulls);
127
/* Use binary-upgrade override for pg_type.oid, if supplied. */
128
if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_type_oid))
130
HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
131
binary_upgrade_next_pg_type_oid = InvalidOid;
135
* insert the tuple in the relation and get the tuple's oid.
137
typoid = simple_heap_insert(pg_type_desc, tup);
139
CatalogUpdateIndexes(pg_type_desc, tup);
142
* Create dependencies. We can/must skip this in bootstrap mode.
144
if (!IsBootstrapProcessingMode())
145
GenerateTypeDependencies(typeNamespace,
164
/* Post creation hook for new shell type */
165
InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typoid, 0);
168
* clean up and return the type-oid
171
heap_close(pg_type_desc, RowExclusiveLock);
176
/* ----------------------------------------------------------------
179
* This does all the necessary work needed to define a new type.
181
* Returns the OID assigned to the new type. If newTypeOid is
182
* zero (the normal case), a new OID is created; otherwise we
183
* use exactly that OID.
184
* ----------------------------------------------------------------
187
TypeCreate(Oid newTypeOid,
188
const char *typeName,
190
Oid relationOid, /* only for relation rowtypes */
191
char relationKind, /* ditto */
200
Oid receiveProcedure,
202
Oid typmodinProcedure,
203
Oid typmodoutProcedure,
204
Oid analyzeProcedure,
206
bool isImplicitArray,
209
const char *defaultTypeValue, /* human readable rep */
210
char *defaultTypeBin, /* cooked rep */
215
int32 typNDims, /* Array dimensions for baseType */
219
Relation pg_type_desc;
221
bool rebuildDeps = false;
223
bool nulls[Natts_pg_type];
224
bool replaces[Natts_pg_type];
225
Datum values[Natts_pg_type];
230
* We assume that the caller validated the arguments individually, but did
231
* not check for bad combinations.
233
* Validate size specifications: either positive (fixed-length) or -1
234
* (varlena) or -2 (cstring).
236
if (!(internalSize > 0 ||
237
internalSize == -1 ||
240
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
241
errmsg("invalid type internal size %d",
247
* Pass-by-value types must have a fixed length that is one of the
248
* values supported by fetch_att() and store_att_byval(); and the
249
* alignment had better agree, too. All this code must match
252
if (internalSize == (int16) sizeof(char))
254
if (alignment != 'c')
256
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
257
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
258
alignment, internalSize)));
260
else if (internalSize == (int16) sizeof(int16))
262
if (alignment != 's')
264
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
265
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
266
alignment, internalSize)));
268
else if (internalSize == (int16) sizeof(int32))
270
if (alignment != 'i')
272
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
273
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
274
alignment, internalSize)));
276
#if SIZEOF_DATUM == 8
277
else if (internalSize == (int16) sizeof(Datum))
279
if (alignment != 'd')
281
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
282
errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
283
alignment, internalSize)));
288
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
289
errmsg("internal size %d is invalid for passed-by-value type",
294
/* varlena types must have int align or better */
295
if (internalSize == -1 && !(alignment == 'i' || alignment == 'd'))
297
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
298
errmsg("alignment \"%c\" is invalid for variable-length type",
300
/* cstring must have char alignment */
301
if (internalSize == -2 && !(alignment == 'c'))
303
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
304
errmsg("alignment \"%c\" is invalid for variable-length type",
308
/* Only varlena types can be toasted */
309
if (storage != 'p' && internalSize != -1)
311
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
312
errmsg("fixed-size types must have storage PLAIN")));
315
* initialize arrays needed for heap_form_tuple or heap_modify_tuple
317
for (i = 0; i < Natts_pg_type; ++i)
321
values[i] = (Datum) 0;
325
* initialize the *values information
328
namestrcpy(&name, typeName);
329
values[i++] = NameGetDatum(&name); /* typname */
330
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
331
values[i++] = ObjectIdGetDatum(ownerId); /* typowner */
332
values[i++] = Int16GetDatum(internalSize); /* typlen */
333
values[i++] = BoolGetDatum(passedByValue); /* typbyval */
334
values[i++] = CharGetDatum(typeType); /* typtype */
335
values[i++] = CharGetDatum(typeCategory); /* typcategory */
336
values[i++] = BoolGetDatum(typePreferred); /* typispreferred */
337
values[i++] = BoolGetDatum(true); /* typisdefined */
338
values[i++] = CharGetDatum(typDelim); /* typdelim */
339
values[i++] = ObjectIdGetDatum(relationOid); /* typrelid */
340
values[i++] = ObjectIdGetDatum(elementType); /* typelem */
341
values[i++] = ObjectIdGetDatum(arrayType); /* typarray */
342
values[i++] = ObjectIdGetDatum(inputProcedure); /* typinput */
343
values[i++] = ObjectIdGetDatum(outputProcedure); /* typoutput */
344
values[i++] = ObjectIdGetDatum(receiveProcedure); /* typreceive */
345
values[i++] = ObjectIdGetDatum(sendProcedure); /* typsend */
346
values[i++] = ObjectIdGetDatum(typmodinProcedure); /* typmodin */
347
values[i++] = ObjectIdGetDatum(typmodoutProcedure); /* typmodout */
348
values[i++] = ObjectIdGetDatum(analyzeProcedure); /* typanalyze */
349
values[i++] = CharGetDatum(alignment); /* typalign */
350
values[i++] = CharGetDatum(storage); /* typstorage */
351
values[i++] = BoolGetDatum(typeNotNull); /* typnotnull */
352
values[i++] = ObjectIdGetDatum(baseType); /* typbasetype */
353
values[i++] = Int32GetDatum(typeMod); /* typtypmod */
354
values[i++] = Int32GetDatum(typNDims); /* typndims */
355
values[i++] = ObjectIdGetDatum(typeCollation); /* typcollation */
358
* initialize the default binary value for this type. Check for nulls of
362
values[i] = CStringGetTextDatum(defaultTypeBin);
365
i++; /* typdefaultbin */
368
* initialize the default value for this type.
370
if (defaultTypeValue)
371
values[i] = CStringGetTextDatum(defaultTypeValue);
374
i++; /* typdefault */
377
* open pg_type and prepare to insert or update a row.
379
* NOTE: updating will not work correctly in bootstrap mode; but we don't
380
* expect to be overwriting any shell types in bootstrap mode.
382
pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);
384
tup = SearchSysCacheCopy2(TYPENAMENSP,
385
CStringGetDatum(typeName),
386
ObjectIdGetDatum(typeNamespace));
387
if (HeapTupleIsValid(tup))
390
* check that the type is not already defined. It may exist as a
391
* shell type, however.
393
if (((Form_pg_type) GETSTRUCT(tup))->typisdefined)
395
(errcode(ERRCODE_DUPLICATE_OBJECT),
396
errmsg("type \"%s\" already exists", typeName)));
399
* shell type must have been created by same owner
401
if (((Form_pg_type) GETSTRUCT(tup))->typowner != ownerId)
402
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TYPE, typeName);
404
/* trouble if caller wanted to force the OID */
405
if (OidIsValid(newTypeOid))
406
elog(ERROR, "cannot assign new OID to existing shell type");
409
* Okay to update existing shell type tuple
411
tup = heap_modify_tuple(tup,
412
RelationGetDescr(pg_type_desc),
417
simple_heap_update(pg_type_desc, &tup->t_self, tup);
419
typeObjectId = HeapTupleGetOid(tup);
421
rebuildDeps = true; /* get rid of shell type's dependencies */
425
tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
429
/* Force the OID if requested by caller */
430
if (OidIsValid(newTypeOid))
431
HeapTupleSetOid(tup, newTypeOid);
432
/* Use binary-upgrade override for pg_type.oid, if supplied. */
433
else if (IsBinaryUpgrade && OidIsValid(binary_upgrade_next_pg_type_oid))
435
HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
436
binary_upgrade_next_pg_type_oid = InvalidOid;
438
/* else allow system to assign oid */
440
typeObjectId = simple_heap_insert(pg_type_desc, tup);
444
CatalogUpdateIndexes(pg_type_desc, tup);
447
* Create dependencies. We can/must skip this in bootstrap mode.
449
if (!IsBootstrapProcessingMode())
450
GenerateTypeDependencies(typeNamespace,
467
stringToNode(defaultTypeBin) :
471
/* Post creation hook for new type */
472
InvokeObjectAccessHook(OAT_POST_CREATE, TypeRelationId, typeObjectId, 0);
477
heap_close(pg_type_desc, RowExclusiveLock);
483
* GenerateTypeDependencies: build the dependencies needed for a type
485
* If rebuild is true, we remove existing dependencies and rebuild them
486
* from scratch. This is needed for ALTER TYPE, and also when replacing
487
* a shell type. We don't remove/rebuild extension dependencies, though.
490
GenerateTypeDependencies(Oid typeNamespace,
492
Oid relationOid, /* only for relation rowtypes */
493
char relationKind, /* ditto */
497
Oid receiveProcedure,
499
Oid typmodinProcedure,
500
Oid typmodoutProcedure,
501
Oid analyzeProcedure,
503
bool isImplicitArray,
509
ObjectAddress myself,
514
deleteDependencyRecordsFor(TypeRelationId, typeObjectId, true);
515
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId, 0);
518
myself.classId = TypeRelationId;
519
myself.objectId = typeObjectId;
520
myself.objectSubId = 0;
523
* Make dependency on namespace and shared dependency on owner.
525
* For a relation rowtype (that's not a composite type), we should skip
526
* these because we'll depend on them indirectly through the pg_class
527
* entry. Likewise, skip for implicit arrays since we'll depend on them
528
* through the element type. The same goes for extension membership.
530
if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) &&
533
referenced.classId = NamespaceRelationId;
534
referenced.objectId = typeNamespace;
535
referenced.objectSubId = 0;
536
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
538
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
540
/* dependency on extension */
542
recordDependencyOnCurrentExtension(&myself);
545
/* Normal dependencies on the I/O functions */
546
if (OidIsValid(inputProcedure))
548
referenced.classId = ProcedureRelationId;
549
referenced.objectId = inputProcedure;
550
referenced.objectSubId = 0;
551
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
554
if (OidIsValid(outputProcedure))
556
referenced.classId = ProcedureRelationId;
557
referenced.objectId = outputProcedure;
558
referenced.objectSubId = 0;
559
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
562
if (OidIsValid(receiveProcedure))
564
referenced.classId = ProcedureRelationId;
565
referenced.objectId = receiveProcedure;
566
referenced.objectSubId = 0;
567
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
570
if (OidIsValid(sendProcedure))
572
referenced.classId = ProcedureRelationId;
573
referenced.objectId = sendProcedure;
574
referenced.objectSubId = 0;
575
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
578
if (OidIsValid(typmodinProcedure))
580
referenced.classId = ProcedureRelationId;
581
referenced.objectId = typmodinProcedure;
582
referenced.objectSubId = 0;
583
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
586
if (OidIsValid(typmodoutProcedure))
588
referenced.classId = ProcedureRelationId;
589
referenced.objectId = typmodoutProcedure;
590
referenced.objectSubId = 0;
591
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
594
if (OidIsValid(analyzeProcedure))
596
referenced.classId = ProcedureRelationId;
597
referenced.objectId = analyzeProcedure;
598
referenced.objectSubId = 0;
599
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
603
* If the type is a rowtype for a relation, mark it as internally
604
* dependent on the relation, *unless* it is a stand-alone composite type
605
* relation. For the latter case, we have to reverse the dependency.
607
* In the former case, this allows the type to be auto-dropped when the
608
* relation is, and not otherwise. And in the latter, of course we get the
611
if (OidIsValid(relationOid))
613
referenced.classId = RelationRelationId;
614
referenced.objectId = relationOid;
615
referenced.objectSubId = 0;
617
if (relationKind != RELKIND_COMPOSITE_TYPE)
618
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
620
recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
624
* If the type is an implicitly-created array type, mark it as internally
625
* dependent on the element type. Otherwise, if it has an element type,
626
* the dependency is a normal one.
628
if (OidIsValid(elementType))
630
referenced.classId = TypeRelationId;
631
referenced.objectId = elementType;
632
referenced.objectSubId = 0;
633
recordDependencyOn(&myself, &referenced,
634
isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL);
637
/* Normal dependency from a domain to its base type. */
638
if (OidIsValid(baseType))
640
referenced.classId = TypeRelationId;
641
referenced.objectId = baseType;
642
referenced.objectSubId = 0;
643
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
646
/* Normal dependency from a domain to its collation. */
647
/* We know the default collation is pinned, so don't bother recording it */
648
if (OidIsValid(typeCollation) && typeCollation != DEFAULT_COLLATION_OID)
650
referenced.classId = CollationRelationId;
651
referenced.objectId = typeCollation;
652
referenced.objectSubId = 0;
653
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
656
/* Normal dependency on the default expression. */
658
recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
663
* This renames a type, as well as any associated array type.
665
* Caller must have already checked privileges.
667
* Currently this is used for renaming table rowtypes and for
668
* ALTER TYPE RENAME TO command.
671
RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
673
Relation pg_type_desc;
678
pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock);
680
tuple = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid));
681
if (!HeapTupleIsValid(tuple))
682
elog(ERROR, "cache lookup failed for type %u", typeOid);
683
typ = (Form_pg_type) GETSTRUCT(tuple);
685
/* We are not supposed to be changing schemas here */
686
Assert(typeNamespace == typ->typnamespace);
688
arrayOid = typ->typarray;
690
/* Just to give a more friendly error than unique-index violation */
691
if (SearchSysCacheExists2(TYPENAMENSP,
692
CStringGetDatum(newTypeName),
693
ObjectIdGetDatum(typeNamespace)))
695
(errcode(ERRCODE_DUPLICATE_OBJECT),
696
errmsg("type \"%s\" already exists", newTypeName)));
698
/* OK, do the rename --- tuple is a copy, so OK to scribble on it */
699
namestrcpy(&(typ->typname), newTypeName);
701
simple_heap_update(pg_type_desc, &tuple->t_self, tuple);
703
/* update the system catalog indexes */
704
CatalogUpdateIndexes(pg_type_desc, tuple);
706
heap_freetuple(tuple);
707
heap_close(pg_type_desc, RowExclusiveLock);
709
/* If the type has an array type, recurse to handle that */
710
if (OidIsValid(arrayOid))
712
char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
714
RenameTypeInternal(arrayOid, arrname, typeNamespace);
722
* - given a base type name, make an array type name for it
724
* the caller is responsible for pfreeing the result
727
makeArrayTypeName(const char *typeName, Oid typeNamespace)
729
char *arr = (char *) palloc(NAMEDATALEN);
730
int namelen = strlen(typeName);
731
Relation pg_type_desc;
735
* The idea is to prepend underscores as needed until we make a name that
736
* doesn't collide with anything...
738
pg_type_desc = heap_open(TypeRelationId, AccessShareLock);
740
for (i = 1; i < NAMEDATALEN - 1; i++)
743
if (i + namelen < NAMEDATALEN)
744
strcpy(arr + i, typeName);
747
memcpy(arr + i, typeName, NAMEDATALEN - i);
748
truncate_identifier(arr, NAMEDATALEN, false);
750
if (!SearchSysCacheExists2(TYPENAMENSP,
751
CStringGetDatum(arr),
752
ObjectIdGetDatum(typeNamespace)))
756
heap_close(pg_type_desc, AccessShareLock);
758
if (i >= NAMEDATALEN - 1)
760
(errcode(ERRCODE_DUPLICATE_OBJECT),
761
errmsg("could not form array type name for type \"%s\"",
770
* - try to reassign an array type name that the user wants to use.
772
* The given type name has been discovered to already exist (with the given
773
* OID). If it is an autogenerated array type, change the array type's name
774
* to not conflict. This allows the user to create type "foo" followed by
775
* type "_foo" without problems. (Of course, there are race conditions if
776
* two backends try to create similarly-named types concurrently, but the
777
* worst that can happen is an unnecessary failure --- anything we do here
778
* will be rolled back if the type creation fails due to conflicting names.)
780
* Note that this must be called *before* calling makeArrayTypeName to
781
* determine the new type's own array type name; else the latter will
782
* certainly pick the same name.
784
* Returns TRUE if successfully moved the type, FALSE if not.
786
* We also return TRUE if the given type is a shell type. In this case
787
* the type has not been renamed out of the way, but nonetheless it can
788
* be expected that TypeCreate will succeed. This behavior is convenient
789
* for most callers --- those that need to distinguish the shell-type case
790
* must do their own typisdefined test.
793
moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
798
/* We need do nothing if it's a shell type. */
799
if (!get_typisdefined(typeOid))
802
/* Can't change it if it's not an autogenerated array type. */
803
elemOid = get_element_type(typeOid);
804
if (!OidIsValid(elemOid) ||
805
get_array_type(elemOid) != typeOid)
809
* OK, use makeArrayTypeName to pick an unused modification of the name.
810
* Note that since makeArrayTypeName is an iterative process, this will
811
* produce a name that it might have produced the first time, had the
812
* conflicting type we are about to create already existed.
814
newname = makeArrayTypeName(typeName, typeNamespace);
816
/* Apply the rename */
817
RenameTypeInternal(typeOid, newname, typeNamespace);
820
* We must bump the command counter so that any subsequent use of
821
* makeArrayTypeName sees what we just did and doesn't pick the same name.
823
CommandCounterIncrement();