add more IT (#17100)
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByIT.java index 490f8f5..2ae5c20 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByIT.java
@@ -18,10 +18,12 @@ */ package org.apache.iotdb.db.it.query; +import org.apache.iotdb.isession.SessionConfig; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.TableClusterIT; import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -29,8 +31,14 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; @RunWith(IoTDBTestRunner.class) @Category({TableLocalStandaloneIT.class, TableClusterIT.class}) @@ -104,10 +112,64 @@ } @Test + public void TestPriority() { + String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; + String[] retArray = {"1,1,1.0,1.0,true,1s,"}; + tableResultSetEqualTest( + "select " + + "first_by(s_int, y_criteria), " + + "first_by(s_long, y_criteria), " + + "first_by(s_float, y_criteria), " + + "first_by(s_double, y_criteria), " + + "first_by(s_bool, y_criteria), " + + "first_by(s_string, y_criteria) " + + "from table_a " + + "where table_a.device='d1'", + expectedHeader, + retArray, + DATABASE_NAME); + } + + @Test + public void testNoTimeStamp() { + + String sql = + "select " + + "first_by(s_int, y_criteria)" + + " from (" + + " select " + + " s_int," + + " s_long," + + " s_float," + + " y_criteria" + + " from table_a" + + ") AS t"; + try (Connection connection = + EnvFactory.getEnv() + .getConnection( + SessionConfig.DEFAULT_USER, + SessionConfig.DEFAULT_PASSWORD, + BaseEnv.TABLE_SQL_DIALECT)) { + connection.setClientInfo("time_zone", "+00:00"); + try (Statement statement = connection.createStatement()) { + statement.execute("use " + DATABASE_NAME); + statement.executeQuery(sql); + } + fail("Missing valid time column, the query should fail"); + } catch (SQLException e) { + assertEquals( + "701: Missing valid time column. The table must contain either a column with the TIME category or at least one TIMESTAMP column.", + e.getMessage()); + } + } + + @Test public void testFirstBy_d1_NoNulls() { String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"5,5,5.0,5.0,false,5s,"}; runTest("d1", expectedHeader, retArray); + runTest2("d1", expectedHeader, retArray); + runTest3("d1", expectedHeader, retArray); } @Test @@ -115,6 +177,8 @@ String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"10,10,10.0,10.0,true,10s,"}; runTest("d2", expectedHeader, retArray); + runTest2("d2", expectedHeader, retArray); + runTest3("d2", expectedHeader, retArray); } @Test @@ -122,6 +186,8 @@ String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"5,5,null,null,null,null,"}; runTest("d3", expectedHeader, retArray); + runTest2("d3", expectedHeader, retArray); + runTest3("d3", expectedHeader, retArray); } @Test @@ -130,6 +196,8 @@ // Expected: No valid s2 found. String[] retArray = {"null,null,null,null,null,null,"}; runTest("d4", expectedHeader, retArray); + runTest2("d4", expectedHeader, retArray); + runTest3("d4", expectedHeader, retArray); } @Test @@ -138,6 +206,8 @@ // Expected: The row with y_criteria=NULL is skipped. The row with y_criteria=50 is picked. String[] retArray = {"50,50,50.0,50.0,false,50s,"}; runTest("d5", expectedHeader, retArray); + runTest2("d5", expectedHeader, retArray); + runTest3("d5", expectedHeader, retArray); } private void runTest(String deviceId, String[] expectedHeader, String[] retArray) { @@ -159,4 +229,43 @@ retArray, DATABASE_NAME); } + + private void runTest2(String deviceId, String[] expectedHeader, String[] retArray) { + tableResultSetEqualTest( + "select " + + "first_by(s_int, y_criteria), " + + "first_by(s_long, y_criteria), " + + "first_by(s_float, y_criteria), " + + "first_by(s_double, y_criteria), " + + "first_by(s_bool, y_criteria), " + + "first_by(s_string, y_criteria) " + + "from " + + "(select s_int, s_long, s_float, s_double, s_bool, s_string, y_criteria, time_type " + + "from table_a left join table_b on table_a.time=table_b.time " + + "where table_a.device='" + + deviceId + + "') ", + expectedHeader, + retArray, + DATABASE_NAME); + } + + /** Test 3: Raw table query with explicit time_type column, 3 arguments */ + private void runTest3(String deviceId, String[] expectedHeader, String[] retArray) { + tableResultSetEqualTest( + "select " + + "first_by(s_int, y_criteria, time_type), " + + "first_by(s_long, y_criteria, time_type), " + + "first_by(s_float, y_criteria, time_type), " + + "first_by(s_double, y_criteria, time_type), " + + "first_by(s_bool, y_criteria, time_type), " + + "first_by(s_string, y_criteria, time_type) " + + "from table_a " + + "where table_a.device='" + + deviceId + + "'", + expectedHeader, + retArray, + DATABASE_NAME); + } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByInGroupIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByInGroupIT.java index 1045d76..f2f3496 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByInGroupIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstByInGroupIT.java
@@ -117,6 +117,7 @@ "p5,50,50,50.0,50.0,false,50s," }; + // 1. eliminate the identity of time column tableResultSetEqualTest( "select " + "partition, " @@ -135,5 +136,42 @@ expectedHeader, retArray, DATABASE_NAME); + + // 2. lack of the third argument, supply with timestamp column + tableResultSetEqualTest( + "select " + + "partition, " + + "first_by(s_int, y_criteria), " + + "first_by(s_long, y_criteria), " + + "first_by(s_float, y_criteria), " + + "first_by(s_double, y_criteria), " + + "first_by(s_bool, y_criteria), " + + "first_by(s_string, y_criteria) " + + "from " + // SubQuery: Rename time_type to 'ts' to avoid ambiguity with physical 'time' + + "(select s_int, s_long, s_float, s_double, s_bool, s_string, y_criteria, partition, time_type " + + "from table_a left join table_b on table_a.time=table_b.time) " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); + + // 3. base table query with column that with timestamp datatype + tableResultSetEqualTest( + "select " + + "partition, " + + "first_by(s_int, y_criteria, time_type), " + + "first_by(s_long, y_criteria, time_type), " + + "first_by(s_float, y_criteria, time_type), " + + "first_by(s_double, y_criteria, time_type), " + + "first_by(s_bool, y_criteria, time_type), " + + "first_by(s_string, y_criteria, time_type) " + + "from table_a " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstIT.java index 92fc151..1ce994a 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstIT.java
@@ -19,10 +19,12 @@ package org.apache.iotdb.db.it.query; +import org.apache.iotdb.isession.SessionConfig; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.TableClusterIT; import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -30,8 +32,14 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; @RunWith(IoTDBTestRunner.class) @Category({TableLocalStandaloneIT.class, TableClusterIT.class}) @@ -90,6 +98,59 @@ EnvFactory.getEnv().cleanClusterEnvironment(); } + // time column prior to field column with timestamp column + @Test + public void testPriority() { + + String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; + String[] retArray = {"-50,-50,-50.0,-50.0,false,-50s,"}; + tableResultSetEqualTest( + "select " + + "first(s_int), " + + "first(s_long), " + + "first(s_float), " + + "first(s_double), " + + "first(s_bool), " + + "first(s_string) " + + "from table_a " + + "where table_a.device='d1' ", + expectedHeader, + retArray, + DATABASE_NAME); + } + + @Test + public void testNoTimeStamp() { + + String sql = + "select " + + "first(s_int)" + + " from (" + + " select " + + " s_int," + + " s_long," + + " s_float" + + " from table_a" + + ") AS t"; + try (Connection connection = + EnvFactory.getEnv() + .getConnection( + SessionConfig.DEFAULT_USER, + SessionConfig.DEFAULT_PASSWORD, + BaseEnv.TABLE_SQL_DIALECT)) { + connection.setClientInfo("time_zone", "+00:00"); + try (Statement statement = connection.createStatement()) { + statement.execute("use " + DATABASE_NAME); + statement.executeQuery(sql); + } + fail("Missing valid time column, the query should fail"); + } catch (SQLException e) { + assertEquals( + "701: Missing valid time column. The table must contain either a column with the TIME category or at least one TIMESTAMP column.", + e.getMessage()); + } + } + @Test public void testAggregation() { @@ -102,6 +163,7 @@ // Corresponding values at time_type=5: s_int=5, s_long=5, ..., s_bool=false, s_string='5s' String[] retArray = {"5,5,5.0,5.0,false,5s,"}; + // 1. through join, eliminate the identity of time column tableResultSetEqualTest( "select " + "first(s_int, time), " @@ -121,6 +183,41 @@ expectedHeader, retArray, DATABASE_NAME); + + // 2. lack of the second the argument + tableResultSetEqualTest( + "select " + + "first(s_int), " + + "first(s_long), " + + "first(s_float), " + + "first(s_double), " + + "first(s_bool), " + + "first(s_string) " + + "from " + + "(select " + + " time_type, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d1') ", + expectedHeader, + retArray, + DATABASE_NAME); + + // 3. through field column that with timestamp datatype + tableResultSetEqualTest( + "select " + + "first(s_int, time_type), " + + "first(s_long, time_type), " + + "first(s_float, time_type), " + + "first(s_double, time_type), " + + "first(s_bool, time_type), " + + "first(s_string, time_type) " + + "from table_a " + + "where table_a.device='d1' ", + expectedHeader, + retArray, + DATABASE_NAME); } @Test @@ -154,6 +251,40 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "first(s_int), " + + "first(s_long), " + + "first(s_float), " + + "first(s_double), " + + "first(s_bool), " + + "first(s_string) " + + "from " + // subQuery: project all the column needed and rename the time_type to the time + + "(select " + + " time_type, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d2') ", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "first(s_int, time_type), " + + "first(s_long, time_type), " + + "first(s_float, time_type), " + + "first(s_double, time_type), " + + "first(s_bool, time_type), " + + "first(s_string, time_type) " + + "from table_a " + + "where table_a.device='d2'", + expectedHeader, + retArray, + DATABASE_NAME); } @Test @@ -181,5 +312,38 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "first(s_int), " + + "first(s_long), " + + "first(s_float), " + + "first(s_double), " + + "first(s_bool), " + + "first(s_string) " + + "from " + + "(select " + + " time_type, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d3') ", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "first(s_int, time_type), " + + "first(s_long, time_type), " + + "first(s_float, time_type), " + + "first(s_double, time_type), " + + "first(s_bool, time_type), " + + "first(s_string, time_type) " + + "from table_a " + + "where table_a.device='d3'", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstInGroupIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstInGroupIT.java index 48decb6..c6fa351 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstInGroupIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationFirstInGroupIT.java
@@ -130,5 +130,43 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "first(s_int), " + + "first(s_long), " + + "first(s_float), " + + "first(s_double), " + + "first(s_bool), " + + "first(s_string) " + + "from " + + "(select " + + " time_type, " + + " partition, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time) " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "first(s_int, time_type), " + + "first(s_long, time_type), " + + "first(s_float, time_type), " + + "first(s_double, time_type), " + + "first(s_bool, time_type), " + + "first(s_string, time_type) " + + "from table_a " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByIT.java index 42bef69..1f30cbf 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByIT.java
@@ -19,10 +19,12 @@ package org.apache.iotdb.db.it.query; +import org.apache.iotdb.isession.SessionConfig; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.TableClusterIT; import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -30,8 +32,14 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; @RunWith(IoTDBTestRunner.class) @Category({TableLocalStandaloneIT.class, TableClusterIT.class}) @@ -106,10 +114,64 @@ } @Test + public void TestPriority() { + String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; + String[] retArray = {"99,99,99.0,99.0,true,99s,"}; + tableResultSetEqualTest( + "select " + + "last_by(s_int, y_criteria), " + + "last_by(s_long, y_criteria), " + + "last_by(s_float, y_criteria), " + + "last_by(s_double, y_criteria), " + + "last_by(s_bool, y_criteria), " + + "last_by(s_string, y_criteria) " + + "from table_a " + + "where table_a.device='d1'", + expectedHeader, + retArray, + DATABASE_NAME); + } + + @Test + public void testNoTimeStamp() { + + String sql = + "select " + + "last_by(s_int, y_criteria)" + + " from (" + + " select " + + " s_int," + + " s_long," + + " s_float," + + " y_criteria" + + " from table_a" + + ") AS t"; + try (Connection connection = + EnvFactory.getEnv() + .getConnection( + SessionConfig.DEFAULT_USER, + SessionConfig.DEFAULT_PASSWORD, + BaseEnv.TABLE_SQL_DIALECT)) { + connection.setClientInfo("time_zone", "+00:00"); + try (Statement statement = connection.createStatement()) { + statement.execute("use " + DATABASE_NAME); + statement.executeQuery(sql); + } + fail("Missing valid time column, the query should fail"); + } catch (SQLException e) { + assertEquals( + "701: Missing valid time column. The table must contain either a column with the TIME category or at least one TIMESTAMP column.", + e.getMessage()); + } + } + + @Test public void testLastBy_d1_NoNulls() { String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"-5,-5,-5.0,-5.0,false,-5s,"}; runTest("d1", expectedHeader, retArray); + runTest2("d1", expectedHeader, retArray); + runTest3("d1", expectedHeader, retArray); } @Test @@ -117,6 +179,8 @@ String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"-10,-10,-10.0,-10.0,true,-10s,"}; runTest("d2", expectedHeader, retArray); + runTest2("d2", expectedHeader, retArray); + runTest3("d2", expectedHeader, retArray); } @Test @@ -124,6 +188,8 @@ String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; String[] retArray = {"-5,-5,null,null,null,null,"}; runTest("d3", expectedHeader, retArray); + runTest2("d3", expectedHeader, retArray); + runTest3("d3", expectedHeader, retArray); } @Test @@ -132,6 +198,8 @@ // Expected: No valid s2 found. String[] retArray = {"null,null,null,null,null,null,"}; runTest("d4", expectedHeader, retArray); + runTest2("d4", expectedHeader, retArray); + runTest3("d4", expectedHeader, retArray); } @Test @@ -140,6 +208,8 @@ // Expected: The row with y_criteria=NULL is skipped. The row with y_criteria=50 is picked. String[] retArray = {"50,50,50.0,50.0,false,50s,"}; runTest("d5", expectedHeader, retArray); + runTest2("d5", expectedHeader, retArray); + runTest3("d5", expectedHeader, retArray); } private void runTest(String deviceId, String[] expectedHeader, String[] retArray) { @@ -161,4 +231,42 @@ retArray, DATABASE_NAME); } + + private void runTest2(String deviceId, String[] expectedHeader, String[] retArray) { + tableResultSetEqualTest( + "select " + + "last_by(s_int, y_criteria), " + + "last_by(s_long, y_criteria), " + + "last_by(s_float, y_criteria), " + + "last_by(s_double, y_criteria), " + + "last_by(s_bool, y_criteria), " + + "last_by(s_string, y_criteria) " + + "from " + + "(select s_int, s_long, s_float, s_double, s_bool, s_string, y_criteria, time_type " + + "from table_a left join table_b on table_a.time=table_b.time " + + "where table_a.device='" + + deviceId + + "') ", + expectedHeader, + retArray, + DATABASE_NAME); + } + + private void runTest3(String deviceId, String[] expectedHeader, String[] retArray) { + tableResultSetEqualTest( + "select " + + "last_by(s_int, y_criteria, time_type), " + + "last_by(s_long, y_criteria, time_type), " + + "last_by(s_float, y_criteria, time_type), " + + "last_by(s_double, y_criteria, time_type), " + + "last_by(s_bool, y_criteria, time_type), " + + "last_by(s_string, y_criteria, time_type) " + + "from table_a " + + "where table_a.device='" + + deviceId + + "'", + expectedHeader, + retArray, + DATABASE_NAME); + } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByInGroupIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByInGroupIT.java index 5b59e08..570e165 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByInGroupIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastByInGroupIT.java
@@ -132,5 +132,39 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "last_by(s_int, y_criteria), " + + "last_by(s_long, y_criteria), " + + "last_by(s_float, y_criteria), " + + "last_by(s_double, y_criteria), " + + "last_by(s_bool, y_criteria), " + + "last_by(s_string, y_criteria) " + + "from " + + "(select time_type, s_int, s_long, s_float, s_double, s_bool, s_string, y_criteria, partition " + + "from table_a left join table_b on table_a.time=table_b.time) " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "last_by(s_int, y_criteria, time_type), " + + "last_by(s_long, y_criteria, time_type), " + + "last_by(s_float, y_criteria, time_type), " + + "last_by(s_double, y_criteria, time_type), " + + "last_by(s_bool, y_criteria, time_type), " + + "last_by(s_string, y_criteria, time_type) " + + "from table_a " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastIT.java index e9e8600..3e132ab 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastIT.java
@@ -19,10 +19,12 @@ package org.apache.iotdb.db.it.query; +import org.apache.iotdb.isession.SessionConfig; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.TableClusterIT; import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -30,8 +32,14 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; @RunWith(IoTDBTestRunner.class) @Category({TableLocalStandaloneIT.class, TableClusterIT.class}) @@ -88,6 +96,57 @@ } @Test + public void TestPriority() { + String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; + String[] retArray = {"50,50,50.0,50.0,false,50s,"}; + tableResultSetEqualTest( + "select " + + "last(s_int), " + + "last(s_long), " + + "last(s_float), " + + "last(s_double), " + + "last(s_bool), " + + "last(s_string) " + + "from table_a " + + "where table_a.device='d1' ", + expectedHeader, + retArray, + DATABASE_NAME); + } + + @Test + public void testNoTimeStamp() { + + String sql = + "select " + + "last(s_int)" + + " from (" + + " select " + + " s_int," + + " s_long," + + " s_float" + + " from table_a" + + ") AS t"; + try (Connection connection = + EnvFactory.getEnv() + .getConnection( + SessionConfig.DEFAULT_USER, + SessionConfig.DEFAULT_PASSWORD, + BaseEnv.TABLE_SQL_DIALECT)) { + connection.setClientInfo("time_zone", "+00:00"); + try (Statement statement = connection.createStatement()) { + statement.execute("use " + DATABASE_NAME); + statement.executeQuery(sql); + } + fail("Missing valid time column, the query should fail"); + } catch (SQLException e) { + assertEquals( + "701: Missing valid time column. The table must contain either a column with the TIME category or at least one TIMESTAMP column.", + e.getMessage()); + } + } + + @Test public void testAggregation() { String[] expectedHeader = {"_col0", "_col1", "_col2", "_col3", "_col4", "_col5"}; @@ -114,6 +173,38 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "last(s_int), " + + "last(s_long), " + + "last(s_float), " + + "last(s_double), " + + "last(s_bool), " + + "last(s_string) " + + "from " + + "(select " + + " s_int, s_long, s_float, s_double, s_bool, s_string, time_type " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d1') ", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "last(s_int, time_type), " + + "last(s_long, time_type), " + + "last(s_float, time_type), " + + "last(s_double, time_type), " + + "last(s_bool, time_type), " + + "last(s_string, time_type) " + + "from table_a " + + "where table_a.device='d1' ", + expectedHeader, + retArray, + DATABASE_NAME); } @Test @@ -143,6 +234,38 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "last(s_int), " + + "last(s_long), " + + "last(s_float), " + + "last(s_double), " + + "last(s_bool), " + + "last(s_string) " + + "from " + + "(select " + + " s_int, s_long, s_float, s_double, s_bool, s_string, time_type " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d2') ", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "last(s_int, time_type), " + + "last(s_long, time_type), " + + "last(s_float, time_type), " + + "last(s_double, time_type), " + + "last(s_bool, time_type), " + + "last(s_string, time_type) " + + "from table_a " + + "where table_a.device='d2'", + expectedHeader, + retArray, + DATABASE_NAME); } @Test @@ -172,5 +295,39 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "last(s_int), " + + "last(s_long), " + + "last(s_float), " + + "last(s_double), " + + "last(s_bool), " + + "last(s_string) " + + "from " + + "(select " + + " time_type, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time " + + "where table_a.device='d3') ", + expectedHeader, + retArray, + DATABASE_NAME); + + // 3. through field column + tableResultSetEqualTest( + "select " + + "last(s_int, time_type), " + + "last(s_long, time_type), " + + "last(s_float, time_type), " + + "last(s_double, time_type), " + + "last(s_bool, time_type), " + + "last(s_string, time_type) " + + "from table_a " + + "where table_a.device='d3'", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastInGroupIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastInGroupIT.java index 1f6b2c6..b065200 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastInGroupIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/query/IoTDBAggregationLastInGroupIT.java
@@ -124,5 +124,43 @@ expectedHeader, retArray, DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "last(s_int), " + + "last(s_long), " + + "last(s_float), " + + "last(s_double), " + + "last(s_bool), " + + "last(s_string) " + + "from " + + "(select " + + " time_type, " + + " partition, " + + " s_int, s_long, s_float, s_double, s_bool, s_string " + + "from table_a " + + "left join table_b on table_a.time=table_b.time) " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); + + tableResultSetEqualTest( + "select " + + "partition, " + + "last(s_int, time_type), " + + "last(s_long, time_type), " + + "last(s_float, time_type), " + + "last(s_double, time_type), " + + "last(s_bool, time_type), " + + "last(s_string, time_type) " + + "from table_a " + + "group by partition " + + "order by partition", + expectedHeader, + retArray, + DATABASE_NAME); } }
diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableWithDefinedTimeIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableWithDefinedTimeIT.java new file mode 100644 index 0000000..4055e8f --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableWithDefinedTimeIT.java
@@ -0,0 +1,228 @@ +/* + * 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.iotdb.relational.it.schema; + +import org.apache.iotdb.db.it.utils.TestUtils; +import org.apache.iotdb.it.env.EnvFactory; +import org.apache.iotdb.it.framework.IoTDBTestRunner; +import org.apache.iotdb.itbase.category.TableClusterIT; +import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Arrays; + +import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +@RunWith(IoTDBTestRunner.class) +@Category({TableLocalStandaloneIT.class, TableClusterIT.class}) +public class IoTDBTableWithDefinedTimeIT { + + private static final String TABLE_DATABASE = "user_defined_time"; + private static final String VIEW_DATABASE = "user_defined_time_for_view"; + private static final String[] SQLS = + new String[] {"CREATE DATABASE " + TABLE_DATABASE, "CREATE DATABASE " + VIEW_DATABASE}; + private final String header = "ColumnName,DataType,Category,"; + + @BeforeClass + public static void setUp() throws Exception { + EnvFactory.getEnv().initClusterEnvironment(); + prepareTableData(SQLS); + } + + @AfterClass + public static void tearDown() throws Exception { + EnvFactory.getEnv().cleanClusterEnvironment(); + } + + @Test + public void testCreateTable() { + try (final Connection connection = + EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT); + final Statement statement = connection.createStatement()) { + statement.execute("use " + TABLE_DATABASE); + + // create table and do not assign the time column name + try { + statement.execute( + "create table default_not_assign_time(device string tag, s1 int32 field)"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe default_not_assign_time"), + header, + Arrays.asList("time,TIMESTAMP,TIME,", "device,STRING,TAG,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("create table without time info fails, the specific message: " + e.getMessage()); + } + + // create table and assign the time column name + try { + statement.execute( + "create table time_in_first(date_time timestamp time, device string tag, s1 int32 field)"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe time_in_first"), + header, + Arrays.asList("date_time,TIMESTAMP,TIME,", "device,STRING,TAG,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("assign the name of time column fails, the specific message: " + e.getMessage()); + } + + // create table which of the time column not at the first column + try { + statement.execute( + "create table time_not_in_first(device string tag, date_time timestamp time, s1 int32 field)"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe time_not_in_first"), + header, + Arrays.asList("device,STRING,TAG,", "date_time,TIMESTAMP,TIME,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("assign the name of time column fails, the specific message: " + e.getMessage()); + } + + // create table with multi time-column + try { + statement.execute( + "create table with_multi_time(time_type timestamp time, device string tag, date_time timestamp time, s1 int32 field)"); + fail("Creating table is not be allowed to assign two time columns"); + } catch (SQLException e) { + assertEquals("701: A table cannot have more than one time column", e.getMessage()); + } + + // create table with time column that is not timestamp data type + try { + statement.execute( + "create table time_other_type(device string tag, date_time int64 time, s1 int32 field)"); + fail("The time column has to be assigned a timestamp data type when creating table"); + } catch (SQLException e) { + assertEquals("701: The time column's type shall be 'timestamp'.", e.getMessage()); + } + + // Columns in table shall not share the same name time when creating table + try { + statement.execute( + "create table shared_time_name(device string tag, time int64 field, s1 int32 field)"); + fail("Columns in table shall not share the same name time when creating table"); + } catch (SQLException e) { + assertEquals("701: Columns in table shall not share the same name time.", e.getMessage()); + } + + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + private void prepareTreeData() { + try (final Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TREE_SQL_DIALECT); + final Statement statement = connection.createStatement()) { + statement.execute("create timeseries root.tt.device.s1 with datatype=int32"); + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void testCreateView() { + prepareTreeData(); + + try (final Connection connection = + EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT); + final Statement statement = connection.createStatement()) { + statement.execute("use " + VIEW_DATABASE); + + // create view and do not assign the time column name + try { + statement.execute( + "create view default_not_assign_time(device string tag, s1 int32 field) as root.tt.**"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe default_not_assign_time"), + header, + Arrays.asList("time,TIMESTAMP,TIME,", "device,STRING,TAG,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("create table without time info fails, the specific message: " + e.getMessage()); + } + + // create view which of the time column at the first column + try { + statement.execute( + "create view time_in_first(date_time timestamp time, device string tag, s1 int32 field) as root.tt.**"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe time_in_first"), + header, + Arrays.asList("date_time,TIMESTAMP,TIME,", "device,STRING,TAG,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("assign the name of time column fails, the specific message: " + e.getMessage()); + } + + // create view which of the time column not at the first column + try { + statement.execute( + "create view time_not_in_first(device string tag, date_time timestamp time, s1 int32 field) as root.tt.**"); + TestUtils.assertResultSetEqual( + statement.executeQuery("describe time_not_in_first"), + header, + Arrays.asList("device,STRING,TAG,", "date_time,TIMESTAMP,TIME,", "s1,INT32,FIELD,")); + } catch (SQLException e) { + fail("assign the name of time column fails, the specific message: " + e.getMessage()); + } + + // create view with multi time-column + try { + statement.execute( + "create view with_multi_time(time_type timestamp time, device string tag, date_time timestamp time, s1 int32 field) as root.tt.**"); + fail("Creating view is not be allowed to assign two time columns"); + } catch (SQLException e) { + assertEquals("701: A table cannot have more than one time column", e.getMessage()); + } + + // create table with time column that is not timestamp data type + try { + statement.execute( + "create view time_other_type(device string tag, date_time int64 time, s1 int32 field) as root.tt.**"); + fail("The time column has to be assigned a timestamp data type when creating view"); + } catch (SQLException e) { + assertEquals("701: The time column's type shall be 'timestamp'.", e.getMessage()); + } + + // Columns in table shall not share the same name time when creating table + try { + statement.execute( + "create view shared_time_time(device string tag, time int64 field, s1 int32 field) as root.tt.**"); + fail("Columns in view shall not share the same name time when creating table"); + } catch (SQLException e) { + assertEquals("701: Columns in table shall not share the same name time.", e.getMessage()); + } + + } catch (SQLException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } +}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java index 90dcb82..81106f8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java
@@ -151,19 +151,13 @@ isAggTableScan); } else if (FIRST.getFunctionName().equals(functionName)) { boolean orderKeyIsTimeColumn = isTimeColumn(inputExpressions.get(1), timeColumnName); + result = ascending && orderKeyIsTimeColumn ? new FirstAccumulator(inputDataTypes.get(0), isAggTableScan) : new FirstDescAccumulator(inputDataTypes.get(0)); } else { - result = - createBuiltinAccumulator( - aggregationType, - inputDataTypes, - inputExpressions, - inputAttributes, - ascending, - isAggTableScan); + result = createBuiltinAccumulator(aggregationType, inputDataTypes); } if (distinct) { @@ -301,12 +295,7 @@ } public static TableAccumulator createBuiltinAccumulator( - TAggregationType aggregationType, - List<TSDataType> inputDataTypes, - List<Expression> inputExpressions, - Map<String, String> inputAttributes, - boolean ascending, - boolean isAggTableScan) { + TAggregationType aggregationType, List<TSDataType> inputDataTypes) { switch (aggregationType) { case COUNT: return new CountAccumulator();
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java index e4d549c..1bc7882 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -3463,13 +3463,7 @@ .collect(Collectors.toList()); TableAccumulator accumulator = - createBuiltinAccumulator( - getAggregationTypeByFuncName(functionName), - originalArgumentTypes, - arguments.stream().map(Map.Entry::getKey).collect(Collectors.toList()), - Collections.emptyMap(), - true, - false); + createBuiltinAccumulator(getAggregationTypeByFuncName(functionName), originalArgumentTypes); BoundSignature signature = resolvedFunction.getSignature(); @@ -4219,13 +4213,7 @@ .map(InternalTypeManager::getTSDataType) .collect(Collectors.toList()); TableAccumulator accumulator = - createBuiltinAccumulator( - getAggregationTypeByFuncName(functionName), - originalArgumentTypes, - function.getArguments(), - Collections.emptyMap(), - true, - false); + createBuiltinAccumulator(getAggregationTypeByFuncName(functionName), originalArgumentTypes); // Create aggregator by accumulator return new WindowAggregator(
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/process/window/function/FunctionTestUtils.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/process/window/function/FunctionTestUtils.java index 47f9063..bad56bb 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/process/window/function/FunctionTestUtils.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/process/window/function/FunctionTestUtils.java
@@ -32,7 +32,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; public class FunctionTestUtils { @@ -101,12 +100,7 @@ // inputExpressions and inputAttributes are not used in this method TableAccumulator accumulator = AccumulatorFactory.createBuiltinAccumulator( - aggregationType, - Collections.singletonList(inputDataType), - new ArrayList<>(), - new HashMap<>(), - ascending, - false); + aggregationType, Collections.singletonList(inputDataType)); WindowAggregator aggregator = new WindowAggregator(accumulator, outputDataType, Collections.singletonList(0)); return new AggregationWindowFunction(aggregator);
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/AggregationTableScanTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/AggregationTableScanTest.java index c03e5e9..698af13 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/AggregationTableScanTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/AggregationTableScanTest.java
@@ -19,11 +19,6 @@ package org.apache.iotdb.db.queryengine.plan.planner.distribution; -import static org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext.createFragmentInstanceContext; - -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.concurrent.ExecutorService; import org.apache.iotdb.common.rpc.thrift.TEndPoint; import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.db.protocol.session.IClientSession; @@ -47,9 +42,15 @@ import org.apache.iotdb.db.queryengine.plan.statement.Statement; import org.apache.iotdb.db.storageengine.dataregion.DataRegion; import org.apache.iotdb.db.storageengine.dataregion.IDataRegionForQuery; + import org.junit.Test; import org.mockito.Mockito; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.concurrent.ExecutorService; + +import static org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext.createFragmentInstanceContext; public class AggregationTableScanTest { @Test
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtil.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtil.java index eaa1b6a..1536dce 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtil.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtil.java
@@ -90,6 +90,14 @@ final String columnName = ReadWriteIOUtils.readString(tsTableBuffer); final TSDataType dataType = ReadWriteIOUtils.readDataType(tsTableBuffer); + // if the time column position in first column and named as "time", skip it + if (i == 0 + && category == TsTableColumnCategory.TIME + && columnName.equalsIgnoreCase(TIME_COLUMN_NAME)) { + skipMap(tsTableBuffer); + continue; + } + if (category == TsTableColumnCategory.FIELD) { ReadWriteIOUtils.readEncoding(tsTableBuffer); ReadWriteIOUtils.readCompressionType(tsTableBuffer);
diff --git a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtilTest.java b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtilTest.java index 4966b43..f39eca4 100644 --- a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtilTest.java +++ b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/table/TsFileTableSchemaUtilTest.java
@@ -325,9 +325,6 @@ final TsFileTableSchemaUtil.ColumnCategoryFilter filter = TsFileTableSchemaUtil.ColumnCategoryFilter.NO_ATTRIBUTE; - // TIME should be filtered out - Assert.assertFalse("TIME should be filtered out", filter.test(TsTableColumnCategory.TIME)); - // ATTRIBUTE should be filtered out Assert.assertFalse( "ATTRIBUTE should be filtered out", filter.test(TsTableColumnCategory.ATTRIBUTE)); @@ -340,8 +337,7 @@ // Test all enum values for (TsTableColumnCategory category : TsTableColumnCategory.values()) { - final boolean shouldInclude = - category != TsTableColumnCategory.TIME && category != TsTableColumnCategory.ATTRIBUTE; + final boolean shouldInclude = category != TsTableColumnCategory.ATTRIBUTE; Assert.assertEquals( "Category " + category + " filter result mismatch", shouldInclude, filter.test(category)); } @@ -641,11 +637,10 @@ public void testToTsFileTableSchemaNoAttributeWithMixedOrder() { // Test with columns in mixed order (TIME, TAG, ATTRIBUTE, FIELD, etc.) final TsTable table = new TsTable("mixedOrderTable"); - table.addColumnSchema(new TimeColumnSchema("time", TSDataType.INT64)); table.addColumnSchema(new TagColumnSchema("tag1", TSDataType.STRING)); table.addColumnSchema(new AttributeColumnSchema("attr1", TSDataType.STRING)); table.addColumnSchema(new FieldColumnSchema("field1", TSDataType.DOUBLE)); - table.addColumnSchema(new TimeColumnSchema("time2", TSDataType.INT64)); + table.addColumnSchema(new TimeColumnSchema("time2", TSDataType.TIMESTAMP)); table.addColumnSchema(new TagColumnSchema("tag2", TSDataType.STRING)); table.addColumnSchema(new AttributeColumnSchema("attr2", TSDataType.STRING)); table.addColumnSchema(new FieldColumnSchema("field2", TSDataType.INT32)); @@ -653,7 +648,7 @@ final TableSchema result = TsFileTableSchemaUtil.toTsFileTableSchemaNoAttribute(table); // Should have 2 TAG + 2 FIELD = 4 columns - Assert.assertEquals("Should have 4 columns", 4, result.getColumnSchemas().size()); + Assert.assertEquals("Should have 5 columns", 5, result.getColumnSchemas().size()); // Verify order: tag1, tag2, field1, field2 (original order preserved) final List<String> columnNames = @@ -662,8 +657,9 @@ .collect(Collectors.toList()); Assert.assertEquals("tag1", columnNames.get(0)); Assert.assertEquals("field1", columnNames.get(1)); - Assert.assertEquals("tag2", columnNames.get(2)); - Assert.assertEquals("field2", columnNames.get(3)); + Assert.assertEquals("time2", columnNames.get(2)); + Assert.assertEquals("tag2", columnNames.get(3)); + Assert.assertEquals("field2", columnNames.get(4)); } @Test