Search in sources :

Example 1 with ItemSubQuery

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

the class BaseHandlerBuilder method handleBlockingSubQuery.

protected void handleBlockingSubQuery() {
    if (node.getSubQueries().size() == 0) {
        return;
    }
    final ReentrantLock lock = new ReentrantLock();
    final Condition finishSubQuery = lock.newCondition();
    final AtomicBoolean finished = new AtomicBoolean(false);
    final AtomicInteger subNodes = new AtomicInteger(node.getSubQueries().size());
    final CopyOnWriteArrayList<ErrorPacket> errorPackets = new CopyOnWriteArrayList<>();
    for (ItemSubQuery itemSubQuery : node.getSubQueries()) {
        if (itemSubQuery instanceof ItemSingleRowSubQuery) {
            final SubQueryHandler tempHandler = new SingleRowSubQueryHandler(getSequenceId(), session, (ItemSingleRowSubQuery) itemSubQuery);
            if (isExplain) {
                handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
            } else {
                handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
            }
        } else if (itemSubQuery instanceof ItemInSubQuery) {
            final SubQueryHandler tempHandler = new InSubQueryHandler(getSequenceId(), session, (ItemInSubQuery) itemSubQuery);
            if (isExplain) {
                handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
            } else {
                handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
            }
        } else if (itemSubQuery instanceof ItemAllAnySubQuery) {
            final SubQueryHandler tempHandler = new AllAnySubQueryHandler(getSequenceId(), session, (ItemAllAnySubQuery) itemSubQuery);
            if (isExplain) {
                handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
            } else {
                handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
            }
        }
    }
    lock.lock();
    try {
        while (!finished.get()) {
            finishSubQuery.await();
        }
    } catch (InterruptedException e) {
        LOGGER.info("execute ScalarSubQuery " + e);
        ErrorPacket errorPackage = new ErrorPacket();
        errorPackage.setErrNo(ErrorCode.ER_UNKNOWN_ERROR);
        String errorMsg = e.getMessage() == null ? e.toString() : e.getMessage();
        errorPackage.setMessage(errorMsg.getBytes(StandardCharsets.UTF_8));
        errorPackets.add(errorPackage);
    } finally {
        lock.unlock();
    }
    if (errorPackets.size() > 0) {
        throw new MySQLOutPutException(errorPackets.get(0).getErrNo(), "", new String(errorPackets.get(0).getMessage(), StandardCharsets.UTF_8));
    }
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) Condition(java.util.concurrent.locks.Condition) SingleRowSubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.SingleRowSubQueryHandler) InSubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.InSubQueryHandler) AllAnySubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.AllAnySubQueryHandler) SubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.SubQueryHandler) SingleRowSubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.SingleRowSubQueryHandler) ItemAllAnySubQuery(com.actiontech.dble.plan.common.item.subquery.ItemAllAnySubQuery) ItemInSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ErrorPacket(com.actiontech.dble.net.mysql.ErrorPacket) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AllAnySubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.AllAnySubQueryHandler) InSubQueryHandler(com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.InSubQueryHandler) ItemSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSubQuery) ItemSingleRowSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSingleRowSubQuery) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) MySQLOutPutException(com.actiontech.dble.plan.common.exception.MySQLOutPutException)

Example 2 with ItemSubQuery

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

the class GlobalTableProcessor method initGlobalStatus.

/**
 * @param tn
 * @return true:parent node maybe is global;false parent node must not be global
 */
