mirror of https://github.com/citusdata/citus.git
Do not rely on fk cache when truncating local data (#5018)
parent
9770a1bf00
commit
5c6069a74a
|
@ -734,8 +734,8 @@ HasForeignKeyWithLocalTable(Oid relationId)
|
|||
|
||||
|
||||
/*
|
||||
* GetForeignKeysWithLocalTables returns a list foreign keys for foreign key
|
||||
* relationaships that relation has with local tables.
|
||||
* GetForeignKeysWithLocalTables returns a list of foreign keys for foreign key
|
||||
* relationships that relation has with local tables.
|
||||
*/
|
||||
static List *
|
||||
GetForeignKeysWithLocalTables(Oid relationId)
|
||||
|
@ -753,6 +753,21 @@ GetForeignKeysWithLocalTables(Oid relationId)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* GetForeignKeysFromLocalTables returns a list of foreign keys where the referencing
|
||||
* relation is a local table.
|
||||
*/
|
||||
List *
|
||||
GetForeignKeysFromLocalTables(Oid relationId)
|
||||
{
|
||||
int referencedFKeysFlag = INCLUDE_REFERENCED_CONSTRAINTS |
|
||||
INCLUDE_LOCAL_TABLES;
|
||||
List *referencingFKeyList = GetForeignKeyOids(relationId, referencedFKeysFlag);
|
||||
|
||||
return referencingFKeyList;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HasForeignKeyToCitusLocalTable returns true if any of the foreign key constraints
|
||||
* on the relation with relationId references to a citus local table.
|
||||
|
@ -1102,6 +1117,30 @@ GetReferencedTableId(Oid foreignKeyId)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* GetReferencingTableId returns OID of the referencing relation for the foreign
|
||||
* key with foreignKeyId. If there is no such foreign key, then this function
|
||||
* returns InvalidOid.
|
||||
*/
|
||||
Oid
|
||||
GetReferencingTableId(Oid foreignKeyId)
|
||||
{
|
||||
HeapTuple heapTuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(foreignKeyId));
|
||||
if (!HeapTupleIsValid(heapTuple))
|
||||
{
|
||||
/* no such foreign key */
|
||||
return InvalidOid;
|
||||
}
|
||||
|
||||
Form_pg_constraint constraintForm = (Form_pg_constraint) GETSTRUCT(heapTuple);
|
||||
Oid referencingTableId = constraintForm->conrelid;
|
||||
|
||||
ReleaseSysCache(heapTuple);
|
||||
|
||||
return referencingTableId;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsTableTypeIncluded returns true if type of the table with relationId (distributed,
|
||||
* reference, Citus local or Postgres local) is included in the flags, false if not
|
||||
|
|
|
@ -217,25 +217,20 @@ EnsureLocalTableCanBeTruncated(Oid relationId)
|
|||
"tables.")));
|
||||
}
|
||||
|
||||
/* make sure there are no foreign key references from a local table */
|
||||
SetForeignConstraintRelationshipGraphInvalid();
|
||||
List *referencingRelationList = ReferencingRelationIdList(relationId);
|
||||
|
||||
Oid referencingRelation = InvalidOid;
|
||||
foreach_oid(referencingRelation, referencingRelationList)
|
||||
List *referencingForeignConstaintsFromLocalTables =
|
||||
GetForeignKeysFromLocalTables(relationId);
|
||||
if (list_length(referencingForeignConstaintsFromLocalTables) > 0)
|
||||
{
|
||||
/* we do not truncate a table if there is a local table referencing it */
|
||||
if (!IsCitusTable(referencingRelation))
|
||||
{
|
||||
char *referencedRelationName = get_rel_name(relationId);
|
||||
char *referencingRelationName = get_rel_name(referencingRelation);
|
||||
Oid foreignKeyId = linitial_oid(referencingForeignConstaintsFromLocalTables);
|
||||
Oid referencingRelation = GetReferencingTableId(foreignKeyId);
|
||||
char *referencedRelationName = get_rel_name(relationId);
|
||||
char *referencingRelationName = get_rel_name(referencingRelation);
|
||||
|
||||
ereport(ERROR, (errmsg("cannot truncate a table referenced in a "
|
||||
"foreign key constraint by a local table"),
|
||||
errdetail("Table \"%s\" references \"%s\"",
|
||||
referencingRelationName,
|
||||
referencedRelationName)));
|
||||
}
|
||||
ereport(ERROR, (errmsg("cannot truncate a table referenced in a "
|
||||
"foreign key constraint by a local table"),
|
||||
errdetail("Table \"%s\" references \"%s\"",
|
||||
referencingRelationName,
|
||||
referencedRelationName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ extern bool AnyForeignKeyDependsOnIndex(Oid indexId);
|
|||
extern bool HasForeignKeyWithLocalTable(Oid relationId);
|
||||
extern bool HasForeignKeyToCitusLocalTable(Oid relationId);
|
||||
extern bool HasForeignKeyToReferenceTable(Oid relationOid);
|
||||
extern List * GetForeignKeysFromLocalTables(Oid relationId);
|
||||
extern bool TableReferenced(Oid relationOid);
|
||||
extern bool TableReferencing(Oid relationOid);
|
||||
extern bool ConstraintIsAUniquenessConstraint(char *inputConstaintName, Oid relationId);
|
||||
|
@ -217,6 +218,7 @@ extern bool ConstraintWithIdIsOfType(Oid constraintId, char targetConstraintType
|
|||
extern bool TableHasExternalForeignKeys(Oid relationId);
|
||||
extern List * GetForeignKeyOids(Oid relationId, int flags);
|
||||
extern Oid GetReferencedTableId(Oid foreignKeyId);
|
||||
extern Oid GetReferencingTableId(Oid foreignKeyId);
|
||||
extern bool RelationInvolvedInAnyNonInheritedForeignKeys(Oid relationId);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue