Search in sources :

Example 16 with TableScanNode

use of io.prestosql.spi.plan.TableScanNode in project hetu-core by openlookeng.

the class SimpleNodeSelector method computeAssignments.

@Override
public SplitPlacementResult computeAssignments(Set<Split> splits, List<RemoteTask> existingTasks, Optional<SqlStageExecution> stage) {
    Multimap<InternalNode, Split> assignment = HashMultimap.create();
    NodeMap nodeMapSlice = this.nodeMap.get().get();
    NodeAssignmentStats assignmentStats = new NodeAssignmentStats(nodeTaskMap, nodeMapSlice, existingTasks);
    ResettableRandomizedIterator<InternalNode> randomCandidates = randomizedNodes(nodeMapSlice, ImmutableSet.of());
    Set<InternalNode> blockedExactNodes = new HashSet<>();
    boolean splitWaitingForAnyNode = false;
    // splitsToBeRedistributed becomes true only when splits go through locality-based assignment
    boolean splitsToBeRedistributed = false;
    Set<Split> remainingSplits = new HashSet<>();
    // Check if the current stage has a TableScanNode which is reading the table for the 2nd time or beyond
    if (stage.isPresent() && stage.get().getStateMachine().getConsumerScanNode() != null) {
        try {
            // if node exists, get the TableScanNode and cast it as consumer
            TableScanNode consumer = stage.get().getStateMachine().getConsumerScanNode();
            // all tables part of this stage
            Map<PlanNodeId, TableInfo> tables = stage.get().getStageInfo().getTables();
            QualifiedObjectName tableName;
            for (Map.Entry<PlanNodeId, TableInfo> entry : tables.entrySet()) {
                tableName = entry.getValue().getTableName();
                if (tableSplitAssignmentInfo.getReuseTableScanMappingIdSplitAssignmentMap().containsKey(consumer.getReuseTableScanMappingId())) {
                    // compare splitkey using equals and then assign nodes accordingly.
                    HashMap<SplitKey, InternalNode> splitKeyNodeAssignment = tableSplitAssignmentInfo.getSplitKeyNodeAssignment(consumer.getReuseTableScanMappingId());
                    Set<SplitKey> splitKeySet = splitKeyNodeAssignment.keySet();
                    assignment.putAll(createConsumerScanNodeAssignment(tableName, splits, splitKeySet, splitKeyNodeAssignment));
                    for (Map.Entry<InternalNode, Split> nodeAssignmentEntry : assignment.entries()) {
                        InternalNode node = nodeAssignmentEntry.getKey();
                        assignmentStats.addAssignedSplit(node);
                    }
                }
            }
            log.debug("Consumer:: Assignment size is " + assignment.size() + " ,Assignment is " + assignment + " ,Assignment Stats is " + assignmentStats);
        } catch (NotImplementedException e) {
            log.error("Not a Hive Split! Other Connector Splits not supported currently. Error: " + e);
            throw new UnsupportedOperationException("Not a Hive Split! Other Connector Splits not supported currently. Error: " + e);
        }
    } else {
        // optimizedLocalScheduling enables prioritized assignment of splits to local nodes when splits contain locality information
        if (optimizedLocalScheduling) {
            // should not hit for consumer case
            for (Split split : splits) {
                if (split.isRemotelyAccessible() && !split.getAddresses().isEmpty()) {
                    List<InternalNode> candidateNodes = selectExactNodes(nodeMapSlice, split.getAddresses(), includeCoordinator);
                    Optional<InternalNode> chosenNode = candidateNodes.stream().filter(ownerNode -> assignmentStats.getTotalSplitCount(ownerNode) < maxSplitsPerNode).min(comparingInt(assignmentStats::getTotalSplitCount));
                    if (chosenNode.isPresent()) {
                        assignment.put(chosenNode.get(), split);
                        // check later
                        assignmentStats.addAssignedSplit(chosenNode.get());
                        splitsToBeRedistributed = true;
                        continue;
                    }
                }
                remainingSplits.add(split);
            }
        } else {
            remainingSplits = splits;
        }
        for (Split split : remainingSplits) {
            randomCandidates.reset();
            List<InternalNode> candidateNodes;
            if (!split.isRemotelyAccessible()) {
                candidateNodes = selectExactNodes(nodeMapSlice, split.getAddresses(), includeCoordinator);
            } else {
                candidateNodes = selectNodes(minCandidates, randomCandidates);
            }
            if (candidateNodes.isEmpty()) {
                log.debug("No nodes available to schedule %s. Available nodes %s", split, nodeMapSlice.getNodesByHost().keys());
                throw new PrestoException(NO_NODES_AVAILABLE, "No nodes available to run query");
            }
            InternalNode chosenNode = null;
            int min = Integer.MAX_VALUE;
            for (InternalNode node : candidateNodes) {
                int totalSplitCount = assignmentStats.getTotalSplitCount(node);
                if (totalSplitCount < min && totalSplitCount < maxSplitsPerNode) {
                    chosenNode = node;
                    min = totalSplitCount;
                }
            }
            if (chosenNode == null) {
                // min is guaranteed to be MAX_VALUE at this line
                for (InternalNode node : candidateNodes) {
                    int totalSplitCount = assignmentStats.getQueuedSplitCountForStage(node);
                    if (totalSplitCount < min && totalSplitCount < maxPendingSplitsPerTask) {
                        chosenNode = node;
                        min = totalSplitCount;
                    }
                }
            }
            if (chosenNode != null) {
                assignment.put(chosenNode, split);
                assignmentStats.addAssignedSplit(chosenNode);
            } else {
                if (split.isRemotelyAccessible()) {
                    splitWaitingForAnyNode = true;
                } else // Exact node set won't matter, if a split is waiting for any node
                if (!splitWaitingForAnyNode) {
                    blockedExactNodes.addAll(candidateNodes);
                }
            }
        }
    }
    ListenableFuture<?> blocked;
    if (splitWaitingForAnyNode) {
        blocked = toWhenHasSplitQueueSpaceFuture(existingTasks, calculateLowWatermark(maxPendingSplitsPerTask));
    } else {
        blocked = toWhenHasSplitQueueSpaceFuture(blockedExactNodes, existingTasks, calculateLowWatermark(maxPendingSplitsPerTask));
    }
    if (!stage.isPresent() || stage.get().getStateMachine().getConsumerScanNode() == null) {
        if (splitsToBeRedistributed) {
            // skip for consumer
            equateDistribution(assignment, assignmentStats, nodeMapSlice);
        }
    }
    // Check if the current stage has a TableScanNode which is reading the table for the 1st time
    if (stage.isPresent() && stage.get().getStateMachine().getProducerScanNode() != null) {
        // if node exists, get the TableScanNode and annotate it as producer
        saveProducerScanNodeAssignment(stage, assignment, assignmentStats);
    }
    // Check if its CTE node and its feeder
    if (stage.isPresent() && stage.get().getFragment().getFeederCTEId().isPresent()) {
        updateFeederNodeAndSplitCount(stage.get(), assignment);
    }
    return new SplitPlacementResult(blocked, assignment);
}
Also used : NodeScheduler.randomizedNodes(io.prestosql.execution.scheduler.NodeScheduler.randomizedNodes) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Logger(io.airlift.log.Logger) Supplier(com.google.common.base.Supplier) HashMap(java.util.HashMap) Split(io.prestosql.metadata.Split) NO_NODES_AVAILABLE(io.prestosql.spi.StandardErrorCode.NO_NODES_AVAILABLE) Multimap(com.google.common.collect.Multimap) AtomicReference(java.util.concurrent.atomic.AtomicReference) QualifiedObjectName(io.prestosql.spi.connector.QualifiedObjectName) InetAddress(java.net.InetAddress) HashSet(java.util.HashSet) HashMultimap(com.google.common.collect.HashMultimap) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) Suppliers(com.google.common.base.Suppliers) NodeTaskMap(io.prestosql.execution.NodeTaskMap) InternalNodeManager(io.prestosql.metadata.InternalNodeManager) PlanNodeId(io.prestosql.spi.plan.PlanNodeId) TableInfo(io.prestosql.execution.TableInfo) PrestoException(io.prestosql.spi.PrestoException) Comparator.comparingInt(java.util.Comparator.comparingInt) ImmutableSet(com.google.common.collect.ImmutableSet) NotImplementedException(sun.reflect.generics.reflectiveObjects.NotImplementedException) HostAddress(io.prestosql.spi.HostAddress) Iterator(java.util.Iterator) NodeScheduler.calculateLowWatermark(io.prestosql.execution.scheduler.NodeScheduler.calculateLowWatermark) IndexedPriorityQueue(io.prestosql.execution.resourcegroups.IndexedPriorityQueue) InternalNode(io.prestosql.metadata.InternalNode) Collection(java.util.Collection) TableScanNode(io.prestosql.spi.plan.TableScanNode) Set(java.util.Set) NodeScheduler.toWhenHasSplitQueueSpaceFuture(io.prestosql.execution.scheduler.NodeScheduler.toWhenHasSplitQueueSpaceFuture) UnknownHostException(java.net.UnknownHostException) Collectors(java.util.stream.Collectors) SetMultimap(com.google.common.collect.SetMultimap) NodeScheduler.selectNodes(io.prestosql.execution.scheduler.NodeScheduler.selectNodes) List(java.util.List) SplitKey(io.prestosql.execution.SplitKey) GENERIC_INTERNAL_ERROR(io.prestosql.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) Optional(java.util.Optional) NodeScheduler.selectDistributionNodes(io.prestosql.execution.scheduler.NodeScheduler.selectDistributionNodes) VisibleForTesting(com.google.common.annotations.VisibleForTesting) SqlStageExecution(io.prestosql.execution.SqlStageExecution) NodeScheduler.selectExactNodes(io.prestosql.execution.scheduler.NodeScheduler.selectExactNodes) RemoteTask(io.prestosql.execution.RemoteTask) SplitKey(io.prestosql.execution.SplitKey) NotImplementedException(sun.reflect.generics.reflectiveObjects.NotImplementedException) PrestoException(io.prestosql.spi.PrestoException) PlanNodeId(io.prestosql.spi.plan.PlanNodeId) TableInfo(io.prestosql.execution.TableInfo) HashSet(java.util.HashSet) QualifiedObjectName(io.prestosql.spi.connector.QualifiedObjectName) TableScanNode(io.prestosql.spi.plan.TableScanNode) InternalNode(io.prestosql.metadata.InternalNode) Split(io.prestosql.metadata.Split) HashMap(java.util.HashMap) Map(java.util.Map) NodeTaskMap(io.prestosql.execution.NodeTaskMap)

