Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
pg_type.h File Reference
#include "catalog/genbki.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_type_d.h"
#include "nodes/nodes.h"
Include dependency graph for pg_type.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef FormData_pg_typeForm_pg_type
 

Functions

 CATALOG (pg_type, 1247, TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71
 
Oid typnamespace BKI_DEFAULT (pg_catalog) BKI_LOOKUP(pg_namespace)
 
Oid typowner BKI_DEFAULT (POSTGRES) BKI_LOOKUP(pg_authid)
 
int16 typlen BKI_ARRAY_DEFAULT (-1)
 
bool typbyval BKI_ARRAY_DEFAULT (f)
 
char typtype BKI_DEFAULT (b) BKI_ARRAY_DEFAULT(b)
 
char typcategory BKI_ARRAY_DEFAULT (A)
 
bool typispreferred BKI_DEFAULT (f) BKI_ARRAY_DEFAULT(f)
 
bool typisdefined BKI_DEFAULT (t)
 
char typdelim BKI_DEFAULT (',')
 
Oid typrelid BKI_DEFAULT (0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP_OPT(pg_class)
 
regproc typsubscript BKI_DEFAULT (-) BKI_ARRAY_DEFAULT(array_subscript_handler) BKI_LOOKUP_OPT(pg_proc)
 
regproc typinput BKI_ARRAY_DEFAULT (array_in) BKI_LOOKUP(pg_proc)
 
regproc typoutput BKI_ARRAY_DEFAULT (array_out) BKI_LOOKUP(pg_proc)
 
regproc typreceive BKI_ARRAY_DEFAULT (array_recv) BKI_LOOKUP_OPT(pg_proc)
 
regproc typsend BKI_ARRAY_DEFAULT (array_send) BKI_LOOKUP_OPT(pg_proc)
 
char typstorage BKI_DEFAULT (p) BKI_ARRAY_DEFAULT(x)
 
 DECLARE_TOAST (pg_type, 4171, 4172)
 
 DECLARE_UNIQUE_INDEX_PKEY (pg_type_oid_index, 2703, TypeOidIndexId, pg_type, btree(oid oid_ops))
 
 DECLARE_UNIQUE_INDEX (pg_type_typname_nsp_index, 2704, TypeNameNspIndexId, pg_type, btree(typname name_ops, typnamespace oid_ops))
 
 MAKE_SYSCACHE (TYPEOID, pg_type_oid_index, 64)
 
 MAKE_SYSCACHE (TYPENAMENSP, pg_type_typname_nsp_index, 64)
 
ObjectAddress TypeShellMake (const char *typeName, Oid typeNamespace, Oid ownerId)
 
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)
 
void GenerateTypeDependencies (HeapTuple typeTuple, Relation typeCatalog, Node *defaultExpr, void *typacl, char relationKind, bool isImplicitArray, bool isDependentType, bool makeExtensionDep, bool rebuild)
 
void RenameTypeInternal (Oid typeOid, const char *newTypeName, Oid typeNamespace)
 
char * makeArrayTypeName (const char *typeName, Oid typeNamespace)
 
bool moveArrayTypeName (Oid typeOid, const char *typeName, Oid typeNamespace)
 
char * makeMultirangeTypeName (const char *rangeTypeName, Oid typeNamespace)
 

Variables

TypeRelation_Rowtype_Id BKI_SCHEMA_MACRO
 
NameData typname
 
char typalign
 
 FormData_pg_type
 

Typedef Documentation

◆ Form_pg_type

Definition at line 261 of file pg_type.h.

Function Documentation

◆ BKI_ARRAY_DEFAULT() [1/7]

int16 typlen BKI_ARRAY_DEFAULT ( 1)

◆ BKI_ARRAY_DEFAULT() [2/7]

char typcategory BKI_ARRAY_DEFAULT ( )

◆ BKI_ARRAY_DEFAULT() [3/7]

regproc typinput BKI_ARRAY_DEFAULT ( array_in  )

◆ BKI_ARRAY_DEFAULT() [4/7]

regproc typoutput BKI_ARRAY_DEFAULT ( array_out  )

◆ BKI_ARRAY_DEFAULT() [5/7]

regproc typreceive BKI_ARRAY_DEFAULT ( array_recv  )

◆ BKI_ARRAY_DEFAULT() [6/7]

regproc typsend BKI_ARRAY_DEFAULT ( array_send  )

◆ BKI_ARRAY_DEFAULT() [7/7]

bool typbyval BKI_ARRAY_DEFAULT ( )

◆ BKI_DEFAULT() [1/9]

char typdelim BKI_DEFAULT ( ,
 
)

◆ BKI_DEFAULT() [2/9]

regproc typsubscript BKI_DEFAULT ( )

◆ BKI_DEFAULT() [3/9]

Oid typrelid BKI_DEFAULT ( )

◆ BKI_DEFAULT() [4/9]

char typtype BKI_DEFAULT ( b  )

◆ BKI_DEFAULT() [5/9]

bool typispreferred BKI_DEFAULT ( )

◆ BKI_DEFAULT() [6/9]

char typstorage BKI_DEFAULT ( )

◆ BKI_DEFAULT() [7/9]

Oid typnamespace BKI_DEFAULT ( pg_catalog  )

◆ BKI_DEFAULT() [8/9]

Oid typowner BKI_DEFAULT ( POSTGRES  )

◆ BKI_DEFAULT() [9/9]

bool typisdefined BKI_DEFAULT ( )

◆ CATALOG()

CATALOG ( pg_type  ,
1247  ,
TypeRelationId   
)

◆ DECLARE_TOAST()

DECLARE_TOAST ( pg_type  ,
4171  ,
4172   
)

◆ DECLARE_UNIQUE_INDEX()

DECLARE_UNIQUE_INDEX ( pg_type_typname_nsp_index  ,
2704  ,
TypeNameNspIndexId  ,
pg_type  ,
btree(typname name_ops, typnamespace oid_ops)   
)

◆ DECLARE_UNIQUE_INDEX_PKEY()

DECLARE_UNIQUE_INDEX_PKEY ( pg_type_oid_index  ,
2703  ,
TypeOidIndexId  ,
pg_type  ,
btree(oid oid_ops)   
)

◆ GenerateTypeDependencies()

void GenerateTypeDependencies ( HeapTuple  typeTuple,
Relation  typeCatalog,
Node defaultExpr,
void *  typacl,
char  relationKind,
bool  isImplicitArray,
bool  isDependentType,
bool  makeExtensionDep,
bool  rebuild 
)

Definition at line 555 of file pg_type.c.

564{
565 Form_pg_type typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
566 Oid typeObjectId = typeForm->oid;
567 Datum datum;
568 bool isNull;
569 ObjectAddress myself,
570 referenced;
571 ObjectAddresses *addrs_normal;
572
573 /* Extract defaultExpr if caller didn't pass it */
574 if (defaultExpr == NULL)
575 {
576 datum = heap_getattr(typeTuple, Anum_pg_type_typdefaultbin,
577 RelationGetDescr(typeCatalog), &isNull);
578 if (!isNull)
579 defaultExpr = stringToNode(TextDatumGetCString(datum));
580 }
581 /* Extract typacl if caller didn't pass it */
582 if (typacl == NULL)
583 {
584 datum = heap_getattr(typeTuple, Anum_pg_type_typacl,
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 {
593 deleteDependencyRecordsFor(TypeRelationId, typeObjectId, true);
594 deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId, 0);
595 }
596
597 ObjectAddressSet(myself, TypeRelationId, typeObjectId);
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 */
609 addrs_normal = new_object_addresses();
610
611 if (!isDependentType || typeForm->typtype == TYPTYPE_MULTIRANGE)
612 {
613 ObjectAddressSet(referenced, NamespaceRelationId,
614 typeForm->typnamespace);
615 add_exact_object_address(&referenced, addrs_normal);
616 }
617
618 if (!isDependentType)
619 {
620 recordDependencyOnOwner(TypeRelationId, typeObjectId,
621 typeForm->typowner);
622
623 recordDependencyOnNewAcl(TypeRelationId, typeObjectId, 0,
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 */
634 if (makeExtensionDep)
635 recordDependencyOnCurrentExtension(&myself, rebuild);
636
637 /* Normal dependencies on the I/O and support functions */
638 if (OidIsValid(typeForm->typinput))
639 {
640 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typinput);
641 add_exact_object_address(&referenced, addrs_normal);
642 }
643
644 if (OidIsValid(typeForm->typoutput))
645 {
646 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typoutput);
647 add_exact_object_address(&referenced, addrs_normal);
648 }
649
650 if (OidIsValid(typeForm->typreceive))
651 {
652 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typreceive);
653 add_exact_object_address(&referenced, addrs_normal);
654 }
655
656 if (OidIsValid(typeForm->typsend))
657 {
658 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsend);
659 add_exact_object_address(&referenced, addrs_normal);
660 }
661
662 if (OidIsValid(typeForm->typmodin))
663 {
664 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodin);
665 add_exact_object_address(&referenced, addrs_normal);
666 }
667
668 if (OidIsValid(typeForm->typmodout))
669 {
670 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodout);
671 add_exact_object_address(&referenced, addrs_normal);
672 }
673
674 if (OidIsValid(typeForm->typanalyze))
675 {
676 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typanalyze);
677 add_exact_object_address(&referenced, addrs_normal);
678 }
679
680 if (OidIsValid(typeForm->typsubscript))
681 {
682 ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsubscript);
683 add_exact_object_address(&referenced, addrs_normal);
684 }
685
686 /* Normal dependency from a domain to its base type. */
687 if (OidIsValid(typeForm->typbasetype))
688 {
689 ObjectAddressSet(referenced, TypeRelationId, typeForm->typbasetype);
690 add_exact_object_address(&referenced, addrs_normal);
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 {
700 ObjectAddressSet(referenced, CollationRelationId, typeForm->typcollation);
701 add_exact_object_address(&referenced, addrs_normal);
702 }
703
705 free_object_addresses(addrs_normal);
706
707 /* Normal dependency on the default expression. */
708 if (defaultExpr)
709 recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
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 {
722 ObjectAddressSet(referenced, RelationRelationId, typeForm->typrelid);
723
724 if (relationKind != RELKIND_COMPOSITE_TYPE)
725 recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
726 else
727 recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
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 {
737 ObjectAddressSet(referenced, TypeRelationId, typeForm->typelem);
738 recordDependencyOn(&myself, &referenced,
739 isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL);
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}
#define DatumGetAclPCopy(X)
Definition: acl.h:121
void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
Definition: aclchk.c:4325
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define OidIsValid(objectId)
Definition: c.h:775
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
Definition: dependency.c:2768
void recordDependencyOnExpr(const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
Definition: dependency.c:1553
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2559
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2513
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2799
@ DEPENDENCY_INTERNAL
Definition: dependency.h:35
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:904
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
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)
Definition: pg_shdepend.c:1047
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:168
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
uint64_t Datum
Definition: postgres.h:70
unsigned int Oid
Definition: postgres_ext.h:32
void * stringToNode(const char *str)
Definition: read.c:90
#define RelationGetDescr(relation)
Definition: rel.h:540

References add_exact_object_address(), DatumGetAclPCopy, deleteDependencyRecordsFor(), deleteSharedDependencyRecordsFor(), DEPENDENCY_INTERNAL, DEPENDENCY_NORMAL, free_object_addresses(), GETSTRUCT(), heap_getattr(), new_object_addresses(), NIL, ObjectAddressSet, OidIsValid, record_object_address_dependencies(), recordDependencyOn(), recordDependencyOnCurrentExtension(), recordDependencyOnExpr(), recordDependencyOnNewAcl(), recordDependencyOnOwner(), RelationGetDescr, stringToNode(), and TextDatumGetCString.

Referenced by AlterDomainDefault(), AlterTypeRecurse(), TypeCreate(), and TypeShellMake().

◆ MAKE_SYSCACHE() [1/2]

MAKE_SYSCACHE ( TYPENAMENSP  ,
pg_type_typname_nsp_index  ,
64   
)

◆ MAKE_SYSCACHE() [2/2]

MAKE_SYSCACHE ( TYPEOID  ,
pg_type_oid_index  ,
64   
)

◆ makeArrayTypeName()

char * makeArrayTypeName ( const char *  typeName,
Oid  typeNamespace 
)

Definition at line 838 of file pg_type.c.

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 {
863 if (!SearchSysCacheExists2(TYPENAMENSP,
864 CStringGetDatum(arr_name),
865 ObjectIdGetDatum(typeNamespace)))
866 break;
867
868 /* That attempt conflicted. Prepare a new name with some digits. */
869 pfree(arr_name);
870 snprintf(suffix, sizeof(suffix), "%d", ++pass);
871 arr_name = makeObjectName("", typeName, suffix);
872 }
873
874 return arr_name;
875}
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:2517
void pfree(void *pointer)
Definition: mcxt.c:1594
#define NAMEDATALEN
#define snprintf
Definition: port.h:239
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition: syscache.h:102

References CStringGetDatum(), makeObjectName(), NAMEDATALEN, ObjectIdGetDatum(), pfree(), SearchSysCacheExists2, and snprintf.

Referenced by DefineDomain(), DefineEnum(), DefineRange(), DefineType(), heap_create_with_catalog(), moveArrayTypeName(), and RenameTypeInternal().

◆ makeMultirangeTypeName()

char * makeMultirangeTypeName ( const char *  rangeTypeName,
Oid  typeNamespace 
)

Definition at line 948 of file pg_type.c.

949{
950 char *buf;
951 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
970 if (SearchSysCacheExists2(TYPENAMENSP,
972 ObjectIdGetDatum(typeNamespace)))
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}
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errhint(const char *fmt,...)
Definition: elog.c:1321
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1084
char * pstrdup(const char *in)
Definition: mcxt.c:1759
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1770
static char * buf
Definition: pg_test_fsync.c:72
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30

References buf, CStringGetDatum(), ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errdetail(), errhint(), errmsg(), ERROR, NAMEDATALEN, ObjectIdGetDatum(), pg_mbcliplen(), pnstrdup(), psprintf(), pstrdup(), and SearchSysCacheExists2.

Referenced by DefineRange().

◆ moveArrayTypeName()

bool moveArrayTypeName ( Oid  typeOid,
const char *  typeName,
Oid  typeNamespace 
)

Definition at line 903 of file pg_type.c.

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}
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2926
bool get_typisdefined(Oid typid)
Definition: lsyscache.c:2340
Oid get_array_type(Oid typid)
Definition: lsyscache.c:2954
void RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace)
Definition: pg_type.c:763
char * makeArrayTypeName(const char *typeName, Oid typeNamespace)
Definition: pg_type.c:838
void CommandCounterIncrement(void)
Definition: xact.c:1100

