Search in sources :

Example 11 with PlanNode

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);
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) PlanNode(com.actiontech.dble.plan.node.PlanNode)

Example 12 with PlanNode

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;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) JoinNode(com.actiontech.dble.plan.node.JoinNode) QueryNode(com.actiontech.dble.plan.node.QueryNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with PlanNode

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;
        }
    }
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) PlanNode(com.actiontech.dble.plan.node.PlanNode) ItemInt(com.actiontech.dble.plan.common.item.ItemInt) ItemSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)

Example 14 with PlanNode

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;
}
Also used : Order(com.actiontech.dble.plan.Order) JoinNode(com.actiontech.dble.plan.node.JoinNode) ItemFuncEqual(com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual) ArrayList(java.util.ArrayList) ItemField(com.actiontech.dble.plan.common.item.ItemField) Item(com.actiontech.dble.plan.common.item.Item) PlanNode(com.actiontech.dble.plan.node.PlanNode) QueryNode(com.actiontech.dble.plan.node.QueryNode) MySQLOutPutException(com.actiontech.dble.plan.common.exception.MySQLOutPutException)

Example 15 with PlanNode

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;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode)

Aggregations

PlanNode (com.actiontech.dble.plan.node.PlanNode)50 JoinNode (com.actiontech.dble.plan.node.JoinNode)16 Item (com.actiontech.dble.plan.common.item.Item)14 ArrayList (java.util.ArrayList)10 QueryNode (com.actiontech.dble.plan.node.QueryNode)8 ItemFuncEqual (com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual)6 MySQLOutPutException (com.actiontech.dble.plan.common.exception.MySQLOutPutException)5 MySQLPlanNodeVisitor (com.actiontech.dble.plan.visitor.MySQLPlanNodeVisitor)5 ItemSubQuery (com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)4 SQLSelectStatement (com.alibaba.druid.sql.ast.statement.SQLSelectStatement)4 DMLResponseHandler (com.actiontech.dble.backend.mysql.nio.handler.query.DMLResponseHandler)3 NamedField (com.actiontech.dble.plan.NamedField)3 ErrorPacket (com.actiontech.dble.net.mysql.ErrorPacket)2 Order (com.actiontech.dble.plan.Order)2 TableNode (com.actiontech.dble.plan.node.TableNode)2 HashSet (java.util.HashSet)2 BaseHandlerBuilder (com.actiontech.dble.backend.mysql.nio.handler.builder.BaseHandlerBuilder)1 HandlerBuilder (com.actiontech.dble.backend.mysql.nio.handler.builder.HandlerBuilder)1 TempTableHandler (com.actiontech.dble.backend.mysql.nio.handler.query.impl.TempTableHandler)1 CallBackHandler (com.actiontech.dble.backend.mysql.nio.handler.util.CallBackHandler)1