Example 17 with TableScanNode

use of io.prestosql.spi.plan.TableScanNode in project hetu-core by openlookeng.

the class SplitFiltering method isSplitFilterApplicable.

public static boolean isSplitFilterApplicable(SqlStageExecution stage) {
    List<PlanNode> filterNodeOptional = getFilterNode(stage);
    if (filterNodeOptional.isEmpty()) {
        return false;
    }
    PlanNode node = filterNodeOptional.get(0);
    if (node instanceof FilterNode) {
        FilterNode filterNode = (FilterNode) node;
        PlanNode sourceNode = filterNode.getSource();
        if (!(sourceNode instanceof TableScanNode)) {
            return false;
        }
        // if a catalog name starts with a $, it's not an normal query, could be something like show tables;
        TableHandle table = ((TableScanNode) sourceNode).getTable();
        String catalogName = table.getCatalogName().getCatalogName();
        if (catalogName.startsWith("$")) {
            return false;
        }
        if (!table.getConnectorHandle().isFilterSupported()) {
            return false;
        }
        if (!isSupportedExpression(filterNode.getPredicate()) && (!((TableScanNode) sourceNode).getPredicate().isPresent() || !isSupportedExpression(((TableScanNode) sourceNode).getPredicate().get()))) {
            return false;
        }
    }
    if (node instanceof TableScanNode) {
        TableScanNode tableScanNode = (TableScanNode) node;
        // if a catalog name starts with a $, it's not an normal query, could be something like show tables;
        TableHandle table = tableScanNode.getTable();
        String catalogName = table.getCatalogName().getCatalogName();
        if (catalogName.startsWith("$")) {
            return false;
        }
        if (!table.getConnectorHandle().isFilterSupported()) {
            return false;
        }
        if (!tableScanNode.getPredicate().isPresent() || !isSupportedExpression(tableScanNode.getPredicate().get())) {
            return false;
        }
    }
    return true;
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) TableScanNode(io.prestosql.spi.plan.TableScanNode) FilterNode(io.prestosql.spi.plan.FilterNode) TableHandle(io.prestosql.spi.metadata.TableHandle)

