Skip to content

Commit ae31d70

Browse files
[FLINK-39715][table-planner] Fix IndexOutOfBoundsException in FlinkExpandConversionRule for global aggregate after sort
1 parent 6c60f4f commit ae31d70

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

‎flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/plan/rules/physical/FlinkExpandConversionRule.scala‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import org.apache.calcite.plan.volcano.AbstractConverter
3030
import org.apache.calcite.rel.{RelCollation, RelCollations, RelCollationTraitDef, RelNode}
3131
import org.apache.calcite.rel.RelDistribution.Type._
3232

33+
import scala.collection.JavaConverters._
34+
3335
/** Rule which converts an [[AbstractConverter]] to a RelNode which satisfies the target traits. */
3436
class FlinkExpandConversionRule(flinkConvention: Convention)
3537
extends RelOptRule(
@@ -68,6 +70,9 @@ class FlinkExpandConversionRule(flinkConvention: Convention)
6870
val toCollation = requiredTraits.getTrait(RelCollationTraitDef.INSTANCE)
6971
transformedNode = satisfyCollation(flinkConvention, transformedNode, toCollation)
7072
}
73+
if (transformedNode == null) {
74+
return
75+
}
7176
checkSatisfyRequiredTrait(transformedNode, requiredTraits)
7277
call.transformTo(transformedNode)
7378
}
@@ -151,6 +156,12 @@ object FlinkExpandConversionRule {
151156
requiredCollation: RelCollation): RelNode = {
152157
val fromCollation = node.getTraitSet.getTrait(RelCollationTraitDef.INSTANCE)
153158
if (!fromCollation.satisfies(requiredCollation)) {
159+
val fieldCount = node.getRowType.getFieldCount
160+
val isValidCollation =
161+
requiredCollation.getFieldCollations.asScala.forall(_.getFieldIndex < fieldCount)
162+
if (!isValidCollation) {
163+
return null
164+
}
154165
val traitSet = node.getTraitSet.replace(requiredCollation).replace(flinkConvention)
155166
val sortCollation = RelCollationTraitDef.INSTANCE.canonize(requiredCollation)
156167
flinkConvention match {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.flink.table.planner.plan.rules.physical;
19+
20+
import org.apache.flink.table.api.EnvironmentSettings;
21+
import org.apache.flink.table.api.TableEnvironment;
22+
23+
import org.junit.jupiter.api.Test;
24+
25+
public class ExpandConversionRuleFixTest {
26+
27+
@Test
28+
public void testOrderByWithGlobalAggregate() {
29+
EnvironmentSettings settings = EnvironmentSettings.newInstance().inBatchMode().build();
30+
TableEnvironment tEnv = TableEnvironment.create(settings);
31+
tEnv.getConfig().set("parallelism.default", "1");
32+
33+
tEnv.executeSql(
34+
"CREATE TABLE MyTable ("
35+
+ " a INT,"
36+
+ " b STRING"
37+
+ ") WITH ("
38+
+ " 'connector' = 'datagen',"
39+
+ " 'number-of-rows' = '5'"
40+
+ ")");
41+
42+
String sql = "SELECT MAX(a) FROM (SELECT a, b FROM MyTable ORDER BY b ASC)";
43+
44+
tEnv.executeSql(sql).collect();
45+
}
46+
}

0 commit comments

Comments
 (0)