use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class FilterJoinColumnPusher method pushFilter.
private static PlanNode pushFilter(PlanNode qtn, List<Item> dnfNodeToPush) {
// the leaf node receive filter as where , or merge the current where and push down
if (qtn.getChildren().isEmpty()) {
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 && (!(qtn.type() == PlanNode.PlanNodeType.JOIN) || ((JoinNode) qtn).isInnerJoin())) {
List<Item> splits = FilterUtils.splitFilter(filterInWhere);
List<Item> nonJoinFilter = new ArrayList<>();
for (Item filter : splits) {
if (!isPossibleERJoinColumnFilter(qtn, filter)) {
nonJoinFilter.add(filter);
} else {
dnfNodeToPush.add(filter);
}
}
if (nonJoinFilter.size() != splits.size()) {
// rollbakc nonJoinFilter
qtn.query(FilterUtils.and(nonJoinFilter));
}
}
PlanNode.PlanNodeType i = qtn.type();
if (i == PlanNode.PlanNodeType.QUERY) {
return pushQueryNodeFilter(qtn, dnfNodeToPush);
} else if (i == PlanNode.PlanNodeType.JOIN) {
return pushJoinNodeFilter(qtn, dnfNodeToPush);
} else if (i == PlanNode.PlanNodeType.MERGE) {
return pushMergeNodeFilter(qtn);
}
return qtn;
}
use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class FilterJoinColumnPusher method pushQueryNodeFilter.
private static PlanNode pushQueryNodeFilter(PlanNode qtn, List<Item> dnfNodeToPush) {
if (dnfNodeToPush.isEmpty()) {
return qtn;
}
refreshPdFilters(qtn, dnfNodeToPush);
PlanNode child = pushFilter(qtn.getChild(), dnfNodeToPush);
((QueryNode) qtn).setChild(child);
return qtn;
}
use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class FilterPreProcessor method preProcess.
private static PlanNode preProcess(PlanNode qtn) {
qtn.having(processFilter(qtn.getHavingFilter()));
qtn.query(processFilter(qtn.getWhereFilter()));
if (qtn instanceof JoinNode) {
JoinNode jn = (JoinNode) qtn;
for (int i = 0; i < ((JoinNode) qtn).getJoinFilter().size(); i++) {
processFilter(jn.getJoinFilter().get(i));
}
jn.setOtherJoinOnFilter(processFilter(jn.getOtherJoinOnFilter()));
}
for (PlanNode child : qtn.getChildren()) {
preProcess(child);
}
return qtn;
}
use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class SelectedProcessor method mergeNodeChildsCheck.
/**
* check merge's subchild have distinct or aggregate function
*
* @param merge
* @return
*/
private static boolean mergeNodeChildsCheck(MergeNode merge) {
for (PlanNode child : merge.getChildren()) {
boolean cdis = child.isDistinct();
boolean bsum = child.getSumFuncs().size() > 0;
if (cdis || bsum)
return false;
}
return true;
}
use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class SelectedProcessor method mergePushSelected.
// union's push is different , when toPushColumn.isEmpty, merge's select can't be change
private static PlanNode mergePushSelected(MergeNode merge, Collection<Item> toPushColumns) {
if (toPushColumns.isEmpty() && merge.getOrderBys().isEmpty()) {
for (PlanNode child : merge.getChildren()) {
pushSelected(child, new HashSet<Item>());
}
return merge;
}
boolean canOverload = mergeNodeChildsCheck(merge) && !toPushColumns.isEmpty();
final Map<String, Integer> colIndexs = merge.getColIndexs();
List<Item> mergeSelects = null;
if (toPushColumns.isEmpty()) {
// merge's select can't be change
mergeSelects = new ArrayList<>();
merge.setComeInFields(mergeSelects);
mergeSelects.addAll(merge.getColumnsSelected());
} else {
mergeSelects = merge.getColumnsSelected();
}
if (canOverload) {
mergeSelects.clear();
mergeSelects.addAll(toPushColumns);
} else {
for (Item toPush : toPushColumns) {
if (!mergeSelects.contains(toPush)) {
mergeSelects.add(toPush);
}
}
}
// add order by
for (Order orderby : merge.getOrderBys()) {
Item orderSel = orderby.getItem();
mergePushOrderBy(orderSel, mergeSelects);
}
// push down the merge's select
List<List<Item>> allChildPushs = new ArrayList<>(toPushColumns.size());
for (Item toPush : mergeSelects) {
// union's order by must be found in selects
if (toPush.getPushDownName() == null && !toPush.type().equals(Item.ItemType.FIELD_ITEM))
toPush.setPushDownName(toPush.getItemName());
List<Item> childPushs = PlanUtil.getPushItemsToUnionChild(merge, toPush, colIndexs);
allChildPushs.add(childPushs);
}
// make all child's count of pushing down is equal
for (int index = 0; index < merge.getChildren().size(); index++) {
List<Item> colSels = merge.getChildren().get(index).getColumnsSelected();
colSels.clear();
for (List<Item> childPushs : allChildPushs) {
colSels.add(childPushs.get(index));
}
pushSelected(merge.getChildren().get(index), new HashSet<Item>());
}
return merge;
}
Aggregations