use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class FilterPusher method pushFilter.
private static PlanNode pushFilter(PlanNode qtn, List<Item> dnfNodeToPush) {
List<Item> subHavingList = new ArrayList<>();
for (Item filter : dnfNodeToPush) {
if (filter.isWithSumFunc()) {
subHavingList.add(filter);
}
}
if (!subHavingList.isEmpty()) {
qtn.having(FilterUtils.and(qtn.getHavingFilter(), FilterUtils.and(subHavingList)));
dnfNodeToPush.removeAll(subHavingList);
}
// root node will receive filter as where ,otherwise merge the current where and push down
if (qtn.getChildren().isEmpty() || PlanUtil.isGlobalOrER(qtn)) {
Item node = FilterUtils.and(dnfNodeToPush);
if (node != null) {
qtn.query(FilterUtils.and(qtn.getWhereFilter(), node));
}
return qtn;
}
Item filterInWhere = qtn.getWhereFilter();
// left/right join: where filter can't be push to child
if (filterInWhere != null) {
List<Item> splits = FilterUtils.splitFilter(filterInWhere);
qtn.query(null);
dnfNodeToPush.addAll(splits);
}
if (qtn.type() == PlanNodeType.QUERY) {
return getQueryNode(qtn, dnfNodeToPush);
} else if (qtn.type() == PlanNodeType.JOIN) {
return getJoinNode(qtn, dnfNodeToPush);
} else if (qtn.type() == PlanNodeType.MERGE) {
return getMergeNode(qtn, dnfNodeToPush);
}
return qtn;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class FilterPusher method getQueryNode.
private static PlanNode getQueryNode(PlanNode qtn, List<Item> dnfNodeToPush) {
if (qtn.getSubQueries().size() > 0) {
Item node = FilterUtils.and(dnfNodeToPush);
if (node != null) {
qtn.query(FilterUtils.and(qtn.getWhereFilter(), node));
}
return qtn;
}
refreshPdFilters(qtn, dnfNodeToPush);
PlanNode child = pushFilter(qtn.getChild(), dnfNodeToPush);
((QueryNode) qtn).setChild(child);
return qtn;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class FilterPusher method getJoinNode.
private static PlanNode getJoinNode(PlanNode qtn, List<Item> dnfNodeToPush) {
JoinNode jn = (JoinNode) qtn;
List<Item> dnfNodetoPushToLeft = new LinkedList<>();
List<Item> dnfNodetoPushToRight = new LinkedList<>();
List<Item> leftCopyedPushFilters = new LinkedList<>();
List<Item> rightCopyedPushFilters = new LinkedList<>();
List<Item> dnfNodeToCurrent = new LinkedList<>();
PlanUtil.findJoinKeysAndRemoveIt(dnfNodeToPush, jn);
for (Item filter : dnfNodeToPush) {
// ex. 1 = -1
if (filter.getReferTables().size() == 0) {
dnfNodetoPushToLeft.add(filter);
dnfNodetoPushToRight.add(filter);
continue;
}
if (PlanUtil.canPush(filter, jn.getLeftNode(), jn)) {
dnfNodetoPushToLeft.add(filter);
} else if (PlanUtil.canPush(filter, jn.getRightNode(), jn)) {
dnfNodetoPushToRight.add(filter);
} else {
dnfNodeToCurrent.add(filter);
}
}
if (jn.isInnerJoin() || jn.isLeftOuterJoin() || jn.isRightOuterJoin()) {
// push the left expr to join filter's right condition
rightCopyedPushFilters.addAll(copyFilterToJoinOnColumns(dnfNodetoPushToLeft, jn.getLeftKeys(), jn.getRightKeys()));
// push the right expr to join filter's left condition
leftCopyedPushFilters.addAll(copyFilterToJoinOnColumns(dnfNodetoPushToRight, jn.getRightKeys(), jn.getLeftKeys()));
}
// if it can not push down, merge to current where
Item node = FilterUtils.and(dnfNodeToCurrent);
if (node != null) {
qtn.query(FilterUtils.and(qtn.getWhereFilter(), node));
}
if (jn.isInnerJoin() || jn.isLeftOuterJoin() || jn.isRightOuterJoin()) {
if (jn.isLeftOuterJoin()) {
// left join, push down the right join ,but still contains right joins condition
jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodetoPushToRight)));
}
if (jn.isRightOuterJoin()) {
// right join, push down the left join ,but still contains left joins condition
jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodetoPushToLeft)));
}
// merge
dnfNodetoPushToRight.addAll(rightCopyedPushFilters);
dnfNodetoPushToLeft.addAll(leftCopyedPushFilters);
refreshPdFilters(jn, dnfNodetoPushToLeft);
refreshPdFilters(jn, dnfNodetoPushToRight);
jn.setLeftNode(pushFilter(jn.getLeftNode(), dnfNodetoPushToLeft));
jn.setRightNode(pushFilter(((JoinNode) qtn).getRightNode(), dnfNodetoPushToRight));
} else {
if (!dnfNodeToPush.isEmpty()) {
jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodeToPush)));
}
}
return jn;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class FilterPusher method pushJoinOnFilter.
/**
* inner join's other join on would add to where when FilterPre and push down,
* when Left join, eg" select * from t1 left join t2 on t1.id=t2.id and t1.id = 10 and
* t2.name = 'aaa' push down t2.id=10 and t2.name='aaa'
*/
private static PlanNode pushJoinOnFilter(PlanNode qtn) {
if (PlanUtil.isGlobalOrER(qtn))
return qtn;
if (qtn.type().equals(PlanNodeType.JOIN)) {
JoinNode jn = (JoinNode) qtn;
Item otherJoinOn = jn.getOtherJoinOnFilter();
if (jn.isLeftOuterJoin() && otherJoinOn != null) {
List<Item> pushToRightNode = new ArrayList<>();
List<Item> splitedFilters = FilterUtils.splitFilter(otherJoinOn);
for (Item filter : splitedFilters) {
if (filter.getReferTables().isEmpty())
pushToRightNode.add(filter);
else if (PlanUtil.canPush(filter, jn.getRightNode(), jn))
pushToRightNode.add(filter);
else if (PlanUtil.canPush(filter, jn.getLeftNode(), jn)) {
Item copyedFilter = copyFilterToJoinOnColumns(filter, jn.getRightKeys(), jn.getLeftKeys());
if (copyedFilter != null)
pushToRightNode.add(copyedFilter);
} else
continue;
}
if (!pushToRightNode.isEmpty()) {
splitedFilters.removeAll(pushToRightNode);
Item newOtherJoinOn = FilterUtils.and(splitedFilters);
jn.setOtherJoinOnFilter(newOtherJoinOn);
refreshPdFilters(jn, pushToRightNode);
List<Item> subHavingList = new ArrayList<>();
List<Item> subWhereList = new ArrayList<>();
for (Item filter : pushToRightNode) {
if (filter.isWithSumFunc()) {
subHavingList.add(filter);
} else {
subWhereList.add(filter);
}
}
Item subHaving = FilterUtils.and(subHavingList);
Item subWhere = FilterUtils.and(subWhereList);
jn.getRightNode().having(FilterUtils.and(jn.getRightNode().getHavingFilter(), subHaving));
jn.getRightNode().setWhereFilter(FilterUtils.and(jn.getRightNode().getWhereFilter(), subWhere));
}
}
}
for (PlanNode child : qtn.getChildren()) pushJoinOnFilter(child);
return qtn;
}
use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.
the class JoinStrategyChooser method handleNestLoopStrategy.
private void handleNestLoopStrategy(boolean isLeftSmall) {
jn.setStrategy(Strategy.NESTLOOP);
TableNode tnLeft = (TableNode) jn.getLeftNode();
TableNode tnRight = (TableNode) jn.getRightNode();
TableNode tnBig = isLeftSmall ? tnRight : tnLeft;
tnBig.setNestLoopFilters(new ArrayList<Item>());
}
Aggregations