* Create dependencies. We can/must skip this in bootstrap mode.
*/
if (!IsBootstrapProcessingMode())
- GenerateTypeDependencies(typeNamespace,
- typoid,
- InvalidOid,
+ GenerateTypeDependencies(typoid,
+ (Form_pg_type) GETSTRUCT(tup),
+ NULL,
+ NULL,
0,
- ownerId,
- F_SHELL_IN,
- F_SHELL_OUT,
- InvalidOid,
- InvalidOid,
- InvalidOid,
- InvalidOid,
- InvalidOid,
- InvalidOid,
false,
- InvalidOid,
- InvalidOid,
- NULL,
+ false,
false);
/* Post creation hook for new shell type */
{
Relation pg_type_desc;
Oid typeObjectId;
+ bool isDependentType;
bool rebuildDeps = false;
+ Acl *typacl;
HeapTuple tup;
bool nulls[Natts_pg_type];
bool replaces[Natts_pg_type];
Datum values[Natts_pg_type];
NameData name;
int i;
- Acl *typacl = NULL;
ObjectAddress address;
/*
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("fixed-size types must have storage PLAIN")));
+ /*
+ * This is a dependent type if it's an implicitly-created array type, or
+ * if it's a relation rowtype that's not a composite type. For such types
+ * we'll leave the ACL empty, and we'll skip creating some dependency
+ * records because there will be a dependency already through the
+ * depended-on type or relation. (Caution: this is closely intertwined
+ * with some behavior in GenerateTypeDependencies.)
+ */
+ isDependentType = isImplicitArray ||
+ (OidIsValid(relationOid) && relationKind != RELKIND_COMPOSITE_TYPE);
+
/*
* initialize arrays needed for heap_form_tuple or heap_modify_tuple
*/
else
nulls[Anum_pg_type_typdefault - 1] = true;
- typacl = get_user_default_acl(OBJECT_TYPE, ownerId,
- typeNamespace);
+ /*
+ * Initialize the type's ACL, too. But dependent types don't get one.
+ */
+ if (isDependentType)
+ typacl = NULL;
+ else
+ typacl = get_user_default_acl(OBJECT_TYPE, ownerId,
+ typeNamespace);
if (typacl != NULL)
values[Anum_pg_type_typacl - 1] = PointerGetDatum(typacl);
else
* Create dependencies. We can/must skip this in bootstrap mode.
*/
if (!IsBootstrapProcessingMode())
- GenerateTypeDependencies(typeNamespace,
- typeObjectId,
- relationOid,
- relationKind,
- ownerId,
- inputProcedure,
- outputProcedure,
- receiveProcedure,
- sendProcedure,
- typmodinProcedure,
- typmodoutProcedure,
- analyzeProcedure,
- elementType,
- isImplicitArray,
- baseType,
- typeCollation,
+ GenerateTypeDependencies(typeObjectId,
+ (Form_pg_type) GETSTRUCT(tup),
(defaultTypeBin ?
stringToNode(defaultTypeBin) :
NULL),
+ typacl,
+ relationKind,
+ isImplicitArray,
+ isDependentType,
rebuildDeps);
/* Post creation hook for new type */
/*
* GenerateTypeDependencies: build the dependencies needed for a type
*
+ * Most of what this function needs to know about the type is passed as the
+ * new pg_type row, typeForm. But we can't get at the varlena fields through
+ * that, so defaultExpr and typacl are passed separately. (typacl is really
+ * "Acl *", but we declare it "void *" to avoid including acl.h in pg_type.h.)
+ *
+ * relationKind and isImplicitArray aren't visible in the pg_type row either,
+ * so they're also passed separately.
+ *
+ * isDependentType is true if this is an implicit array or relation rowtype;
+ * that means it doesn't need its own dependencies on owner etc.
+ *
* If rebuild is true, we remove existing dependencies and rebuild them
* from scratch. This is needed for ALTER TYPE, and also when replacing
* a shell type. We don't remove an existing extension dependency, though.
* that type will become a member of the extension.)
*/
void
-GenerateTypeDependencies(Oid typeNamespace,
- Oid typeObjectId,
- Oid relationOid, /* only for relation rowtypes */
- char relationKind, /* ditto */
- Oid owner,
- Oid inputProcedure,
- Oid outputProcedure,
- Oid receiveProcedure,
- Oid sendProcedure,
- Oid typmodinProcedure,
- Oid typmodoutProcedure,
- Oid analyzeProcedure,
- Oid elementType,
- bool isImplicitArray,
- Oid baseType,
- Oid typeCollation,
+GenerateTypeDependencies(Oid typeObjectId,
+ Form_pg_type typeForm,
Node *defaultExpr,
+ void *typacl,
+ char relationKind, /* only for relation rowtypes */
+ bool isImplicitArray,
+ bool isDependentType,
bool rebuild)
{
ObjectAddress myself,
myself.objectSubId = 0;
/*
- * Make dependencies on namespace, owner, extension.
+ * Make dependencies on namespace, owner, ACL, extension.
*
- * For a relation rowtype (that's not a composite type), we should skip
- * these because we'll depend on them indirectly through the pg_class
- * entry. Likewise, skip for implicit arrays since we'll depend on them
- * through the element type.
+ * Skip these for a dependent type, since it will have such dependencies
+ * indirectly through its depended-on type or relation.
*/
- if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) &&
- !isImplicitArray)
+ if (!isDependentType)
{
referenced.classId = NamespaceRelationId;
- referenced.objectId = typeNamespace;
+ referenced.objectId = typeForm->typnamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
- recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
+ recordDependencyOnOwner(TypeRelationId, typeObjectId,
+ typeForm->typowner);
+
+ recordDependencyOnNewAcl(TypeRelationId, typeObjectId, 0,
+ typeForm->typowner, typacl);
recordDependencyOnCurrentExtension(&myself, rebuild);
}
/* Normal dependencies on the I/O functions */
- if (OidIsValid(inputProcedure))
+ if (OidIsValid(typeForm->typinput))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = inputProcedure;
+ referenced.objectId = typeForm->typinput;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(outputProcedure))
+ if (OidIsValid(typeForm->typoutput))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = outputProcedure;
+ referenced.objectId = typeForm->typoutput;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(receiveProcedure))
+ if (OidIsValid(typeForm->typreceive))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = receiveProcedure;
+ referenced.objectId = typeForm->typreceive;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(sendProcedure))
+ if (OidIsValid(typeForm->typsend))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = sendProcedure;
+ referenced.objectId = typeForm->typsend;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(typmodinProcedure))
+ if (OidIsValid(typeForm->typmodin))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = typmodinProcedure;
+ referenced.objectId = typeForm->typmodin;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(typmodoutProcedure))
+ if (OidIsValid(typeForm->typmodout))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = typmodoutProcedure;
+ referenced.objectId = typeForm->typmodout;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
- if (OidIsValid(analyzeProcedure))
+ if (OidIsValid(typeForm->typanalyze))
{
referenced.classId = ProcedureRelationId;
- referenced.objectId = analyzeProcedure;
+ referenced.objectId = typeForm->typanalyze;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
* relation is, and not otherwise. And in the latter, of course we get the
* opposite effect.
*/
- if (OidIsValid(relationOid))
+ if (OidIsValid(typeForm->typrelid))
{
referenced.classId = RelationRelationId;
- referenced.objectId = relationOid;
+ referenced.objectId = typeForm->typrelid;
referenced.objectSubId = 0;
if (relationKind != RELKIND_COMPOSITE_TYPE)
* dependent on the element type. Otherwise, if it has an element type,
* the dependency is a normal one.
*/
- if (OidIsValid(elementType))
+ if (OidIsValid(typeForm->typelem))
{
referenced.classId = TypeRelationId;
- referenced.objectId = elementType;
+ referenced.objectId = typeForm->typelem;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced,
isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL);
}
/* Normal dependency from a domain to its base type. */
- if (OidIsValid(baseType))
+ if (OidIsValid(typeForm->typbasetype))
{
referenced.classId = TypeRelationId;
- referenced.objectId = baseType;
+ referenced.objectId = typeForm->typbasetype;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Normal dependency from a domain to its collation. */
/* We know the default collation is pinned, so don't bother recording it */
- if (OidIsValid(typeCollation) && typeCollation != DEFAULT_COLLATION_OID)
+ if (OidIsValid(typeForm->typcollation) &&
+ typeForm->typcollation != DEFAULT_COLLATION_OID)
{
referenced.classId = CollationRelationId;
- referenced.objectId = typeCollation;
+ referenced.objectId = typeForm->typcollation;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}