Search in sources :

Example 6 with JoinNode

use of com.actiontech.dble.plan.node.JoinNode in project dble by actiontech.

the class JoinPreProcessor method findAndChangeRightJoinToLeftJoin.

/**
 * change right join to left join.
 * <p>
 * <pre>
 * eg: A right join B on A.id = B.id
 * change to B left join B on A.id = B.id
 * </pre>
 */
private static PlanNode findAndChangeRightJoinToLeftJoin(PlanNode qtn) {
    for (PlanNode child : qtn.getChildren()) {
        findAndChangeRightJoinToLeftJoin(child);
    }
    if (qtn instanceof JoinNode && ((JoinNode) qtn).isRightOuterJoin()) {
        JoinNode jn = (JoinNode) qtn;
        jn.exchangeLeftAndRight();
    }
    return qtn;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) JoinNode(com.actiontech.dble.plan.node.JoinNode)

Example 7 with JoinNode

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

Example 8 with JoinNode

use of com.actiontech.dble.plan.node.JoinNode 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 9 with JoinNode

use of com.actiontech.dble.plan.node.JoinNode 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 10 with JoinNode

use of com.actiontech.dble.plan.node.JoinNode in project dble by actiontech.

the class ERJoinChooser method joinWithGlobal.

private PlanNode joinWithGlobal(PlanNode t, List<PlanNode> globalList) {
    PlanNode newT = t;
    while (globalList.size() > 0) {
        boolean foundJoin = false;
        for (int i = 0; i < globalList.size(); i++) {
            PlanNode global = globalList.get(i);
            // try join
            JoinNode joinNode = new JoinNode(newT, global);
            List<ItemFuncEqual> jnFilter = makeJoinFilter(joinNode, newT, global, false);
            // @if no join column, then the other is cross join
            if (jnFilter.size() > 0 || selLists.size() == 0) {
                // join
                replaceSelListReferedTn(newT, global, joinNode);
                foundJoin = true;
                joinNode.setJoinFilter(jnFilter);
                globalList.remove(i);
                newT = joinNode;
                break;
            }
        }
        if (// no join can do from t and globals
        !foundJoin)
            break;
    }
    return newT;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) JoinNode(com.actiontech.dble.plan.node.JoinNode) ItemFuncEqual(com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual)

Aggregations

JoinNode (com.actiontech.dble.plan.node.JoinNode)21 PlanNode (com.actiontech.dble.plan.node.PlanNode)16 Item (com.actiontech.dble.plan.common.item.Item)6 ItemFuncEqual (com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual)5 ArrayList (java.util.ArrayList)4 ItemField (com.actiontech.dble.plan.common.item.ItemField)3 QueryNode (com.actiontech.dble.plan.node.QueryNode)3 ERTable (com.actiontech.dble.config.model.ERTable)2 MySQLOutPutException (com.actiontech.dble.plan.common.exception.MySQLOutPutException)2 TableNode (com.actiontech.dble.plan.node.TableNode)2 LinkedList (java.util.LinkedList)2 NamedField (com.actiontech.dble.plan.NamedField)1 Order (com.actiontech.dble.plan.Order)1 ItemSubQuery (com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)1 MergeNode (com.actiontech.dble.plan.node.MergeNode)1 ERJoinChooser (com.actiontech.dble.plan.optimizer.ERJoinChooser)1 Method (java.lang.reflect.Method)1 HashSet (java.util.HashSet)1 List (java.util.List)1