Search in sources :

Example 31 with Item

use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.

the class FilterPusher method pushFilter.

private static PlanNode pushFilter(PlanNode qtn, List<Item> dnfNodeToPush) {
    List<Item> subHavingList = new ArrayList<>();
    for (Item filter : dnfNodeToPush) {
        if (filter.isWithSumFunc()) {
            subHavingList.add(filter);
        }
    }
    if (!subHavingList.isEmpty()) {
        qtn.having(FilterUtils.and(qtn.getHavingFilter(), FilterUtils.and(subHavingList)));
        dnfNodeToPush.removeAll(subHavingList);
    }
    // root node will receive filter as where ,otherwise merge the current where and push down
    if (qtn.getChildren().isEmpty() || PlanUtil.isGlobalOrER(qtn)) {
        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) {
        List<Item> splits = FilterUtils.splitFilter(filterInWhere);
        qtn.query(null);
        dnfNodeToPush.addAll(splits);
    }
    if (qtn.type() == PlanNodeType.QUERY) {
        return getQueryNode(qtn, dnfNodeToPush);
    } else if (qtn.type() == PlanNodeType.JOIN) {
        return getJoinNode(qtn, dnfNodeToPush);
    } else if (qtn.type() == PlanNodeType.MERGE) {
        return getMergeNode(qtn, dnfNodeToPush);
    }
    return qtn;
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) ArrayList(java.util.ArrayList)

Example 32 with Item

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

Example 33 with Item

use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.

the class FilterPusher method getJoinNode.

private static PlanNode getJoinNode(PlanNode qtn, List<Item> dnfNodeToPush) {
    JoinNode jn = (JoinNode) qtn;
    List<Item> dnfNodetoPushToLeft = new LinkedList<>();
    List<Item> dnfNodetoPushToRight = new LinkedList<>();
    List<Item> leftCopyedPushFilters = new LinkedList<>();
    List<Item> rightCopyedPushFilters = new LinkedList<>();
    List<Item> dnfNodeToCurrent = new LinkedList<>();
    PlanUtil.findJoinKeysAndRemoveIt(dnfNodeToPush, jn);
    for (Item filter : dnfNodeToPush) {
        // ex. 1 = -1
        if (filter.getReferTables().size() == 0) {
            dnfNodetoPushToLeft.add(filter);
            dnfNodetoPushToRight.add(filter);
            continue;
        }
        if (PlanUtil.canPush(filter, jn.getLeftNode(), jn)) {
            dnfNodetoPushToLeft.add(filter);
        } else if (PlanUtil.canPush(filter, jn.getRightNode(), jn)) {
            dnfNodetoPushToRight.add(filter);
        } else {
            dnfNodeToCurrent.add(filter);
        }
    }
    if (jn.isInnerJoin() || jn.isLeftOuterJoin() || jn.isRightOuterJoin()) {
        // push the left expr to join filter's right condition
        rightCopyedPushFilters.addAll(copyFilterToJoinOnColumns(dnfNodetoPushToLeft, jn.getLeftKeys(), jn.getRightKeys()));
        // push the right expr to join filter's left condition
        leftCopyedPushFilters.addAll(copyFilterToJoinOnColumns(dnfNodetoPushToRight, jn.getRightKeys(), jn.getLeftKeys()));
    }
    // if it can not push down, merge to current where
    Item node = FilterUtils.and(dnfNodeToCurrent);
    if (node != null) {
        qtn.query(FilterUtils.and(qtn.getWhereFilter(), node));
    }
    if (jn.isInnerJoin() || jn.isLeftOuterJoin() || jn.isRightOuterJoin()) {
        if (jn.isLeftOuterJoin()) {
            // left join, push down the right join ,but still contains right joins condition
            jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodetoPushToRight)));
        }
        if (jn.isRightOuterJoin()) {
            // right join, push down the left join ,but still contains left joins condition
            jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodetoPushToLeft)));
        }
        // merge
        dnfNodetoPushToRight.addAll(rightCopyedPushFilters);
        dnfNodetoPushToLeft.addAll(leftCopyedPushFilters);
        refreshPdFilters(jn, dnfNodetoPushToLeft);
        refreshPdFilters(jn, dnfNodetoPushToRight);
        jn.setLeftNode(pushFilter(jn.getLeftNode(), dnfNodetoPushToLeft));
        jn.setRightNode(pushFilter(((JoinNode) qtn).getRightNode(), dnfNodetoPushToRight));
    } else {
        if (!dnfNodeToPush.isEmpty()) {
            jn.query(FilterUtils.and(qtn.getWhereFilter(), FilterUtils.and(dnfNodeToPush)));
        }
    }
    return jn;
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) JoinNode(com.actiontech.dble.plan.node.JoinNode) LinkedList(java.util.LinkedList)

Example 34 with Item

use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.

