|
19 | 19 |
|
20 | 20 | import com.google.common.collect.Lists; |
21 | 21 | import org.apache.calcite.util.ImmutableBitSet; |
| 22 | +import org.apache.drill.exec.expr.fn.impl.CollectToListVarcharFunction; |
22 | 23 | import org.apache.drill.exec.planner.logical.DrillAggregateRel; |
23 | 24 | import org.apache.drill.exec.planner.logical.RelOptHelper; |
24 | 25 | import org.apache.drill.exec.planner.physical.AggPrelBase.OperatorPhase; |
25 | 26 | import org.apache.calcite.rel.InvalidRelException; |
26 | 27 | import org.apache.calcite.rel.RelNode; |
| 28 | +import org.apache.calcite.rel.core.AggregateCall; |
27 | 29 | import org.apache.calcite.plan.RelOptRule; |
28 | 30 | import org.apache.calcite.plan.RelOptRuleCall; |
29 | 31 | import org.apache.calcite.plan.RelTrait; |
@@ -58,6 +60,10 @@ public void onMatch(RelOptRuleCall call) { |
58 | 60 | final DrillAggregateRel aggregate = call.rel(0); |
59 | 61 | final RelNode input = call.rel(1); |
60 | 62 |
|
| 63 | + if (hasIncompatibleAggCalls(aggregate)) { |
| 64 | + return; |
| 65 | + } |
| 66 | + |
61 | 67 | if (aggregate.containsDistinctCall() || aggregate.getGroupCount() == 0) { |
62 | 68 | // currently, don't use HashAggregate if any of the logical aggrs contains DISTINCT or |
63 | 69 | // if there are no grouping keys |
@@ -168,4 +174,35 @@ private void createTransformRequest(RelOptRuleCall call, DrillAggregateRel aggre |
168 | 174 | call.transformTo(newAgg); |
169 | 175 | } |
170 | 176 |
|
| 177 | + /** |
| 178 | + * Evaluates the logical aggregate expressions to determine if any are |
| 179 | + * incompatible with the Hash Aggregate physical operator. |
| 180 | + * <p> |
| 181 | + * While Hash Aggregate is generally performant for many aggregation types, |
| 182 | + * certain functions (such as {@code collect_to_list_varchar}) may require specific |
| 183 | + * data ordering or memory management patterns that the Hash Aggregate |
| 184 | + * implementation does not provide. |
| 185 | + * </p> |
| 186 | + * <p> |
| 187 | + * <b>Current Incompatibilities:</b> |
| 188 | + * <ul> |
| 189 | + * <li>{@link org.apache.drill.exec.expr.fn.impl.CollectToListVarcharFunction}: Excluded from |
| 190 | + * HashAgg because it requires data ordering and cannot be processed efficiently in an unordered |
| 191 | + * fashion. {@code SortAggPrule} is intended to handle this, ensuring deterministic results. |
| 192 | + * </li> |
| 193 | + * </ul> |
| 194 | + * </p> |
| 195 | + * @param aggregate The logical aggregate relational nodes containing the |
| 196 | + * list of {@link AggregateCall}s to inspect. |
| 197 | + * @return {@code true} if at least one aggregation call is incompatible |
| 198 | + * with HashAgg; {@code false} otherwise. |
| 199 | + */ |
| 200 | + private boolean hasIncompatibleAggCalls(DrillAggregateRel aggregate) { |
| 201 | + for (AggregateCall aggCall : aggregate.getAggCallList()) { |
| 202 | + if (CollectToListVarcharFunction.NAME.equalsIgnoreCase(aggCall.getAggregation().getName())) { |
| 203 | + return true; |
| 204 | + } |
| 205 | + } |
| 206 | + return false; |
| 207 | + } |
171 | 208 | } |
0 commit comments