References CommandCounterIncrement(), get_array_type(), get_element_type(), get_typisdefined(), makeArrayTypeName(), OidIsValid, pfree(), and RenameTypeInternal().

Referenced by DefineCompositeType(), DefineDomain(), DefineEnum(), DefineRange(), DefineType(), heap_create_with_catalog(), and RenameTypeInternal().

◆ RenameTypeInternal()

void RenameTypeInternal ( Oid  typeOid,
const char *  newTypeName,
Oid  typeNamespace 
)

Definition at line 763 of file pg_type.c.

764{
765 Relation pg_type_desc;
766 HeapTuple tuple;
767 Form_pg_type typ;
768 Oid arrayOid;
769 Oid oldTypeOid;
770
771 pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
772
773 tuple = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid));
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. */
784 oldTypeOid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid,
785 CStringGetDatum(newTypeName),
786 ObjectIdGetDatum(typeNamespace));
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 */
795 if (OidIsValid(oldTypeOid))
796 {
797 if (get_typisdefined(oldTypeOid) &&
798 moveArrayTypeName(oldTypeOid, newTypeName, typeNamespace))
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
811 InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0);
812
813 heap_freetuple(tuple);
814 table_close(pg_type_desc, RowExclusiveLock);
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 */
821 if (OidIsValid(arrayOid) && arrayOid != oldTypeOid)
822 {
823 char *arrname = makeArrayTypeName(newTypeName, typeNamespace);
824
825 RenameTypeInternal(arrayOid, arrname, typeNamespace);
826 pfree(arrname);
827 }
828}
#define elog(elevel,...)
Definition: elog.h:226
Assert(PointerIsAligned(start, uint64))
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
#define RowExclusiveLock
Definition: lockdefs.h:38
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
bool moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace)
Definition: pg_type.c:903
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:91
#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