Example 18 with TableScanNode

use of io.prestosql.spi.plan.TableScanNode in project hetu-core by openlookeng.

the class SplitFiltering method getFullyQualifiedName.

public static Optional<String> getFullyQualifiedName(SqlStageExecution stage) {
    List<PlanNode> filterNodeOptional = getFilterNode(stage);
    if (filterNodeOptional.size() == 0) {
        return Optional.empty();
    }
    TableScanNode tableScanNode;
    if (filterNodeOptional.get(0) instanceof FilterNode) {
        FilterNode filterNode = (FilterNode) filterNodeOptional.get(0);
        tableScanNode = (TableScanNode) filterNode.getSource();
    } else {
        tableScanNode = (TableScanNode) filterNodeOptional.get(0);
    }
    String fullQualifiedTableName = tableScanNode.getTable().getFullyQualifiedName();
    return Optional.of(fullQualifiedTableName);
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) TableScanNode(io.prestosql.spi.plan.TableScanNode) FilterNode(io.prestosql.spi.plan.FilterNode)

Example 19 with TableScanNode

use of io.prestosql.spi.plan.TableScanNode in project hetu-core by openlookeng.

the class SplitFiltering method getFilterNode.

private static List<PlanNode> getFilterNode(SqlStageExecution stage) {
    PlanFragment fragment = stage.getFragment();
    PlanNode root = fragment.getRoot();
    List<PlanNode> result = new LinkedList<>();
    Queue<PlanNode> queue = new LinkedList<>();
    queue.add(root);
    while (!queue.isEmpty()) {
        PlanNode node = queue.poll();
        if (node instanceof FilterNode || node instanceof TableScanNode) {
            result.add(node);
        }
        queue.addAll(node.getSources());
    }
    return result;
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) TableScanNode(io.prestosql.spi.plan.TableScanNode) FilterNode(io.prestosql.spi.plan.FilterNode) PlanFragment(io.prestosql.sql.planner.PlanFragment) LinkedList(java.util.LinkedList)