private static boolean initGlobalStatus(PlanNode tn) {
    if (tn == null || ((tn.type() == PlanNodeType.TABLE || tn.type() == PlanNodeType.NONAME) && tn.getSubQueries().size() == 0)) {
        return true;
    }
    boolean status = true;
    for (PlanNode child : tn.getChildren()) {
        boolean ret = initGlobalStatus(child);
        if (status) {
            status = ret;
        }
    }
    for (ItemSubQuery subQuery : tn.getSubQueries()) {
        boolean ret = initGlobalStatus(subQuery.getPlanNode());
        if (status) {
            status = ret;
        }
    }
    if (PlanUtil.isERNode(tn)) {
        // treat er join as an un global table
        tn.setUnGlobalTableCount(1);
        Set<String> newSet = new HashSet<>();
        newSet.addAll(tn.getReferedTableNodes().get(0).getNoshardNode());
        tn.setNoshardNode(newSet);
    } else {
        int unGlobalCount = calcUnGlobalCount(tn);
        tn.setUnGlobalTableCount(unGlobalCount);
        if (tn.getNoshardNode() != null && tn.getNoshardNode().size() == 0) {
            tn.setNoshardNode(null);
        }
        if (!status) {
            tn.setNoshardNode(null);
            return false;
        }
        if (unGlobalCount == 1 && tn instanceof JoinNode) {
            // joinNode
            JoinNode jn = (JoinNode) tn;
            if (jn.isNotIn()) {
                tn.setNoshardNode(null);
                status = false;
            } else if (jn.isInnerJoin()) {
                if (!isGlobalTableBigEnough(jn)) {
                    tn.setNoshardNode(null);
                    status = false;
                }
            } else {
                // left join
                PlanNode left = jn.getLeftNode();
                if (left.getUnGlobalTableCount() == 0) {
                    // left node is global,left join will not push down
                    tn.setNoshardNode(null);
                    status = false;
                } else if (left.type() == PlanNode.PlanNodeType.TABLE || !PlanUtil.isERNode(left)) {
                    if (!isGlobalTableBigEnough(jn)) {
                        tn.setNoshardNode(null);
                        status = false;
                    }
                } else {
                    // left node is not single table or er table
                    tn.setNoshardNode(null);
                    status = false;
                }
            }
        } else if (unGlobalCount != 0) {
            tn.setNoshardNode(null);
            status = false;
        }
    }
    return status;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) JoinNode(com.actiontech.dble.plan.node.JoinNode) ItemSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSubQuery) HashSet(java.util.HashSet)

Example 3 with ItemSubQuery

use of com.actiontech.dble.plan.common.item.subquery.ItemSubQuery 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 4 with ItemSubQuery

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

the class GlobalTableProcessor method calcUnGlobalCount.

private static int calcUnGlobalCount(PlanNode tn) {
    int unGlobalCount = 0;
    for (ItemSubQuery subQuery : tn.getSubQueries()) {
        PlanNode subNode = subQuery.getPlanNode();
        resetNoShardNode(tn, subNode);
        unGlobalCount += subNode.getUnGlobalTableCount();
    }
    for (PlanNode tnChild : tn.getChildren()) {
        if (tnChild != null) {
            resetNoShardNode(tn, tnChild);
            unGlobalCount += tnChild.getUnGlobalTableCount();
        }
    }
    return unGlobalCount;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) ItemSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)

Example 5 with ItemSubQuery

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

the class MyOptimizer method updateReferedTableNodes.

private static List<TableNode> updateReferedTableNodes(PlanNode node) {
    List<TableNode> subTables = new ArrayList<>();
    for (PlanNode childNode : node.getChildren()) {
        List<TableNode> childSubTables = updateReferedTableNodes(childNode);
        node.getReferedTableNodes().addAll(childSubTables);
        subTables.addAll(childSubTables);
    }
    for (ItemSubQuery subQuery : node.getSubQueries()) {
        List<TableNode> childSubTables = subQuery.getPlanNode().getReferedTableNodes();
        node.getReferedTableNodes().addAll(childSubTables);
        subTables.addAll(childSubTables);
    }
    return subTables;
}
Also used : PlanNode(com.actiontech.dble.plan.node.PlanNode) TableNode(com.actiontech.dble.plan.node.TableNode) ArrayList(java.util.ArrayList) ItemSubQuery(com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)

Aggregations

ItemSubQuery (com.actiontech.dble.plan.common.item.subquery.ItemSubQuery)5 PlanNode (com.actiontech.dble.plan.node.PlanNode)4 AllAnySubQueryHandler (com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.AllAnySubQueryHandler)1 InSubQueryHandler (com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.InSubQueryHandler)1 SingleRowSubQueryHandler (com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.SingleRowSubQueryHandler)1 SubQueryHandler (com.actiontech.dble.backend.mysql.nio.handler.query.impl.subquery.SubQueryHandler)1 ErrorPacket (com.actiontech.dble.net.mysql.ErrorPacket)1 MySQLOutPutException (com.actiontech.dble.plan.common.exception.MySQLOutPutException)1 Item (com.actiontech.dble.plan.common.item.Item)1 ItemInt (com.actiontech.dble.plan.common.item.ItemInt)1 ItemAllAnySubQuery (com.actiontech.dble.plan.common.item.subquery.ItemAllAnySubQuery)1 ItemInSubQuery (com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery)1 ItemSingleRowSubQuery (com.actiontech.dble.plan.common.item.subquery.ItemSingleRowSubQuery)1 JoinNode (com.actiontech.dble.plan.node.JoinNode)1 TableNode (com.actiontech.dble.plan.node.TableNode)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1