@@ -1003,11 +1003,19 @@ private Pair<List<RexNode>, List<AggCall>> aggregateWithTrimming(
10031003 // During aggregation, Calcite projects both input dependencies and output group-by fields.
10041004 // When names conflict, Calcite adds numeric suffixes (e.g., "value0").
10051005 // Apply explicit renaming to restore the intended aliases.
1006- context .relBuilder .rename (names );
1007-
1006+ if (names .size () == reResolved .getLeft ().size ()) {
1007+ // Defense check: if any group-by key is not aliased, do not rename
1008+ context .relBuilder .rename (names );
1009+ }
10081010 return Pair .of (reResolved .getLeft (), reResolved .getRight ());
10091011 }
10101012
1013+ /**
1014+ * Imitates {@code Registrar.registerExpression} of {@link RelBuilder} to derive the output order
1015+ * of group-by keys after aggregation.
1016+ *
1017+ * <p>The projected input reference comes first, while any other computed expression follows.
1018+ */
10111019 private List <String > getGroupKeyNamesAfterAggregation (List <RexNode > nodes ) {
10121020 List <RexNode > reordered = new ArrayList <>();
10131021 List <RexNode > left = new ArrayList <>();
@@ -1026,10 +1034,7 @@ private List<String> getGroupKeyNamesAfterAggregation(List<RexNode> nodes) {
10261034 .toList ();
10271035 }
10281036
1029- /**
1030- * Immitates registerExpression of {@link RelBuilder.Registrar} to derive the output order of
1031- * group-by keys after aggregation
1032- */
1037+ /** Whether a rex node is an aliased input reference */
10331038 private boolean isInputRef (RexNode node ) {
10341039 return switch (node .getKind ()) {
10351040 case AS , DESCENDING , NULLS_FIRST , NULLS_LAST -> {
0 commit comments