Search in sources :

Example 21 with JoinNode

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

the class PushTopNThroughOuterJoin method apply.

@Override
public Result apply(TopNNode parent, Captures captures, Context context) {
    JoinNode joinNode = captures.get(JOIN_CHILD);
    List<Symbol> orderBySymbols = parent.getOrderingScheme().getOrderBy();
    PlanNode left = joinNode.getLeft();
    PlanNode right = joinNode.getRight();
    JoinNode.Type type = joinNode.getType();
    if ((type == LEFT) && ImmutableSet.copyOf(left.getOutputSymbols()).containsAll(orderBySymbols) && !isAtMost(left, context.getLookup(), parent.getCount())) {
        return Result.ofPlanNode(joinNode.replaceChildren(ImmutableList.of(parent.replaceChildren(ImmutableList.of(left)), right)));
    }
    if ((type == RIGHT) && ImmutableSet.copyOf(right.getOutputSymbols()).containsAll(orderBySymbols) && !isAtMost(right, context.getLookup(), parent.getCount())) {
        return Result.ofPlanNode(joinNode.replaceChildren(ImmutableList.of(left, parent.replaceChildren(ImmutableList.of(right)))));
    }
    return Result.empty();
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) JoinNode(io.prestosql.spi.plan.JoinNode) Symbol(io.prestosql.spi.plan.Symbol)

Example 22 with JoinNode

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

the class DynamicFilterService method registerTasksHelper.