References Assert(), CatalogTupleUpdate(), CStringGetDatum(), elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, get_typisdefined(), GETSTRUCT(), GetSysCacheOid2, heap_freetuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, makeArrayTypeName(), moveArrayTypeName(), namestrcpy(), ObjectIdGetDatum(), OidIsValid, pfree(), RenameTypeInternal(), RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, table_close(), and table_open().

Referenced by moveArrayTypeName(), RenameRelationInternal(), RenameType(), and RenameTypeInternal().

◆ TypeCreate()

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 at line 195 of file pg_type.c.

227{
228 Relation pg_type_desc;
229 Oid typeObjectId;
230 bool isDependentType;
231 bool rebuildDeps = false;
232 Acl *typacl;
233 HeapTuple tup;
234 bool nulls[Natts_pg_type];
235 bool replaces[Natts_pg_type];
236 Datum values[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))
252 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
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 {
266 if (alignment != TYPALIGN_CHAR)
268 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
269 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
270 alignment, internalSize)));
271 }
272 else if (internalSize == (int16) sizeof(int16))
273 {
274 if (alignment != TYPALIGN_SHORT)
276 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
277 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
278 alignment, internalSize)));
279 }
280 else if (internalSize == (int16) sizeof(int32))
281 {
282 if (alignment != TYPALIGN_INT)
284 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
285 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
286 alignment, internalSize)));
287 }
288 else if (internalSize == (int16) sizeof(int64))
289 {
290 if (alignment != TYPALIGN_DOUBLE)
292 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
293 errmsg("alignment \"%c\" is invalid for passed-by-value type of size %d",
294 alignment, internalSize)));
295 }
296 else
298 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
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 &&
306 !(alignment == TYPALIGN_INT || alignment == TYPALIGN_DOUBLE))
308 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
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))
314 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
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)
322 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
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 */
333 isDependentType = isImplicitArray ||
334 typeType == TYPTYPE_MULTIRANGE ||
335 (OidIsValid(relationOid) && relationKind != RELKIND_COMPOSITE_TYPE);
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);
351 values[Anum_pg_type_typname - 1] = NameGetDatum(&name);
352 values[Anum_pg_type_typnamespace - 1] = ObjectIdGetDatum(typeNamespace);
353 values[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(ownerId);
354 values[Anum_pg_type_typlen - 1] = Int16GetDatum(internalSize);
355 values[Anum_pg_type_typbyval - 1] = BoolGetDatum(passedByValue);
356 values[Anum_pg_type_typtype - 1] = CharGetDatum(typeType);
357 values[Anum_pg_type_typcategory - 1] = CharGetDatum(typeCategory);
358 values[Anum_pg_type_typispreferred - 1] = BoolGetDatum(typePreferred);
359 values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(true);
360 values[Anum_pg_type_typdelim - 1] = CharGetDatum(typDelim);
361 values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(relationOid);
362 values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(subscriptProcedure);
363 values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(elementType);
364 values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(arrayType);
365 values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(inputProcedure);
366 values[Anum_pg_type_typoutput - 1] = ObjectIdGetDatum(outputProcedure);
367 values[Anum_pg_type_typreceive - 1] = ObjectIdGetDatum(receiveProcedure);
368 values[Anum_pg_type_typsend - 1] = ObjectIdGetDatum(sendProcedure);
369 values[Anum_pg_type_typmodin - 1] = ObjectIdGetDatum(typmodinProcedure);
370 values[Anum_pg_type_typmodout - 1] = ObjectIdGetDatum(typmodoutProcedure);
371 values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(analyzeProcedure);
372 values[Anum_pg_type_typalign - 1] = CharGetDatum(alignment);
373 values[Anum_pg_type_typstorage - 1] = CharGetDatum(storage);
374 values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(typeNotNull);
375 values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(baseType);
376 values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(typeMod);
377 values[Anum_pg_type_typndims - 1] = Int32GetDatum(typNDims);
378 values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(typeCollation);
379
380 /*
381 * initialize the default binary value for this type. Check for nulls of
382 * course.
383 */
384 if (defaultTypeBin)
385 values[Anum_pg_type_typdefaultbin - 1] = CStringGetTextDatum(defaultTypeBin);
386 else
387 nulls[Anum_pg_type_typdefaultbin - 1] = true;
388
389 /*
390 * initialize the default value for this type.
391 */
392 if (defaultTypeValue)
393 values[Anum_pg_type_typdefault - 1] = CStringGetTextDatum(defaultTypeValue);
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
403 typacl = get_user_default_acl(OBJECT_TYPE, ownerId,
404 typeNamespace);
405 if (typacl != NULL)
406 values[Anum_pg_type_typacl - 1] = PointerGetDatum(typacl);
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 */
416 pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
417
418 tup = SearchSysCacheCopy2(TYPENAMENSP,
419 CStringGetDatum(typeName),
420 ObjectIdGetDatum(typeNamespace));
421 if (HeapTupleIsValid(tup))
422 {
423 Form_pg_type typform = (Form_pg_type) GETSTRUCT(tup);
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 */
441 if (OidIsValid(newTypeOid))
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 */
449 tup = heap_modify_tuple(tup,
450 RelationGetDescr(pg_type_desc),
451 values,
452 nulls,
453 replaces);
454
455 CatalogTupleUpdate(pg_type_desc, &tup->t_self, tup);
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 */
464 if (OidIsValid(newTypeOid))
465 typeObjectId = newTypeOid;
466 /* Use binary-upgrade override for pg_type.oid, if supplied. */
467 else if (IsBinaryUpgrade)
468 {
471 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
472 errmsg("pg_type OID value not set when in binary upgrade mode")));
473
474 typeObjectId = binary_upgrade_next_pg_type_oid;
476 }
477 else
478 {
479 typeObjectId = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId,
480 Anum_pg_type_oid);
481 }
482
483 values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typeObjectId);
484
485 tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
486 values, nulls);
487
488 CatalogTupleInsert(pg_type_desc, tup);
489 }
490
491 /*
492 * Create dependencies. We can/must skip this in bootstrap mode.
493 */
496 pg_type_desc,
497 (defaultTypeBin ?
498 stringToNode(defaultTypeBin) :
499 NULL),
500 typacl,
501 relationKind,
502 isImplicitArray,
503 isDependentType,
504 true, /* make extension dependency */
505 rebuildDeps);
506
507 /* Post creation hook for new type */
508 InvokeObjectPostCreateHook(TypeRelationId, typeObjectId, 0);
509
510 ObjectAddressSet(address, TypeRelationId, typeObjectId);
511
512 /*
513 * finish up
514 */
515 table_close(pg_type_desc, RowExclusiveLock);
516
517 return address;
518}
@ ACLCHECK_NOT_OWNER
Definition: acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:2652
Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid)
Definition: aclchk.c:4245
static Datum values[MAXATTR]
Definition: bootstrap.c:153
#define CStringGetTextDatum(s)
Definition: builtins.h:97
int64_t int64
Definition: c.h:536
int16_t int16
Definition: c.h:534
int32_t int32
Definition: c.h:535
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:448
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
#define storage
Definition: indent_codes.h:68
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
int i
Definition: isn.c:77
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:476
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:173
@ OBJECT_TYPE
Definition: parsenodes.h:2373
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
Oid binary_upgrade_next_pg_type_oid
Definition: pg_type.c:41
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:182
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:383
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
static Datum CharGetDatum(char X)
Definition: postgres.h:132
#define InvalidOid
Definition: postgres_ext.h:37
Definition: c.h:747
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:93
const char * name

