mirror of https://github.com/citusdata/citus.git
parent
27d74f1540
commit
928cee6af6
|
@ -78,7 +78,14 @@ typedef struct ForeignConstraintRelationshipEdge
|
||||||
|
|
||||||
static ForeignConstraintRelationshipGraph *fConstraintRelationshipGraph = NULL;
|
static ForeignConstraintRelationshipGraph *fConstraintRelationshipGraph = NULL;
|
||||||
|
|
||||||
|
static ForeignConstraintRelationshipNode * GetRelationshipNodeForRelationId(Oid
|
||||||
|
relationId,
|
||||||
|
bool *isFound);
|
||||||
static void CreateForeignConstraintRelationshipGraph(void);
|
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 void PopulateAdjacencyLists(void);
|
||||||
static int CompareForeignConstraintRelationshipEdges(const void *leftElement,
|
static int CompareForeignConstraintRelationshipEdges(const void *leftElement,
|
||||||
const void *rightElement);
|
const void *rightElement);
|
||||||
|
@ -108,7 +115,7 @@ ReferencedRelationIdList(Oid relationId)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ReferencingRelationIdList is a wrapper function around GetForeignConstraintRelationshipHelper
|
* 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
|
* 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
|
* by relation C, then the result list for relation C consists of the relation
|
||||||
|
@ -129,16 +136,9 @@ ReferencingRelationIdList(Oid relationId)
|
||||||
static List *
|
static List *
|
||||||
GetForeignConstraintRelationshipHelper(Oid relationId, bool isReferencing)
|
GetForeignConstraintRelationshipHelper(Oid relationId, bool isReferencing)
|
||||||
{
|
{
|
||||||
List *foreignConstraintList = NIL;
|
|
||||||
List *foreignNodeList = NIL;
|
|
||||||
bool isFound = false;
|
bool isFound = false;
|
||||||
|
ForeignConstraintRelationshipNode *relationshipNode =
|
||||||
CreateForeignConstraintRelationshipGraph();
|
GetRelationshipNodeForRelationId(relationId, &isFound);
|
||||||
|
|
||||||
ForeignConstraintRelationshipNode *relationNode =
|
|
||||||
(ForeignConstraintRelationshipNode *) hash_search(
|
|
||||||
fConstraintRelationshipGraph->nodeMap, &relationId,
|
|
||||||
HASH_FIND, &isFound);
|
|
||||||
|
|
||||||
if (!isFound)
|
if (!isFound)
|
||||||
{
|
{
|
||||||
|
@ -149,24 +149,39 @@ GetForeignConstraintRelationshipHelper(Oid relationId, bool isReferencing)
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetConnectedListHelper(relationNode, &foreignNodeList, isReferencing);
|
List *foreignNodeList = NIL;
|
||||||
|
GetConnectedListHelper(relationshipNode, &foreignNodeList, isReferencing);
|
||||||
|
|
||||||
/*
|
/* reset visited flags in foreign key graph */
|
||||||
* We need only their OIDs, we get back node list to make their visited
|
SetRelationshipNodeListNotVisited(foreignNodeList);
|
||||||
* variable to false for using them iteratively.
|
|
||||||
*/
|
|
||||||
ForeignConstraintRelationshipNode *currentNode = NULL;
|
|
||||||
foreach_ptr(currentNode, foreignNodeList)
|
|
||||||
{
|
|
||||||
foreignConstraintList = lappend_oid(foreignConstraintList,
|
|
||||||
currentNode->relationId);
|
|
||||||
currentNode->visited = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set to false separately, since we don't add itself to foreign node list */
|
/* 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,
|
GetConnectedListHelper(ForeignConstraintRelationshipNode *node, List **adjacentNodeList,
|
||||||
bool isReferencing)
|
bool isReferencing)
|
||||||
{
|
{
|
||||||
List *neighbourList = NIL;
|
|
||||||
|
|
||||||
node->visited = true;
|
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)
|
if (isReferencing)
|
||||||
{
|
{
|
||||||
neighbourList = node->backAdjacencyList;
|
return relationshipNode->backAdjacencyList;
|
||||||
}
|
}
|
||||||
else
|
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;
|
return relationIdList;
|
||||||
foreach_ptr(neighborNode, neighbourList)
|
|
||||||
{
|
|
||||||
if (neighborNode->visited == false)
|
|
||||||
{
|
|
||||||
*adjacentNodeList = lappend(*adjacentNodeList, neighborNode);
|
|
||||||
GetConnectedListHelper(neighborNode, adjacentNodeList, isReferencing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue