Search in sources :

Example 1 with ItemFuncEqual

use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.

the class OrderByPusher method getJoinColumnOrders.

/**
 * generatejoinOnFilters,if joinOn's orderBy can change to match implicitOrders ,return true
 *
 * @param joinOnFilters  in
 * @param leftOnOrders   out
 * @param rightOnOrders  out
 * @param implicitOrders in
 * @return
 */
private static boolean getJoinColumnOrders(List<ItemFuncEqual> joinOnFilters, List<Order> leftOnOrders, List<Order> rightOnOrders, List<Order> implicitOrders) {
    List<Item> leftOnSels = new ArrayList<>();
    List<Item> rightOnSels = new ArrayList<>();
    for (ItemFuncEqual bf : joinOnFilters) {
        leftOnSels.add(bf.arguments().get(0));
        rightOnSels.add(bf.arguments().get(1));
    }
    // is on's orderBy can be changed to match implicitOrders
    boolean canMatch = false;
    if (implicitOrders.size() < leftOnSels.size())
        canMatch = false;
    else {
        Map<Integer, SQLOrderingSpecification> foundOnIndexs = new LinkedHashMap<>();
        for (Order orderby : implicitOrders) {
            Item orderSel = orderby.getItem();
            int index = -1;
            if ((index = leftOnSels.indexOf(orderSel)) >= 0) {
                foundOnIndexs.put(index, orderby.getSortOrder());
            } else if ((index = rightOnSels.indexOf(orderSel)) >= 0) {
                foundOnIndexs.put(index, orderby.getSortOrder());
            } else {
                // neither belong to leftOn nor belong to rightOn
                break;
            }
        }
        if (foundOnIndexs.size() == leftOnSels.size()) {
            canMatch = true;
            for (Map.Entry<Integer, SQLOrderingSpecification> entry : foundOnIndexs.entrySet()) {
                int foundOnIndex = entry.getKey();
                SQLOrderingSpecification sortOrder = entry.getValue();
                Item leftOn = leftOnSels.get(foundOnIndex);
                Item rightOn = rightOnSels.get(foundOnIndex);
                // add lefton order
                Order leftOnOrder = new Order(leftOn, sortOrder);
                leftOnOrders.add(leftOnOrder);
                // add righton order
                Order rightOnOrder = new Order(rightOn, sortOrder);
                rightOnOrders.add(rightOnOrder);
            }
            return canMatch;
        }
    }
    // can not match
    for (int index = 0; index < leftOnSels.size(); index++) {
        SQLOrderingSpecification sortOrder = SQLOrderingSpecification.ASC;
        Item leftOn = leftOnSels.get(index);
        Item rightOn = rightOnSels.get(index);
        // add lefton order
        Order leftOnOrder = new Order(leftOn, sortOrder);
        leftOnOrders.add(leftOnOrder);
        // add righton order
        Order rightOnOrder = new Order(rightOn, sortOrder);
        rightOnOrders.add(rightOnOrder);
    }
    return canMatch;
}
Also used : Order(com.actiontech.dble.plan.Order) ItemFuncEqual(com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual) ArrayList(java.util.ArrayList) SQLOrderingSpecification(com.alibaba.druid.sql.ast.SQLOrderingSpecification) LinkedHashMap(java.util.LinkedHashMap) Item(com.actiontech.dble.plan.common.item.Item) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 2 with ItemFuncEqual

use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual 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 3 with ItemFuncEqual

use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual 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)

Example 4 with ItemFuncEqual

use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.

the class ERJoinChooser method makeJoinFilter.

/**
 * join t0 and t1, find relation in selLists and make joinfilter
 * [if a.id=b.id and a.id = b.name would not appear]
 *
 * @param join
 * @param t0
 * @param t1
 * @param replaceSelList
 * @return
 */
private List<ItemFuncEqual> makeJoinFilter(JoinNode join, PlanNode t0, PlanNode t1, boolean replaceSelList) {
    List<ItemFuncEqual> filters = new ArrayList<>();
    for (List<JoinKeyInfo> selList : selLists) {
        JoinKeyInfo jkit0 = null;
        JoinKeyInfo jkit1 = null;
        for (JoinKeyInfo jki : selList) {
            if (jki.tn == t0) {
                jkit0 = jki;
            } else if (jki.tn == t1) {
                jkit1 = jki;
            }
        }
        // t0and t1 in sel list can make jkit0 jkit1 join
        if (jkit0 != null && jkit1 != null) {
            JoinKeyInfo newJki = new JoinKeyInfo(jkit0.key);
            newJki.tn = join;
            if (jkit0.cm != null && jkit1.cm != null && isErRelation(jkit0.cm, jkit1.cm)) {
                newJki.cm = jkit0.cm;
                join.getERkeys().add(newJki.cm);
            }
            ItemFuncEqual bf = FilterUtils.equal(jkit0.key, jkit1.key);
            filters.add(bf);
            selList.remove(jkit0);
            selList.remove(jkit1);
            selList.add(newJki);
        }
    }
    if (replaceSelList)
        replaceSelListReferedTn(t0, t1, join);
    return filters;
}
Also used : ItemFuncEqual(com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual) ArrayList(java.util.ArrayList)

Example 5 with ItemFuncEqual

use of com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual in project dble by actiontech.

the class ERJoinChooser method makeERJoin.

// generate er join node ,remove jk of rKeyIndexs in selListIndex,replace the other selList's tn
private JoinNode makeERJoin(List<JoinKeyInfo> erKeys) {
    PlanNode t0 = erKeys.get(0).tn;
    PlanNode t1 = erKeys.get(1).tn;
    JoinNode joinNode = new JoinNode(t0, t1);
    List<ItemFuncEqual> joinFilter = makeJoinFilter(joinNode, t0, t1, true);
    joinNode.setJoinFilter(joinFilter);
    for (int index = 2; index < erKeys.size(); index++) {
        t0 = joinNode;
        t1 = erKeys.get(index).tn;
        joinNode = new JoinNode(t0, t1);
        joinFilter = makeJoinFilter(joinNode, t0, t1, true);
        joinNode.setJoinFilter(joinFilter);
    }
    for (JoinKeyInfo jki : erKeys) {
        // remove join units
        for (int index = joinUnits.size() - 1; index > -1; index--) {
            PlanNode tn = joinUnits.get(index);
            if (tn == jki.tn)
                joinUnits.remove(index);
        }
    }
    return joinNode;
}
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

ItemFuncEqual (com.actiontech.dble.plan.common.item.function.operator.cmpfunc.ItemFuncEqual)14 Item (com.actiontech.dble.plan.common.item.Item)6 PlanNode (com.actiontech.dble.plan.node.PlanNode)6 JoinNode (com.actiontech.dble.plan.node.JoinNode)5 ItemField (com.actiontech.dble.plan.common.item.ItemField)4 ArrayList (java.util.ArrayList)4 Order (com.actiontech.dble.plan.Order)2 MySQLOutPutException (com.actiontech.dble.plan.common.exception.MySQLOutPutException)2 ERTable (com.actiontech.dble.config.model.ERTable)1 ItemCondAnd (com.actiontech.dble.plan.common.item.function.operator.logic.ItemCondAnd)1 QueryNode (com.actiontech.dble.plan.node.QueryNode)1 TableNode (com.actiontech.dble.plan.node.TableNode)1 SQLOrderingSpecification (com.alibaba.druid.sql.ast.SQLOrderingSpecification)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1