You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2026/10/23 23:46:36 UTC

(iotdb) 01/01: Distinguish tree and table unordered result test helpers

This is an automated email from the ASF dual-hosted git repository.

JackieTien97 pushed a commit to branch ty/unordered-result-test-helpers
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 944db97956ff466546701d15440cba0791432113
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Sat Oct 24 07:46:21 2026 +0800

    Distinguish tree and table unordered result test helpers
---
 integration-test/AGENTS.md                         |  8 +++-
 .../db/it/aggregation/IoTDBTimeDurationIT.java     |  4 +-
 .../org/apache/iotdb/db/it/utils/TestUtils.java    | 45 ++++++++++++++++++++--
 .../it/query/recent/IoTDBCollectFanInIT.java       | 28 +++++++++-----
 4 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/integration-test/AGENTS.md b/integration-test/AGENTS.md
index 9f3df1541e3..401dbf9b779 100644
--- a/integration-test/AGENTS.md
+++ b/integration-test/AGENTS.md
@@ -71,12 +71,16 @@ These instructions apply to `integration-test/` and supplement the repository-le
 ### Result ordering across DataNodes
 
 - When row order is not part of the query's contract and may differ across DataNodes, use
-  `TestUtils.resultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray)` for tree-model
-  SQL cases. When the test already owns a result set (including table-model queries), use
+  `TestUtils.treeResultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray)` for tree-model
+  SQL cases, or
+  `TestUtils.tableResultSetEqualTestUnordered(sql, expectedHeader, expectedRetArray, database)`
+  for table-model SQL cases (`database` may be `null` when no `USE` is needed).
+  When the test already owns a result set, use
   `TestUtils.assertResultSetEqualUnordered(resultSet, expectedHeader, expectedRows)` and close
   the original result set after the assertion. Reuse these helpers instead of writing per-node
   comparison loops in individual tests.
 - These helpers check every node independently, including headers, values, and duplicate counts.
+  They use `ClusterTestResultSet.getNodeResultSets` to read each DataNode's underlying result set.
   The default `ClusterTestResultSet` compares nodes at the same cursor position; collecting or
   sorting rows after reading through that wrapper cannot avoid row-order mismatches. Do not
   replace the helpers with set equality or single-node checks that weaken these assertions.
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
index ce2ea3eef36..4542c4f78a6 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/aggregation/IoTDBTimeDurationIT.java
@@ -34,7 +34,7 @@ import org.junit.runner.RunWith;
 import static org.apache.iotdb.db.it.utils.TestUtils.assertTestFail;
 import static org.apache.iotdb.db.it.utils.TestUtils.prepareData;
 import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest;
-import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTestUnordered;
+import static org.apache.iotdb.db.it.utils.TestUtils.treeResultSetEqualTestUnordered;
 
 @RunWith(IoTDBTestRunner.class)
 @Category({LocalStandaloneIT.class, ClusterIT.class})