private void registerTasksHelper(PlanNode node, Symbol buildSymbol, Map<String, Symbol> dynamicFiltersMap, Set<TaskId> taskIds, Set<InternalNode> workers, StageStateMachine stateMachine) {
    final StateStore stateStore = stateStoreProvider.getStateStore();
    String queryId = stateMachine.getSession().getQueryId().toString();
    for (Map.Entry<String, Symbol> entry : dynamicFiltersMap.entrySet()) {
        Symbol buildSymbolToCheck = buildSymbol != null ? buildSymbol : node.getOutputSymbols().contains(entry.getValue()) ? entry.getValue() : null;
        if (buildSymbolToCheck != null && entry.getValue().getName().equals(buildSymbol.getName())) {
            String filterId = entry.getKey();
            stateStore.createStateCollection(createKey(DynamicFilterUtils.TASKSPREFIX, filterId, queryId), SET);
            stateStore.createStateCollection(createKey(DynamicFilterUtils.PARTIALPREFIX, filterId, queryId), SET);
            dynamicFilters.putIfAbsent(queryId, new ConcurrentHashMap<>());
            Map<String, DynamicFilterRegistryInfo> filters = dynamicFilters.get(queryId);
            if (node instanceof JoinNode) {
                filters.put(filterId, extractDynamicFilterRegistryInfo((JoinNode) node, stateMachine.getSession(), filterId));
            } else if (node instanceof SemiJoinNode) {
                filters.put(filterId, extractDynamicFilterRegistryInfo((SemiJoinNode) node, stateMachine.getSession()));
            }
            dynamicFiltersToTask.putIfAbsent(filterId + "-" + queryId, new CopyOnWriteArraySet<>());
            CopyOnWriteArraySet<TaskId> taskSet = dynamicFiltersToTask.get(filterId + "-" + queryId);
            taskSet.addAll(taskIds);
            log.debug("registerTasks source " + filterId + " filters:" + filters + ", workers: " + workers.stream().map(x -> x.getNodeIdentifier()).collect(Collectors.joining(",")) + ", taskIds: " + taskIds.stream().map(TaskId::toString).collect(Collectors.joining(",")));
        }
    }
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) DynamicFilter(io.prestosql.spi.dynamicfilter.DynamicFilter) Inject(com.google.inject.Inject) StateStore(io.prestosql.spi.statestore.StateStore) DynamicFilterUtils.findFilterNodeInStage(io.prestosql.utils.DynamicFilterUtils.findFilterNodeInStage) CallExpression(io.prestosql.spi.relation.CallExpression) PreDestroy(javax.annotation.PreDestroy) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) FilterNode(io.prestosql.spi.plan.FilterNode) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) SystemSessionProperties.getDynamicFilteringDataType(io.prestosql.SystemSessionProperties.getDynamicFilteringDataType) PrestoException(io.prestosql.spi.PrestoException) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) StateMap(io.prestosql.spi.statestore.StateMap) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) DynamicFilters(io.prestosql.sql.DynamicFilters) PlanNode(io.prestosql.spi.plan.PlanNode) StateSet(io.prestosql.spi.statestore.StateSet) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Threads.threadsNamed(io.airlift.concurrent.Threads.threadsNamed) Collectors(java.util.stream.Collectors) DynamicFilterUtils.getDynamicFilterDataType(io.prestosql.utils.DynamicFilterUtils.getDynamicFilterDataType) Executors(java.util.concurrent.Executors) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Type(io.prestosql.spi.dynamicfilter.DynamicFilter.Type) List(java.util.List) PostConstruct(javax.annotation.PostConstruct) Entry(java.util.Map.Entry) GENERIC_INTERNAL_ERROR(io.prestosql.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR) Optional(java.util.Optional) LOCAL(io.prestosql.spi.dynamicfilter.DynamicFilter.Type.LOCAL) TaskId(io.prestosql.execution.TaskId) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Logger(io.airlift.log.Logger) HASHSET(io.prestosql.spi.dynamicfilter.DynamicFilter.DataType.HASHSET) HashMap(java.util.HashMap) Supplier(java.util.function.Supplier) SemiJoinNode(io.prestosql.sql.planner.plan.SemiJoinNode) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BloomFilter(io.prestosql.spi.util.BloomFilter) DataType(io.prestosql.spi.dynamicfilter.DynamicFilter.DataType) Objects.requireNonNull(java.util.Objects.requireNonNull) Session(io.prestosql.Session) BloomFilterDynamicFilter(io.prestosql.spi.dynamicfilter.BloomFilterDynamicFilter) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) QueryId(io.prestosql.spi.QueryId) JoinNode(io.prestosql.spi.plan.JoinNode) Symbol(io.prestosql.spi.plan.Symbol) StageStateMachine(io.prestosql.execution.StageStateMachine) StateCollection(io.prestosql.spi.statestore.StateCollection) InternalNode(io.prestosql.metadata.InternalNode) IOException(java.io.IOException) BLOOM_FILTER(io.prestosql.spi.dynamicfilter.DynamicFilter.DataType.BLOOM_FILTER) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) TimeUnit(java.util.concurrent.TimeUnit) GLOBAL(io.prestosql.spi.dynamicfilter.DynamicFilter.Type.GLOBAL) DynamicFilterUtils(io.prestosql.utils.DynamicFilterUtils) DynamicFilterUtils.createKey(io.prestosql.utils.DynamicFilterUtils.createKey) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) StateStoreProvider(io.prestosql.statestore.StateStoreProvider) RowExpression(io.prestosql.spi.relation.RowExpression) MAP(io.prestosql.spi.statestore.StateCollection.Type.MAP) DynamicFilterFactory(io.prestosql.spi.dynamicfilter.DynamicFilterFactory) Collections(java.util.Collections) SET(io.prestosql.spi.statestore.StateCollection.Type.SET) TaskId(io.prestosql.execution.TaskId) Symbol(io.prestosql.spi.plan.Symbol) SemiJoinNode(io.prestosql.sql.planner.plan.SemiJoinNode) JoinNode(io.prestosql.spi.plan.JoinNode) StateStore(io.prestosql.spi.statestore.StateStore) SemiJoinNode(io.prestosql.sql.planner.plan.SemiJoinNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) StateMap(io.prestosql.spi.statestore.StateMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 23 with JoinNode

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

the class CubeOptimizer method parseNodeRecursively.

private void parseNodeRecursively(PlanNode node) {
    if (node instanceof ProjectNode) {
        ProjectNode projection = ((ProjectNode) node);
        validateProjection(projection);
        parseNodeRecursively(projection.getSource());
        handleProjection(projection);
    } else if (node instanceof JoinNode) {
        JoinNode localJoinNode = (JoinNode) node;
        parseNodeRecursively(localJoinNode.getLeft());
        parseNodeRecursively(localJoinNode.getRight());
        localJoinNode.getOutputSymbols().stream().map(Symbol::getName).forEach(symbol -> originalPlanMappings.put(symbol, originalPlanMappings.get(symbol)));
        localJoinNode.getCriteria().forEach(equiJoinClause -> {
            // Join condition(s) must be defined on column from Source table
            ColumnWithTable leftColumn = originalPlanMappings.get(equiJoinClause.getLeft().getName());
            ColumnWithTable rightColumn = originalPlanMappings.get(equiJoinClause.getRight().getName());
            ColumnWithTable sourceTableColumn = leftColumn.getFQTableName().equalsIgnoreCase(sourceTableName) ? leftColumn : rightColumn;
            dimensions.add(sourceTableColumn.getColumnName());
            groupBy.add(sourceTableColumn.getColumnName());
            matchingMetadataList.removeIf(metadata -> {
                // Retain Cube metadata, only if one of the join column is part of Cube
                return !metadata.getDimensions().contains(sourceTableColumn.getColumnName());
            });
        });
    } else if (node instanceof TableScanNode) {
        TableScanNode scanNode = (TableScanNode) node;
        TableMetadata tableMetadata = metadata.getTableMetadata(context.getSession(), scanNode.getTable());
        scanNode.getOutputSymbols().forEach(output -> {
            ColumnWithTable columnWithTable = new ColumnWithTable(tableMetadata.getQualifiedName().toString(), scanNode.getAssignments().get(output).getColumnName());
            originalPlanMappings.put(output.getName(), columnWithTable);
        });
        // Assumption: Cubes are defined on only of the tables involved in Join. That table will be considered Source Table.
        List<CubeMetadata> metadataList = cubeMetaStore.getMetadataList(tableMetadata.getQualifiedName().toString());
        if (sourceTableScanNode == null && !metadataList.isEmpty()) {
            sourceTableScanNode = scanNode;
            sourceTableMetadata = tableMetadata;
            sourceTableName = sourceTableMetadata.getQualifiedName().toString();
            sourceTableHandle = sourceTableScanNode.getTable();
            matchingMetadataList.addAll(metadataList);
            sourceTableColumnMap.putAll(metadata.getColumnHandles(context.getSession(), sourceTableHandle));
        }
    } else {
        throw new UnsupportedOperationException("Unexpected plan node. Expected TableScan, JoinNode or ProjectNode. Actual is " + node.getClass());
    }
}
Also used : LongSupplier(java.util.function.LongSupplier) ConstantExpression(io.prestosql.spi.relation.ConstantExpression) PrestoWarning(io.prestosql.spi.PrestoWarning) TypeProvider(io.prestosql.sql.planner.TypeProvider) SqlParser(io.prestosql.sql.parser.SqlParser) ColumnNotFoundException(io.prestosql.spi.connector.ColumnNotFoundException) AggregationNode(io.prestosql.spi.plan.AggregationNode) CallExpression(io.prestosql.spi.relation.CallExpression) Cast(io.prestosql.sql.tree.Cast) FilterNode(io.prestosql.spi.plan.FilterNode) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) OriginalExpressionUtils.castToRowExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression) Type(io.prestosql.spi.type.Type) OriginalExpressionUtils.castToExpression(io.prestosql.sql.relational.OriginalExpressionUtils.castToExpression) CubeFilter(io.hetu.core.spi.cube.CubeFilter) ENGLISH(java.util.Locale.ENGLISH) Identifier(io.prestosql.sql.tree.Identifier) AggregationNode.singleGroupingSet(io.prestosql.spi.plan.AggregationNode.singleGroupingSet) CubeMetaStore(io.hetu.core.spi.cube.io.CubeMetaStore) PrestoException(io.prestosql.spi.PrestoException) SymbolsExtractor(io.prestosql.sql.planner.SymbolsExtractor) SUM(io.hetu.core.spi.cube.CubeAggregateFunction.SUM) ImmutableMap(com.google.common.collect.ImmutableMap) CubeAggregateFunction(io.hetu.core.spi.cube.CubeAggregateFunction) TableScanNode(io.prestosql.spi.plan.TableScanNode) Set(java.util.Set) PlanNode(io.prestosql.spi.plan.PlanNode) UUID(java.util.UUID) ProjectNode(io.prestosql.spi.plan.ProjectNode) Collectors(java.util.stream.Collectors) Metadata(io.prestosql.metadata.Metadata) String.format(java.lang.String.format) FunctionHandle(io.prestosql.spi.function.FunctionHandle) Objects(java.util.Objects) SymbolUtils.toSymbolReference(io.prestosql.sql.planner.SymbolUtils.toSymbolReference) ReuseExchangeOperator(io.prestosql.spi.operator.ReuseExchangeOperator) List(java.util.List) ExpressionUtils(io.prestosql.sql.ExpressionUtils) LongLiteral(io.prestosql.sql.tree.LongLiteral) SymbolReference(io.prestosql.sql.tree.SymbolReference) AggregationSignature(io.hetu.core.spi.cube.aggregator.AggregationSignature) Optional(java.util.Optional) NOT_SUPPORTED(io.prestosql.spi.StandardErrorCode.NOT_SUPPORTED) TypeSignature(io.prestosql.spi.type.TypeSignature) OriginalExpressionUtils(io.prestosql.sql.relational.OriginalExpressionUtils) Iterables(com.google.common.collect.Iterables) COUNT(io.hetu.core.spi.cube.CubeAggregateFunction.COUNT) TableMetadata(io.prestosql.metadata.TableMetadata) Logger(io.airlift.log.Logger) TypeSignatureProvider(io.prestosql.sql.analyzer.TypeSignatureProvider) Literal(io.prestosql.sql.tree.Literal) HashMap(java.util.HashMap) TableHandle(io.prestosql.spi.metadata.TableHandle) ExpressionTreeRewriter(io.prestosql.sql.tree.ExpressionTreeRewriter) QualifiedObjectName(io.prestosql.spi.connector.QualifiedObjectName) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SchemaTableName(io.prestosql.spi.connector.SchemaTableName) Lists(com.google.common.collect.Lists) ArithmeticBinaryExpression(io.prestosql.sql.tree.ArithmeticBinaryExpression) ImmutableList(com.google.common.collect.ImmutableList) ExpressionDomainTranslator(io.prestosql.sql.planner.ExpressionDomainTranslator) BooleanLiteral(io.prestosql.sql.tree.BooleanLiteral) Objects.requireNonNull(java.util.Objects.requireNonNull) Session(io.prestosql.Session) RowExpressionRewriter(io.prestosql.expressions.RowExpressionRewriter) RowExpressionTreeRewriter(io.prestosql.expressions.RowExpressionTreeRewriter) ExpressionRewriter(io.prestosql.sql.tree.ExpressionRewriter) JoinNode(io.prestosql.spi.plan.JoinNode) ParsingOptions(io.prestosql.sql.parser.ParsingOptions) Symbol(io.prestosql.spi.plan.Symbol) AssignmentUtils(io.prestosql.sql.planner.plan.AssignmentUtils) EXPIRED_CUBE(io.prestosql.spi.connector.StandardWarningCode.EXPIRED_CUBE) Assignments(io.prestosql.spi.plan.Assignments) Rule(io.prestosql.sql.planner.iterative.Rule) ColumnMetadata(io.prestosql.spi.connector.ColumnMetadata) TupleDomain(io.prestosql.spi.predicate.TupleDomain) ComparisonExpression(io.prestosql.sql.tree.ComparisonExpression) VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) SymbolAllocator(io.prestosql.spi.SymbolAllocator) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) ColumnHandle(io.prestosql.spi.connector.ColumnHandle) CUBE_ERROR(io.prestosql.spi.StandardErrorCode.CUBE_ERROR) RowExpression(io.prestosql.spi.relation.RowExpression) CubeMetadata(io.hetu.core.spi.cube.CubeMetadata) Comparator(java.util.Comparator) Expression(io.prestosql.sql.tree.Expression) TableMetadata(io.prestosql.metadata.TableMetadata) TableScanNode(io.prestosql.spi.plan.TableScanNode) JoinNode(io.prestosql.spi.plan.JoinNode) Symbol(io.prestosql.spi.plan.Symbol) ProjectNode(io.prestosql.spi.plan.ProjectNode) CubeMetadata(io.hetu.core.spi.cube.CubeMetadata)

