PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_type.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * pg_type.c
4 * routines to support manipulation of the pg_type relation
5 *
6 * Portions Copyright (c) 1996-2026, 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"
21#include "catalog/catalog.h"
22#include "catalog/dependency.h"
23#include "catalog/indexing.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 "utils/acl.h"
34#include "utils/builtins.h"
35#include "utils/fmgroids.h"
36#include "utils/lsyscache.h"
37#include "utils/rel.h"
38#include "utils/syscache.h"
39
40/* Potentially set by pg_upgrade_support functions */
42
43/* ----------------------------------------------------------------
44 * TypeShellMake
45 *
46 * This procedure inserts a "shell" tuple into the pg_type relation.
47 * The type tuple inserted has valid but dummy values, and its
48 * "typisdefined" field is false indicating it's not really defined.
49 *
50 * This is used so that a tuple exists in the catalogs. The I/O
51 * functions for the type will link to this tuple. When the full
52 * CREATE TYPE command is issued, the bogus values will be replaced
53 * with correct ones, and "typisdefined" will be set to true.
54 * ----------------------------------------------------------------
55 */
57TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
58{
60 TupleDesc tupDesc;
61 int i;
64 bool nulls[Natts_pg_type];
65 Oid typoid;
67 ObjectAddress address;
68
69 Assert(typeName);
70
71 /*
72 * open pg_type
73 */
75 tupDesc = pg_type_desc->rd_att;
76
77 /*
78 * initialize our *nulls and *values arrays
79 */
80 for (i = 0; i < Natts_pg_type; ++i)
81 {
82 nulls[i] = false;
83 values[i] = (Datum) 0; /* redundant, but safe */
84 }
85
86 /*
87 * initialize *values with the type name and dummy values
88 *
89 * The representational details are the same as int4 ... it doesn't really
90 * matter what they are so long as they are consistent. Also note that we
91 * give it typtype = TYPTYPE_PSEUDO as extra insurance that it won't be
92 * mistaken for a usable type.
93 */
94 namestrcpy(&name, typeName);
123 nulls[Anum_pg_type_typdefaultbin - 1] = true;
124 nulls[Anum_pg_type_typdefault - 1] = true;
125 nulls[Anum_pg_type_typacl - 1] = true;
126
127 /* Use binary-upgrade override for pg_type.oid? */
128 if (IsBinaryUpgrade)
129 {
133 errmsg("pg_type OID value not set when in binary upgrade mode")));
134
137 }
138 else
139 {
142 }
143
145
146 /*
147 * create a new type tuple
148 */
149 tup = heap_form_tuple(tupDesc, values, nulls);
150
151 /*
152 * insert the tuple in the relation and get the tuple's oid.
153 */
155
156 /*
157 * Create dependencies. We can/must skip this in bootstrap mode.
158 */
162 NULL,
163 NULL,
164 0,
165 false,
166 false,
167 true, /* make extension dependency */
168 false);
169
170 /* Post creation hook for new shell type */
172
173 ObjectAddressSet(address, TypeRelationId, typoid);
174
175 /*
176 * clean up and return the type-oid
177 */
180
181 return address;
182}
183
184/* ----------------------------------------------------------------
185 * TypeCreate
186 *
187 * This does all the necessary work needed to define a new type.
188 *
189 * Returns the ObjectAddress assigned to the new type.
190 * If newTypeOid is zero (the normal case), a new OID is created;
191 * otherwise we use exactly that OID.
192 * ----------------------------------------------------------------
193 */
196 const char *typeName,
198 Oid relationOid, /* only for relation rowtypes */
199 char relationKind, /* ditto */
200 Oid ownerId,
202 char typeType,
203 char typeCategory,
204 bool typePreferred,
205 char typDelim,
215 bool isImplicitArray,
217 Oid baseType,
218 const char *defaultTypeValue, /* human-readable rep */
219 char *defaultTypeBin, /* cooked rep */
220 bool passedByValue,
221 char alignment,
222 char storage,
224 int32 typNDims, /* Array dimensions for baseType */
225 bool typeNotNull,
227{
230 bool isDependentType;
231 bool rebuildDeps = false;
232 Acl *typacl;
234 bool nulls[Natts_pg_type];
238 int i;
239 ObjectAddress address;
240
241 /*
242 * We assume that the caller validated the arguments individually, but did
243 * not check for bad combinations.
244 *
245 * Validate size specifications: either positive (fixed-length) or -1
246 * (varlena) or -2 (cstring).
247 */
248 if (!(internalSize > 0 ||
249 internalSize == -1 ||
250 internalSize == -2))
253 errmsg("invalid type internal size %d",
254 internalSize)));
255
256 if (passedByValue)
257 {
258 /*
259 * Pass-by-value types must have a fixed length that is one of the
260 * values supported by fetch_att() and store_att_byval(); and the
261 * alignment had better agree, too. All this code must match
262 * access/tupmacs.h!
263 */
264 if (internalSize == (int16) sizeof(char))
265 {
269 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
271 }
272 else if (internalSize == (int16) sizeof(int16))
273 {
277 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
279 }
280 else if (internalSize == (int16) sizeof(int32))
281 {
282 if (alignment != TYPALIGN_INT)
285 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
287 }
288 else if (internalSize == (int16) sizeof(int64))
289 {
293 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
295 }
296 else
299 errmsg("internal size %d is invalid for passed-by-value type",
300 internalSize)));
301 }
302 else
303 {
304 /* varlena types must have int align or better */
305 if (internalSize == -1 &&
309 errmsg("alignment \"%c\" is invalid for variable-length type",
310 alignment)));
311 /* cstring must have char alignment */
312 if (internalSize == -2 && !(alignment == TYPALIGN_CHAR))
315 errmsg("alignment \"%c\" is invalid for variable-length type",
316 alignment)));
317 }
318
319 /* Only varlena types can be toasted */
320 if (storage != TYPSTORAGE_PLAIN && internalSize != -1)
323 errmsg("fixed-size types must have storage PLAIN")));
324
325 /*
326 * This is a dependent type if it's an implicitly-created array type or
327 * multirange type, or if it's a relation rowtype that's not a composite
328 * type. For such types we'll leave the ACL empty, and we'll skip
329 * creating some dependency records because there will be a dependency
330 * already through the depended-on type or relation. (Caution: this is
331 * closely intertwined with some behavior in GenerateTypeDependencies.)
332 */
336
337 /*
338 * initialize arrays needed for heap_form_tuple or heap_modify_tuple
339 */
340 for (i = 0; i < Natts_pg_type; ++i)
341 {
342 nulls[i] = false;
343 replaces[i] = true;
344 values[i] = (Datum) 0;
345 }
346
347 /*
348 * insert data values
349 */
350 namestrcpy(&name, typeName);
379
380 /*
381 * initialize the default binary value for this type. Check for nulls of
382 * course.
383 */
384 if (defaultTypeBin)
386 else
387 nulls[Anum_pg_type_typdefaultbin - 1] = true;
388
389 /*
390 * initialize the default value for this type.
391 */
394 else
395 nulls[Anum_pg_type_typdefault - 1] = true;
396
397 /*
398 * Initialize the type's ACL, too. But dependent types don't get one.
399 */
400 if (isDependentType)
401 typacl = NULL;
402 else
405 if (typacl != NULL)
407 else
408 nulls[Anum_pg_type_typacl - 1] = true;
409
410 /*
411 * open pg_type and prepare to insert or update a row.
412 *
413 * NOTE: updating will not work correctly in bootstrap mode; but we don't
414 * expect to be overwriting any shell types in bootstrap mode.
415 */
417
419 CStringGetDatum(typeName),
422 {
424
425 /*
426 * check that the type is not already defined. It may exist as a
427 * shell type, however.
428 */
429 if (typform->typisdefined)
432 errmsg("type \"%s\" already exists", typeName)));
433
434 /*
435 * shell type must have been created by same owner
436 */
437 if (typform->typowner != ownerId)
439
440 /* trouble if caller wanted to force the OID */
442 elog(ERROR, "cannot assign new OID to existing shell type");
443
444 replaces[Anum_pg_type_oid - 1] = false;
445
446 /*
447 * Okay to update existing shell type tuple
448 */
451 values,
452 nulls,
453 replaces);
454
456
457 typeObjectId = typform->oid;
458
459 rebuildDeps = true; /* get rid of shell type's dependencies */
460 }
461 else
462 {
463 /* Force the OID if requested by caller */
466 /* Use binary-upgrade override for pg_type.oid, if supplied. */
467 else if (IsBinaryUpgrade)
468 {
472 errmsg("pg_type OID value not set when in binary upgrade mode")));
473
476 }
477 else
478 {
481 }
482
484
486 values, nulls);
487
489 }
490
491 /*
492 * Create dependencies. We can/must skip this in bootstrap mode.
493 */
499 NULL),
500 typacl,
504 true, /* make extension dependency */
506
507 /* Post creation hook for new type */
509
511
512 /*
513 * finish up
514 */
516
517 return address;
518}
519
520/*
521 * GenerateTypeDependencies: build the dependencies needed for a type
522 *
523 * Most of what this function needs to know about the type is passed as the
524 * new pg_type row, typeTuple. We make callers pass the pg_type Relation
525 * as well, so that we have easy access to a tuple descriptor for the row.
526 *
527 * While this is able to extract the defaultExpr and typacl from the tuple,
528 * doing so is relatively expensive, and callers may have those values at
529 * hand already. Pass those if handy, otherwise pass NULL. (typacl is really
530 * "Acl *", but we declare it "void *" to avoid including acl.h in pg_type.h.)
531 *
532 * relationKind and isImplicitArray are likewise somewhat expensive to deduce
533 * from the tuple, so we make callers pass those (they're not optional).
534 *
535 * isDependentType is true if this is an implicit array, multirange, or
536 * relation rowtype; that means it doesn't need its own dependencies on owner
537 * etc.
538 *
539 * We make an extension-membership dependency if we're in an extension
540 * script and makeExtensionDep is true.
541 * makeExtensionDep should be true when creating a new type or replacing a
542 * shell type, but not for ALTER TYPE on an existing type. Passing false
543 * causes the type's extension membership to be left alone.
544 *
545 * rebuild should be true if this is a pre-existing type. We will remove
546 * existing dependencies and rebuild them from scratch. This is needed for
547 * ALTER TYPE, and also when replacing a shell type. We don't remove any
548 * existing extension dependency, though; hence, if makeExtensionDep is also
549 * true and we're in an extension script, an error will occur unless the
550 * type already belongs to the current extension. That's the behavior we
551 * want when replacing a shell type, which is the only case where both flags
552 * are true.
553 */
554void
558 void *typacl,
559 char relationKind, /* only for relation rowtypes */
560 bool isImplicitArray,
561 bool isDependentType,
562 bool makeExtensionDep,
563 bool rebuild)
564{
567 Datum datum;
568 bool isNull;
572
573 /* Extract defaultExpr if caller didn't pass it */
574 if (defaultExpr == NULL)
575 {
577 RelationGetDescr(typeCatalog), &isNull);
578 if (!isNull)
580 }
581 /* Extract typacl if caller didn't pass it */
582 if (typacl == NULL)
583 {
585 RelationGetDescr(typeCatalog), &isNull);
586 if (!isNull)
587 typacl = DatumGetAclPCopy(datum);
588 }
589
590 /* If rebuild, first flush old dependencies, except extension deps */
591 if (rebuild)
592 {
595 }
596
598
599 /*
600 * Make dependencies on namespace, owner, ACL.
601 *
602 * Skip these for a dependent type, since it will have such dependencies
603 * indirectly through its depended-on type or relation. An exception is
604 * that multiranges need their own namespace dependency, since we don't
605 * force them to be in the same schema as their range type.
606 */
607
608 /* collects normal dependencies for bulk recording */
610
611 if (!isDependentType || typeForm->typtype == TYPTYPE_MULTIRANGE)
612 {
614 typeForm->typnamespace);
616 }
617
618 if (!isDependentType)
619 {
621 typeForm->typowner);
622
624 typeForm->typowner, typacl);
625 }
626
627 /*
628 * Make extension dependency if requested.
629 *
630 * We used to skip this for dependent types, but it seems better to record
631 * their extension membership explicitly; otherwise code such as
632 * postgres_fdw's shippability test will be fooled.
633 */
636
637 /* Normal dependencies on the I/O and support functions */
638 if (OidIsValid(typeForm->typinput))
639 {
642 }
643
644 if (OidIsValid(typeForm->typoutput))
645 {
648 }
649
650 if (OidIsValid(typeForm->typreceive))
651 {
654 }
655
656 if (OidIsValid(typeForm->typsend))
657 {
660 }
661
662 if (OidIsValid(typeForm->typmodin))
663 {
666 }
667
668 if (OidIsValid(typeForm->typmodout))
669 {
672 }
673
674 if (OidIsValid(typeForm->typanalyze))
675 {
678 }
679
680 if (OidIsValid(typeForm->typsubscript))
681 {
684 }
685
686 /* Normal dependency from a domain to its base type. */
687 if (OidIsValid(typeForm->typbasetype))
688 {
691 }
692
693 /*
694 * Normal dependency from a domain to its collation. We know the default
695 * collation is pinned, so don't bother recording it.
696 */
697 if (OidIsValid(typeForm->typcollation) &&
698 typeForm->typcollation != DEFAULT_COLLATION_OID)
699 {
702 }
703
706
707 /* Normal dependency on the default expression. */
708 if (defaultExpr)
710
711 /*
712 * If the type is a rowtype for a relation, mark it as internally
713 * dependent on the relation, *unless* it is a stand-alone composite type
714 * relation. For the latter case, we have to reverse the dependency.
715 *
716 * In the former case, this allows the type to be auto-dropped when the
717 * relation is, and not otherwise. And in the latter, of course we get the
718 * opposite effect.
719 */
720 if (OidIsValid(typeForm->typrelid))
721 {
723
726 else
728 }
729
730 /*
731 * If the type is an implicitly-created array type, mark it as internally
732 * dependent on the element type. Otherwise, if it has an element type,
733 * the dependency is a normal one.
734 */
735 if (OidIsValid(typeForm->typelem))
736 {
740 }
741
742 /*
743 * Note: you might expect that we should record an internal dependency of
744 * a multirange on its range type here, by analogy with the cases above.
745 * But instead, that is done by RangeCreate(), which also handles
746 * recording of other range-type-specific dependencies. That's pretty
747 * bogus. It's okay for now, because there are no cases where we need to
748 * regenerate the dependencies of a range or multirange type. But someday
749 * we might need to move that logic here to allow such regeneration.
750 */
751}
752
753/*
754 * RenameTypeInternal
755 * This renames a type, as well as any associated array type.
756 *
757 * Caller must have already checked privileges.
758 *
759 * Currently this is used for renaming table rowtypes and for
760 * ALTER TYPE RENAME TO command.
761 */
762void
764{
766 HeapTuple tuple;
770
772
774 if (!HeapTupleIsValid(tuple))
775 elog(ERROR, "cache lookup failed for type %u", typeOid);
776 typ = (Form_pg_type) GETSTRUCT(tuple);
777
778 /* We are not supposed to be changing schemas here */
779 Assert(typeNamespace == typ->typnamespace);
780
781 arrayOid = typ->typarray;
782
783 /* Check for a conflicting type name. */
787
788 /*
789 * If there is one, see if it's an autogenerated array type, and if so
790 * rename it out of the way. (But we must skip that for a shell type
791 * because moveArrayTypeName will do the wrong thing in that case.)
792 * Otherwise, we can at least give a more friendly error than unique-index
793 * violation.
794 */
796 {
799 /* successfully dodged the problem */ ;
800 else
803 errmsg("type \"%s\" already exists", newTypeName)));
804 }
805
806 /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
807 namestrcpy(&(typ->typname), newTypeName);
808
809 CatalogTupleUpdate(pg_type_desc, &tuple->t_self, tuple);
810
812
813 heap_freetuple(tuple);
815
816 /*
817 * If the type has an array type, recurse to handle that. But we don't
818 * need to do anything more if we already renamed that array type above
819 * (which would happen when, eg, renaming "foo" to "_foo").
820 */
822 {
824
826 pfree(arrname);
827 }
828}
829
830
831/*
832 * makeArrayTypeName
833 * - given a base type name, make an array type name for it
834 *
835 * the caller is responsible for pfreeing the result
836 */
837char *
838makeArrayTypeName(const char *typeName, Oid typeNamespace)
839{
840 char *arr_name;
841 int pass = 0;
842 char suffix[NAMEDATALEN];
843
844 /*
845 * Per ancient Postgres tradition, array type names are made by prepending
846 * an underscore to the base type name. Much client code knows that
847 * convention, so don't muck with it. However, the tradition is less
848 * clear about what to do in the corner cases where the resulting name is
849 * too long or conflicts with an existing name. Our current rules are (1)
850 * truncate the base name on the right as needed, and (2) if there is a
851 * conflict, append another underscore and some digits chosen to make it
852 * unique. This is similar to what ChooseRelationName() does.
853 *
854 * The actual name generation can be farmed out to makeObjectName() by
855 * giving it an empty first name component.
856 */
857
858 /* First, try with no numeric suffix */
859 arr_name = makeObjectName("", typeName, NULL);
860
861 for (;;)
862 {
866 break;
867
868 /* That attempt conflicted. Prepare a new name with some digits. */
870 snprintf(suffix, sizeof(suffix), "%d", ++pass);
871 arr_name = makeObjectName("", typeName, suffix);
872 }
873
874 return arr_name;
875}
876
877
878/*
879 * moveArrayTypeName
880 * - try to reassign an array type name that the user wants to use.
881 *
882 * The given type name has been discovered to already exist (with the given
883 * OID). If it is an autogenerated array type, change the array type's name
884 * to not conflict. This allows the user to create type "foo" followed by
885 * type "_foo" without problems. (Of course, there are race conditions if
886 * two backends try to create similarly-named types concurrently, but the
887 * worst that can happen is an unnecessary failure --- anything we do here
888 * will be rolled back if the type creation fails due to conflicting names.)
889 *
890 * Note that this must be called *before* calling makeArrayTypeName to
891 * determine the new type's own array type name; else the latter will
892 * certainly pick the same name.
893 *
894 * Returns true if successfully moved the type, false if not.
895 *
896 * We also return true if the given type is a shell type. In this case
897 * the type has not been renamed out of the way, but nonetheless it can
898 * be expected that TypeCreate will succeed. This behavior is convenient
899 * for most callers --- those that need to distinguish the shell-type case
900 * must do their own typisdefined test.
901 */
902bool
903moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
904{
905 Oid elemOid;
906 char *newname;
907
908 /* We need do nothing if it's a shell type. */
909 if (!get_typisdefined(typeOid))
910 return true;
911
912 /* Can't change it if it's not an autogenerated array type. */
913 elemOid = get_element_type(typeOid);
914 if (!OidIsValid(elemOid) ||
915 get_array_type(elemOid) != typeOid)
916 return false;
917
918 /*
919 * OK, use makeArrayTypeName to pick an unused modification of the name.
920 * Note that since makeArrayTypeName is an iterative process, this will
921 * produce a name that it might have produced the first time, had the
922 * conflicting type we are about to create already existed.
923 */
924 newname = makeArrayTypeName(typeName, typeNamespace);
925
926 /* Apply the rename */
927 RenameTypeInternal(typeOid, newname, typeNamespace);
928
929 /*
930 * We must bump the command counter so that any subsequent use of
931 * makeArrayTypeName sees what we just did and doesn't pick the same name.
932 */
934
935 pfree(newname);
936
937 return true;
938}
939
940
941/*
942 * makeMultirangeTypeName
943 * - given a range type name, make a multirange type name for it
944 *
945 * caller is responsible for pfreeing the result
946 */
947char *
949{
950 char *buf;
951 const char *rangestr;
952
953 /*
954 * If the range type name contains "range" then change that to
955 * "multirange". Otherwise add "_multirange" to the end.
956 */
957 rangestr = strstr(rangeTypeName, "range");
958 if (rangestr)
959 {
960 char *prefix = pnstrdup(rangeTypeName, rangestr - rangeTypeName);
961
962 buf = psprintf("%s%s%s", prefix, "multi", rangestr);
963 }
964 else
965 buf = psprintf("%s_multirange", pnstrdup(rangeTypeName, NAMEDATALEN - 12));
966
967 /* clip it at NAMEDATALEN-1 bytes */
968 buf[pg_mbcliplen(buf, strlen(buf), NAMEDATALEN - 1)] = '\0';
969
975 errmsg("type \"%s\" already exists", buf),
976 errdetail("Failed while creating a multirange type for type \"%s\".", rangeTypeName),
977 errhint("You can manually specify a multirange type name using the \"multirange_type_name\" attribute.")));
978
979 return pstrdup(buf);
980}
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
#define DatumGetAclPCopy(X)
Definition acl.h:121
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition aclchk.c:4327
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition aclchk.c:4247
static Datum values[MAXATTR]
Definition bootstrap.c:155
#define CStringGetTextDatum(s)
Definition builtins.h:97
#define TextDatumGetCString(d)
Definition builtins.h:98
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
int16_t int16
Definition c.h:541
int32_t int32
Definition c.h:542
#define OidIsValid(objectId)
Definition c.h:788
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:448
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
@ DEPENDENCY_INTERNAL
Definition dependency.h:35
@ DEPENDENCY_NORMAL
Definition dependency.h:33
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
bool IsBinaryUpgrade
Definition globals.c:121
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define storage
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition indexcmds.c:2543
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
int i
Definition isn.c:77
#define RowExclusiveLock
Definition lockdefs.h:38
Oid get_element_type(Oid typid)
Definition lsyscache.c:2909
bool get_typisdefined(Oid typid)
Definition lsyscache.c:2323
Oid get_array_type(Oid typid)
Definition lsyscache.c:2937
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition mbutils.c:1086
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
char * pnstrdup(const char *in, Size len)
Definition mcxt.c:1792
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
void namestrcpy(Name name, const char *str)
Definition name.c:233
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
@ OBJECT_TYPE
#define NAMEDATALEN
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition pg_depend.c:45
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition pg_depend.c:301
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition pg_depend.c:193
#define NIL
Definition pg_list.h:68
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
static char buf[DEFAULT_XLOG_SEG_SIZE]
void GenerateTypeDependencies(HeapTuple typeTuple, Relation typeCatalog, Node *defaultExpr, void *typacl, char relationKind, bool isImplicitArray, bool isDependentType, bool makeExtensionDep, bool rebuild)
Definition pg_type.c:555
void RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
Definition pg_type.c:763
Oid binary_upgrade_next_pg_type_oid
Definition pg_type.c:41
ObjectAddress TypeCreate(Oid newTypeOid, const char *typeName, Oid typeNamespace, Oid relationOid, char relationKind, Oid ownerId, int16 internalSize, char typeType, char typeCategory, bool typePreferred, char typDelim, Oid inputProcedure, Oid outputProcedure, Oid receiveProcedure, Oid sendProcedure, Oid typmodinProcedure, Oid typmodoutProcedure, Oid analyzeProcedure, Oid subscriptProcedure, Oid elementType, bool isImplicitArray, Oid arrayType, Oid baseType, const char *defaultTypeValue, char *defaultTypeBin, bool passedByValue, char alignment, char storage, int32 typeMod, int32 typNDims, bool typeNotNull, Oid typeCollation)
Definition pg_type.c:195
bool moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
Definition pg_type.c:903
ObjectAddress TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
Definition pg_type.c:57
char * makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace)
Definition pg_type.c:948
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition pg_type.c:838
FormData_pg_type * Form_pg_type
Definition pg_type.h:261
#define snprintf
Definition port.h:260
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:403
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define InvalidOid
unsigned int Oid
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
void * stringToNode(const char *str)
Definition read.c:90
#define RelationGetDescr(relation)
Definition rel.h:540
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
ItemPointerData t_self
Definition htup.h:65
Definition nodes.h:135
Definition c.h:760
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition syscache.h:93
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition syscache.h:102
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
#define DEFAULT_TYPDELIM
Definition typecmds.h:22
const char * name
void CommandCounterIncrement(void)
Definition xact.c:1101