You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by "gustavodemorais (via GitHub)" <gi...@apache.org> on 2026/04/15 16:23:59 UTC

Re: [PR] [FLINK-38551][table-planner] Extend MultiJoin tests based on current join tests [flink]

gustavodemorais commented on code in PR #27415:
URL: https://github.com/apache/flink/pull/27415#discussion_r3087896137


##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/stream/sql/MultiJoinITCase.java:
##########
@@ -0,0 +1,1178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.runtime.stream.sql;
+
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment;

Review Comment:
   Nit: this imports the Scala `StreamTableEnvironment` bridge instead of the Java one. Should be `org.apache.flink.table.api.bridge.java.StreamTableEnvironment` - see `JoinReorderITCase.java:27` for reference.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/stream/sql/MultiJoinITCase.java:
##########
@@ -0,0 +1,1178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.runtime.stream.sql;
+
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment;
+import org.apache.flink.table.api.config.OptimizerConfigOptions;
+import org.apache.flink.table.planner.factories.TestValuesTableFactory;
+import org.apache.flink.table.planner.runtime.utils.StreamingWithMiniBatchTestBase;
+import org.apache.flink.table.types.AbstractDataType;
+import org.apache.flink.table.types.UnresolvedDataType;
+import org.apache.flink.types.Row;
+
+import org.apache.calcite.rel.rules.MultiJoin;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import scala.collection.JavaConverters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link MultiJoin} that verify consistency when executed with a parallelism
+ * greater than 1.
+ */

Review Comment:
   The other Java IT tests in this directory and the base class use JUnit 5 - would be good to align here. That means `@ExtendWith(ParameterizedTestExtension.class)`, `@TestTemplate` instead of `@Test`, `@BeforeEach`/`@AfterEach`, and `TestInfo` parameter instead of `@Rule TestName`. `JoinITCase.scala` and `DataStreamJavaITCase.java` are good references for the pattern.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/stream/sql/MultiJoinITCase.java:
##########
@@ -0,0 +1,1178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.runtime.stream.sql;
+
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment;
+import org.apache.flink.table.api.config.OptimizerConfigOptions;
+import org.apache.flink.table.planner.factories.TestValuesTableFactory;
+import org.apache.flink.table.planner.runtime.utils.StreamingWithMiniBatchTestBase;
+import org.apache.flink.table.types.AbstractDataType;
+import org.apache.flink.table.types.UnresolvedDataType;
+import org.apache.flink.types.Row;
+
+import org.apache.calcite.rel.rules.MultiJoin;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import scala.collection.JavaConverters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link MultiJoin} that verify consistency when executed with a parallelism
+ * greater than 1.
+ */
+@RunWith(Parameterized.class)
+public class MultiJoinITCase extends StreamingWithMiniBatchTestBase {
+
+    private StreamExecutionEnvironment env;
+
+    @Rule public TestName testName = new TestName();
+
+    public MultiJoinITCase(MiniBatchMode miniBatch, StateBackendMode state) {
+        super(miniBatch, state);
+    }
+
+    static List<Row> usersData =
+            Arrays.asList(
+                    Row.of("u1", "Will", 100),
+                    Row.of("u2", "Eleven", 50),
+                    Row.of("u3", "Dustin", 70),
+                    Row.of("u4", "Mike", 200),
+                    Row.of("u5", "Lucas", 100));
+
+    static List<Row> ordersData =
+            Arrays.asList(
+                    Row.of("o1", "u1", "Map"),
+                    Row.of("o2", "u1", "Flashlight"),
+                    Row.of("o3", "u2", "Waffles"),
+                    Row.of("o4", "u3", "Bike"),
+                    Row.of("o5", "u4", "Comics"),
+                    Row.of("o6", "u5", "Radio set"));
+
+    static List<Row> paymentsData =
+            Arrays.asList(
+                    Row.of("p1", 10, "u1"),
+                    Row.of("p2", 20, "u1"),
+                    Row.of("p3", 30, "u2"),
+                    Row.of("p4", 100, "u1"),
+                    Row.of("p5", 50, "u2"),
+                    Row.of("p6", 100, "u5"),
+                    Row.of("p7", 70, "u6"),
+                    Row.of("p8", 200, "u7"),
+                    Row.of("p9", 100, "u8"),
+                    Row.of("p10", 100, "u9"),
+                    Row.of("p11", 999, "u10"));
+
+    // Table data for consistency with JoinITCase
+    List<Row> simple3Data =
+            Arrays.asList(
+                    Row.of(1, 1L, "Hi"),
+                    Row.of(2, 2L, "Hello"),
+                    Row.of(3, 2L, "Hello world"),
+                    Row.of(5, 2L, "Hello world"));
+
+    List<Row> simple5Data =
+            Arrays.asList(
+                    Row.of(1, 1L, 0, "Hallo", 1L),
+                    Row.of(2, 2L, 1, "Hallo Welt", 2L),
+                    Row.of(2, 3L, 2, "Hallo Welt wie", 1L),
+                    Row.of(3, 4L, 3, "Hallo Welt wie gehts?", 2L),
+                    Row.of(3, 5L, 4, "ABC", 2L),
+                    Row.of(3, 6L, 5, "BCD", 3L));
+
+    @Before
+    @Override
+    public void before() {
+        super.before();
+
+        env = env();
+    }
+
+    @After
+    @Override
+    public void after() {
+        super.after();
+    }
+
+    private void createTableView(TableInfo tableInfo, StreamTableEnvironment env) {
+        String[] columnNames = tableInfo.getColumnNames();
+        TypeInformation<?>[] columnTypes = tableInfo.getColumnTypes();
+        List<String> primaryKeys = tableInfo.getPrimaryKeys();
+
+        TypeInformation<Row> rowTypeInformation =
+                Types.ROW_NAMED(columnNames, tableInfo.getColumnTypes());
+        DataStream<Row> dataStream =
+                failingDataSource(
+                        JavaConverters.asScalaBuffer(tableInfo.getData()).toSeq(),
+                        rowTypeInformation);
+        Schema.Builder schemaBuilder = Schema.newBuilder();
+
+        for (int i = 0; i < columnNames.length; i++) {
+            AbstractDataType<UnresolvedDataType> dt = DataTypes.of(columnTypes[i]);
+
+            if (primaryKeys.contains(columnNames[i])) {
+                dt = dt.notNull();
+            }
+
+            schemaBuilder.column(columnNames[i], dt);
+        }
+
+        if (!primaryKeys.isEmpty()) {
+            schemaBuilder.primaryKey(primaryKeys);
+        }
+
+        env.createTemporaryView(tableInfo.getName(), dataStream, schemaBuilder.build());
+    }
+
+    public List<String> executeQuery(
+            TableInfo[] sourceTables, TableInfo sinkTable, String query, boolean useMultiJoin)
+            throws Exception {
+        TestValuesTableFactory.clearAllData();
+
+        StreamTableEnvironment tEnv = StreamTableEnvironment.create(env);
+
+        tEnv.getConfig()
+                .set(OptimizerConfigOptions.TABLE_OPTIMIZER_MULTI_JOIN_ENABLED, useMultiJoin);
+
+        for (TableInfo sourceTable : sourceTables) {
+            createTableView(sourceTable, tEnv);
+        }
+
+        createSinkTable(tEnv, sinkTable);
+
+        tEnv.executeSql(query).await();
+
+        return TestValuesTableFactory.getResultsAsStrings(sinkTable.getName());
+    }
+

Review Comment:
   Since the sink schemas are fixed (only `ResultSink` and `ABCSink`), it might be simpler to just inline the DDL strings directly like the other IT tests do (`JoinReorderITCaseBase`, `JoinITCase`). That also avoids the `TypeInformation.toString()` on line 193 producing things like `"String"` and `"Integer"` instead of proper SQL types.



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/runtime/stream/sql/MultiJoinITCase.java:
##########
@@ -0,0 +1,1178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.runtime.stream.sql;
+
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.common.typeinfo.Types;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.Schema;
+import org.apache.flink.table.api.TableException;
+import org.apache.flink.table.api.bridge.scala.StreamTableEnvironment;
+import org.apache.flink.table.api.config.OptimizerConfigOptions;
+import org.apache.flink.table.planner.factories.TestValuesTableFactory;
+import org.apache.flink.table.planner.runtime.utils.StreamingWithMiniBatchTestBase;
+import org.apache.flink.table.types.AbstractDataType;
+import org.apache.flink.table.types.UnresolvedDataType;
+import org.apache.flink.types.Row;
+
+import org.apache.calcite.rel.rules.MultiJoin;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import scala.collection.JavaConverters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link MultiJoin} that verify consistency when executed with a parallelism
+ * greater than 1.
+ */
+@RunWith(Parameterized.class)
+public class MultiJoinITCase extends StreamingWithMiniBatchTestBase {
+
+    private StreamExecutionEnvironment env;
+
+    @Rule public TestName testName = new TestName();
+
+    public MultiJoinITCase(MiniBatchMode miniBatch, StateBackendMode state) {
+        super(miniBatch, state);
+    }
+
+    static List<Row> usersData =
+            Arrays.asList(
+                    Row.of("u1", "Will", 100),
+                    Row.of("u2", "Eleven", 50),
+                    Row.of("u3", "Dustin", 70),
+                    Row.of("u4", "Mike", 200),
+                    Row.of("u5", "Lucas", 100));
+
+    static List<Row> ordersData =
+            Arrays.asList(
+                    Row.of("o1", "u1", "Map"),
+                    Row.of("o2", "u1", "Flashlight"),
+                    Row.of("o3", "u2", "Waffles"),
+                    Row.of("o4", "u3", "Bike"),
+                    Row.of("o5", "u4", "Comics"),
+                    Row.of("o6", "u5", "Radio set"));
+
+    static List<Row> paymentsData =
+            Arrays.asList(
+                    Row.of("p1", 10, "u1"),
+                    Row.of("p2", 20, "u1"),
+                    Row.of("p3", 30, "u2"),
+                    Row.of("p4", 100, "u1"),
+                    Row.of("p5", 50, "u2"),
+                    Row.of("p6", 100, "u5"),
+                    Row.of("p7", 70, "u6"),
+                    Row.of("p8", 200, "u7"),
+                    Row.of("p9", 100, "u8"),
+                    Row.of("p10", 100, "u9"),
+                    Row.of("p11", 999, "u10"));
+
+    // Table data for consistency with JoinITCase
+    List<Row> simple3Data =
+            Arrays.asList(
+                    Row.of(1, 1L, "Hi"),
+                    Row.of(2, 2L, "Hello"),
+                    Row.of(3, 2L, "Hello world"),
+                    Row.of(5, 2L, "Hello world"));
+
+    List<Row> simple5Data =
+            Arrays.asList(
+                    Row.of(1, 1L, 0, "Hallo", 1L),
+                    Row.of(2, 2L, 1, "Hallo Welt", 2L),
+                    Row.of(2, 3L, 2, "Hallo Welt wie", 1L),
+                    Row.of(3, 4L, 3, "Hallo Welt wie gehts?", 2L),
+                    Row.of(3, 5L, 4, "ABC", 2L),
+                    Row.of(3, 6L, 5, "BCD", 3L));
+
+    @Before
+    @Override
+    public void before() {
+        super.before();
+
+        env = env();
+    }
+
+    @After

Review Comment:
   Nit: this just delegates to `super.after()` - safe to remove.



-- 
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: issues-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org