Example 24 with JoinNode

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

the class OptimizeAggregationOverJoin method apply.

@Override
public Result apply(AggregationNode node, Captures captures, Context context) {
    long startOptimizationTime = System.currentTimeMillis();
    Optional<PlanNode> preProjectNodeOne = captures.get(OPTIONAL_PRE_PROJECT_ONE);
    Optional<PlanNode> preProjectNodeTwo = captures.get(OPTIONAL_PRE_PROJECT_TWO);
    List<ProjectNode> projectNodes = new ArrayList<>();
    if ((preProjectNodeOne.isPresent() && !(preProjectNodeOne.get() instanceof ProjectNode)) || (preProjectNodeTwo.isPresent() && !(preProjectNodeTwo.get() instanceof ProjectNode))) {
        return Result.empty();
    }
    preProjectNodeOne.map(ProjectNode.class::cast).map(projectNodes::add);
    preProjectNodeTwo.map(ProjectNode.class::cast).map(projectNodes::add);
    Optional<PlanNode> filterNode = captures.get(OPTIONAL_FILTER);
    JoinNode joinNode = (JoinNode) Plans.resolveGroupReferences(captures.get(JOIN_NODE), context.getLookup());
    try {
        Optional<PlanNode> optimized = CubeOptimizer.forPlan(context, metadata, cubeMetaStore, node, projectNodes, filterNode.map(FilterNode.class::cast).orElse(null), joinNode).optimize();
        return optimized.map(Result::ofPlanNode).orElseGet(Result::empty);
    } catch (RuntimeException ex) {
        LOGGER.warn("Encountered exception '" + ex.getMessage() + "' while applying the CubeOptimizer", ex);
        return Result.empty();
    } finally {
        long endOptimizationTime = System.currentTimeMillis();
        LOGGER.debug("Star-tree total optimization time: %d millis", (endOptimizationTime - startOptimizationTime));
    }
}
Also used : PlanNode(io.prestosql.spi.plan.PlanNode) JoinNode(io.prestosql.spi.plan.JoinNode) ArrayList(java.util.ArrayList) ProjectNode(io.prestosql.spi.plan.ProjectNode)