@@ -346,7 +346,7 @@ public class IoTDBTimeDurationIT {
     // group by tags
     expectedHeader = new String[] {"city", "time_duration(s1)"};
     retArray = new String[] {"Beijing,1677570933,", "Nanjing,1677570938,"};
-    resultSetEqualTestUnordered(
+    treeResultSetEqualTestUnordered(
         "select time_duration(s1) from root.db1.**,root.db.** group by tags(city)",
         expectedHeader,
         retArray);
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
index a0d768ec771..5b9482c362b 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/utils/TestUtils.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.it.env.cluster.env.AbstractEnv;
 import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
 import org.apache.iotdb.itbase.env.BaseEnv;
 import org.apache.iotdb.itbase.runtime.ClusterTestConnection;
+import org.apache.iotdb.itbase.runtime.ClusterTestResultSet;
 import org.apache.iotdb.rpc.IoTDBConnectionException;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.StatementExecutionException;
@@ -283,10 +284,17 @@ public class TestUtils {
 
   /**
    * Executes a tree-model query and checks unordered rows on every read node, including duplicate
-   * multiplicity. Use only when the query's final result does not require a particular row order or
-   * select a nondeterministic subset of rows.
+   * multiplicity.
+   *
+   * <p>Delegates to {@link #assertResultSetEqualUnordered(ResultSet, String, List)}, which uses
+   * {@link ClusterTestResultSet#getNodeResultSets(ResultSet)} to obtain each DataNode's underlying
+   * result set. Iterating those results bypasses the cluster wrapper's default cross-node,
+   * row-by-row comparison.
+   *
+   * <p>Use only when the query's final result does not require a particular row order or select a
+   * nondeterministic subset of rows.
    */
-  public static void resultSetEqualTestUnordered(
+  public static void treeResultSetEqualTestUnordered(
       String sql, String[] expectedHeader, String[] expectedRetArray) {
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
@@ -301,6 +309,37 @@ public class TestUtils {
     }
   }
 
+  /**
+   * Executes a table-model query and checks unordered rows on every read node, including duplicate
+   * multiplicity. Selects {@code database} before the query when it is non-null.
+   *
+   * <p>Delegates to {@link #assertResultSetEqualUnordered(ResultSet, String, List)}, which uses
+   * {@link ClusterTestResultSet#getNodeResultSets(ResultSet)} to obtain each DataNode's underlying
+   * result set. Iterating those results bypasses the cluster wrapper's default cross-node,
+   * row-by-row comparison.
+   *
+   * <p>Use only when the query's final result does not require a particular row order or select a
+   * nondeterministic subset of rows.
+   */
+  public static void tableResultSetEqualTestUnordered(
+      String sql, String[] expectedHeader, String[] expectedRetArray, String database) {
+    try (Connection connection = EnvFactory.getEnv().getTableConnection()) {
+      connection.setClientInfo("time_zone", "+00:00");
+      try (Statement statement = connection.createStatement()) {
+        if (database != null) {
+          statement.execute("use " + database);
+        }
+        try (ResultSet resultSet = statement.executeQuery(sql)) {
+          assertResultSetEqualUnordered(
+              resultSet, String.join(",", expectedHeader) + ",", Arrays.asList(expectedRetArray));
+        }
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
   public static void tableResultSetEqualTest(
       String sql, String[] expectedHeader, String[] expectedRetArray, String database) {
     tableResultSetEqualTest(
diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
index 745ec969d18..4d38448cf4b 100644
--- a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBCollectFanInIT.java
@@ -41,6 +41,7 @@ import java.util.List;
 import java.util.Set;
 
 import static org.apache.iotdb.db.it.utils.TestUtils.assertResultSetEqualUnordered;
+import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTestUnordered;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -101,16 +102,23 @@ public class IoTDBCollectFanInIT {
         expectedRows.add(row);
       }
     }
-    try (Connection connection = EnvFactory.getEnv().getTableConnection();
-        Statement statement = connection.createStatement()) {
-      statement.execute("USE " + DATABASE);
-      String sql =
-          "SELECT device, zone, value FROM readings1 UNION ALL "
-              + "SELECT device, zone, value FROM readings1";
-      try (ResultSet result = statement.executeQuery(sql)) {
-        assertResultSetEqualUnordered(result, "device,zone,value,", expectedRows);
-      }
-    }
+    String[] expectedHeader = {"device", "zone", "value"};
+    String[] expectedRetArray = expectedRows.toArray(new String[0]);
+    tableResultSetEqualTestUnordered(
+        "SELECT device, zone, value FROM readings1 UNION ALL "
+            + "SELECT device, zone, value FROM readings1",
+        expectedHeader,
+        expectedRetArray,
+        DATABASE);
+    tableResultSetEqualTestUnordered(
+        "SELECT device, zone, value FROM "
+            + DATABASE
+            + ".readings1 UNION ALL SELECT device, zone, value FROM "
+            + DATABASE
+            + ".readings1",
+        expectedHeader,
+        expectedRetArray,
+        null);
   }
 
   @Test