the class FilterPusher method pushJoinOnFilter.

/**
 * inner join's other join on would add to where when FilterPre and push down,
 * when Left join, eg" select * from t1 left join t2 on t1.id=t2.id and t1.id = 10 and
 * t2.name = 'aaa' push down t2.id=10 and t2.name='aaa'
 */
private static PlanNode pushJoinOnFilter(PlanNode qtn) {
    if (PlanUtil.isGlobalOrER(qtn))
        return qtn;
    if (qtn.type().equals(PlanNodeType.JOIN)) {
        JoinNode jn = (JoinNode) qtn;
        Item otherJoinOn = jn.getOtherJoinOnFilter();
        if (jn.isLeftOuterJoin() && otherJoinOn != null) {
            List<Item> pushToRightNode = new ArrayList<>();
            List<Item> splitedFilters = FilterUtils.splitFilter(otherJoinOn);
            for (Item filter : splitedFilters) {
                if (filter.getReferTables().isEmpty())
                    pushToRightNode.add(filter);
                else if (PlanUtil.canPush(filter, jn.getRightNode(), jn))
                    pushToRightNode.add(filter);
                else if (PlanUtil.canPush(filter, jn.getLeftNode(), jn)) {
                    Item copyedFilter = copyFilterToJoinOnColumns(filter, jn.getRightKeys(), jn.getLeftKeys());
                    if (copyedFilter != null)
                        pushToRightNode.add(copyedFilter);
                } else
                    continue;
            }
            if (!pushToRightNode.isEmpty()) {
                splitedFilters.removeAll(pushToRightNode);
                Item newOtherJoinOn = FilterUtils.and(splitedFilters);
                jn.setOtherJoinOnFilter(newOtherJoinOn);
                refreshPdFilters(jn, pushToRightNode);
                List<Item> subHavingList = new ArrayList<>();
                List<Item> subWhereList = new ArrayList<>();
                for (Item filter : pushToRightNode) {
                    if (filter.isWithSumFunc()) {
                        subHavingList.add(filter);
                    } else {
                        subWhereList.add(filter);
                    }
                }
                Item subHaving = FilterUtils.and(subHavingList);
                Item subWhere = FilterUtils.and(subWhereList);
                jn.getRightNode().having(FilterUtils.and(jn.getRightNode().getHavingFilter(), subHaving));
                jn.getRightNode().setWhereFilter(FilterUtils.and(jn.getRightNode().getWhereFilter(), subWhere));
            }
        }
    }
    for (PlanNode child : qtn.getChildren()) pushJoinOnFilter(child);
    return qtn;
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) PlanNode(com.actiontech.dble.plan.node.PlanNode) JoinNode(com.actiontech.dble.plan.node.JoinNode) ArrayList(java.util.ArrayList)

Example 35 with Item

use of com.actiontech.dble.plan.common.item.Item in project dble by actiontech.

the class JoinStrategyChooser method handleNestLoopStrategy.

private void handleNestLoopStrategy(boolean isLeftSmall) {
    jn.setStrategy(Strategy.NESTLOOP);
    TableNode tnLeft = (TableNode) jn.getLeftNode();
    TableNode tnRight = (TableNode) jn.getRightNode();
    TableNode tnBig = isLeftSmall ? tnRight : tnLeft;
    tnBig.setNestLoopFilters(new ArrayList<Item>());
}
Also used : Item(com.actiontech.dble.plan.common.item.Item) TableNode(com.actiontech.dble.plan.node.TableNode)

Aggregations

Item (com.actiontech.dble.plan.common.item.Item)122 ArrayList (java.util.ArrayList)26 Order (com.actiontech.dble.plan.Order)16 PlanNode (com.actiontech.dble.plan.node.PlanNode)14 MySQLOutPutException (com.actiontech.dble.plan.common.exception.MySQLOutPutException)10 ItemField (com.actiontech.dble.plan.common.item.ItemField)10 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)7 MySqlSelectQueryBlock (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock)7 Test (org.junit.Test)7 FieldPacket (com.actiontech.dble.net.mysql.FieldPacket)6 ItemFuncEqual (com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual)6 ItemSum (com.actiontech.dble.plan.common.item.function.sumfunc.ItemSum)6 JoinNode (com.actiontech.dble.plan.node.JoinNode)6 SQLAggregateExpr (com.alibaba.druid.sql.ast.expr.SQLAggregateExpr)6 ItemFunc (com.actiontech.dble.plan.common.item.function.ItemFunc)5 ItemInt (com.actiontech.dble.plan.common.item.ItemInt)4 ItemString (com.actiontech.dble.plan.common.item.ItemString)4 BigDecimal (java.math.BigDecimal)4 RowDataPacket (com.actiontech.dble.net.mysql.RowDataPacket)3 NamedField (com.actiontech.dble.plan.NamedField)3