private AggregationNode map(AggregationNode node, PlanNode source, PlanNodeId newNodeId) { ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder(); for (Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) { aggregations.put(map(entry.getKey()), map(entry.getValue())); } return new AggregationNode( newNodeId, source, aggregations.build(), groupingSets( mapAndDistinct(node.getGroupingKeys()), node.getGroupingSetCount(), node.getGlobalGroupingSets()), ImmutableList.of(), node.getStep(), node.getHashSymbol().map(this::map), node.getGroupIdSymbol().map(this::map)); }
private AggregationNode map(AggregationNode node, PlanNode source, PlanNodeId newNodeId) { ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder(); for (Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) { aggregations.put(map(entry.getKey()), map(entry.getValue())); } return new AggregationNode( newNodeId, source, aggregations.build(), groupingSets( mapAndDistinct(node.getGroupingKeys()), node.getGroupingSetCount(), node.getGlobalGroupingSets()), ImmutableList.of(), node.getStep(), node.getHashSymbol().map(this::map), node.getGroupIdSymbol().map(this::map)); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by local hash exchange") public void testSingleNodeFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))); validatePlan(root, true); }
@Test public void testSingleThreadFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.values())))); validatePlan(root, true); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by remote hash exchange") public void testGloballyDistributedFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))); validatePlan(root, false); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by remote hash exchange") public void testGloballyDistributedFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))); validatePlan(root, false); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by local hash exchange") public void testSingleNodeFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))); validatePlan(root, true); }
subPlan.getRoot(), aggregations, groupingSets( groupingKeys.build(), groupingSets.size(),
@Test public void testSingleThreadFinalAggregationInTheSameStageAsPartialAggregation() { PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.values())))); validatePlan(root, true); }
subPlan.getRoot(), aggregations, groupingSets( groupingKeys.build(), groupingSets.size(),
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by local hash exchange") public void testWithPartialAggregationBelowJoinWithoutSeparatingExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.join( INNER, builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)), builder.values()))); validatePlan(root, true); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Final aggregation with default value not separated from partial aggregation by local hash exchange") public void testWithPartialAggregationBelowJoinWithoutSeparatingExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.join( INNER, builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)), builder.values()))); validatePlan(root, true); }
@Test public void testSingleNodeFinalAggregationSeparatedFromPartialAggregationByLocalHashExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.exchange(e -> e .type(REPARTITION) .scope(LOCAL) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))))); validatePlan(root, true); }
@Test public void testSingleNodeFinalAggregationSeparatedFromPartialAggregationByLocalHashExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.exchange(e -> e .type(REPARTITION) .scope(LOCAL) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))))); validatePlan(root, true); }
@Test public void testGloballyDistributedFinalAggregationSeparatedFromPartialAggregationByRemoteHashExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.exchange(e -> e .type(REPARTITION) .scope(REMOTE) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))))); validatePlan(root, false); }
@Test public void testGloballyDistributedFinalAggregationSeparatedFromPartialAggregationByRemoteHashExchange() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.exchange(e -> e .type(REPARTITION) .scope(REMOTE) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))))); validatePlan(root, false); }
@Test public void testWithPartialAggregationBelowJoin() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.join( INNER, builder.exchange(e -> e .type(REPARTITION) .scope(LOCAL) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))), builder.values()))); validatePlan(root, true); }
@Test public void testWithPartialAggregationBelowJoin() { Symbol symbol = new Symbol("symbol"); PlanNode root = builder.aggregation( af -> af.step(FINAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(builder.join( INNER, builder.exchange(e -> e .type(REPARTITION) .scope(LOCAL) .fixedHashDistributionParitioningScheme(ImmutableList.of(symbol), ImmutableList.of(symbol)) .addInputsSet(symbol) .addSource(builder.aggregation(ap -> ap .step(PARTIAL) .groupingSets(groupingSets(ImmutableList.of(symbol), 2, ImmutableSet.of(0))) .source(tableScanNode)))), builder.values()))); validatePlan(root, true); }