use of com.actiontech.dble.plan.node.PlanNode in project dble by actiontech.
the class ItemSum method fixRefer.
@Override
public final void fixRefer(ReferContext context) {
PlanNode planNode = context.getPlanNode();
planNode.addSelToReferedMap(planNode, this);
boolean needAddArgToRefer = true;
if (context.isPushDownNode() && !planNode.existUnPushDownGroup()) {
boolean isUnpushSum = PlanUtil.isUnPushDownSum(this);
if (isUnpushSum) {
// this function can not be push down
planNode.setExistUnPushDownGroup(true);
needAddArgToRefer = true;
// add args of sunfuncs
for (ItemSum sumfunc : planNode.getSumFuncs()) {
for (Item sumArg : sumfunc.args) {
sumArg.fixRefer(context);
}
}
} else {
needAddArgToRefer = false;
}
}
if (needAddArgToRefer) {
for (Item arg : this.args) {
arg.fixRefer(context);
}
}
planNode.getSumFuncs().add(this);
}
use of com.actiontech.dble.plan.node.PlanNode 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.PlanNode in project dble by actiontech.
the class SelectedProcessor method pushSelected.
/**
* pushSelected
* if parent's selected refered isA.id,A.name,B.id,B.name,
* node of A only need push A.id,A.nam
*
* @param qtn
* @param toPushColumns
* @return
*/
private static PlanNode pushSelected(PlanNode qtn, Collection<Item> toPushColumns) {
boolean isPushDownNode = false;
if (PlanUtil.isGlobalOrER(qtn)) {
// TODO:buildColumnRefers for every child
List<Item> selList = qtn.getColumnsSelected();
for (Item pdSel : toPushColumns) {
if (!selList.contains(pdSel)) {
selList.add(pdSel);
}
}
isPushDownNode = true;
qtn.setUpRefers(isPushDownNode);
return qtn;
}
isPushDownNode = (qtn.type() == PlanNode.PlanNodeType.TABLE || qtn.type() == PlanNode.PlanNodeType.NONAME);
if (qtn.type() == PlanNode.PlanNodeType.MERGE) {
return mergePushSelected((MergeNode) qtn, toPushColumns);
} else {
if (qtn.getSubQueries().size() > 0) {
for (ItemSubQuery itemSubQuery : qtn.getSubQueries()) {
pushSelected(itemSubQuery.getPlanNode(), new HashSet<Item>());
}
}
if (toPushColumns.isEmpty()) {
qtn.setUpRefers(isPushDownNode);
} else if (qtn.isDistinct()) {
List<Item> selList = qtn.getColumnsSelected();
for (Item pdSel : toPushColumns) {
if (!selList.contains(pdSel)) {
selList.add(pdSel);
}
}
qtn.setUpRefers(isPushDownNode);
} else {
List<Item> selList = qtn.getColumnsSelected();
selList.clear();
boolean existSum = false;
for (Item toPush : toPushColumns) {
selList.add(toPush);
existSum |= toPush.type().equals(Item.ItemType.SUM_FUNC_ITEM);
}
// if only push id,it will miss sum(id)
if (!existSum && qtn.getSumFuncs().size() > 0) {
selList.add(qtn.getSumFuncs().iterator().next());
}
qtn.setUpRefers(isPushDownNode);
}
PlanNode.PlanNodeType i = qtn.type();
if (i == PlanNode.PlanNodeType.NONAME) {
return qtn;
} else if (i == PlanNode.PlanNodeType.TABLE) {
return qtn;
} else {
for (PlanNode child : qtn.getChildren()) {
List<Item> referList = qtn.getColumnsReferedByChild(child);
if (referList.isEmpty()) {
referList.add(new ItemInt(1));
}
Collection<Item> pdRefers = getPushDownSel(qtn, child, referList);
pushSelected(child, pdRefers);
}
return qtn;
}
}
}
use of com.actiontech.dble.plan.node.PlanNode 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.PlanNode in project dble by actiontech.
the class PlanUtil method isJoinKey.
/**
* is bf can be the joinkey for node?make bf's left related to left to node
*
* @param bf ItemFuncEqual
* @param node node
* @return is Join Key
*/
public static boolean isJoinKey(ItemFuncEqual bf, JoinNode node) {
// only funEqula may become joinkey
boolean isJoinKey = false;
Item selCol = bf.arguments().get(0);
Item selVal = bf.arguments().get(1);
Set<PlanNode> colTns = selCol.getReferTables();
Set<PlanNode> valTns = selVal.getReferTables();
if (colTns.size() == 1 && valTns.size() == 1) {
// a.id=b.id is join key,else not
PlanNode colTn = colTns.iterator().next();
PlanNode valTn = valTns.iterator().next();
if (colTn == node.getLeftNode() && valTn == node.getRightNode()) {
isJoinKey = true;
} else if (colTn == node.getRightNode() && valTn == node.getLeftNode()) {
isJoinKey = true;
bf.arguments().set(0, selVal);
bf.arguments().set(1, selCol);
}
}
return isJoinKey;
}
Aggregations