use of com.actiontech.dble.plan.node.QueryNode 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.node.QueryNode in project dble by actiontech.
the class LimitPusher method findChild.
private static PlanNode findChild(PlanNode qtn) {
if (qtn instanceof MergeNode) {
// optimizer limit
// union: push down limit to children
// union all:push down limit to children and add distinct
MergeNode node = (MergeNode) qtn;
long limitFrom = node.getLimitFrom();
long limitTo = node.getLimitTo();
if (limitFrom != -1 && limitTo != -1) {
for (PlanNode child : node.getChildren()) {
pushLimit(child, limitFrom, limitTo, node.isUnion());
}
}
} else if ((qtn instanceof JoinNode) || (qtn instanceof QueryNode)) {
for (PlanNode child : qtn.getChildren()) {
findChild(child);
}
}
return qtn;
}
use of com.actiontech.dble.plan.node.QueryNode in project dble by actiontech.
the class OrderByPusher method pushOrderBy.
private static PlanNode pushOrderBy(PlanNode qtn) {
if (PlanUtil.isGlobalOrER(qtn))
return qtn;
if (qtn.type() == PlanNodeType.MERGE) {
// note:do not execute mergenode
for (PlanNode child : qtn.getChildren()) {
pushOrderBy(child);
}
return qtn;
} else if (qtn.type() == PlanNodeType.JOIN) {
JoinNode join = (JoinNode) qtn;
// sort merge join's order by, need to push down to left/right node
List<Order> implicitOrders = getOrderBysGroupFirst(join);
boolean canMatch = getJoinColumnOrders(join.getJoinFilter(), join.getLeftJoinOnOrders(), join.getRightJoinOnOrders(), implicitOrders);
boolean leftOrderPushSuc = false;
boolean rightOrderPushSuc = false;
if (canMatch) {
// push down join column first
leftOrderPushSuc = tryPushOrderToChild(join, join.getLeftJoinOnOrders(), join.getLeftNode());
if (leftOrderPushSuc) {
tryPushOrderToChild(join, implicitOrders, join.getLeftNode());
}
rightOrderPushSuc = tryPushOrderToChild(join, join.getRightJoinOnOrders(), join.getRightNode());
if (rightOrderPushSuc) {
tryPushOrderToChild(join, implicitOrders, join.getRightNode());
}
} else {
leftOrderPushSuc = tryPushOrderToChild(join, join.getLeftJoinOnOrders(), join.getLeftNode());
rightOrderPushSuc = tryPushOrderToChild(join, join.getRightJoinOnOrders(), join.getRightNode());
}
join.setLeftOrderMatch(leftOrderPushSuc);
join.setRightOrderMatch(rightOrderPushSuc);
} else if (qtn.type() == PlanNodeType.QUERY) {
// push order to subQuery
QueryNode query = (QueryNode) qtn;
tryPushOrderToChild(query, getOrderBysGroupFirst(query), query.getChild());
}
for (PlanNode child : qtn.getChildren()) {
if (child instanceof PlanNode) {
pushOrderBy(child);
}
}
return qtn;
}
use of com.actiontech.dble.plan.node.QueryNode in project dble by actiontech.
the class SubQueryPreProcessor method transformInSubQuery.
private static SubQueryFilter transformInSubQuery(SubQueryFilter qtn, ItemInSubQuery filter, BoolPtr childTransform) {
Item leftColumn = filter.getLeftOperand();
PlanNode query = filter.getPlanNode();
query = findComparisonsSubQueryToJoinNode(query, childTransform);
QueryNode changeQuery = new QueryNode(query);
String alias = AUTOALIAS + query.getPureName();
changeQuery.setAlias(alias);
if (query.getColumnsSelected().size() != 1)
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "only support subquery of one column");
query.setSubQuery(true).setDistinct(true);
final List<Item> newSelects = qtn.query.getColumnsSelected();
SubQueryFilter result = new SubQueryFilter();
Item rightColumn = query.getColumnsSelected().get(0);
qtn.query.setColumnsSelected(new ArrayList<Item>());
String rightJoinName = rightColumn.getAlias();
if (StringUtils.isEmpty(rightJoinName)) {
if (rightColumn instanceof ItemField) {
rightJoinName = rightColumn.getItemName();
} else {
rightColumn.setAlias(AUTONAME);
rightJoinName = AUTONAME;
}
}
ItemField rightJoinColumn = new ItemField(null, alias, rightJoinName);
// rename the left column's table name
result.query = new JoinNode(qtn.query, changeQuery);
// leave origin sql to new join node
result.query.setSql(qtn.query.getSql());
qtn.query.setSql(null);
result.query.select(newSelects);
qtn.query.setSubQuery(false);
if (!qtn.query.getOrderBys().isEmpty()) {
List<Order> orderBys = new ArrayList<>();
orderBys.addAll(qtn.query.getOrderBys());
result.query.setOrderBys(orderBys);
qtn.query.getOrderBys().clear();
}
if (!qtn.query.getGroupBys().isEmpty()) {
List<Order> groupBys = new ArrayList<>();
groupBys.addAll(qtn.query.getGroupBys());
result.query.setGroupBys(groupBys);
qtn.query.getGroupBys().clear();
result.query.having(qtn.query.getHavingFilter());
qtn.query.having(null);
}
if (qtn.query.getLimitFrom() != -1) {
result.query.setLimitFrom(qtn.query.getLimitFrom());
qtn.query.setLimitFrom(-1);
}
if (qtn.query.getLimitTo() != -1) {
result.query.setLimitTo(qtn.query.getLimitTo());
qtn.query.setLimitTo(-1);
}
if (filter.isNeg()) {
((JoinNode) result.query).setLeftOuterJoin().setNotIn(true);
ItemFuncEqual joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
((JoinNode) result.query).addJoinFilter(joinFilter);
result.filter = null;
} else {
Item joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
result.query.query(joinFilter);
result.filter = joinFilter;
}
result.query.setUpFields();
return result;
}
use of com.actiontech.dble.plan.node.QueryNode 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;
}
Aggregations