Example 20 with TableScanNode

use of io.prestosql.spi.plan.TableScanNode in project hetu-core by openlookeng.

the class TestCubeStatementGenerator method setup.

@BeforeClass
public void setup() {
    planBuilder = new PlanBuilder(new PlanNodeIdAllocator(), dummyMetadata());
    symbolAllocator = new PlanSymbolAllocator();
    builder = CubeStatement.newBuilder();
    columnOrderkey = symbolAllocator.newSymbol("orderkey", BIGINT);
    columnTotalprice = symbolAllocator.newSymbol("totalprice", DOUBLE);
    columnAvgPrice = symbolAllocator.newSymbol("avgprice", DOUBLE);
    orderkeyHandle = new TpchColumnHandle("orderkey", BIGINT);
    totalpriceHandle = new TpchColumnHandle("totalprice", DOUBLE);
    columnMapping = new HashMap<>();
    columnMapping.put("orderkey", orderkeyHandle);
    columnMapping.put("totalprice", totalpriceHandle);
    columnMapping.put("avgprice", columnAvgPrice);
    Map<Symbol, ColumnHandle> assignments = ImmutableMap.<Symbol, ColumnHandle>builder().put(columnOrderkey, orderkeyHandle).put(columnTotalprice, totalpriceHandle).build();
    TpchTableHandle orders = new TpchTableHandle("orders", 1.0);
    TableHandle ordersTableHandle = new TableHandle(new CatalogName("test"), orders, TpchTransactionHandle.INSTANCE, Optional.of(new TpchTableLayoutHandle(orders, TupleDomain.all())));
    baseTableScan = new TableScanNode(new PlanNodeId(UUID.randomUUID().toString()), ordersTableHandle, ImmutableList.copyOf(assignments.keySet()), assignments, Optional.empty(), ReuseExchangeOperator.STRATEGY.REUSE_STRATEGY_DEFAULT, new UUID(0, 0), 0, false);
}
Also used : TpchColumnHandle(io.prestosql.plugin.tpch.TpchColumnHandle) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) TpchColumnHandle(io.prestosql.plugin.tpch.TpchColumnHandle) Symbol(io.prestosql.spi.plan.Symbol) TpchTableLayoutHandle(io.prestosql.plugin.tpch.TpchTableLayoutHandle) PlanBuilder(io.prestosql.sql.planner.iterative.rule.test.PlanBuilder) PlanSymbolAllocator(io.prestosql.sql.planner.PlanSymbolAllocator) PlanNodeId(io.prestosql.spi.plan.PlanNodeId) TableScanNode(io.prestosql.spi.plan.TableScanNode) PlanNodeIdAllocator(io.prestosql.spi.plan.PlanNodeIdAllocator) TpchTableHandle(io.prestosql.plugin.tpch.TpchTableHandle) TableHandle(io.prestosql.spi.metadata.TableHandle) CatalogName(io.prestosql.spi.connector.CatalogName) UUID(java.util.UUID) TpchTableHandle(io.prestosql.plugin.tpch.TpchTableHandle) BeforeClass(org.testng.annotations.BeforeClass)

Aggregations

TableScanNode (io.prestosql.spi.plan.TableScanNode)77 Symbol (io.prestosql.spi.plan.Symbol)42 PlanNode (io.prestosql.spi.plan.PlanNode)41 Test (org.testng.annotations.Test)33 ColumnHandle (io.prestosql.spi.connector.ColumnHandle)30 FilterNode (io.prestosql.spi.plan.FilterNode)28 RowExpression (io.prestosql.spi.relation.RowExpression)24 Type (io.prestosql.spi.type.Type)22 JoinNode (io.prestosql.spi.plan.JoinNode)21 PlanNodeId (io.prestosql.spi.plan.PlanNodeId)21 Map (java.util.Map)21 TableHandle (io.prestosql.spi.metadata.TableHandle)20 ProjectNode (io.prestosql.spi.plan.ProjectNode)20 Optional (java.util.Optional)20 ImmutableList (com.google.common.collect.ImmutableList)18 Expression (io.prestosql.sql.tree.Expression)18 HashMap (java.util.HashMap)16 List (java.util.List)16 ImmutableMap (com.google.common.collect.ImmutableMap)15 Session (io.prestosql.Session)15