mirror of https://github.com/citusdata/citus.git
refactor
parent
2ac2399005
commit
6bacdbab46
|
@ -136,7 +136,7 @@ static List * TranslatedVars(PlannerInfo *root, int relationIndex);
|
|||
static void WarnIfListHasForeignDistributedTable(List *rangeTableList);
|
||||
static void ErrorIfMergeHasUnsupportedTables(Query *parse, List *rangeTableList);
|
||||
static void AddFastPathRestrictInfoIntoPlannerContext(
|
||||
PlannerRestrictionContext *plannerRestrictionContext);
|
||||
PlannerRestrictionContext *plannerRestrictionContext, int fastPathRelId);
|
||||
static List * GenerateImplicitJoinRestrictInfoList(PlannerInfo *plannerInfo,
|
||||
RelOptInfo *innerrel,
|
||||
RelOptInfo *outerrel);
|
||||
|
@ -706,9 +706,6 @@ PlanFastPathDistributedStmt(DistributedPlanningContext *planContext,
|
|||
planContext->plannerRestrictionContext->fastPathRestrictionContext->
|
||||
fastPathRouterQuery = true;
|
||||
|
||||
planContext->plannerRestrictionContext->fastPathRestrictionContext->
|
||||
distRelId = fastPathRelId;
|
||||
|
||||
if (distributionKeyValue == NULL)
|
||||
{
|
||||
/* nothing to record */
|
||||
|
@ -726,7 +723,8 @@ PlanFastPathDistributedStmt(DistributedPlanningContext *planContext,
|
|||
planContext->boundParams);
|
||||
|
||||
/* generate simple base restrict info inside plannerRestrictionContext */
|
||||
AddFastPathRestrictInfoIntoPlannerContext(planContext->plannerRestrictionContext);
|
||||
AddFastPathRestrictInfoIntoPlannerContext(planContext->plannerRestrictionContext,
|
||||
fastPathRelId);
|
||||
|
||||
return CreateDistributedPlannedStmt(planContext);
|
||||
}
|
||||
|
@ -1860,7 +1858,7 @@ CheckNodeCopyAndSerialization(Node *node)
|
|||
static
|
||||
void
|
||||
AddFastPathRestrictInfoIntoPlannerContext(
|
||||
PlannerRestrictionContext *plannerRestrictionContext)
|
||||
PlannerRestrictionContext *plannerRestrictionContext, int fastPathRelId)
|
||||
{
|
||||
if (plannerRestrictionContext->fastPathRestrictionContext == NULL ||
|
||||
plannerRestrictionContext->fastPathRestrictionContext->distributionKeyValue ==
|
||||
|
@ -1871,8 +1869,7 @@ AddFastPathRestrictInfoIntoPlannerContext(
|
|||
|
||||
Const *distKeyVal =
|
||||
plannerRestrictionContext->fastPathRestrictionContext->distributionKeyValue;
|
||||
Var *partitionColumn = PartitionColumn(
|
||||
plannerRestrictionContext->fastPathRestrictionContext->distRelId, 1);
|
||||
Var *partitionColumn = PartitionColumn(fastPathRelId, 1);
|
||||
OpExpr *partitionExpression = MakeOpExpression(partitionColumn,
|
||||
BTEqualStrategyNumber);
|
||||
Node *rightOp = get_rightop((Expr *) partitionExpression);
|
||||
|
|
|
@ -67,8 +67,8 @@ static List * LatestLargeDataTransfer(List *candidateJoinOrders);
|
|||
static void PrintJoinOrderList(List *joinOrder);
|
||||
static uint32 LargeDataTransferLocation(List *joinOrder);
|
||||
static List * TableEntryListDifference(List *lhsTableList, List *rhsTableList);
|
||||
static bool ConvertSemiToInnerInJoinInfoContext(JoinInfoContext *joinOrderContext);
|
||||
static bool JoinInfoContextHasAntiJoin(JoinInfoContext *joinOrderContext);
|
||||
static bool ConvertSemiToInnerInJoinOrderInfoList(List *joinOrderInfoList);
|
||||
static bool JoinOrderInfoListContainsAntiJoin(List *joinOrderInfoList);
|
||||
static List * FindApplicableJoinClausesForTables(List *joinRestrictInfoListList,
|
||||
List *generatedEcJoinClauseList,
|
||||
List *lhsTableIdList,
|
||||
|
@ -532,11 +532,11 @@ ExtractApplicableJoinClauseContextFromJoinList(List *joinOrderList)
|
|||
* applicable join rules for the nodes in the list.
|
||||
*/
|
||||
List *
|
||||
FixedJoinOrderList(List *tableEntryList, JoinInfoContext *joinInfoContext,
|
||||
FixedJoinOrderList(List *tableEntryList, List *joinOrderInfoList,
|
||||
List *joinRestrictInfoListList, List *generatedEcJoinClauseList)
|
||||
{
|
||||
/* we donot support anti joins as ruleutils files cannot deparse JOIN_ANTI */
|
||||
if (JoinInfoContextHasAntiJoin(joinInfoContext))
|
||||
if (JoinOrderInfoListContainsAntiJoin(joinOrderInfoList))
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg(
|
||||
|
@ -550,14 +550,14 @@ FixedJoinOrderList(List *tableEntryList, JoinInfoContext *joinInfoContext,
|
|||
* at query_pushdown_planning that planner did not actually plan any semi join.
|
||||
* ruleutils files cannot deparse JOIN_SEMI, so we convert those to JOIN_INNER.
|
||||
*/
|
||||
ConvertSemiToInnerInJoinInfoContext(joinInfoContext);
|
||||
ConvertSemiToInnerInJoinOrderInfoList(joinOrderInfoList);
|
||||
|
||||
List *joinOrderList = NIL;
|
||||
List *joinedTableList = NIL;
|
||||
JoinOrderNode *nextJoinNode = NULL;
|
||||
|
||||
/* fetch joininfo */
|
||||
JoinInfo *firstJoinInfo = (JoinInfo *) list_nth(joinInfoContext->joinInfoList, 0);
|
||||
JoinOrderInfo *firstJoinInfo = (JoinOrderInfo *) list_nth(joinOrderInfoList, 0);
|
||||
|
||||
/* add first table into joinedtable list */
|
||||
TableEntry *firstTable = TableEntryByRangeTableId(tableEntryList,
|
||||
|
@ -577,18 +577,18 @@ FixedJoinOrderList(List *tableEntryList, JoinInfoContext *joinInfoContext,
|
|||
firstJoinInfo->joinType);
|
||||
joinOrderList = lappend(joinOrderList, currentJoinNode);
|
||||
|
||||
JoinInfo *joinInfo = NULL;
|
||||
foreach_ptr(joinInfo, joinInfoContext->joinInfoList)
|
||||
JoinOrderInfo *joinOrderInfo = NULL;
|
||||
foreach_ptr(joinOrderInfo, joinOrderInfoList)
|
||||
{
|
||||
TableEntry *nextTable = TableEntryByRangeTableId(tableEntryList,
|
||||
joinInfo->rightTableIdx);
|
||||
joinOrderInfo->rightTableIdx);
|
||||
|
||||
nextJoinNode = EvaluateJoinRules(joinedTableList,
|
||||
currentJoinNode,
|
||||
nextTable,
|
||||
joinRestrictInfoListList,
|
||||
generatedEcJoinClauseList,
|
||||
joinInfo->joinType);
|
||||
joinOrderInfo->joinType);
|
||||
|
||||
if (nextJoinNode == NULL)
|
||||
{
|
||||
|
@ -618,16 +618,16 @@ FixedJoinOrderList(List *tableEntryList, JoinInfoContext *joinInfoContext,
|
|||
|
||||
|
||||
/*
|
||||
* JoinInfoContextHasAntiJoin returns true if given join info context contains
|
||||
* JoinOrderInfoListContainsAntiJoin returns true if given join order info list contains
|
||||
* an anti join.
|
||||
*/
|
||||
static bool
|
||||
JoinInfoContextHasAntiJoin(JoinInfoContext *joinOrderContext)
|
||||
JoinOrderInfoListContainsAntiJoin(List *joinOrderInfoList)
|
||||
{
|
||||
JoinInfo *joinInfo = NULL;
|
||||
foreach_ptr(joinInfo, joinOrderContext->joinInfoList)
|
||||
JoinOrderInfo *joinOrderInfo = NULL;
|
||||
foreach_ptr(joinOrderInfo, joinOrderInfoList)
|
||||
{
|
||||
if (joinInfo->joinType == JOIN_ANTI)
|
||||
if (joinOrderInfo->joinType == JOIN_ANTI)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -638,20 +638,20 @@ JoinInfoContextHasAntiJoin(JoinInfoContext *joinOrderContext)
|
|||
|
||||
|
||||
/*
|
||||
* ConvertSemiToInnerInJoinInfoContext converts semi joins in given join info context
|
||||
* ConvertSemiToInnerInJoinOrderInfoList converts semi joins in given join order info list
|
||||
* to inner joins as we checked at query_pushdown_planning that planner did not actually
|
||||
* plan any semi join. ruleutils files cannot deparse JOIN_SEMI, so we convert those
|
||||
* to JOIN_INNER.
|
||||
*/
|
||||
static bool
|
||||
ConvertSemiToInnerInJoinInfoContext(JoinInfoContext *joinOrderContext)
|
||||
ConvertSemiToInnerInJoinOrderInfoList(List *joinOrderInfoList)
|
||||
{
|
||||
JoinInfo *joinInfo = NULL;
|
||||
foreach_ptr(joinInfo, joinOrderContext->joinInfoList)
|
||||
JoinOrderInfo *joinOrderInfo = NULL;
|
||||
foreach_ptr(joinOrderInfo, joinOrderInfoList)
|
||||
{
|
||||
if (joinInfo->joinType == JOIN_SEMI)
|
||||
if (joinOrderInfo->joinType == JOIN_SEMI)
|
||||
{
|
||||
joinInfo->joinType = JOIN_INNER;
|
||||
joinOrderInfo->joinType = JOIN_INNER;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,8 +93,8 @@ static MultiSelect * MultiSelectNode(List *pushdownableClauseList,
|
|||
static bool IsSelectClause(Node *clause);
|
||||
static List * SelectClauseList(List *clauseList);
|
||||
|
||||
static JoinInfoContext * FetchJoinOrderContext(FromExpr *fromExpr);
|
||||
static bool JoinInfoWalker(Node *node, JoinInfoContext *joinInfoContext);
|
||||
static List * FetchJoinOrderInfoList(FromExpr *fromExpr);
|
||||
static bool JoinOrderInfoWalker(Node *node, List **joinOrderInfoList);
|
||||
|
||||
/* Local functions forward declarations for applying joins */
|
||||
static MultiNode * ApplyJoinRule(MultiNode *leftNode, MultiNode *rightNode,
|
||||
|
@ -698,11 +698,11 @@ MultiNodeTree(Query *queryTree, PlannerRestrictionContext *plannerRestrictionCon
|
|||
*/
|
||||
if (FindNodeMatchingCheckFunction((Node *) queryTree->jointree, IsOuterJoinExpr))
|
||||
{
|
||||
/* extract join infos for left recursive join tree */
|
||||
JoinInfoContext *joinInfoContext = FetchJoinOrderContext(queryTree->jointree);
|
||||
/* extract join order info list for left recursive join tree */
|
||||
List *joinOrderInfoList = FetchJoinOrderInfoList(queryTree->jointree);
|
||||
|
||||
/* we simply donot commute joins as we have at least 1 outer join */
|
||||
joinOrderList = FixedJoinOrderList(tableEntryList, joinInfoContext,
|
||||
joinOrderList = FixedJoinOrderList(tableEntryList, joinOrderInfoList,
|
||||
joinRestrictInfoListList,
|
||||
generatedEcJoinClauseList);
|
||||
}
|
||||
|
@ -890,34 +890,34 @@ ExtractRestrictInfosFromPlannerContext(
|
|||
|
||||
|
||||
/*
|
||||
* FetchJoinOrderContext returns all join info for given node.
|
||||
* FetchJoinOrderInfoList returns all join order info list for given node.
|
||||
*/
|
||||
static JoinInfoContext *
|
||||
FetchJoinOrderContext(FromExpr *fromExpr)
|
||||
static List *
|
||||
FetchJoinOrderInfoList(FromExpr *fromExpr)
|
||||
{
|
||||
/* we do not allow cartesian product for outer joins */
|
||||
Assert(fromExpr->fromlist && list_length(fromExpr->fromlist) == 1);
|
||||
|
||||
JoinInfoContext *joinInfoContext = palloc0(sizeof(JoinInfoContext));
|
||||
JoinInfoWalker((Node *) fromExpr, joinInfoContext);
|
||||
List *joinOrderInfoList = NIL;
|
||||
JoinOrderInfoWalker((Node *) fromExpr, &joinOrderInfoList);
|
||||
|
||||
/* only leftmost table will have valid(ltableIdx != 0) ltableIdx */
|
||||
int leftMostTableIdx = 0;
|
||||
ExtractLeftMostRangeTableIndex((Node *) fromExpr, &leftMostTableIdx);
|
||||
Assert(list_length(joinInfoContext->joinInfoList) > 0);
|
||||
JoinInfo *leftMostJoinInfo = list_nth(joinInfoContext->joinInfoList, 0);
|
||||
Assert(list_length(joinOrderInfoList) > 0);
|
||||
JoinOrderInfo *leftMostJoinInfo = list_nth(joinOrderInfoList, 0);
|
||||
leftMostJoinInfo->leftTableIdx = leftMostTableIdx;
|
||||
|
||||
return joinInfoContext;
|
||||
return joinOrderInfoList;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* JoinInfoWalker descends into given node and pushes all join info into
|
||||
* joinInfoContext.
|
||||
* JoinOrderInfoWalker descends into given node and pushes all join order infos into
|
||||
* joinOrderInfoList.
|
||||
*/
|
||||
static bool
|
||||
JoinInfoWalker(Node *node, JoinInfoContext *joinInfoContext)
|
||||
JoinOrderInfoWalker(Node *node, List **joinOrderInfoList)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
|
@ -925,8 +925,8 @@ JoinInfoWalker(Node *node, JoinInfoContext *joinInfoContext)
|
|||
}
|
||||
|
||||
/* process the deepest node first */
|
||||
bool walkerResult = expression_tree_walker(node, JoinInfoWalker,
|
||||
(void *) joinInfoContext);
|
||||
bool walkerResult = expression_tree_walker(node, JoinOrderInfoWalker,
|
||||
joinOrderInfoList);
|
||||
|
||||
/*
|
||||
* Get qualifier lists of join and from expression nodes. Note that in the
|
||||
|
@ -951,56 +951,14 @@ JoinInfoWalker(Node *node, JoinInfoContext *joinInfoContext)
|
|||
"equal operator")));
|
||||
}
|
||||
|
||||
Node *joinQualifiersNode = joinExpression->quals;
|
||||
JoinType joinType = joinExpression->jointype;
|
||||
RangeTblRef *rightTableRef = (RangeTblRef *) joinExpression->rarg;
|
||||
|
||||
List *joinQualifierList = NIL;
|
||||
if (joinQualifiersNode != NULL)
|
||||
{
|
||||
if (IsA(joinQualifiersNode, List))
|
||||
{
|
||||
joinQualifierList = (List *) joinQualifiersNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this part of code only run for subqueries */
|
||||
Node *joinClause = eval_const_expressions(NULL, joinQualifiersNode);
|
||||
joinClause = (Node *) canonicalize_qual((Expr *) joinClause, false);
|
||||
joinQualifierList = make_ands_implicit((Expr *) joinClause);
|
||||
}
|
||||
}
|
||||
JoinOrderInfo *joinOrderInfo = palloc0(sizeof(JoinOrderInfo));
|
||||
joinOrderInfo->joinType = joinType;
|
||||
joinOrderInfo->rightTableIdx = rightTableRef->rtindex;
|
||||
|
||||
JoinInfo *joinInfo = palloc0(sizeof(JoinInfo));
|
||||
joinInfo->joinType = joinType;
|
||||
joinInfo->rightTableIdx = rightTableRef->rtindex;
|
||||
joinInfo->joinQualifierList = joinQualifierList;
|
||||
|
||||
joinInfoContext->joinInfoList = lappend(joinInfoContext->joinInfoList, joinInfo);
|
||||
}
|
||||
else if (IsA(node, FromExpr))
|
||||
{
|
||||
List *fromQualifierList = NIL;
|
||||
FromExpr *fromExpression = (FromExpr *) node;
|
||||
Node *fromQualifiersNode = fromExpression->quals;
|
||||
|
||||
if (fromQualifiersNode != NULL)
|
||||
{
|
||||
if (IsA(fromQualifiersNode, List))
|
||||
{
|
||||
fromQualifierList = (List *) fromQualifiersNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this part of code only run for subqueries */
|
||||
Node *fromClause = eval_const_expressions(NULL, fromQualifiersNode);
|
||||
fromClause = (Node *) canonicalize_qual((Expr *) fromClause, false);
|
||||
fromQualifierList = make_ands_implicit((Expr *) fromClause);
|
||||
}
|
||||
|
||||
joinInfoContext->baseQualifierList =
|
||||
list_concat(joinInfoContext->baseQualifierList, fromQualifierList);
|
||||
}
|
||||
*joinOrderInfoList = lappend(*joinOrderInfoList, joinOrderInfo);
|
||||
}
|
||||
|
||||
return walkerResult;
|
||||
|
|
|
@ -106,8 +106,6 @@ typedef struct FastPathRestrictionContext
|
|||
* Set to true when distKey = Param; in the queryTree
|
||||
*/
|
||||
bool distributionKeyHasParam;
|
||||
|
||||
int distRelId;
|
||||
}FastPathRestrictionContext;
|
||||
|
||||
typedef struct PlannerRestrictionContext
|
||||
|
|
|
@ -96,28 +96,18 @@ typedef struct JoinOrderNode
|
|||
} JoinOrderNode;
|
||||
|
||||
|
||||
/* JoinInfoContext stores list of JoinInfo and base qualifications */
|
||||
typedef struct JoinInfoContext
|
||||
{
|
||||
List *baseQualifierList;
|
||||
List *joinInfoList;
|
||||
} JoinInfoContext;
|
||||
|
||||
|
||||
/*
|
||||
* JoinInfo stores information about a join between 2 tables.
|
||||
* JoinOrderInfo stores information about a join between 2 tables.
|
||||
* joinType: join type between left and right tables in join
|
||||
* leftTableIdx: rtable index for left table in join
|
||||
* rightTableIdx: rtable index for right table in join
|
||||
* joinQualifierList: list of join qualifications in join, i.e. ON (...)
|
||||
*/
|
||||
typedef struct JoinInfo
|
||||
typedef struct JoinOrderInfo
|
||||
{
|
||||
JoinType joinType;
|
||||
uint32 leftTableIdx;
|
||||
uint32 rightTableIdx;
|
||||
List *joinQualifierList;
|
||||
} JoinInfo;
|
||||
} JoinOrderInfo;
|
||||
|
||||
|
||||
/* Config variables managed via guc.c */
|
||||
|
@ -130,7 +120,7 @@ extern List * JoinExprList(FromExpr *fromExpr);
|
|||
extern List * JoinOrderList(List *rangeTableEntryList, List *joinRestrictInfoListList,
|
||||
List *generatedEcJoinClauseList);
|
||||
extern List * FixedJoinOrderList(List *rangeTableEntryList,
|
||||
JoinInfoContext *joinInfoContext,
|
||||
List *joinOrderInfoList,
|
||||
List *joinRestrictInfoListList,
|
||||
List *generatedEcJoinClauseList);
|
||||
extern bool IsApplicableJoinClause(List *leftTableIdList, uint32 rightTableId,
|
||||
|
|
Loading…
Reference in New Issue