From 928cee6af67a757486e270e9a320d2647bf88675 Mon Sep 17 00:00:00 2001 From: Onur Tirtir Date: Tue, 22 Dec 2020 18:12:02 +0300 Subject: [PATCH] Refactor foreign_key_relationship.c (#4438) (cherry picked from commit 3f60b08b11c8b3ec5de14b737e78b6b29be67d0d) --- .../utils/foreign_key_relationship.c | 133 +++++++++++++----- 1 file changed, 96 insertions(+), 37 deletions(-) diff --git a/src/backend/distributed/utils/foreign_key_relationship.c b/src/backend/distributed/utils/foreign_key_relationship.c index 1dd61bcf5..71cfbee48 100644 --- a/src/backend/distributed/utils/foreign_key_relationship.c +++ b/src/backend/distributed/utils/foreign_key_relationship.c @@ -78,7 +78,14 @@ typedef struct ForeignConstraintRelationshipEdge static ForeignConstraintRelationshipGraph *fConstraintRelationshipGraph = NULL; +static ForeignConstraintRelationshipNode * GetRelationshipNodeForRelationId(Oid + relationId, + bool *isFound); static void CreateForeignConstraintRelationshipGraph(void); +static List * GetNeighbourList(ForeignConstraintRelationshipNode *relationshipNode, + bool isReferencing); +static void SetRelationshipNodeListNotVisited(List *relationshipNodeList); +static List * GetRelationIdsFromRelationshipNodeList(List *fKeyRelationshipNodeList); static void PopulateAdjacencyLists(void); static int CompareForeignConstraintRelationshipEdges(const void *leftElement, const void *rightElement); @@ -108,7 +115,7 @@ ReferencedRelationIdList(Oid relationId) /* * ReferencingRelationIdList is a wrapper function around GetForeignConstraintRelationshipHelper - * to get list of relation IDs which are referencing by the given relation id. + * to get list of relation IDs which are referencing to given relation id. * * Note that, if relation A is referenced by relation B and relation B is referenced * by relation C, then the result list for relation C consists of the relation @@ -129,16 +136,9 @@ ReferencingRelationIdList(Oid relationId) static List * GetForeignConstraintRelationshipHelper(Oid relationId, bool isReferencing) { - List *foreignConstraintList = NIL; - List *foreignNodeList = NIL; bool isFound = false; - - CreateForeignConstraintRelationshipGraph(); - - ForeignConstraintRelationshipNode *relationNode = - (ForeignConstraintRelationshipNode *) hash_search( - fConstraintRelationshipGraph->nodeMap, &relationId, - HASH_FIND, &isFound); + ForeignConstraintRelationshipNode *relationshipNode = + GetRelationshipNodeForRelationId(relationId, &isFound); if (!isFound) { @@ -149,24 +149,39 @@ GetForeignConstraintRelationshipHelper(Oid relationId, bool isReferencing) return NIL; } - GetConnectedListHelper(relationNode, &foreignNodeList, isReferencing); + List *foreignNodeList = NIL; + GetConnectedListHelper(relationshipNode, &foreignNodeList, isReferencing); - /* - * We need only their OIDs, we get back node list to make their visited - * variable to false for using them iteratively. - */ - ForeignConstraintRelationshipNode *currentNode = NULL; - foreach_ptr(currentNode, foreignNodeList) - { - foreignConstraintList = lappend_oid(foreignConstraintList, - currentNode->relationId); - currentNode->visited = false; - } + /* reset visited flags in foreign key graph */ + SetRelationshipNodeListNotVisited(foreignNodeList); /* set to false separately, since we don't add itself to foreign node list */ - relationNode->visited = false; + relationshipNode->visited = false; - return foreignConstraintList; + List *relationIdList = GetRelationIdsFromRelationshipNodeList(foreignNodeList); + return relationIdList; +} + + +/* + * GetRelationshipNodeForRelationId searches foreign key graph for relation + * with relationId and returns ForeignConstraintRelationshipNode object for + * relation if it exists in graph. Otherwise, sets isFound to false. + * + * Also before searching foreign key graph, this function implicitly builds + * foreign key graph if it's invalid or not built yet. + */ +static ForeignConstraintRelationshipNode * +GetRelationshipNodeForRelationId(Oid relationId, bool *isFound) +{ + CreateForeignConstraintRelationshipGraph(); + + ForeignConstraintRelationshipNode *relationshipNode = + (ForeignConstraintRelationshipNode *) hash_search( + fConstraintRelationshipGraph->nodeMap, &relationId, + HASH_FIND, isFound); + + return relationshipNode; } @@ -259,28 +274,72 @@ static void GetConnectedListHelper(ForeignConstraintRelationshipNode *node, List **adjacentNodeList, bool isReferencing) { - List *neighbourList = NIL; - node->visited = true; + ForeignConstraintRelationshipNode *neighbourNode = NULL; + List *neighbourList = GetNeighbourList(node, isReferencing); + foreach_ptr(neighbourNode, neighbourList) + { + if (neighbourNode->visited == false) + { + *adjacentNodeList = lappend(*adjacentNodeList, neighbourNode); + GetConnectedListHelper(neighbourNode, adjacentNodeList, isReferencing); + } + } +} + + +/* + * GetNeighbourList returns copy of relevant adjacency list of given + * ForeignConstraintRelationshipNode object depending on the isReferencing + * flag. + */ +static List * +GetNeighbourList(ForeignConstraintRelationshipNode *relationshipNode, bool isReferencing) +{ if (isReferencing) { - neighbourList = node->backAdjacencyList; + return relationshipNode->backAdjacencyList; } else { - neighbourList = node->adjacencyList; + return relationshipNode->adjacencyList; + } +} + + +/* + * SetRelationshipNodeListNotVisited takes a list of ForeignConstraintRelationshipNode + * objects and sets their visited flags to false. + */ +static void +SetRelationshipNodeListNotVisited(List *relationshipNodeList) +{ + ForeignConstraintRelationshipNode *relationshipNode = NULL; + foreach_ptr(relationshipNode, relationshipNodeList) + { + relationshipNode->visited = false; + } +} + + +/* + * GetRelationIdsFromRelationshipNodeList returns list of relationId's for + * given ForeignConstraintRelationshipNode object list. + */ +static List * +GetRelationIdsFromRelationshipNodeList(List *fKeyRelationshipNodeList) +{ + List *relationIdList = NIL; + + ForeignConstraintRelationshipNode *fKeyRelationshipNode = NULL; + foreach_ptr(fKeyRelationshipNode, fKeyRelationshipNodeList) + { + Oid relationId = fKeyRelationshipNode->relationId; + relationIdList = lappend_oid(relationIdList, relationId); } - ForeignConstraintRelationshipNode *neighborNode = NULL; - foreach_ptr(neighborNode, neighbourList) - { - if (neighborNode->visited == false) - { - *adjacentNodeList = lappend(*adjacentNodeList, neighborNode); - GetConnectedListHelper(neighborNode, adjacentNodeList, isReferencing); - } - } + return relationIdList; }