morrySnow commented on code in PR #67884:
URL: https://github.com/apache/doris/pull/67884#discussion_r4070717684
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/SimplifyAggGroupBy.java:
##########
@@ -19,118 +19,54 @@
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.trees.expressions.Add;
-import org.apache.doris.nereids.trees.expressions.BinaryArithmetic;
-import org.apache.doris.nereids.trees.expressions.Cast;
-import org.apache.doris.nereids.trees.expressions.Divide;
import org.apache.doris.nereids.trees.expressions.Expression;
-import org.apache.doris.nereids.trees.expressions.Multiply;
import org.apache.doris.nereids.trees.expressions.Slot;
-import org.apache.doris.nereids.trees.expressions.Subtract;
-import org.apache.doris.nereids.trees.expressions.literal.Literal;
-import org.apache.doris.nereids.util.ExpressionUtils;
-import org.apache.doris.nereids.util.Utils;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
- * Simplify Aggregate group by Multiple to One. For example
+ * Remove deterministic grouping expressions whose inputs are already bare
grouping slots.
* <p>
- * GROUP BY ClientIP, ClientIP - 1, ClientIP - 2, ClientIP - 3
+ * GROUP BY ClientIP, ClientIP + 1, ClientIP + 2
* -->
* GROUP BY ClientIP
+ *
+ * <p>Retain existing bare slots so aggregate outputs can still reference
them. A cast group key
+ * cannot generally provide its original slot to those outputs. Never
synthesize a slot from
+ * derived keys, since doing so can split groups formed by non-injective
expressions.</p>
*/
public class SimplifyAggGroupBy extends OneRewriteRuleFactory {
- private static final ImmutableSet<Class<? extends Expression>>
supportedFunctions
- = ImmutableSet.of(Add.class, Subtract.class, Multiply.class,
Divide.class);
-
@Override
public Rule build() {
return logicalAggregate()
- .when(agg -> agg.getGroupByExpressions().size() > 1
- &&
ExpressionUtils.allMatch(agg.getGroupByExpressions(),
- SimplifyAggGroupBy::isBinaryArithmeticSlot))
+ .when(agg -> agg.getGroupByExpressions().size() > 1)
.then(agg -> {
- List<Expression> groupByExpressions =
agg.getGroupByExpressions();
- ImmutableSet.Builder<Expression> inputSlots
- =
ImmutableSet.builderWithExpectedSize(groupByExpressions.size());
- for (Expression groupByExpression : groupByExpressions) {
- inputSlots.addAll(groupByExpression.getInputSlots());
- }
- Set<Expression> slots = inputSlots.build();
- if (slots.size() != 1) {
+ List<Expression> simplified =
simplifyGroupBy(agg.getGroupByExpressions());
+ if (simplified == null) {
return null;
}
- return
agg.withGroupByAndOutput(Utils.fastToImmutableList(slots),
agg.getOutputExpressions());
+ return agg.withGroupByAndOutput(simplified,
agg.getOutputExpressions());
})
.toRule(RuleType.SIMPLIFY_AGG_GROUP_BY);
}
@VisibleForTesting
- protected static boolean isBinaryArithmeticSlot(Expression expr) {
- if (expr instanceof Slot) {
- return true;
- }
- if (!(expr instanceof BinaryArithmetic)) {
- return false;
- }
- if (!supportedFunctions.contains(expr.getClass())) {
- return false;
- }
-
- // Float/double arithmetic: precision loss for all operations
- if (expr.child(0).getDataType().isFloatLikeType()
- || expr.child(1).getDataType().isFloatLikeType()) {
- return false;
+ protected static List<Expression> simplifyGroupBy(List<Expression>
groupByExpressions) {
+ Set<Expression> distinctGroupBy = new
LinkedHashSet<>(groupByExpressions);
+ Set<Expression> determinants = distinctGroupBy.stream()
+
.filter(Slot.class::isInstance).collect(ImmutableSet.toImmutableSet());
+ // Keep at least one key: removing all constant keys changes the
result for empty input.
+ if (!determinants.isEmpty()) {
+ distinctGroupBy.removeIf(expression -> !(expression instanceof
Slot)
+ && !expression.containsVolatileExpression()
Review Comment:
not intro by this PR
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]