Example 25 with JoinNode

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

the class PushAggregationThroughOuterJoin method coalesceWithNullAggregation.

// When the aggregation is done after the join, there will be a null value that gets aggregated over
// where rows did not exist in the inner table.  For some aggregate functions, such as count, the result
// of an aggregation over a single null row is one or zero rather than null. In order to ensure correct results,
// we add a coalesce function with the output of the new outer join and the agggregation performed over a single
// null row.
private Optional<PlanNode> coalesceWithNullAggregation(AggregationNode aggregationNode, PlanNode outerJoin, PlanSymbolAllocator planSymbolAllocator, PlanNodeIdAllocator idAllocator, Lookup lookup) {
    // Create an aggregation node over a row of nulls.
    Optional<MappedAggregationInfo> aggregationOverNullInfoResultNode = createAggregationOverNull(aggregationNode, planSymbolAllocator, idAllocator, lookup);
    if (!aggregationOverNullInfoResultNode.isPresent()) {
        return Optional.empty();
    }
    MappedAggregationInfo aggregationOverNullInfo = aggregationOverNullInfoResultNode.get();
    AggregationNode aggregationOverNull = aggregationOverNullInfo.getAggregation();
    Map<Symbol, Symbol> sourceAggregationToOverNullMapping = aggregationOverNullInfo.getSymbolMapping();
    // Do a cross join with the aggregation over null
    JoinNode crossJoin = new JoinNode(idAllocator.getNextId(), JoinNode.Type.INNER, outerJoin, aggregationOverNull, ImmutableList.of(), ImmutableList.<Symbol>builder().addAll(outerJoin.getOutputSymbols()).addAll(aggregationOverNull.getOutputSymbols()).build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
    // Add coalesce expressions for all aggregation functions
    Assignments.Builder assignmentsBuilder = Assignments.builder();
    for (Symbol symbol : outerJoin.getOutputSymbols()) {
        if (aggregationNode.getAggregations().containsKey(symbol)) {
            assignmentsBuilder.put(symbol, new SpecialForm(COALESCE, planSymbolAllocator.getTypes().get(symbol), ImmutableList.of(toVariableReference(symbol, planSymbolAllocator.getTypes()), toVariableReference(sourceAggregationToOverNullMapping.get(symbol), planSymbolAllocator.getTypes()))));
        } else {
            assignmentsBuilder.put(symbol, toVariableReference(symbol, planSymbolAllocator.getTypes()));
        }
    }
    return Optional.of(new ProjectNode(idAllocator.getNextId(), crossJoin, assignmentsBuilder.build()));
}
Also used : Symbol(io.prestosql.spi.plan.Symbol) JoinNode(io.prestosql.spi.plan.JoinNode) Assignments(io.prestosql.spi.plan.Assignments) AggregationNode(io.prestosql.spi.plan.AggregationNode) ProjectNode(io.prestosql.spi.plan.ProjectNode) SpecialForm(io.prestosql.spi.relation.SpecialForm)

Aggregations

JoinNode (io.prestosql.spi.plan.JoinNode)55 Symbol (io.prestosql.spi.plan.Symbol)44 PlanNode (io.prestosql.spi.plan.PlanNode)31 RowExpression (io.prestosql.spi.relation.RowExpression)22 TableScanNode (io.prestosql.spi.plan.TableScanNode)19 Test (org.testng.annotations.Test)18 FilterNode (io.prestosql.spi.plan.FilterNode)17 ImmutableList (com.google.common.collect.ImmutableList)16 Expression (io.prestosql.sql.tree.Expression)16 ProjectNode (io.prestosql.spi.plan.ProjectNode)15 CallExpression (io.prestosql.spi.relation.CallExpression)14 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)13 ColumnHandle (io.prestosql.spi.connector.ColumnHandle)13 OriginalExpressionUtils.castToRowExpression (io.prestosql.sql.relational.OriginalExpressionUtils.castToRowExpression)13 ComparisonExpression (io.prestosql.sql.tree.ComparisonExpression)13 Assignments (io.prestosql.spi.plan.Assignments)12 SemiJoinNode (io.prestosql.sql.planner.plan.SemiJoinNode)12 Optional (java.util.Optional)12 Session (io.prestosql.Session)11 List (java.util.List)11