Refactor foreign_key_relationship.c (#4438)

pull/4436/head
Onur Tirtir 2020-12-22 18:12:02 +03:00 committed by GitHub
parent dca83e5938
commit 3f60b08b11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 96 additions and 37 deletions

View File

@ -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;
}