static void storeProcedures(List *opfamilyname, Oid amoid,
Oid opfamilyoid, Oid opclassoid,
List *procedures, bool isAdd);
+static bool typeDepNeeded(Oid typid, OpFamilyMember *member, bool isProc);
static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
List *operators);
static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
foreach(l, operators)
{
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
+ DependencyType opdeptype;
char oppurpose;
/*
if (OidIsValid(opclassoid))
{
/* if contained in an opclass, use a NORMAL dep on operator */
+ opdeptype = DEPENDENCY_NORMAL;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* ... and an INTERNAL dep on the opclass */
else
{
/* if "loose" in the opfamily, use a AUTO dep on operator */
+ opdeptype = DEPENDENCY_AUTO;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
/* ... and an AUTO dep on the opfamily */
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
+ if (typeDepNeeded(op->lefttype, op, false))
+ {
+ referenced.classId = TypeRelationId;
+ referenced.objectId = op->lefttype;
+ referenced.objectSubId = 0;
+
+ /* use same dependency type as for operator */
+ recordDependencyOn(&myself, &referenced, opdeptype);
+ }
+
+ if (op->lefttype != op->righttype &&
+ typeDepNeeded(op->righttype, op, false))
+ {
+ referenced.classId = TypeRelationId;
+ referenced.objectId = op->righttype;
+ referenced.objectSubId = 0;
+
+ /* use same dependency type as for operator */
+ recordDependencyOn(&myself, &referenced, opdeptype);
+ }
+
/* A search operator also needs a dep on the referenced opfamily */
if (OidIsValid(op->sortfamily))
{
foreach(l, procedures)
{
OpFamilyMember *proc = (OpFamilyMember *) lfirst(l);
+ DependencyType procdeptype;
/*
* If adding to an existing family, check for conflict with an
if (OidIsValid(opclassoid))
{
/* if contained in an opclass, use a NORMAL dep on procedure */
+ procdeptype = DEPENDENCY_NORMAL;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* ... and an INTERNAL dep on the opclass */
else
{
/* if "loose" in the opfamily, use a AUTO dep on procedure */
+ procdeptype = DEPENDENCY_AUTO;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
/* ... and an AUTO dep on the opfamily */
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
+
+ if (typeDepNeeded(proc->lefttype, proc, true))
+ {
+ referenced.classId = TypeRelationId;
+ referenced.objectId = proc->lefttype;
+ referenced.objectSubId = 0;
+
+ /* use same dependency type as for procedure */
+ recordDependencyOn(&myself, &referenced, procdeptype);
+ }
+
+ if (proc->lefttype != proc->righttype &&
+ typeDepNeeded(proc->righttype, proc, true))
+ {
+ referenced.classId = TypeRelationId;
+ referenced.objectId = proc->righttype;
+ referenced.objectSubId = 0;
+
+ /* use same dependency type as for procedure */
+ recordDependencyOn(&myself, &referenced, procdeptype);
+ }
+
/* Post create hook of access method procedure */
InvokeObjectPostCreateHook(AccessMethodProcedureRelationId,
entryoid, 0);
table_close(rel, RowExclusiveLock);
}
+/*
+ * Detect whether a pg_amop or pg_amproc entry needs an explicit dependency
+ * on its lefttype or righttype.
+ *
+ * We make such a dependency unless the entry has an indirect dependency
+ * via its referenced operator or function. That's nearly always true
+ * for operators, but might well not be true for support functions.
+ */
+static bool
+typeDepNeeded(Oid typid, OpFamilyMember *member, bool isProc)
+{
+ bool result = true;
+
+ if (isProc)
+ {
+ Oid *argtypes;
+ int nargs;
+
+ (void) get_func_signature(member->object, &argtypes, &nargs);
+ for (int i = 0; i < nargs; i++)
+ {
+ if (typid == argtypes[i])
+ {
+ result = false; /* match, no dependency needed */
+ break;
+ }
+ }
+ pfree(argtypes);
+ }
+ else
+ {
+ Oid lefttype,
+ righttype;
+
+ op_input_types(member->object, &lefttype, &righttype);
+ if (typid == lefttype || typid == righttype)
+ result = false; /* match, no dependency needed */
+ }
+ return result;
+}
+
/*
* Remove operator entries from an opfamily.