References aclcheck_error(), ACLCHECK_NOT_OWNER, binary_upgrade_next_pg_type_oid, BoolGetDatum(), CatalogTupleInsert(), CatalogTupleUpdate(), CharGetDatum(), CStringGetDatum(), CStringGetTextDatum, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, GenerateTypeDependencies(), get_user_default_acl(), GetNewOidWithIndex(), GETSTRUCT(), heap_form_tuple(), heap_modify_tuple(), HeapTupleIsValid, i, Int16GetDatum(), Int32GetDatum(), InvalidOid, InvokeObjectPostCreateHook, IsBinaryUpgrade, IsBootstrapProcessingMode, name, NameGetDatum(), namestrcpy(), OBJECT_TYPE, ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, PointerGetDatum(), RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy2, storage, stringToNode(), HeapTupleData::t_self, table_close(), table_open(), and values.

Referenced by AddNewRelationType(), DefineDomain(), DefineEnum(), DefineRange(), DefineType(), and heap_create_with_catalog().

◆ TypeShellMake()

ObjectAddress TypeShellMake ( const char *  typeName,
Oid  typeNamespace,
Oid  ownerId 
)

Definition at line 57 of file pg_type.c.

58{
59 Relation pg_type_desc;
60 TupleDesc tupDesc;
61 int i;
62 HeapTuple tup;
63 Datum values[Natts_pg_type];
64 bool nulls[Natts_pg_type];
65 Oid typoid;
67 ObjectAddress address;
68
69 Assert(typeName);
70
71 /*
72 * open pg_type
73 */
74 pg_type_desc = table_open(TypeRelationId, RowExclusiveLock);
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);
95 values[Anum_pg_type_typname - 1] = NameGetDatum(&name);
96 values[Anum_pg_type_typnamespace - 1] = ObjectIdGetDatum(typeNamespace);
97 values[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(ownerId);
98 values[Anum_pg_type_typlen - 1] = Int16GetDatum(sizeof(int32));
99 values[Anum_pg_type_typbyval - 1] = BoolGetDatum(true);
100 values[Anum_pg_type_typtype - 1] = CharGetDatum(TYPTYPE_PSEUDO);
101 values[Anum_pg_type_typcategory - 1] = CharGetDatum(TYPCATEGORY_PSEUDOTYPE);
102 values[Anum_pg_type_typispreferred - 1] = BoolGetDatum(false);
103 values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(false);
104 values[Anum_pg_type_typdelim - 1] = CharGetDatum(DEFAULT_TYPDELIM);
105 values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(InvalidOid);
106 values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(InvalidOid);
107 values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(InvalidOid);
108 values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(InvalidOid);
109 values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(F_SHELL_IN);
110 values[Anum_pg_type_typoutput - 1] = ObjectIdGetDatum(F_SHELL_OUT);
111 values[Anum_pg_type_typreceive - 1] = ObjectIdGetDatum(InvalidOid);
112 values[Anum_pg_type_typsend - 1] = ObjectIdGetDatum(InvalidOid);
113 values[Anum_pg_type_typmodin - 1] = ObjectIdGetDatum(InvalidOid);
114 values[Anum_pg_type_typmodout - 1] = ObjectIdGetDatum(InvalidOid);
115 values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(InvalidOid);
116 values[Anum_pg_type_typalign - 1] = CharGetDatum(TYPALIGN_INT);
117 values[Anum_pg_type_typstorage - 1] = CharGetDatum(TYPSTORAGE_PLAIN);
118 values[Anum_pg_type_typnotnull - 1] = BoolGetDatum(false);
119 values[Anum_pg_type_typbasetype - 1] = ObjectIdGetDatum(InvalidOid);
120 values[Anum_pg_type_typtypmod - 1] = Int32GetDatum(-1);
121 values[Anum_pg_type_typndims - 1] = Int32GetDatum(0);
122 values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid);
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 {
132 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
133 errmsg("pg_type OID value not set when in binary upgrade mode")));
134
137 }
138 else
139 {
140 typoid = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId,
141 Anum_pg_type_oid);
142 }
143
144 values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typoid);
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 */
154 CatalogTupleInsert(pg_type_desc, tup);
155
156 /*
157 * Create dependencies. We can/must skip this in bootstrap mode.
158 */
161 pg_type_desc,
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 */
171 InvokeObjectPostCreateHook(TypeRelationId, typoid, 0);
172
173 ObjectAddressSet(address, TypeRelationId, typoid);
174
175 /*
176 * clean up and return the type-oid
177 */
178 heap_freetuple(tup);
179 table_close(pg_type_desc, RowExclusiveLock);
180
181 return address;
182}
TupleDesc rd_att
Definition: rel.h:112
#define DEFAULT_TYPDELIM
Definition: typecmds.h:22

References Assert(), binary_upgrade_next_pg_type_oid, BoolGetDatum(), CatalogTupleInsert(), CharGetDatum(), DEFAULT_TYPDELIM, ereport, errcode(), errmsg(), ERROR, GenerateTypeDependencies(), GetNewOidWithIndex(), heap_form_tuple(), heap_freetuple(), i, Int16GetDatum(), Int32GetDatum(), InvalidOid, InvokeObjectPostCreateHook, IsBinaryUpgrade, IsBootstrapProcessingMode, name, NameGetDatum(), namestrcpy(), ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, RelationData::rd_att, RowExclusiveLock, table_close(), table_open(), and values.

Referenced by compute_return_type(), and DefineType().

Variable Documentation

◆ BKI_SCHEMA_MACRO

TypeRelation_Rowtype_Id BKI_SCHEMA_MACRO
Initial value:
{
Oid oid

Definition at line 36 of file pg_type.h.

◆ FormData_pg_type

FormData_pg_type

Definition at line 254 of file pg_type.h.

◆ typalign

◆ typname