This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 380b0b4e0e4 FreeMarker code generation for mathematical functions and
operators
380b0b4e0e4 is described below
commit 380b0b4e0e4b44a9087824e04cc7146b5e55851f
Author: FearfulTomcat27 <[email protected]>
AuthorDate: Wed Sep 4 17:53:56 2024 +0800
FreeMarker code generation for mathematical functions and operators
---
.../db/it/IoTDBMultiIDsWithAttributesTableIT.java | 12 +-
.../it/query/old/IoTDBNestedQueryTableIT.java | 48 +--
.../alignbydevice/IoTDBAlignByDeviceTableIT.java | 16 +-
.../old/aligned/IoTDBPredicatePushDownTableIT.java | 402 ++++++++++++---------
.../it/query/old/orderBy/IoTDBOrderByTableIT.java | 6 +-
.../it/query/old/query/IoTDBArithmeticTableIT.java | 330 +++++++++++------
.../java/org/apache/iotdb/rpc/TSStatusCode.java | 4 +
iotdb-core/datanode/src/main/codegen/config.fmpp | 4 +-
.../MathematicalDataType.tdd} | 40 +-
.../MathematicalOperator.tdd} | 42 ++-
.../ArithmeticBinaryColumnTransformer.ftl | 301 +++++++++++++++
.../templates/ArithmeticColumnTransformerApi.ftl | 218 +++++++++++
.../templates/ArithmeticUnaryColumnTransformer.ftl | 67 ++++
.../relational/ColumnTransformerBuilder.java | 59 ++-
.../multi/builtin/helper/CastFunctionHelper.java | 6 +-
.../function/arithmetic/AdditionResolver.java | 78 ++++
.../function/arithmetic/DivisionResolver.java | 66 ++++
.../function/arithmetic/ModulusResolver.java | 66 ++++
.../arithmetic/MultiplicationResolver.java | 66 ++++
.../function/arithmetic/SubtractionResolver.java | 74 ++++
.../relational/metadata/TableMetadataImpl.java | 65 +++-
.../scalar/CastFunctionColumnTransformer.java | 2 +-
.../apache/iotdb/db/utils/ErrorHandlingUtils.java | 3 +
pom.xml | 2 +-
24 files changed, 1621 insertions(+), 356 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
index 4457055bd3e..bdbe468bb1b 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
@@ -395,12 +395,12 @@ public class IoTDBMultiIDsWithAttributesTableIT {
String[] expectedHeader = new String[] {"time", "level", "device",
"add_num"};
String[] retArray =
new String[] {
- "1970-01-01T00:00:00.100Z,l5,d1,9.0,",
- "1971-01-01T00:00:01.000Z,l4,d1,6.0,",
- "1971-01-01T00:00:10.000Z,l5,d1,8.0,",
- "1971-04-26T18:01:40.000Z,l4,d1,14.0,",
- "1971-08-20T11:33:20.000Z,l5,d1,16.0,",
- "1970-01-01T00:00:00.080Z,l4,d2,10.0,",
+ "1970-01-01T00:00:00.100Z,l5,d1,9,",
+ "1971-01-01T00:00:01.000Z,l4,d1,6,",
+ "1971-01-01T00:00:10.000Z,l5,d1,8,",
+ "1971-04-26T18:01:40.000Z,l4,d1,14,",
+ "1971-08-20T11:33:20.000Z,l5,d1,16,",
+ "1970-01-01T00:00:00.080Z,l4,d2,10,",
};
expectedHeader = new String[] {"time", "level", "device", "add_num"};
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryTableIT.java
index 48077696c5b..48fbd7096ae 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/IoTDBNestedQueryTableIT.java
@@ -151,7 +151,7 @@ public class IoTDBNestedQueryTableIT {
for (int i = 1; i <= ITERATION_TIMES; i++) {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
- Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(2), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -161,7 +161,7 @@ public class IoTDBNestedQueryTableIT {
for (int i = 1; i <= ITERATION_TIMES; i++) {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
- Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(2), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -182,8 +182,8 @@ public class IoTDBNestedQueryTableIT {
for (int i = 1; i <= ITERATION_TIMES; i++) {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
- Assert.assertEquals(i + 1.0D, rs.getDouble(2), 0.01);
- Assert.assertEquals(i + 1.0D, rs.getDouble(3), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(2), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(3), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -206,10 +206,10 @@ public class IoTDBNestedQueryTableIT {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
Assert.assertEquals(i, rs.getInt(2));
- Assert.assertEquals(i + 1.0D, rs.getDouble(3), 0.01);
- Assert.assertEquals(i + 1.0D, rs.getDouble(4), 0.01);
- Assert.assertEquals(i * 2.0D, rs.getDouble(5), 0.01);
- Assert.assertEquals(i * 2.0D, rs.getDouble(6), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(3), 0.01);
+ Assert.assertEquals(i + 1, rs.getInt(4), 0.01);
+ Assert.assertEquals(i * 2, rs.getInt(5), 0.01);
+ Assert.assertEquals(i * 2, rs.getInt(6), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -232,12 +232,12 @@ public class IoTDBNestedQueryTableIT {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
Assert.assertEquals(i, rs.getInt(2));
- Assert.assertEquals(i + 3.0D, rs.getDouble(3), 0.01);
- Assert.assertEquals(i + 3.0D, rs.getDouble(4), 0.01);
- Assert.assertEquals(i + 3.0D, rs.getDouble(5), 0.01);
- Assert.assertEquals(i * 6.0D, rs.getDouble(6), 0.01);
- Assert.assertEquals(i * 6.0D, rs.getDouble(7), 0.01);
- Assert.assertEquals(i * 6.0D, rs.getDouble(8), 0.01);
+ Assert.assertEquals(i + 3, rs.getInt(3), 0.01);
+ Assert.assertEquals(i + 3, rs.getInt(4), 0.01);
+ Assert.assertEquals(i + 3, rs.getInt(5), 0.01);
+ Assert.assertEquals(i * 6, rs.getInt(6), 0.01);
+ Assert.assertEquals(i * 6, rs.getInt(7), 0.01);
+ Assert.assertEquals(i * 6, rs.getInt(8), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -260,10 +260,10 @@ public class IoTDBNestedQueryTableIT {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
Assert.assertEquals(i, rs.getInt(2));
- Assert.assertEquals(2 * i + 2.0D, rs.getDouble(3), 0.01);
- Assert.assertEquals(2 * i + 2.0D, rs.getDouble(4), 0.01);
- Assert.assertEquals(i / 2.0D + 0.5D, rs.getDouble(5), 0.01);
- Assert.assertEquals(i / 2.0D + 0.5D, rs.getDouble(6), 0.01);
+ Assert.assertEquals(2 * i + 2, rs.getInt(3), 0.01);
+ Assert.assertEquals(2 * i + 2, rs.getInt(4), 0.01);
+ Assert.assertEquals((i + 1) / 2, rs.getInt(5), 0.01);
+ Assert.assertEquals(i / 2 + 1 / 2, rs.getInt(6), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -289,9 +289,9 @@ public class IoTDBNestedQueryTableIT {
for (int i = 1; i <= ITERATION_TIMES; i++) {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
- Assert.assertEquals(2 * i + 2.0D, rs.getDouble(2), 0.01);
- Assert.assertEquals(2 * i + 3.0D, rs.getDouble(3), 0.01);
- Assert.assertEquals(3 * i + 3.0D, rs.getDouble(4), 0.01);
+ Assert.assertEquals(2 * i + 2, rs.getInt(2), 0.01);
+ Assert.assertEquals(2 * i + 3, rs.getInt(3), 0.01);
+ Assert.assertEquals(3 * i + 3, rs.getInt(4), 0.01);
}
Assert.assertFalse(rs.next());
}
@@ -302,9 +302,9 @@ public class IoTDBNestedQueryTableIT {
for (int i = 1; i <= ITERATION_TIMES; i++) {
Assert.assertTrue(rs.next());
Assert.assertEquals(i, rs.getLong(1));
- Assert.assertEquals(2.0D - i / 2.0D, rs.getDouble(2), 0.01);
- Assert.assertEquals(1.5 - i / 2.0D, rs.getDouble(3), 0.01);
- Assert.assertEquals((1.0D / 3.0D) * (1.0D - i), rs.getDouble(4),
0.01);
+ Assert.assertEquals(2 - i / 2, rs.getInt(2), 0.01);
+ Assert.assertEquals((1 - i) / 2 + 1, rs.getInt(3), 0.01);
+ Assert.assertEquals((1 - i) / (2 + 1), rs.getInt(4), 0.01);
}
Assert.assertFalse(rs.next());
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/alignbydevice/IoTDBAlignByDeviceTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/alignbydevice/IoTDBAlignByDeviceTableIT.java
index 3d52c616d72..0ba23f288f5 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/alignbydevice/IoTDBAlignByDeviceTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/alignbydevice/IoTDBAlignByDeviceTableIT.java
@@ -314,14 +314,14 @@ public class IoTDBAlignByDeviceTableIT {
String[] expectedHeader = new String[] {"Time", "device_id", "_col2",
"_col3", "alias"};
String[] retArray =
new String[] {
- "1970-01-01T00:00:00.001Z,d0,1102.0,1102.0,1102.0,",
- "1970-01-01T00:00:00.002Z,d0,40001.0,40001.0,40001.0,",
- "1970-01-01T00:00:00.050Z,d0,50001.0,50001.0,50001.0,",
- "1970-01-01T00:00:00.100Z,d0,200.0,200.0,200.0,",
- "1970-01-01T00:00:00.101Z,d0,200.0,200.0,200.0,",
- "1970-01-01T00:00:00.103Z,d0,200.0,200.0,200.0,",
- "1970-01-01T00:00:00.105Z,d0,200.0,200.0,200.0,",
- "1970-01-01T00:00:01.000Z,d0,55556.0,55556.0,55556.0,",
+ "1970-01-01T00:00:00.001Z,d0,1102,1102,1102,",
+ "1970-01-01T00:00:00.002Z,d0,40001,40001,40001,",
+ "1970-01-01T00:00:00.050Z,d0,50001,50001,50001,",
+ "1970-01-01T00:00:00.100Z,d0,200,200,200,",
+ "1970-01-01T00:00:00.101Z,d0,200,200,200,",
+ "1970-01-01T00:00:00.103Z,d0,200,200,200,",
+ "1970-01-01T00:00:00.105Z,d0,200,200,200,",
+ "1970-01-01T00:00:01.000Z,d0,55556,55556,55556,",
};
tableResultSetEqualTest(
"select Time, device_id, s1+1, s1+1, s1+1 as alias from vehicle where
(((\"time\" > 10) AND (\"s1\" > 190)) OR (\"s2\" > 190.0) OR ((\"time\" < 4)
AND (\"s1\" > 100))) order by device_id, time",
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/aligned/IoTDBPredicatePushDownTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/aligned/IoTDBPredicatePushDownTableIT.java
index 33baa557d43..438f82d6952 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/aligned/IoTDBPredicatePushDownTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/aligned/IoTDBPredicatePushDownTableIT.java
@@ -31,7 +31,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
-import static
org.apache.iotdb.relational.it.query.old.aligned.TableUtils.tableResultSetEqualTest;
+import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest;
@RunWith(IoTDBTestRunner.class)
@Category({TableLocalStandaloneIT.class, TableClusterIT.class})
@@ -62,16 +62,16 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader1 = new String[] {"Time", "s2", "s3"};
String[] retArray1 =
new String[] {
- "10,10,10,",
- "11,11,11,",
- "12,12,12,",
- "14,14,14,",
- "15,15,15,",
- "16,16,16,",
- "17,17,17,",
- "18,18,18,",
- "19,19,19,",
- "20,20,20,"
+ "1970-01-01T00:00:00.010Z,10,10,",
+ "1970-01-01T00:00:00.011Z,11,11,",
+ "1970-01-01T00:00:00.012Z,12,12,",
+ "1970-01-01T00:00:00.014Z,14,14,",
+ "1970-01-01T00:00:00.015Z,15,15,",
+ "1970-01-01T00:00:00.016Z,16,16,",
+ "1970-01-01T00:00:00.017Z,17,17,",
+ "1970-01-01T00:00:00.018Z,18,18,",
+ "1970-01-01T00:00:00.019Z,19,19,",
+ "1970-01-01T00:00:00.020Z,20,20,"
};
tableResultSetEqualTest(
"select Time,s2, s3 from table0 where device='d1' and s2 - 1 >= 9 and
s2 < 30",
@@ -82,8 +82,16 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader2 = new String[] {"Time", "s3"};
String[] retArray2 =
new String[] {
- "10,10,", "11,11,", "12,12,", "14,14,", "15,15,", "16,16,",
"17,17,", "18,18,", "19,19,",
- "20,20,"
+ "1970-01-01T00:00:00.010Z,10,",
+ "1970-01-01T00:00:00.011Z,11,",
+ "1970-01-01T00:00:00.012Z,12,",
+ "1970-01-01T00:00:00.014Z,14,",
+ "1970-01-01T00:00:00.015Z,15,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,"
};
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d1' and s2 - 1 >= 9 and s2 <
30",
@@ -94,8 +102,16 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader3 = new String[] {"Time", "s2"};
String[] retArray3 =
new String[] {
- "10,10,", "11,11,", "12,12,", "14,14,", "15,15,", "16,16,",
"17,17,", "18,18,", "19,19,",
- "20,20,"
+ "1970-01-01T00:00:00.010Z,10,",
+ "1970-01-01T00:00:00.011Z,11,",
+ "1970-01-01T00:00:00.012Z,12,",
+ "1970-01-01T00:00:00.014Z,14,",
+ "1970-01-01T00:00:00.015Z,15,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,"
};
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d1' and s2 - 1 >= 9 and s2 <
30",
@@ -104,7 +120,8 @@ public class IoTDBPredicatePushDownTableIT {
database);
String[] expectedHeader4 = new String[] {"Time", "s2"};
- String[] retArray4 = new String[] {"14,14,", "15,15,"};
+ String[] retArray4 =
+ new String[] {"1970-01-01T00:00:00.014Z,14,",
"1970-01-01T00:00:00.015Z,15,"};
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d1' and s2 - 1 >= 9 and s2 <
30 offset 3 limit 2",
expectedHeader4,
@@ -118,23 +135,23 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader1 = new String[] {"Time", "s2", "_col2"};
String[] retArray1 =
new String[] {
- "3,null,30001.0,",
- "13,130000,130001.0,",
- "16,16,17.0,",
- "17,17,18.0,",
- "18,18,19.0,",
- "19,19,20.0,",
- "20,20,21.0,",
- "21,null,22.0,",
- "22,null,23.0,",
- "23,null,230001.0,",
- "24,null,25.0,",
- "25,null,26.0,",
- "26,null,27.0,",
- "27,null,28.0,",
- "28,null,29.0,",
- "29,null,30.0,",
- "30,null,31.0,",
+ "1970-01-01T00:00:00.003Z,null,30001,",
+ "1970-01-01T00:00:00.013Z,130000,130001,",
+ "1970-01-01T00:00:00.016Z,16,17,",
+ "1970-01-01T00:00:00.017Z,17,18,",
+ "1970-01-01T00:00:00.018Z,18,19,",
+ "1970-01-01T00:00:00.019Z,19,20,",
+ "1970-01-01T00:00:00.020Z,20,21,",
+ "1970-01-01T00:00:00.021Z,null,22,",
+ "1970-01-01T00:00:00.022Z,null,23,",
+ "1970-01-01T00:00:00.023Z,null,230001,",
+ "1970-01-01T00:00:00.024Z,null,25,",
+ "1970-01-01T00:00:00.025Z,null,26,",
+ "1970-01-01T00:00:00.026Z,null,27,",
+ "1970-01-01T00:00:00.027Z,null,28,",
+ "1970-01-01T00:00:00.028Z,null,29,",
+ "1970-01-01T00:00:00.029Z,null,30,",
+ "1970-01-01T00:00:00.030Z,null,31,",
};
tableResultSetEqualTest(
"select Time,s2, s3 + 1 from table0 where device='d1' and s3 + 1 > 16",
@@ -145,23 +162,23 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader2 = new String[] {"Time", "s2"};
String[] retArray2 =
new String[] {
- "3,null,",
- "13,130000,",
- "16,16,",
- "17,17,",
- "18,18,",
- "19,19,",
- "20,20,",
- "21,null,",
- "22,null,",
- "23,null,",
- "24,null,",
- "25,null,",
- "26,null,",
- "27,null,",
- "28,null,",
- "29,null,",
- "30,null,",
+ "1970-01-01T00:00:00.003Z,null,",
+ "1970-01-01T00:00:00.013Z,130000,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,",
+ "1970-01-01T00:00:00.021Z,null,",
+ "1970-01-01T00:00:00.022Z,null,",
+ "1970-01-01T00:00:00.023Z,null,",
+ "1970-01-01T00:00:00.024Z,null,",
+ "1970-01-01T00:00:00.025Z,null,",
+ "1970-01-01T00:00:00.026Z,null,",
+ "1970-01-01T00:00:00.027Z,null,",
+ "1970-01-01T00:00:00.028Z,null,",
+ "1970-01-01T00:00:00.029Z,null,",
+ "1970-01-01T00:00:00.030Z,null,",
};
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d1' and s3 + 1 > 16",
@@ -172,23 +189,23 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader3 = new String[] {"Time", "s3"};
String[] retArray3 =
new String[] {
- "3,30000,",
- "13,130000,",
- "16,16,",
- "17,17,",
- "18,18,",
- "19,19,",
- "20,20,",
- "21,21,",
- "22,22,",
- "23,230000,",
- "24,24,",
- "25,25,",
- "26,26,",
- "27,27,",
- "28,28,",
- "29,29,",
- "30,30,",
+ "1970-01-01T00:00:00.003Z,30000,",
+ "1970-01-01T00:00:00.013Z,130000,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,",
+ "1970-01-01T00:00:00.021Z,21,",
+ "1970-01-01T00:00:00.022Z,22,",
+ "1970-01-01T00:00:00.023Z,230000,",
+ "1970-01-01T00:00:00.024Z,24,",
+ "1970-01-01T00:00:00.025Z,25,",
+ "1970-01-01T00:00:00.026Z,26,",
+ "1970-01-01T00:00:00.027Z,27,",
+ "1970-01-01T00:00:00.028Z,28,",
+ "1970-01-01T00:00:00.029Z,29,",
+ "1970-01-01T00:00:00.030Z,30,",
};
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d1' and s3 + 1 > 16",
@@ -197,7 +214,12 @@ public class IoTDBPredicatePushDownTableIT {
database);
String[] expectedHeader4 = new String[] {"Time", "s3"};
- String[] retArray4 = new String[] {"3,30000,", "13,130000,", "16,16,"};
+ String[] retArray4 =
+ new String[] {
+ "1970-01-01T00:00:00.003Z,30000,",
+ "1970-01-01T00:00:00.013Z,130000,",
+ "1970-01-01T00:00:00.016Z,16,"
+ };
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d1' and s3 + 1 > 16 limit 3",
expectedHeader4,
@@ -210,17 +232,17 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader1 = new String[] {"Time", "s2", "s3"};
String[] retArray1 =
new String[] {
- "10,10,10,",
- "11,11,11,",
- "12,12,12,",
- "13,13,13,",
- "14,14,14,",
- "15,15,15,",
- "16,16,16,",
- "17,17,17,",
- "18,18,18,",
- "19,19,19,",
- "20,20,20,"
+ "1970-01-01T00:00:00.010Z,10,10,",
+ "1970-01-01T00:00:00.011Z,11,11,",
+ "1970-01-01T00:00:00.012Z,12,12,",
+ "1970-01-01T00:00:00.013Z,13,13,",
+ "1970-01-01T00:00:00.014Z,14,14,",
+ "1970-01-01T00:00:00.015Z,15,15,",
+ "1970-01-01T00:00:00.016Z,16,16,",
+ "1970-01-01T00:00:00.017Z,17,17,",
+ "1970-01-01T00:00:00.018Z,18,18,",
+ "1970-01-01T00:00:00.019Z,19,19,",
+ "1970-01-01T00:00:00.020Z,20,20,"
};
tableResultSetEqualTest(
"select Time,s2, s3 from table0 where device='d2' and s2 - 1 >= 9 and
s2 < 30",
@@ -231,8 +253,17 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader2 = new String[] {"Time", "s3"};
String[] retArray2 =
new String[] {
- "10,10,", "11,11,", "12,12,", "13,13,", "14,14,", "15,15,",
"16,16,", "17,17,", "18,18,",
- "19,19,", "20,20,"
+ "1970-01-01T00:00:00.010Z,10,",
+ "1970-01-01T00:00:00.011Z,11,",
+ "1970-01-01T00:00:00.012Z,12,",
+ "1970-01-01T00:00:00.013Z,13,",
+ "1970-01-01T00:00:00.014Z,14,",
+ "1970-01-01T00:00:00.015Z,15,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,"
};
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d2' and s2 - 1 >= 9 and s2 <
30",
@@ -243,8 +274,17 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader3 = new String[] {"Time", "s2"};
String[] retArray3 =
new String[] {
- "10,10,", "11,11,", "12,12,", "13,13,", "14,14,", "15,15,",
"16,16,", "17,17,", "18,18,",
- "19,19,", "20,20,"
+ "1970-01-01T00:00:00.010Z,10,",
+ "1970-01-01T00:00:00.011Z,11,",
+ "1970-01-01T00:00:00.012Z,12,",
+ "1970-01-01T00:00:00.013Z,13,",
+ "1970-01-01T00:00:00.014Z,14,",
+ "1970-01-01T00:00:00.015Z,15,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,"
};
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d2' and s2 - 1 >= 9 and s2 <
30",
@@ -253,7 +293,12 @@ public class IoTDBPredicatePushDownTableIT {
database);
String[] expectedHeader4 = new String[] {"Time", "s2"};
- String[] retArray4 = new String[] {"12,12,", "13,13,", "14,14,"};
+ String[] retArray4 =
+ new String[] {
+ "1970-01-01T00:00:00.012Z,12,",
+ "1970-01-01T00:00:00.013Z,13,",
+ "1970-01-01T00:00:00.014Z,14,"
+ };
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d2' and s2 - 1 >= 9 and s2 <
30 offset 2 limit 3",
expectedHeader4,
@@ -266,21 +311,21 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader1 = new String[] {"Time", "s2", "s3"};
String[] retArray1 =
new String[] {
- "16,16,16,",
- "17,17,17,",
- "18,18,18,",
- "19,19,19,",
- "20,20,20,",
- "21,null,21,",
- "22,null,22,",
- "23,null,23,",
- "24,null,24,",
- "25,null,25,",
- "26,null,26,",
- "27,null,27,",
- "28,null,28,",
- "29,null,29,",
- "30,null,30,",
+ "1970-01-01T00:00:00.016Z,16,16,",
+ "1970-01-01T00:00:00.017Z,17,17,",
+ "1970-01-01T00:00:00.018Z,18,18,",
+ "1970-01-01T00:00:00.019Z,19,19,",
+ "1970-01-01T00:00:00.020Z,20,20,",
+ "1970-01-01T00:00:00.021Z,null,21,",
+ "1970-01-01T00:00:00.022Z,null,22,",
+ "1970-01-01T00:00:00.023Z,null,23,",
+ "1970-01-01T00:00:00.024Z,null,24,",
+ "1970-01-01T00:00:00.025Z,null,25,",
+ "1970-01-01T00:00:00.026Z,null,26,",
+ "1970-01-01T00:00:00.027Z,null,27,",
+ "1970-01-01T00:00:00.028Z,null,28,",
+ "1970-01-01T00:00:00.029Z,null,29,",
+ "1970-01-01T00:00:00.030Z,null,30,",
};
tableResultSetEqualTest(
"select Time,s2, s3 from table0 where device='d2' and s3 + 1 > 16",
@@ -291,21 +336,21 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader2 = new String[] {"Time", "s2"};
String[] retArray2 =
new String[] {
- "16,16,",
- "17,17,",
- "18,18,",
- "19,19,",
- "20,20,",
- "21,null,",
- "22,null,",
- "23,null,",
- "24,null,",
- "25,null,",
- "26,null,",
- "27,null,",
- "28,null,",
- "29,null,",
- "30,null,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,",
+ "1970-01-01T00:00:00.021Z,null,",
+ "1970-01-01T00:00:00.022Z,null,",
+ "1970-01-01T00:00:00.023Z,null,",
+ "1970-01-01T00:00:00.024Z,null,",
+ "1970-01-01T00:00:00.025Z,null,",
+ "1970-01-01T00:00:00.026Z,null,",
+ "1970-01-01T00:00:00.027Z,null,",
+ "1970-01-01T00:00:00.028Z,null,",
+ "1970-01-01T00:00:00.029Z,null,",
+ "1970-01-01T00:00:00.030Z,null,",
};
tableResultSetEqualTest(
"select Time,s2 from table0 where device='d2' and s3 + 1 > 16",
@@ -316,8 +361,21 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader3 = new String[] {"Time", "s3"};
String[] retArray3 =
new String[] {
- "16,16,", "17,17,", "18,18,", "19,19,", "20,20,", "21,21,",
"22,22,", "23,23,", "24,24,",
- "25,25,", "26,26,", "27,27,", "28,28,", "29,29,", "30,30,",
+ "1970-01-01T00:00:00.016Z,16,",
+ "1970-01-01T00:00:00.017Z,17,",
+ "1970-01-01T00:00:00.018Z,18,",
+ "1970-01-01T00:00:00.019Z,19,",
+ "1970-01-01T00:00:00.020Z,20,",
+ "1970-01-01T00:00:00.021Z,21,",
+ "1970-01-01T00:00:00.022Z,22,",
+ "1970-01-01T00:00:00.023Z,23,",
+ "1970-01-01T00:00:00.024Z,24,",
+ "1970-01-01T00:00:00.025Z,25,",
+ "1970-01-01T00:00:00.026Z,26,",
+ "1970-01-01T00:00:00.027Z,27,",
+ "1970-01-01T00:00:00.028Z,28,",
+ "1970-01-01T00:00:00.029Z,29,",
+ "1970-01-01T00:00:00.030Z,30,",
};
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d2' and s3 + 1 > 16",
@@ -328,7 +386,11 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader4 = new String[] {"Time", "s3"};
String[] retArray4 =
new String[] {
- "26,26,", "27,27,", "28,28,", "29,29,", "30,30,",
+ "1970-01-01T00:00:00.026Z,26,",
+ "1970-01-01T00:00:00.027Z,27,",
+ "1970-01-01T00:00:00.028Z,28,",
+ "1970-01-01T00:00:00.029Z,29,",
+ "1970-01-01T00:00:00.030Z,30,",
};
tableResultSetEqualTest(
"select Time,s3 from table0 where device='d2' and s3 + 1 > 16 offset
10",
@@ -539,27 +601,27 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader = new String[] {"Time", "Device", "s2", "s3"};
String[] retArray =
new String[] {
- "10,d2,10,10,",
- "11,d2,11,11,",
- "12,d2,12,12,",
- "13,d2,13,13,",
- "14,d2,14,14,",
- "15,d2,15,15,",
- "16,d2,16,16,",
- "17,d2,17,17,",
- "18,d2,18,18,",
- "19,d2,19,19,",
- "20,d2,20,20,",
- "10,d1,10,10,",
- "11,d1,11,11,",
- "12,d1,12,12,",
- "14,d1,14,14,",
- "15,d1,15,15,",
- "16,d1,16,16,",
- "17,d1,17,17,",
- "18,d1,18,18,",
- "19,d1,19,19,",
- "20,d1,20,20,"
+ "1970-01-01T00:00:00.010Z,d2,10,10,",
+ "1970-01-01T00:00:00.011Z,d2,11,11,",
+ "1970-01-01T00:00:00.012Z,d2,12,12,",
+ "1970-01-01T00:00:00.013Z,d2,13,13,",
+ "1970-01-01T00:00:00.014Z,d2,14,14,",
+ "1970-01-01T00:00:00.015Z,d2,15,15,",
+ "1970-01-01T00:00:00.016Z,d2,16,16,",
+ "1970-01-01T00:00:00.017Z,d2,17,17,",
+ "1970-01-01T00:00:00.018Z,d2,18,18,",
+ "1970-01-01T00:00:00.019Z,d2,19,19,",
+ "1970-01-01T00:00:00.020Z,d2,20,20,",
+ "1970-01-01T00:00:00.010Z,d1,10,10,",
+ "1970-01-01T00:00:00.011Z,d1,11,11,",
+ "1970-01-01T00:00:00.012Z,d1,12,12,",
+ "1970-01-01T00:00:00.014Z,d1,14,14,",
+ "1970-01-01T00:00:00.015Z,d1,15,15,",
+ "1970-01-01T00:00:00.016Z,d1,16,16,",
+ "1970-01-01T00:00:00.017Z,d1,17,17,",
+ "1970-01-01T00:00:00.018Z,d1,18,18,",
+ "1970-01-01T00:00:00.019Z,d1,19,19,",
+ "1970-01-01T00:00:00.020Z,d1,20,20,",
};
tableResultSetEqualTest(
"select Time, Device,s2, s3 from table0 where s2 - 1 >= 9 and s2 < 30
order by device desc",
@@ -573,38 +635,38 @@ public class IoTDBPredicatePushDownTableIT {
String[] expectedHeader = new String[] {"Time", "Device", "s2", "_col3"};
String[] retArray =
new String[] {
- "3,d1,null,30001.0,",
- "13,d1,130000,130001.0,",
- "16,d1,16,17.0,",
- "17,d1,17,18.0,",
- "18,d1,18,19.0,",
- "19,d1,19,20.0,",
- "20,d1,20,21.0,",
- "21,d1,null,22.0,",
- "22,d1,null,23.0,",
- "23,d1,null,230001.0,",
- "24,d1,null,25.0,",
- "25,d1,null,26.0,",
- "26,d1,null,27.0,",
- "27,d1,null,28.0,",
- "28,d1,null,29.0,",
- "29,d1,null,30.0,",
- "30,d1,null,31.0,",
- "16,d2,16,17.0,",
- "17,d2,17,18.0,",
- "18,d2,18,19.0,",
- "19,d2,19,20.0,",
- "20,d2,20,21.0,",
- "21,d2,null,22.0,",
- "22,d2,null,23.0,",
- "23,d2,null,24.0,",
- "24,d2,null,25.0,",
- "25,d2,null,26.0,",
- "26,d2,null,27.0,",
- "27,d2,null,28.0,",
- "28,d2,null,29.0,",
- "29,d2,null,30.0,",
- "30,d2,null,31.0,",
+ "1970-01-01T00:00:00.003Z,d1,null,30001,",
+ "1970-01-01T00:00:00.013Z,d1,130000,130001,",
+ "1970-01-01T00:00:00.016Z,d1,16,17,",
+ "1970-01-01T00:00:00.017Z,d1,17,18,",
+ "1970-01-01T00:00:00.018Z,d1,18,19,",
+ "1970-01-01T00:00:00.019Z,d1,19,20,",
+ "1970-01-01T00:00:00.020Z,d1,20,21,",
+ "1970-01-01T00:00:00.021Z,d1,null,22,",
+ "1970-01-01T00:00:00.022Z,d1,null,23,",
+ "1970-01-01T00:00:00.023Z,d1,null,230001,",
+ "1970-01-01T00:00:00.024Z,d1,null,25,",
+ "1970-01-01T00:00:00.025Z,d1,null,26,",
+ "1970-01-01T00:00:00.026Z,d1,null,27,",
+ "1970-01-01T00:00:00.027Z,d1,null,28,",
+ "1970-01-01T00:00:00.028Z,d1,null,29,",
+ "1970-01-01T00:00:00.029Z,d1,null,30,",
+ "1970-01-01T00:00:00.030Z,d1,null,31,",
+ "1970-01-01T00:00:00.016Z,d2,16,17,",
+ "1970-01-01T00:00:00.017Z,d2,17,18,",
+ "1970-01-01T00:00:00.018Z,d2,18,19,",
+ "1970-01-01T00:00:00.019Z,d2,19,20,",
+ "1970-01-01T00:00:00.020Z,d2,20,21,",
+ "1970-01-01T00:00:00.021Z,d2,null,22,",
+ "1970-01-01T00:00:00.022Z,d2,null,23,",
+ "1970-01-01T00:00:00.023Z,d2,null,24,",
+ "1970-01-01T00:00:00.024Z,d2,null,25,",
+ "1970-01-01T00:00:00.025Z,d2,null,26,",
+ "1970-01-01T00:00:00.026Z,d2,null,27,",
+ "1970-01-01T00:00:00.027Z,d2,null,28,",
+ "1970-01-01T00:00:00.028Z,d2,null,29,",
+ "1970-01-01T00:00:00.029Z,d2,null,30,",
+ "1970-01-01T00:00:00.030Z,d2,null,31,",
};
tableResultSetEqualTest(
"select Time,Device,s2, s3 + 1 from table0 where s3 + 1 > 16 order by
device",
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
index 91ff9309c82..d3cc7b19f36 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
@@ -277,7 +277,7 @@ public class IoTDBOrderByTableIT {
while (resultSet.next()) {
long actualTime = resultSet.getLong(1);
- double actualNum = resultSet.getDouble(2);
+ double actualNum = resultSet.getLong(2);
double actualFloat = resultSet.getDouble(3);
assertEquals(Long.parseLong(RES[ans[i]][0]), actualTime);
@@ -351,7 +351,7 @@ public class IoTDBOrderByTableIT {
while (resultSet.next()) {
long actualTime = resultSet.getLong(1);
- double actualNum = resultSet.getDouble(2);
+ double actualNum = resultSet.getLong(2);
assertEquals(Long.parseLong(RES[ans[i]][0]), actualTime);
assertEquals(
@@ -744,7 +744,7 @@ public class IoTDBOrderByTableIT {
while (resultSet.next()) {
long actualTime = resultSet.getLong(1);
String actualDevice = resultSet.getString(2);
- double actualNum = resultSet.getDouble(3);
+ double actualNum = resultSet.getLong(3);
assertEquals(device, actualDevice);
assertEquals(Long.parseLong(RES[ans[i]][0]), actualTime);
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBArithmeticTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBArithmeticTableIT.java
index 27304ad2ada..1dfd5dcc05a 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBArithmeticTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBArithmeticTableIT.java
@@ -1,20 +1,15 @@
/*
- * 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
+ * Licensed 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.
+ * 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.query.old.query;
@@ -27,7 +22,6 @@ import org.apache.iotdb.itbase.env.BaseEnv;
import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
@@ -37,14 +31,15 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData;
import static org.apache.iotdb.db.it.utils.TestUtils.tableAssertTestFail;
import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(IoTDBTestRunner.class)
@@ -53,15 +48,27 @@ public class IoTDBArithmeticTableIT {
private static final double E = 0.0001;
+ private static final String DATABASE_NAME = "test";
+
+ private static final double[][] BASE_ANS = {{1, 1, 1.0, 1.0}, {2, 2, 2.0,
2.0}, {3, 3, 3.0, 3.0}};
+
+ private static final Map<String, BiFunction<Double, Double, Double>>
OPERATIONS = new HashMap<>();
+
+ static {
+ OPERATIONS.put(" + ", (a, b) -> a + b);
+ OPERATIONS.put(" - ", (a, b) -> a - b);
+ OPERATIONS.put(" * ", (a, b) -> a * b);
+ OPERATIONS.put(" / ", (a, b) -> a / b);
+ OPERATIONS.put(" % ", (a, b) -> a % b);
+ }
+
private static final String[] INSERTION_SQLS = {
- "CREATE DATABASE test",
- "USE test",
- "CREATE TABLE table1 (device STRING ID, s1 INT32 MEASUREMENT, s2 INT32
MEASUREMENT, s3 INT64 MEASUREMENT, s4 INT32 MEASUREMENT, s5 BOOLEAN
MEASUREMENT, s6 TEXT MEASUREMENT, s7 INT32 MEASUREMENT, s8 INT32 MEASUREMENT)",
- "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7) values
('d1', 1, 1, 1, 1, 1, false, '1', 1)",
- "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s8) values
('d1', 2, 2, 2, 2, 2, false, '2', 2)",
- "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7) values
('d1', 3, 3, 3, 3, 3, true, '3', 3)",
- "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s8) values
('d1', 4, 4, 4, 4, 4, true, '4', 4)",
- "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7, s8) values
('d1', 5, 5, 5, 5, 5, true, '5', 5, 5)",
+ "CREATE DATABASE " + DATABASE_NAME,
+ "USE " + DATABASE_NAME,
+ "CREATE TABLE table1 (device STRING ID, s1 INT32 MEASUREMENT, s2 INT64
MEASUREMENT, s3 FLOAT MEASUREMENT, s4 DOUBLE MEASUREMENT, s5 DATE MEASUREMENT,
s6 TIMESTAMP MEASUREMENT, s7 BOOLEAN MEASUREMENT, s8 TEXT MEASUREMENT)",
+ "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7, s8) values
('d1', 1, 1, 1, 1.0, 1.0, '2024-01-01', 10, true, 'test')",
+ "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7, s8) values
('d1', 2, 2, 2, 2.0, 2.0, '2024-02-01', 20, true, 'test')",
+ "insert into table1(device, time, s1, s2, s3, s4, s5, s6, s7, s8) values
('d1', 3, 3, 3, 3.0, 3.0, '2024-03-01', 30, true, 'test')",
};
@BeforeClass
@@ -75,49 +82,56 @@ public class IoTDBArithmeticTableIT {
EnvFactory.getEnv().cleanClusterEnvironment();
}
+ public static double[][] calculateExpectedAns(String operator) {
+ double[][] expectedAns = new double[BASE_ANS.length][BASE_ANS[0].length *
BASE_ANS[0].length];
+ BiFunction<Double, Double, Double> operation = OPERATIONS.get(operator);
+ if (operation == null) {
+ throw new IllegalArgumentException("Unsupported operator: " + operator);
+ }
+
+ for (int i = 0; i < BASE_ANS.length; i++) {
+ int baseLength = BASE_ANS[i].length;
+ for (int j = 0; j < baseLength; j++) {
+ for (int k = 0; k < baseLength; k++) {
+ expectedAns[i][j * baseLength + k] = operation.apply(BASE_ANS[i][j],
BASE_ANS[i][k]);
+ }
+ }
+ }
+ return expectedAns;
+ }
+
@Test
- public void testArithmeticBinary() {
+ public void testArithmeticBinaryWithoutDateAndTimestamp() {
try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
-
statement.execute("USE test");
- String[] operands = new String[] {"s1", "s2", "s3", "s4"};
+
+ // generate sql
+
for (String operator : new String[] {" + ", " - ", " * ", " / ", " % "})
{
List<String> expressions = new ArrayList<>();
+ String[] operands = new String[] {"s1", "s2", "s3", "s4"};
for (String leftOperand : operands) {
for (String rightOperand : operands) {
expressions.add(leftOperand + operator + rightOperand);
}
}
- String sql = String.format("select %s from table1", String.join(",",
expressions));
+ String sql = String.format("select %s from table1", String.join(",",
expressions));
ResultSet resultSet = statement.executeQuery(sql);
+ // generate answer
+ double[][] expectedAns = calculateExpectedAns(operator);
+
+ // Make sure the number of columns in the result set is correct
assertEquals(expressions.size(),
resultSet.getMetaData().getColumnCount());
- for (int i = 1; i < 6; ++i) {
+ // check the result
+ for (double[] expectedAn : expectedAns) {
resultSet.next();
- for (int j = 0; j < expressions.size(); ++j) {
- double expected = 0;
- switch (operator) {
- case " + ":
- expected = i + i;
- break;
- case " - ":
- expected = i - i;
- break;
- case " * ":
- expected = i * i;
- break;
- case " / ":
- expected = i / i;
- break;
- case " % ":
- expected = i % i;
- break;
- }
- double actual = Double.parseDouble(resultSet.getString(j + 1));
- assertEquals(expected, actual, E);
+ for (int i = 0; i < expectedAn.length; i++) {
+ double result = Double.parseDouble(resultSet.getString(i + 1));
+ assertEquals(expectedAn[i], result, E);
}
}
}
@@ -127,47 +141,55 @@ public class IoTDBArithmeticTableIT {
}
@Test
- public void testArithmeticUnary() {
+ public void testArithmeticBinaryWithDateAndTimestamp() {
try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
statement.execute("USE test");
- String[] expressions = new String[] {"- s1", "- s2", "- s3", "- s4"};
- String sql = String.format("select %s from table1", String.join(",",
expressions));
+
+ String sql =
+ "select
s1+s5,s1+s6,s2+s5,s2+s6,s5+s1,s5+s2,s6+s1,s6+s2,s5-s1,s5-s2,s6-s1,s6-s2 from
table1";
ResultSet resultSet = statement.executeQuery(sql);
- assertEquals(expressions.length,
resultSet.getMetaData().getColumnCount());
+ assertEquals(12, resultSet.getMetaData().getColumnCount());
- for (int i = 1; i < 6; ++i) {
+ int[][] expectedAns = {
+ {20240101, 11, 20240101, 11, 20240101, 20240101, 11, 11, 20231231,
20231231, 9, 9},
+ {20240201, 22, 20240201, 22, 20240201, 20240201, 22, 22, 20240131,
20240131, 18, 18},
+ {20240301, 33, 20240301, 33, 20240301, 20240301, 33, 33, 20240229,
20240229, 27, 27}
+ };
+
+ for (int[] expectedAn : expectedAns) {
resultSet.next();
- for (int j = 0; j < expressions.length; ++j) {
- double expected = -i;
- double actual = Double.parseDouble(resultSet.getString(j + 1));
- assertEquals(expected, actual, E);
+
+ for (int i = 0; i < expectedAn.length; i++) {
+ int result = resultSet.getInt(i + 1);
+ assertEquals(expectedAn[i], result);
}
}
- resultSet.close();
} catch (SQLException throwable) {
fail(throwable.getMessage());
}
}
- // TODO After support 'sin'
- @Ignore
@Test
- public void testHybridQuery() {
+ public void testArithmeticUnary() {
try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
- String[] expressions = new String[] {"s1", "s1 + s2", "sin(s1)"};
+ statement.execute("USE test");
+
+ String[] expressions = new String[] {"- s1", "- s2", "- s3", "- s4"};
String sql = String.format("select %s from table1", String.join(",",
expressions));
ResultSet resultSet = statement.executeQuery(sql);
- assertEquals(1 + expressions.length,
resultSet.getMetaData().getColumnCount());
+ assertEquals(expressions.length,
resultSet.getMetaData().getColumnCount());
- for (int i = 1; i < 6; ++i) {
+ for (int i = 1; i < 4; ++i) {
resultSet.next();
- assertEquals(i, Double.parseDouble(resultSet.getString(2)), E);
- assertEquals(i + i, Double.parseDouble(resultSet.getString(3)), E);
- assertEquals(Math.sin(i), Double.parseDouble(resultSet.getString(4)),
E);
+ for (int j = 0; j < expressions.length; ++j) {
+ double expected = -i;
+ double actual = Double.parseDouble(resultSet.getString(j + 1));
+ assertEquals(expected, actual, E);
+ }
}
resultSet.close();
} catch (SQLException throwable) {
@@ -176,51 +198,147 @@ public class IoTDBArithmeticTableIT {
}
@Test
- public void testNonAlign() {
- try (Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
- Statement statement = connection.createStatement()) {
- statement.execute("USE test");
- ResultSet resultSet = statement.executeQuery("select s7 + s8 from
table1");
- assertEquals(1, resultSet.getMetaData().getColumnCount());
- assertTrue(resultSet.next());
- String curr = null;
- while (curr == null) {
- curr = resultSet.getString(1);
- resultSet.next();
- }
- assertEquals(10, Double.parseDouble(resultSet.getString(1)), E);
- assertFalse(resultSet.next());
-
- resultSet = statement.executeQuery("select s7 + s8 from table1 where
time < 5");
- assertEquals(1, resultSet.getMetaData().getColumnCount());
- curr = null;
- while (curr == null) {
- if (!resultSet.next()) {
- break;
- }
- curr = resultSet.getString(1);
- }
- assertEquals(null, curr);
- resultSet.close();
- } catch (SQLException throwable) {
- fail(throwable.getMessage());
- }
+ public void testBinaryWrongType() {
+
+ testBinaryDifferentCombinationsFail(
+ new String[] {" * ", " / ", " % "},
+ new String[] {"s1", "s2", "s3", "s4"},
+ new String[] {"s5", "s6"},
+ "table1",
+ "701: Cannot apply operator",
+ "test");
+
+ testBinaryDifferentCombinationsFail(
+ new String[] {" * ", " / ", " % "},
+ new String[] {"s5", "s6"},
+ new String[] {"s1", "s2", "s3", "s4"},
+ "table1",
+ "701: Cannot apply operator",
+ "test");
+ }
+
+ @Test
+ public void testUnaryWrongType() {
+ tableAssertTestFail("select -s5 from table1", "701: Cannot negate",
"test");
+ tableAssertTestFail("select -s7 from table1", "701: Cannot negate",
"test");
+ tableAssertTestFail("select -s8 from table1", "701: Cannot negate",
"test");
+ }
+
+ @Test
+ public void testOverflow() {
+ // int addition overflow
+ tableAssertTestFail(
+ String.format("select s1+%d from table1", Integer.MAX_VALUE),
+ "750: int Addition overflow",
+ "test");
+
+ // int subtraction overflow
+ tableAssertTestFail(
+ String.format("select s1-(%d) from table1", Integer.MIN_VALUE),
+ "750: int Subtraction overflow",
+ "test");
+
+ // int multiplication overflow
+ tableAssertTestFail(
+ String.format("select (s1+1)*%d from table1", Integer.MAX_VALUE),
+ "750: int Multiplication overflow",
+ "test");
+
+ // Date addition overflow
+ tableAssertTestFail(
+ String.format("select s5+%d from table1", Long.MAX_VALUE),
+ "750: long Addition overflow",
+ "test");
+
+ // Date subtraction overflow
+ tableAssertTestFail(
+ String.format("select s5-(%d) from table1", Long.MIN_VALUE),
+ "750: long Subtraction overflow",
+ "test");
+
+ // long addition overflow
+ tableAssertTestFail(
+ String.format("select s2+%d from table1", Long.MAX_VALUE),
+ "750: long Addition overflow",
+ "test");
+
+ // long subtraction overflow
+ tableAssertTestFail(
+ String.format("select s2-(%d) from table1", Long.MIN_VALUE),
+ "750: long Subtraction overflow",
+ "test");
+
+ // Timestamp addition overflow
+ tableAssertTestFail(
+ String.format("select s6+%d from table1", Long.MAX_VALUE),
+ "750: long Addition overflow",
+ "test");
+
+ // Timestamp subtraction overflow
+ tableAssertTestFail(
+ String.format("select s6-(%d) from table1", Long.MIN_VALUE),
+ "750: long Subtraction overflow",
+ "test");
}
@Test
- public void testWrongTypeBoolean() {
- tableAssertTestFail("select s1 + s5 from table1", "701: Cannot apply
operator", "test");
+ public void testFloatDivisionByZeroSpecialCase() {
+ String[] expectedHeader = new String[5];
+ for (int i = 0; i < expectedHeader.length; i++) {
+ expectedHeader[i] = "_col" + i;
+ }
+ String[] expectedAns = {
+ "Infinity,0.0,NaN,-0.0,-Infinity,",
+ "Infinity,0.0,NaN,-0.0,-Infinity,",
+ "Infinity,0.0,NaN,-0.0,-Infinity,"
+ };
+
+ tableResultSetEqualTest(
+ "select s3/0.0,0.0/s3,0.0/0.0,0.0/-s3,-s3/0.0 from table1",
+ expectedHeader,
+ expectedAns,
+ "test");
}
@Test
- public void testWrongTypeText() {
- tableAssertTestFail("select s1 + s6 from table1", "701: Cannot apply
operator", "test");
+ public void testDoubleDivisionByZeroSpecialCase() {
+ String[] expectedHeader = new String[5];
+ for (int i = 0; i < expectedHeader.length; i++) {
+ expectedHeader[i] = "_col" + i;
+ }
+ String[] expectedAns = {"NaN,0.0,NaN,0.0,NaN,", "NaN,0.0,NaN,0.0,NaN,",
"NaN,0.0,NaN,0.0,NaN,"};
+
+ tableResultSetEqualTest(
+ "select s3%0.0,0.0%s3,0.0%0.0,0.0%-s3,-s3%0.0 from table1",
+ expectedHeader, expectedAns, "test");
}
@Test
- public void testNot() {
- String[] header = new String[] {"_col0"};
- String[] retArray = new String[] {"true,", "true,", "false,", "false,",
"false,"};
- tableResultSetEqualTest("select not(s5) from table1", header, retArray,
"test");
+ public void testDivisionByZero() {
+ tableAssertTestFail("select s1/0 from table1", "751: Division by zero",
"test");
+ tableAssertTestFail("select s2/0 from table1", "751: Division by zero",
"test");
+
+ tableAssertTestFail("select s1%0 from table1", "751: Division by zero",
"test");
+ tableAssertTestFail("select s2%0 from table1", "751: Division by zero",
"test");
+ }
+
+ private void testBinaryDifferentCombinationsFail(
+ String[] operators,
+ String[] leftOperands,
+ String[] rightOperands,
+ String tableName,
+ String errMsg,
+ String databaseName) {
+ for (String operator : operators) {
+ for (String leftOperand : leftOperands) {
+ for (String rightOperand : rightOperands) {
+ tableAssertTestFail(
+ String.format(
+ "select %s %s %s from %s", leftOperand, operator,
rightOperand, tableName),
+ errMsg,
+ databaseName);
+ }
+ }
+ }
}
}
diff --git
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index 4964ff4c06b..49db2987a12 100644
---
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -133,6 +133,10 @@ public enum TSStatusCode {
OPERATOR_NOT_FOUND(716),
+ // Arithmetic
+ NUMERIC_VALUE_OUT_OF_RANGE(750),
+ DIVISION_BY_ZERO(751),
+
// Authentication
INIT_AUTH_ERROR(800),
WRONG_LOGIN_PASSWORD(801),
diff --git a/iotdb-core/datanode/src/main/codegen/config.fmpp
b/iotdb-core/datanode/src/main/codegen/config.fmpp
index 2112c459367..46b529484ab 100644
--- a/iotdb-core/datanode/src/main/codegen/config.fmpp
+++ b/iotdb-core/datanode/src/main/codegen/config.fmpp
@@ -19,7 +19,9 @@
data: {
allDataTypes: tdd(../dataModel/AllDataType.tdd),
decimalDataTypes: tdd(../dataModel/DecimalDataType.tdd),
- compareTypes: tdd(../dataModel/CompareType.tdd)
+ compareTypes: tdd(../dataModel/CompareType.tdd),
+ mathematicalOperator: tdd(../dataModel/MathematicalOperator.tdd),
+ mathematicalDataType: tdd(../dataModel/MathematicalDataType.tdd)
}
freemarkerLinks: {
includes: includes/
diff --git a/iotdb-core/datanode/src/main/codegen/config.fmpp
b/iotdb-core/datanode/src/main/codegen/dataModel/MathematicalDataType.tdd
similarity index 58%
copy from iotdb-core/datanode/src/main/codegen/config.fmpp
copy to iotdb-core/datanode/src/main/codegen/dataModel/MathematicalDataType.tdd
index 2112c459367..f60d818c6d9 100644
--- a/iotdb-core/datanode/src/main/codegen/config.fmpp
+++ b/iotdb-core/datanode/src/main/codegen/dataModel/MathematicalDataType.tdd
@@ -16,11 +16,37 @@
* limitations under the License.
-->
-data: {
- allDataTypes: tdd(../dataModel/AllDataType.tdd),
- decimalDataTypes: tdd(../dataModel/DecimalDataType.tdd),
- compareTypes: tdd(../dataModel/CompareType.tdd)
-}
-freemarkerLinks: {
- includes: includes/
+{
+ "types": [
+ {
+ "type": "IntType",
+ "dataType": "int",
+ "instance": "INT"
+ },
+ {
+ "type": "LongType",
+ "dataType": "long",
+ "instance": "LONG"
+ },
+ {
+ "type": "FloatType",
+ "dataType": "float",
+ "instance": "FLOAT"
+ },
+ {
+ "type": "DoubleType",
+ "dataType": "double",
+ "instance": "DOUBLE"
+ },
+ {
+ "type": "DateType",
+ "dataType": "int",
+ "instance": "DATE"
+ },
+ {
+ "type": "TimestampType",
+ "dataType": "long",
+ "instance": "TIMESTAMP"
+ }
+ ]
}
diff --git a/iotdb-core/datanode/src/main/codegen/config.fmpp
b/iotdb-core/datanode/src/main/codegen/dataModel/MathematicalOperator.tdd
similarity index 59%
copy from iotdb-core/datanode/src/main/codegen/config.fmpp
copy to iotdb-core/datanode/src/main/codegen/dataModel/MathematicalOperator.tdd
index 2112c459367..722b32bc43e 100644
--- a/iotdb-core/datanode/src/main/codegen/config.fmpp
+++ b/iotdb-core/datanode/src/main/codegen/dataModel/MathematicalOperator.tdd
@@ -16,11 +16,37 @@
* limitations under the License.
-->
-data: {
- allDataTypes: tdd(../dataModel/AllDataType.tdd),
- decimalDataTypes: tdd(../dataModel/DecimalDataType.tdd),
- compareTypes: tdd(../dataModel/CompareType.tdd)
-}
-freemarkerLinks: {
- includes: includes/
-}
+{
+ "binaryOperators": [
+ {
+ "name": "Addition",
+ "operator": "ADD",
+ "symbol": "+"
+ },
+ {
+ "name": "Subtraction",
+ "operator": "SUBTRACT",
+ "symbol": "-"
+ },
+ {
+ "name": "Multiplication",
+ "operator": "MULTIPLY",
+ "symbol": "*"
+ },
+ {
+ "name": "Division",
+ "operator": "DIVIDE",
+ "symbol": "/"
+ },
+ {
+ "name": "Modulus",
+ "operator": "MODULUS",
+ "symbol": "%"
+ }
+ ],
+ "unaryOperators": [
+ {
+ "operator": "NEGATION"
+ }
+ ]
+}
\ No newline at end of file
diff --git
a/iotdb-core/datanode/src/main/codegen/templates/ArithmeticBinaryColumnTransformer.ftl
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticBinaryColumnTransformer.ftl
new file mode 100644
index 00000000000..42a6d200620
--- /dev/null
+++
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticBinaryColumnTransformer.ftl
@@ -0,0 +1,301 @@
+/*
+ * 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.
+ */
+
+<@pp.dropOutputFile />
+<#list mathematicalOperator.binaryOperators as operator>
+<#list mathematicalDataType.types as first>
+<#list mathematicalDataType.types as second>
+<#--Parting line-->
+<#assign className =
"${first.type?replace('Type','')}${operator.name}${second.type?replace('Type','')}ColumnTransformer">
+
+<#--Main Part-->
+<#if (first.instance == "DATE" || first.instance == "TIMESTAMP") &&
(second.instance == "INT" || second.instance == "LONG")><#if operator.name ==
"Addition" || operator.name == "Subtraction">
+<@pp.changeOutputFile
name="/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/${className}.java"
/>
+<#--Date + int || Date + long || Timestamp + int || Timestamp + long-->
+<#--Date - int || Date - long || Timestamp - int || Timestamp - long-->
+package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
+
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import org.apache.iotdb.db.utils.DateTimeUtils;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.DateUtils;
+
+import java.time.ZoneId;
+
+<#if first.dataType == "int" || second.dataType == "int" || first.dataType ==
"long" || second.dataType == "long">
+import static org.apache.iotdb.rpc.TSStatusCode.NUMERIC_VALUE_OUT_OF_RANGE;
+</#if>
+
+public class ${className} extends BinaryColumnTransformer {
+
+ private static ZoneId zoneId;
+
+ public ${className}(
+ Type returnType, ColumnTransformer leftTransformer, ColumnTransformer
rightTransformer, ZoneId zoneId) {
+ super(returnType, leftTransformer, rightTransformer);
+ this.zoneId = zoneId;
+ }
+
+ @Override
+ protected void doTransform(
+ Column leftColumn, Column rightColumn, ColumnBuilder builder, int
positionCount) {
+ for (int i = 0; i < positionCount; i++) {
+ if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+ returnType.write${first.dataType?cap_first}(
+ builder,
+ transform(
+
leftTransformer.getType().get${first.dataType?cap_first}(leftColumn, i),
+
rightTransformer.getType().get${second.dataType?cap_first}(rightColumn, i)));
+ } else {
+ builder.appendNull();
+ }
+ }
+ }
+
+ @Override
+ protected void checkType() {
+ // do nothing
+ }
+
+ public static ${first.dataType} transform(${first.dataType} left,
${second.dataType} right) {
+ <#switch operator.name>
+ <#case "Addition">
+ <#if first.instance == "DATE">
+ <#--Date + int || Date + long-->
+ try{
+ long timestamp =
Math.addExact(DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(left,zoneId)),
right);
+ return
DateUtils.parseDateExpressionToInt(DateTimeUtils.convertToLocalDate(timestamp,
zoneId));
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s + %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ <#else>
+ <#--Timestamp + int || Timestamp + long-->
+ try{
+ return Math.addExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s + %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ </#if>
+ <#break>
+ <#case "Subtraction">
+ <#if first.instance == "DATE">
+ <#--Date - int || Date - long-->
+ try{
+ long timestamp =
Math.subtractExact(DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(left,
zoneId)), right);
+ return
DateUtils.parseDateExpressionToInt(DateTimeUtils.convertToLocalDate(timestamp,
zoneId));
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s - %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ <#else>
+ <#--Timestamp - int || Timestamp - long-->
+ try{
+ return Math.subtractExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s - %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ </#if>
+ <#break>
+ </#switch>
+ }
+}
+</#if>
+<#elseif (second.instance == "DATE" || second.instance =="TIMESTAMP") &&
(first.instance == "INT" || first.instance == "LONG")>
+ <#if operator.name == "Addition">
+<#--int + Date || long + Date || int + Timestamp || long + Timestamp-->
+<@pp.changeOutputFile
name="/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/${className}.java"
/>
+package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
+
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import org.apache.iotdb.db.utils.DateTimeUtils;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.Type;
+import org.apache.tsfile.utils.DateUtils;
+
+import java.time.ZoneId;
+
+<#if first.dataType == "int" || second.dataType == "int" || first.dataType ==
"long" || second.dataType == "long">
+import static org.apache.iotdb.rpc.TSStatusCode.NUMERIC_VALUE_OUT_OF_RANGE;
+</#if>
+
+public class ${className} extends BinaryColumnTransformer {
+
+ private static ZoneId zoneId;
+
+ public ${className}(
+ Type returnType, ColumnTransformer leftTransformer, ColumnTransformer
rightTransformer, ZoneId zoneId) {
+ super(returnType, leftTransformer, rightTransformer);
+ this.zoneId = zoneId;
+ }
+
+ @Override
+ protected void doTransform(
+ Column leftColumn, Column rightColumn, ColumnBuilder builder, int
positionCount) {
+ for (int i = 0; i < positionCount; i++) {
+ if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+ returnType.write${second.dataType?cap_first}(
+ builder,
+ transform(
+
leftTransformer.getType().get${first.dataType?cap_first}(leftColumn, i),
+
rightTransformer.getType().get${second.dataType?cap_first}(rightColumn, i)));
+ } else {
+ builder.appendNull();
+ }
+ }
+ }
+
+ @Override
+ protected void checkType() {
+ // do nothing
+ }
+
+ public static ${second.dataType} transform(${first.dataType} left,
${second.dataType} right) {
+ <#if second.instance == "DATE">
+ try{
+ long timestamp =
Math.addExact(left,DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(right,
zoneId)));
+ return
DateUtils.parseDateExpressionToInt(DateTimeUtils.convertToLocalDate(timestamp,
zoneId));
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s + %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ <#else>
+ try{
+ return Math.addExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("long ${operator.name}
overflow: %s + %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ </#if>
+ }
+}
+</#if>
+<#elseif first.instance != "DATE" && first.instance != "TIMESTAMP" &&
second.instance != "DATE" && second.instance != "TIMESTAMP">
+<@pp.changeOutputFile
name="/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/${className}.java"
/>
+<#--int、long、float、double with + - * / %-->
+<#--assign resultType-->
+<#if first.dataType == "double" || second.dataType == "double">
+ <#assign resultType = "double" />
+<#elseif first.dataType == "float" || second.dataType == "float">
+ <#assign resultType = "float" />
+<#elseif first.dataType == "long" || second.dataType == "long">
+ <#assign resultType = "long" />
+<#else>
+ <#assign resultType = "int" />
+</#if>
+<#--Parting line-->
+package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
+
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.Type;
+
+<#if operator.name == "Division" || operator.name == "Modulus">
+import static org.apache.iotdb.rpc.TSStatusCode.DIVISION_BY_ZERO;
+</#if>
+<#if first.dataType == "int" || second.dataType == "int" || first.dataType ==
"long" || second.dataType == "long">
+import static org.apache.iotdb.rpc.TSStatusCode.NUMERIC_VALUE_OUT_OF_RANGE;
+</#if>
+
+public class ${className} extends BinaryColumnTransformer {
+ public ${className}(
+ Type returnType, ColumnTransformer leftTransformer, ColumnTransformer
rightTransformer) {
+ super(returnType, leftTransformer, rightTransformer);
+ }
+
+ @Override
+ protected void doTransform(
+ Column leftColumn, Column rightColumn, ColumnBuilder builder, int
positionCount) {
+ for (int i = 0; i < positionCount; i++) {
+ if (!leftColumn.isNull(i) && !rightColumn.isNull(i)) {
+ returnType.write${resultType?cap_first}(
+ builder,
+ transform(
+
leftTransformer.getType().get${first.dataType?cap_first}(leftColumn, i),
+
rightTransformer.getType().get${second.dataType?cap_first}(rightColumn, i)));
+ } else {
+ builder.appendNull();
+ }
+ }
+ }
+
+ @Override
+ protected void checkType() {
+ // do nothing
+ }
+
+ public static ${resultType} transform(${first.dataType} left,
${second.dataType} right) {
+ <#if (first.dataType == "int" || first.dataType == "long") &&
(second.dataType == "int" || second.dataType =="long")>
+ <#switch operator.name>
+ <#case "Addition">
+ try{
+ return Math.addExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("${resultType}
${operator.name} overflow: %s + %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),false);
+ }
+ <#break>
+ <#case "Subtraction">
+ try{
+ return Math.subtractExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("${resultType}
${operator.name} overflow: %s - %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),false);
+ }
+ <#break>
+ <#case "Multiplication">
+ try{
+ return Math.multiplyExact(left, right);
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException(String.format("${resultType}
${operator.name} overflow: %s * %s", left,
right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ <#break>
+ <#case "Division">
+ try{
+ if (left == <#if first.dataType == "int">Integer.MIN_VALUE<#elseif
first.dataType == "long">Long.MIN_VALUE</#if> && right == -1) {
+ throw new IoTDBRuntimeException(String.format("${resultType} overflow:
%s / %s", left, right),NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(),true);
+ }
+ return left / right;
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException("Division by
zero",DIVISION_BY_ZERO.getStatusCode(),true);
+ }
+ <#break>
+ <#case "Modulus">
+ try{
+ return left % right;
+ }catch (ArithmeticException e){
+ throw new IoTDBRuntimeException("Division by
zero",DIVISION_BY_ZERO.getStatusCode(),true);
+ }
+ <#break>
+ </#switch>
+ <#else>
+ return left ${operator.symbol} right;
+ </#if>
+ }
+}
+</#if>
+<#--Parting line-->
+</#list>
+</#list>
+</#list>
\ No newline at end of file
diff --git
a/iotdb-core/datanode/src/main/codegen/templates/ArithmeticColumnTransformerApi.ftl
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticColumnTransformerApi.ftl
new file mode 100644
index 00000000000..3ec6a9b432c
--- /dev/null
+++
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticColumnTransformerApi.ftl
@@ -0,0 +1,218 @@
+/*
+ * Licensed 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.
+ */
+
+<@pp.dropOutputFile />
+<@pp.changeOutputFile
name="/org/apache/iotdb/db/queryengine/transformation/dag/column/binary/ArithmeticColumnTransformerApi.java"
/>
+package org.apache.iotdb.db.queryengine.transformation.dag.column.binary;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.AdditionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.DivisionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.ModulusResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.MultiplicationResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.SubtractionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.metadata.OperatorNotFoundException;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.DoubleNegationColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.FloatNegationColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.IntNegationColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.LongNegationColumnTransformer;
+
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.List;
+
+public class ArithmeticColumnTransformerApi {
+ <#list mathematicalOperator.binaryOperators as operator>
+
+ public static ColumnTransformer get${operator.name}Transformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ switch (leftTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return getInt${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ case INT64:
+ return getLong${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ case FLOAT:
+ return getFloat${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ case DOUBLE:
+ return getDouble${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ <#if operator.name == "Addition" || operator.name == "Subtraction">
+ case DATE:
+ return getDate${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ case TIMESTAMP:
+ return getTimestamp${operator.name}Transformer(leftTransformer,
rightTransformer, zoneId);
+ </#if>
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+ </#list>
+
+ public static ColumnTransformer getNegationTransformer(ColumnTransformer
columnTransformer) {
+ switch (columnTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new IntNegationColumnTransformer(columnTransformer.getType(),
columnTransformer);
+ case INT64:
+ return new LongNegationColumnTransformer(columnTransformer.getType(),
columnTransformer);
+ case FLOAT:
+ return new FloatNegationColumnTransformer(columnTransformer.getType(),
columnTransformer);
+ case DOUBLE:
+ return new
DoubleNegationColumnTransformer(columnTransformer.getType(), columnTransformer);
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+ <#-- Parting line -->
+ <#list mathematicalOperator.binaryOperators as operator>
+ <#list mathematicalDataType.types as first>
+ <#assign firstType = first.type?replace("Type","")>
+ <#-- The getTransformer method without Date and Timesatmp -->
+ <#if firstType != "Date" && firstType != "Timestamp">
+
+ private static ColumnTransformer get${firstType}${operator.name}Transformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ List<? extends Type> argumentTypes =
+ Arrays.asList(leftTransformer.getType(), rightTransformer.getType());
+ switch (rightTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new ${firstType}${operator.name}IntColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer);
+ case INT64:
+ return new ${firstType}${operator.name}LongColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer);
+ case FLOAT:
+ return new ${firstType}${operator.name}FloatColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer);
+ case DOUBLE:
+ return new ${firstType}${operator.name}DoubleColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer);
+ <#if operator.name == "Addition" && (firstType == "Int" || firstType ==
"Long")>
+ case DATE:
+ return new ${firstType}${operator.name}DateColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ case TIMESTAMP:
+ return new ${firstType}${operator.name}TimestampColumnTransformer(
+ ${operator.name}Resolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ </#if>
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+ </#if>
+ </#list>
+ </#list>
+
+ private static ColumnTransformer getDateAdditionTransformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ List<? extends Type> argumentTypes =
+ Arrays.asList(leftTransformer.getType(), rightTransformer.getType());
+ switch (rightTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new DateAdditionIntColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ case INT64:
+ return new DateAdditionLongColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+
+ private static ColumnTransformer getTimestampAdditionTransformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ List<? extends Type> argumentTypes =
+ Arrays.asList(leftTransformer.getType(), rightTransformer.getType());
+ switch (rightTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new TimestampAdditionIntColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ case INT64:
+ return new TimestampAdditionLongColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+
+ private static ColumnTransformer getDateSubtractionTransformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ List<? extends Type> argumentTypes =
+ Arrays.asList(leftTransformer.getType(), rightTransformer.getType());
+ switch (rightTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new DateSubtractionIntColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ case INT64:
+ return new DateSubtractionLongColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+
+ private static ColumnTransformer getTimestampSubtractionTransformer(
+ ColumnTransformer leftTransformer, ColumnTransformer rightTransformer,
ZoneId zoneId) {
+ List<? extends Type> argumentTypes =
+ Arrays.asList(leftTransformer.getType(), rightTransformer.getType());
+ switch (rightTransformer.getType().getTypeEnum()) {
+ case INT32:
+ return new TimestampSubtractionIntColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ case INT64:
+ return new TimestampSubtractionLongColumnTransformer(
+ AdditionResolver.checkConditions(argumentTypes).get(),
+ leftTransformer,
+ rightTransformer,
+ zoneId);
+ default:
+ throw new UnsupportedOperationException("Unsupported Type");
+ }
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/codegen/templates/ArithmeticUnaryColumnTransformer.ftl
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticUnaryColumnTransformer.ftl
new file mode 100644
index 00000000000..cfd49a51223
--- /dev/null
+++
b/iotdb-core/datanode/src/main/codegen/templates/ArithmeticUnaryColumnTransformer.ftl
@@ -0,0 +1,67 @@
+/*
+ * Licensed 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.
+ */
+
+<@pp.dropOutputFile />
+<#list mathematicalDataType.types as type>
+ <#assign newType = type.type?replace("Type","")>
+ <#assign className = "${newType}NegationColumnTransformer">
+<#if newType != "Date" && newType != "Timestamp">
+ <@pp.changeOutputFile
name="/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/${className}.java"
/>
+package org.apache.iotdb.db.queryengine.transformation.dag.column.unary;
+
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.read.common.type.Type;
+
+import static org.apache.iotdb.rpc.TSStatusCode.NUMERIC_VALUE_OUT_OF_RANGE;
+
+public class ${className} extends UnaryColumnTransformer {
+
+ public ${className}(
+ Type returnType, ColumnTransformer childColumnTransformer) {
+ super(returnType, childColumnTransformer);
+ }
+
+ @Override
+ protected void doTransform(
+ Column column, ColumnBuilder columnBuilder) {
+ for (int i = 0, n = column.getPositionCount(); i < n; i++) {
+ if (!column.isNull(i)) {
+ returnType.write${type.dataType?cap_first}(
+ columnBuilder,
transform(childColumnTransformer.getType().get${type.dataType?cap_first}(column,
i)));
+ } else {
+ columnBuilder.appendNull();
+ }
+ }
+ }
+
+ @Override
+ protected void checkType() {
+ // do nothing
+ }
+
+ public static ${type.dataType} transform(${type.dataType} value){
+ <#if type.dataType == "Int" || type.dataType == "Long">
+ if(value == ${type.dataType}.MIN_VALUE){
+ throw new IoTDBRuntimeException(String.format("The %s is out of range of
${type.dataType}.", value), NUMERIC_VALUE_OUT_OF_RANGE.getStatusCode(), true);
+ }
+ </#if>
+ return -value;
+ }
+}
+</#if>
+</#list>
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
index 59150d1a703..82179fff746 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
@@ -23,6 +23,11 @@ import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.queryengine.common.SessionInfo;
import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.InputLocation;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.AdditionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.DivisionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.ModulusResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.MultiplicationResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.SubtractionResolver;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ArithmeticBinaryExpression;
@@ -59,13 +64,10 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SimpleCaseExpress
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.StringLiteral;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SymbolReference;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Trim;
+import
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager;
import
org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.ColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticAdditionColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticDivisionColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticModuloColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticMultiplicationColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticSubtractionColumnTransformer;
+import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ArithmeticColumnTransformerApi;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareEqualToColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareGreaterEqualColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareGreaterThanColumnTransformer;
@@ -87,7 +89,6 @@ import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InMultiCo
import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalAndMultiColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalOrMultiColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.BetweenColumnTransformer;
-import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.ArithmeticNegationColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.IsNullColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.LogicNotColumnTransformer;
import
org.apache.iotdb.db.queryengine.transformation.dag.column.unary.RegularColumnTransformer;
@@ -159,7 +160,9 @@ import org.apache.tsfile.read.common.type.Type;
import org.apache.tsfile.read.common.type.TypeEnum;
import org.apache.tsfile.utils.Binary;
+import java.time.ZoneId;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -195,34 +198,61 @@ public class ColumnTransformerBuilder
ArithmeticBinaryExpression node, Context context) {
if (!context.cache.containsKey(node)) {
if (context.hasSeen.containsKey(node)) {
+ ColumnTransformer left = process(node.getLeft(), context);
+ ColumnTransformer right = process(node.getRight(), context);
+ List<Type> types = Arrays.asList(left.getType(), right.getType());
+ Type type;
+ switch (node.getOperator()) {
+ case ADD:
+ type = AdditionResolver.checkConditions(types).get();
+ break;
+ case SUBTRACT:
+ type = SubtractionResolver.checkConditions(types).get();
+ break;
+ case MULTIPLY:
+ type = MultiplicationResolver.checkConditions(types).get();
+ break;
+ case DIVIDE:
+ type = DivisionResolver.checkConditions(types).get();
+ break;
+ case MODULUS:
+ type = ModulusResolver.checkConditions(types).get();
+ break;
+ default:
+ throw new UnsupportedOperationException(
+ String.format(UNSUPPORTED_EXPRESSION, node.getOperator()));
+ }
+ TSDataType tsDataType = InternalTypeManager.getTSDataType(type);
IdentityColumnTransformer identity =
new IdentityColumnTransformer(
- DOUBLE, context.originSize +
context.commonTransformerList.size());
+ type, context.originSize +
context.commonTransformerList.size());
ColumnTransformer columnTransformer = context.hasSeen.get(node);
columnTransformer.addReferenceCount();
context.commonTransformerList.add(columnTransformer);
context.leafList.add(identity);
- context.inputDataTypes.add(TSDataType.DOUBLE);
+ context.inputDataTypes.add(tsDataType);
context.cache.put(node, identity);
} else {
+ ZoneId zoneId = context.sessionInfo.getZoneId();
ColumnTransformer left = process(node.getLeft(), context);
ColumnTransformer right = process(node.getRight(), context);
ColumnTransformer child;
switch (node.getOperator()) {
case ADD:
- child = new ArithmeticAdditionColumnTransformer(DOUBLE, left,
right);
+ child =
ArithmeticColumnTransformerApi.getAdditionTransformer(left, right, zoneId);
break;
case SUBTRACT:
- child = new ArithmeticSubtractionColumnTransformer(DOUBLE, left,
right);
+ child =
ArithmeticColumnTransformerApi.getSubtractionTransformer(left, right, zoneId);
break;
case MULTIPLY:
- child = new ArithmeticMultiplicationColumnTransformer(DOUBLE,
left, right);
+ child =
+
ArithmeticColumnTransformerApi.getMultiplicationTransformer(left, right,
zoneId);
break;
case DIVIDE:
- child = new ArithmeticDivisionColumnTransformer(DOUBLE, left,
right);
+ child =
ArithmeticColumnTransformerApi.getDivisionTransformer(left, right, zoneId);
break;
case MODULUS:
- child = new ArithmeticModuloColumnTransformer(DOUBLE, left, right);
+ child = ArithmeticColumnTransformerApi.getModulusTransformer(left,
right, zoneId);
break;
default:
throw new UnsupportedOperationException(
@@ -257,7 +287,8 @@ public class ColumnTransformerBuilder
} else {
ColumnTransformer childColumnTransformer =
process(node.getValue(), context);
context.cache.put(
- node, new ArithmeticNegationColumnTransformer(DOUBLE,
childColumnTransformer));
+ node,
+
ArithmeticColumnTransformerApi.getNegationTransformer(childColumnTransformer));
}
}
ColumnTransformer res = context.cache.get(node);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/multi/builtin/helper/CastFunctionHelper.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/multi/builtin/helper/CastFunctionHelper.java
index 32e3df941d2..9a610ba05fc 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/multi/builtin/helper/CastFunctionHelper.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/expression/multi/builtin/helper/CastFunctionHelper.java
@@ -175,7 +175,7 @@ public class CastFunctionHelper implements
BuiltInScalarFunctionHelper {
return castInt(intV, targetType);
case DATE:
int dateV = value instanceof Integer ? (int) value : ((Long)
value).intValue();
- return castDate(dateV, targetType);
+ return castDate(dateV, targetType, session.getZoneId());
case INT64:
long longV = (Long) value;
return castLong(longV, targetType);
@@ -226,7 +226,7 @@ public class CastFunctionHelper implements
BuiltInScalarFunctionHelper {
}
}
- private static Object castDate(int value, Type targetType) {
+ private static Object castDate(int value, Type targetType, ZoneId zoneId) {
switch (targetType.getTypeEnum()) {
case INT32:
case DATE:
@@ -234,7 +234,7 @@ public class CastFunctionHelper implements
BuiltInScalarFunctionHelper {
case INT64:
return (long) value;
case TIMESTAMP:
- return
DateTimeUtils.correctPrecision(DateUtils.parseIntToDate(value).getTime());
+ return
DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(value, zoneId));
case FLOAT:
return (float) value;
case DOUBLE:
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java
new file mode 100644
index 00000000000..b3d1836e687
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/AdditionResolver.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed 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.db.queryengine.plan.relational.function.arithmetic;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.tsfile.read.common.type.DateType.DATE;
+import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
+import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
+import static org.apache.tsfile.read.common.type.IntType.INT32;
+import static org.apache.tsfile.read.common.type.LongType.INT64;
+import static org.apache.tsfile.read.common.type.TimestampType.TIMESTAMP;
+
+public class AdditionResolver {
+
+ private static final Map<Type, Map<Type, Type>> CONDITION_MAP = new
HashMap<>();
+
+ static {
+ addCondition(INT32, INT32, INT32);
+ addCondition(INT32, INT64, INT64);
+ addCondition(INT32, FLOAT, FLOAT);
+ addCondition(INT32, DOUBLE, DOUBLE);
+ addCondition(INT32, DATE, DATE);
+ addCondition(INT32, TIMESTAMP, TIMESTAMP);
+
+ addCondition(INT64, INT32, INT64);
+ addCondition(INT64, INT64, INT64);
+ addCondition(INT64, FLOAT, FLOAT);
+ addCondition(INT64, DOUBLE, DOUBLE);
+ addCondition(INT64, DATE, DATE);
+ addCondition(INT64, TIMESTAMP, TIMESTAMP);
+
+ addCondition(FLOAT, INT32, FLOAT);
+ addCondition(FLOAT, INT64, FLOAT);
+ addCondition(FLOAT, FLOAT, FLOAT);
+ addCondition(FLOAT, DOUBLE, DOUBLE);
+
+ addCondition(DOUBLE, INT32, DOUBLE);
+ addCondition(DOUBLE, INT64, DOUBLE);
+ addCondition(DOUBLE, FLOAT, DOUBLE);
+ addCondition(DOUBLE, DOUBLE, DOUBLE);
+
+ addCondition(DATE, INT32, DATE);
+ addCondition(DATE, INT64, DATE);
+
+ addCondition(TIMESTAMP, INT32, TIMESTAMP);
+ addCondition(TIMESTAMP, INT64, TIMESTAMP);
+ }
+
+ private static void addCondition(Type condition1, Type condition2, Type
result) {
+ CONDITION_MAP.computeIfAbsent(condition1, k -> new
HashMap<>()).put(condition2, result);
+ }
+
+ public static Optional<Type> checkConditions(List<? extends Type>
argumentTypes) {
+ return Optional.ofNullable(
+ CONDITION_MAP
+ .getOrDefault(argumentTypes.get(0), Collections.emptyMap())
+ .getOrDefault(argumentTypes.get(1), null));
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java
new file mode 100644
index 00000000000..0d6bf4664ec
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/DivisionResolver.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed 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.db.queryengine.plan.relational.function.arithmetic;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
+import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
+import static org.apache.tsfile.read.common.type.IntType.INT32;
+import static org.apache.tsfile.read.common.type.LongType.INT64;
+
+public class DivisionResolver {
+
+ private static final Map<Type, Map<Type, Type>> CONDITION_MAP = new
HashMap<>();
+
+ static {
+ addCondition(INT32, INT32, INT32);
+ addCondition(INT32, INT64, INT64);
+ addCondition(INT32, FLOAT, FLOAT);
+ addCondition(INT32, DOUBLE, DOUBLE);
+
+ addCondition(INT64, INT32, INT64);
+ addCondition(INT64, INT64, INT64);
+ addCondition(INT64, FLOAT, FLOAT);
+ addCondition(INT64, DOUBLE, DOUBLE);
+
+ addCondition(FLOAT, INT32, FLOAT);
+ addCondition(FLOAT, INT64, FLOAT);
+ addCondition(FLOAT, FLOAT, FLOAT);
+ addCondition(FLOAT, DOUBLE, DOUBLE);
+
+ addCondition(DOUBLE, INT32, DOUBLE);
+ addCondition(DOUBLE, INT64, DOUBLE);
+ addCondition(DOUBLE, FLOAT, DOUBLE);
+ addCondition(DOUBLE, DOUBLE, DOUBLE);
+ }
+
+ private static void addCondition(Type condition1, Type condition2, Type
result) {
+ CONDITION_MAP.computeIfAbsent(condition1, k -> new
HashMap<>()).put(condition2, result);
+ }
+
+ public static Optional<Type> checkConditions(List<? extends Type>
argumentTypes) {
+ return Optional.ofNullable(
+ CONDITION_MAP
+ .getOrDefault(argumentTypes.get(0), Collections.emptyMap())
+ .getOrDefault(argumentTypes.get(1), null));
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java
new file mode 100644
index 00000000000..c0e77765520
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/ModulusResolver.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed 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.db.queryengine.plan.relational.function.arithmetic;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
+import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
+import static org.apache.tsfile.read.common.type.IntType.INT32;
+import static org.apache.tsfile.read.common.type.LongType.INT64;
+
+public class ModulusResolver {
+
+ private static final Map<Type, Map<Type, Type>> CONDITION_MAP = new
HashMap<>();
+
+ static {
+ addCondition(INT32, INT32, INT32);
+ addCondition(INT32, INT64, INT64);
+ addCondition(INT32, FLOAT, FLOAT);
+ addCondition(INT32, DOUBLE, DOUBLE);
+
+ addCondition(INT64, INT32, INT64);
+ addCondition(INT64, INT64, INT64);
+ addCondition(INT64, FLOAT, FLOAT);
+ addCondition(INT64, DOUBLE, DOUBLE);
+
+ addCondition(FLOAT, INT32, FLOAT);
+ addCondition(FLOAT, INT64, FLOAT);
+ addCondition(FLOAT, FLOAT, FLOAT);
+ addCondition(FLOAT, DOUBLE, DOUBLE);
+
+ addCondition(DOUBLE, INT32, DOUBLE);
+ addCondition(DOUBLE, INT64, DOUBLE);
+ addCondition(DOUBLE, FLOAT, DOUBLE);
+ addCondition(DOUBLE, DOUBLE, DOUBLE);
+ }
+
+ private static void addCondition(Type condition1, Type condition2, Type
result) {
+ CONDITION_MAP.computeIfAbsent(condition1, k -> new
HashMap<>()).put(condition2, result);
+ }
+
+ public static Optional<Type> checkConditions(List<? extends Type>
argumentTypes) {
+ return Optional.ofNullable(
+ CONDITION_MAP
+ .getOrDefault(argumentTypes.get(0), Collections.emptyMap())
+ .getOrDefault(argumentTypes.get(1), null));
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java
new file mode 100644
index 00000000000..769e0172f8e
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/MultiplicationResolver.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed 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.db.queryengine.plan.relational.function.arithmetic;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
+import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
+import static org.apache.tsfile.read.common.type.IntType.INT32;
+import static org.apache.tsfile.read.common.type.LongType.INT64;
+
+public class MultiplicationResolver {
+
+ private static final Map<Type, Map<Type, Type>> CONDITION_MAP = new
HashMap<>();
+
+ static {
+ addCondition(INT32, INT32, INT32);
+ addCondition(INT32, INT64, INT64);
+ addCondition(INT32, FLOAT, FLOAT);
+ addCondition(INT32, DOUBLE, DOUBLE);
+
+ addCondition(INT64, INT32, INT64);
+ addCondition(INT64, INT64, INT64);
+ addCondition(INT64, FLOAT, FLOAT);
+ addCondition(INT64, DOUBLE, DOUBLE);
+
+ addCondition(FLOAT, INT32, FLOAT);
+ addCondition(FLOAT, INT64, FLOAT);
+ addCondition(FLOAT, FLOAT, FLOAT);
+ addCondition(FLOAT, DOUBLE, DOUBLE);
+
+ addCondition(DOUBLE, INT32, DOUBLE);
+ addCondition(DOUBLE, INT64, DOUBLE);
+ addCondition(DOUBLE, FLOAT, DOUBLE);
+ addCondition(DOUBLE, DOUBLE, DOUBLE);
+ }
+
+ private static void addCondition(Type condition1, Type condition2, Type
result) {
+ CONDITION_MAP.computeIfAbsent(condition1, k -> new
HashMap<>()).put(condition2, result);
+ }
+
+ public static Optional<Type> checkConditions(List<? extends Type>
argumentTypes) {
+ return Optional.ofNullable(
+ CONDITION_MAP
+ .getOrDefault(argumentTypes.get(0), Collections.emptyMap())
+ .getOrDefault(argumentTypes.get(1), null));
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java
new file mode 100644
index 00000000000..5b7f4a79022
--- /dev/null
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/function/arithmetic/SubtractionResolver.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed 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.db.queryengine.plan.relational.function.arithmetic;
+
+import org.apache.tsfile.read.common.type.Type;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.apache.tsfile.read.common.type.DateType.DATE;
+import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
+import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
+import static org.apache.tsfile.read.common.type.IntType.INT32;
+import static org.apache.tsfile.read.common.type.LongType.INT64;
+import static org.apache.tsfile.read.common.type.TimestampType.TIMESTAMP;
+
+public class SubtractionResolver {
+
+ private static final Map<Type, Map<Type, Type>> CONDITION_MAP = new
HashMap<>();
+
+ static {
+ addCondition(INT32, INT32, INT32);
+ addCondition(INT32, INT64, INT64);
+ addCondition(INT32, FLOAT, FLOAT);
+ addCondition(INT32, DOUBLE, DOUBLE);
+
+ addCondition(INT64, INT32, INT64);
+ addCondition(INT64, INT64, INT64);
+ addCondition(INT64, FLOAT, FLOAT);
+ addCondition(INT64, DOUBLE, DOUBLE);
+
+ addCondition(FLOAT, INT32, FLOAT);
+ addCondition(FLOAT, INT64, FLOAT);
+ addCondition(FLOAT, FLOAT, FLOAT);
+ addCondition(FLOAT, DOUBLE, DOUBLE);
+
+ addCondition(DOUBLE, INT32, DOUBLE);
+ addCondition(DOUBLE, INT64, DOUBLE);
+ addCondition(DOUBLE, FLOAT, DOUBLE);
+ addCondition(DOUBLE, DOUBLE, DOUBLE);
+
+ addCondition(DATE, INT32, DATE);
+ addCondition(DATE, INT64, DATE);
+
+ addCondition(TIMESTAMP, INT32, TIMESTAMP);
+ addCondition(TIMESTAMP, INT64, TIMESTAMP);
+ }
+
+ private static void addCondition(Type condition1, Type condition2, Type
result) {
+ CONDITION_MAP.computeIfAbsent(condition1, k -> new
HashMap<>()).put(condition2, result);
+ }
+
+ public static Optional<Type> checkConditions(List<? extends Type>
argumentTypes) {
+ return Optional.ofNullable(
+ CONDITION_MAP
+ .getOrDefault(argumentTypes.get(0), Collections.emptyMap())
+ .getOrDefault(argumentTypes.get(1), null));
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index 04b03e12dce..8f4d1e23eb0 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -30,6 +30,11 @@ import org.apache.iotdb.db.queryengine.common.SessionInfo;
import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher;
import org.apache.iotdb.db.queryengine.plan.analyze.IPartitionFetcher;
import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.AdditionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.DivisionResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.ModulusResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.MultiplicationResolver;
+import
org.apache.iotdb.db.queryengine.plan.relational.function.arithmetic.SubtractionResolver;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaFetcher;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableDeviceSchemaValidator;
import
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.TableHeaderSchemaValidator;
@@ -59,6 +64,7 @@ import static
org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT;
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
import static org.apache.tsfile.read.common.type.BinaryType.TEXT;
import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN;
+import static org.apache.tsfile.read.common.type.DateType.DATE;
import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
import static org.apache.tsfile.read.common.type.IntType.INT32;
@@ -104,25 +110,58 @@ public class TableMetadataImpl implements Metadata {
switch (operatorType) {
case ADD:
+ if (!isTwoTypeCalculable(argumentTypes)
+ || !AdditionResolver.checkConditions(argumentTypes).isPresent()) {
+ throw new OperatorNotFoundException(
+ operatorType,
+ argumentTypes,
+ new IllegalArgumentException("Should have two numeric
operands."));
+ }
+ return AdditionResolver.checkConditions(argumentTypes).get();
case SUBTRACT:
+ if (!isTwoTypeCalculable(argumentTypes)
+ ||
!SubtractionResolver.checkConditions(argumentTypes).isPresent()) {
+ throw new OperatorNotFoundException(
+ operatorType,
+ argumentTypes,
+ new IllegalArgumentException("Should have two numeric
operands."));
+ }
+ return SubtractionResolver.checkConditions(argumentTypes).get();
case MULTIPLY:
+ if (!isTwoTypeCalculable(argumentTypes)
+ ||
!MultiplicationResolver.checkConditions(argumentTypes).isPresent()) {
+ throw new OperatorNotFoundException(
+ operatorType,
+ argumentTypes,
+ new IllegalArgumentException("Should have two numeric
operands."));
+ }
+ return MultiplicationResolver.checkConditions(argumentTypes).get();
case DIVIDE:
+ if (!isTwoTypeCalculable(argumentTypes)
+ || !DivisionResolver.checkConditions(argumentTypes).isPresent()) {
+ throw new OperatorNotFoundException(
+ operatorType,
+ argumentTypes,
+ new IllegalArgumentException("Should have two numeric
operands."));
+ }
+ return DivisionResolver.checkConditions(argumentTypes).get();
case MODULUS:
- if (!isTwoNumericType(argumentTypes)) {
+ if (!isTwoTypeCalculable(argumentTypes)
+ || !ModulusResolver.checkConditions(argumentTypes).isPresent()) {
throw new OperatorNotFoundException(
operatorType,
argumentTypes,
new IllegalArgumentException("Should have two numeric
operands."));
}
- return DOUBLE;
+ return ModulusResolver.checkConditions(argumentTypes).get();
case NEGATION:
- if (!isOneNumericType(argumentTypes)) {
+ if (!isOneNumericType(argumentTypes) &&
!isTimestampType(argumentTypes.get(0))) {
throw new OperatorNotFoundException(
operatorType,
argumentTypes,
new IllegalArgumentException("Should have one numeric
operands."));
}
- return DOUBLE;
+ return argumentTypes.get(0);
case EQUAL:
case LESS_THAN:
case LESS_THAN_OR_EQUAL:
@@ -745,4 +784,22 @@ public class TableMetadataImpl implements Metadata {
// Boolean type and Binary Type can not be compared with other types
return (isNumericType(left) && isNumericType(right)) || (isCharType(left)
&& isCharType(right));
}
+
+ public static boolean isArithmeticType(Type type) {
+ return INT32.equals(type)
+ || INT64.equals(type)
+ || FLOAT.equals(type)
+ || DOUBLE.equals(type)
+ || DATE.equals(type)
+ || TIMESTAMP.equals(type);
+ }
+
+ public static boolean isTwoTypeCalculable(List<? extends Type>
argumentTypes) {
+ if (argumentTypes.size() != 2) {
+ return false;
+ }
+ Type left = argumentTypes.get(0);
+ Type right = argumentTypes.get(1);
+ return isArithmeticType(left) && isArithmeticType(right);
+ }
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
index 8a3c02fd1ae..b1f15a6af2d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/unary/scalar/CastFunctionColumnTransformer.java
@@ -137,7 +137,7 @@ public class CastFunctionColumnTransformer extends
UnaryColumnTransformer {
case TIMESTAMP:
returnType.writeLong(
columnBuilder,
-
DateTimeUtils.correctPrecision(DateUtils.parseIntToDate(value).getTime()));
+
DateTimeUtils.correctPrecision(DateUtils.parseIntToTimestamp(value, zoneId)));
break;
case FLOAT:
returnType.writeFloat(columnBuilder, value);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
index 2ac49494acd..f527d068ee1 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.utils;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.IoTDBException;
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
import org.apache.iotdb.db.exception.BatchProcessException;
import org.apache.iotdb.db.exception.QueryInBatchStatementException;
import org.apache.iotdb.db.exception.StorageGroupNotReadyException;
@@ -152,6 +153,8 @@ public class ErrorHandlingUtils {
((IoTDBException) t.getCause()).getErrorCode(),
rootCause.getMessage());
}
return RpcUtils.getStatus(TSStatusCode.SEMANTIC_ERROR,
rootCause.getMessage());
+ } else if (t instanceof IoTDBRuntimeException) {
+ return RpcUtils.getStatus(((IoTDBRuntimeException) t).getErrorCode(),
t.getMessage());
} else if (t instanceof MemoryNotEnoughException) {
return RpcUtils.getStatus(TSStatusCode.QUOTA_MEM_QUERY_NOT_ENOUGH,
rootCause.getMessage());
}
diff --git a/pom.xml b/pom.xml
index eae203cc7e5..a1713a76d7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -166,7 +166,7 @@
<thrift.version>0.14.1</thrift.version>
<xz.version>1.9</xz.version>
<zstd-jni.version>1.5.6-3</zstd-jni.version>
- <tsfile.version>1.2.0-efc8f71d-SNAPSHOT</tsfile.version>
+ <tsfile.version>1.2.0-0c274ae2-SNAPSHOT</tsfile.version>
</properties>
<!--
if we claim dependencies in dependencyManagement, then we do not claim