From e5dacc08fcfe5b153405212996212eda2230f840 Mon Sep 17 00:00:00 2001 From: FearfulTomcat27 <1471335448@qq.com> Date: Tue, 11 Feb 2025 09:24:19 +0800 Subject: [PATCH] Add Greatest and Least Comparison functions --- .../old/query/IoTDBGreatestLeastTableIT.java | 305 ++++++++++++++++++ .../relational/ColumnTransformerBuilder.java | 15 + .../metadata/TableMetadataImpl.java | 20 ++ ...bstractGreatestLeastColumnTransformer.java | 109 +++++++ .../BinaryGreatestColumnTransformer.java | 53 +++ .../multi/BinaryLeastColumnTransformer.java | 53 +++ .../BooleanGreatestColumnTransformer.java | 52 +++ .../multi/BooleanLeastColumnTransformer.java | 49 +++ .../DoubleGreatestColumnTransformer.java | 52 +++ .../multi/DoubleLeastColumnTransformer.java | 52 +++ .../multi/FloatGreatestColumnTransformer.java | 52 +++ .../multi/FloatLeastColumnTransformer.java | 52 +++ .../multi/Int32GreatestColumnTransformer.java | 52 +++ .../multi/Int32LeastColumnTransformer.java | 52 +++ .../multi/Int64GreatestColumnTransformer.java | 52 +++ .../multi/Int64LeastColumnTransformer.java | 52 +++ .../TableBuiltinScalarFunction.java | 2 + 17 files changed, 1074 insertions(+) create mode 100644 integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBGreatestLeastTableIT.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/AbstractGreatestLeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryGreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryLeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanGreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanLeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleGreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleLeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatGreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatLeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32GreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32LeastColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64GreatestColumnTransformer.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64LeastColumnTransformer.java diff --git a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBGreatestLeastTableIT.java b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBGreatestLeastTableIT.java new file mode 100644 index 000000000000..529b4daeabe8 --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/query/IoTDBGreatestLeastTableIT.java @@ -0,0 +1,305 @@ +/* + * 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.relational.it.query.old.query; + +import org.apache.iotdb.it.env.EnvFactory; +import org.apache.iotdb.it.framework.IoTDBTestRunner; +import org.apache.iotdb.itbase.category.TableClusterIT; +import org.apache.iotdb.itbase.category.TableLocalStandaloneIT; +import org.apache.iotdb.itbase.env.BaseEnv; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import java.sql.Connection; +import java.sql.Statement; + +import static org.apache.iotdb.db.it.utils.TestUtils.tableAssertTestFail; +import static org.apache.iotdb.db.it.utils.TestUtils.tableResultSetEqualTest; + +@RunWith(IoTDBTestRunner.class) +@Category({TableLocalStandaloneIT.class, TableClusterIT.class}) +public class IoTDBGreatestLeastTableIT { + + private static final String DATABASE_NAME = "db"; + + private static final String[] SQLs = + new String[] { + "CREATE DATABASE " + DATABASE_NAME, + "USE " + DATABASE_NAME, + "CREATE TABLE boolean_table(device_id STRING TAG, bool1 BOOLEAN FIELD, bool2 BOOLEAN FIELD)", + "CREATE TABLE number_table(device_id STRING TAG, int1 INT32 FIELD, int2 INT32 FIELD, long1 INT64 FIELD, long2 INT64 FIELD, float1 FLOAT FIELD, float2 FLOAT FIELD, double1 DOUBLE FIELD, double2 DOUBLE FIELD)", + "CREATE TABLE string_table(device_id STRING TAG, string1 STRING FIELD, string2 STRING FIELD, text1 TEXT FIELD, text2 TEXT FIELD)", + "CREATE TABLE mix_type_table(device_id STRING TAG, s1 INT32 FIELD, s2 INT64 FIELD, s3 FLOAT FIELD, s4 DOUBLE FIELD, s5 BOOLEAN FIELD, s6 STRING FIELD, s7 TEXT FIELD)", + "CREATE TABLE null_table(device_id STRING TAG, string1 STRING FIELD, string2 STRING FIELD, int1 INT32 FIELD, int2 INT32 FIELD, double1 DOUBLE FIELD, double2 DOUBLE FIELD, timestamp1 TIMESTAMP FIELD, timestamp2 TIMESTAMP FIELD)", + "CREATE TABLE any_null_table(device_id STRING TAG, string1 STRING FIELD, string2 STRING FIELD, int1 INT32 FIELD, int2 INT32 FIELD, double1 DOUBLE FIELD, double2 DOUBLE FIELD, timestamp1 TIMESTAMP FIELD, timestamp2 TIMESTAMP FIELD)", + // normal case + "INSERT INTO number_table(time, device_id, int1, int2, long1, long2, float1, float2, double1, double2) VALUES (10, 'd1', 1000000, 2000000, 1000000, 2000000, 10.1, 20.2, 10.1, 20.2)", + "INSERT INTO string_table(time, device_id, string1, string2, text1, text2) VALUES(10, 'd1', 'aaa', 'bbb', 'aaa', 'bbb')", + "INSERT INTO boolean_table(time, device_id, bool1, bool2) VALUES(10, 'd1', true, false)", + "INSERT INTO mix_type_table(time, device_id, s1, s2, s3, s4, s5, s6, s7) VALUES(10, 'd1', 1, 1, 1.0, 1.0, true, 'a', 'a')", + "INSERT INTO null_table(time, device_id) VALUES(10, 'd1')", + "INSERT INTO any_null_table(time, device_id, string2, int2, double2, timestamp2) VALUES(10, 'd1', 'test', 10, 10.0, 10)", + }; + + @BeforeClass + public static void setUp() throws Exception { + EnvFactory.getEnv().initClusterEnvironment(); + insertData(); + } + + protected static void insertData() { + try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT); + Statement statement = connection.createStatement()) { + + for (String sql : SQLs) { + statement.execute(sql); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + @AfterClass + public static void tearDown() throws Exception { + EnvFactory.getEnv().cleanClusterEnvironment(); + } + + @Test + public void testNumberTypeGreatestFunction() { + + tableResultSetEqualTest( + "SELECT GREATEST(int1, int2) FROM number_table", + new String[] {"_col0"}, + new String[] {"2000000,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(long1, long2) FROM number_table", + new String[] {"_col0"}, + new String[] {"2000000,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(float1, float2) FROM number_table", + new String[] {"_col0"}, + new String[] {"20.2,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(double1, double2) FROM number_table", + new String[] {"_col0"}, + new String[] {"20.2,"}, + DATABASE_NAME); + } + + @Test + public void testNumberTypeLeastFunction() { + tableResultSetEqualTest( + "SELECT LEAST(int1, int2) FROM number_table", + new String[] {"_col0"}, + new String[] {"1000000,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(long1, long2) FROM number_table", + new String[] {"_col0"}, + new String[] {"1000000,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(float1, float2) FROM number_table", + new String[] {"_col0"}, + new String[] {"10.1,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(double1, double2) FROM number_table", + new String[] {"_col0"}, + new String[] {"10.1,"}, + DATABASE_NAME); + } + + @Test + public void testStringTypeGreatestFunction() { + tableResultSetEqualTest( + "SELECT GREATEST(string1, string2) FROM string_table", + new String[] {"_col0"}, + new String[] {"bbb,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(text1, text2) FROM string_table", + new String[] {"_col0"}, + new String[] {"bbb,"}, + DATABASE_NAME); + } + + @Test + public void testStringTypeLeastFunction() { + tableResultSetEqualTest( + "SELECT LEAST(string1, string2) FROM string_table", + new String[] {"_col0"}, + new String[] {"aaa,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(text1, text2) FROM string_table", + new String[] {"_col0"}, + new String[] {"aaa,"}, + DATABASE_NAME); + } + + @Test + public void testBooleanTypeGreatestFunction() { + tableResultSetEqualTest( + "SELECT GREATEST(bool1, bool2) FROM boolean_table", + new String[] {"_col0"}, + new String[] {"true,"}, + DATABASE_NAME); + } + + @Test + public void testBooleanTypeLeastFunction() { + tableResultSetEqualTest( + "SELECT LEAST(bool1, bool2) FROM boolean_table", + new String[] {"_col0"}, + new String[] {"false,"}, + DATABASE_NAME); + } + + @Test + public void testAllNullValue() { + tableResultSetEqualTest( + "SELECT GREATEST(string1, string2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(string1, string2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(int1, int2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(int1, int2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(double1, double2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(double1, double2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(timestamp1, timestamp2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(timestamp1, timestamp2) FROM null_table", + new String[] {"_col0"}, + new String[] {"null,"}, + DATABASE_NAME); + } + + @Test + public void testAnyNullValue() { + tableResultSetEqualTest( + "SELECT GREATEST(string1, string2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"test,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(string1, string2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"test,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(int1, int2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"10,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(int1, int2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"10,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(double1, double2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"10.0,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(double1, double2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"10.0,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT GREATEST(timestamp1, timestamp2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"1970-01-01T00:00:00.010Z,"}, + DATABASE_NAME); + + tableResultSetEqualTest( + "SELECT LEAST(timestamp1, timestamp2) FROM any_null_table", + new String[] {"_col0"}, + new String[] {"1970-01-01T00:00:00.010Z,"}, + DATABASE_NAME); + } + + @Test + public void testAnomalies() { + // do not support different type + for (int i = 1; i <= 7; i++) { + for (int j = i + 1; j <= 7; j++) { + tableAssertTestFail( + String.format("SELECT LEAST(s%d, s%d) FROM mix_type_table", i, j), + "701: Scalar function least must have at least two arguments, and all type must be the same.", + DATABASE_NAME); + + tableAssertTestFail( + String.format("SELECT GREATEST(s%d, s%d) FROM mix_type_table", i, j), + "701: Scalar function greatest must have at least two arguments, and all type must be the same.", + DATABASE_NAME); + } + } + } +} 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 ce69b23c3bcf..badd487b5fe2 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 @@ -86,6 +86,7 @@ import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.LeafColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.TimeColumnTransformer; +import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.AbstractGreatestLeastColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.CoalesceColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBinaryMultiColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBooleanMultiColumnTransformer; @@ -977,6 +978,20 @@ private ColumnTransformer getFunctionColumnTransformer( } return new FormatColumnTransformer( STRING, columnTransformers, context.sessionInfo.getZoneId()); + } else if (TableBuiltinScalarFunction.GREATEST + .getFunctionName() + .equalsIgnoreCase(functionName)) { + List columnTransformers = + children.stream().map(child -> this.process(child, context)).collect(Collectors.toList()); + Type returnType = columnTransformers.get(0).getType(); + return AbstractGreatestLeastColumnTransformer.getGreatestColumnTransformer( + returnType, columnTransformers); + } else if (TableBuiltinScalarFunction.LEAST.getFunctionName().equalsIgnoreCase(functionName)) { + List columnTransformers = + children.stream().map(child -> this.process(child, context)).collect(Collectors.toList()); + Type returnType = columnTransformers.get(0).getType(); + return AbstractGreatestLeastColumnTransformer.getLeastColumnTransformer( + returnType, columnTransformers); } else { // user defined function if (TableUDFUtils.isScalarFunction(functionName)) { 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 607b1c371355..8364ea489b36 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 @@ -541,6 +541,15 @@ && isIntegerNumber(argumentTypes.get(2)))) { + " must have at least two arguments, and first argument must be char type."); } return STRING; + } else if (TableBuiltinScalarFunction.GREATEST.getFunctionName().equalsIgnoreCase(functionName) + || TableBuiltinScalarFunction.LEAST.getFunctionName().equalsIgnoreCase(functionName)) { + if (argumentTypes.size() < 2 || !areAllTypesSameAndComparable(argumentTypes)) { + throw new SemanticException( + "Scalar function " + + functionName.toLowerCase(Locale.ENGLISH) + + " must have at least two arguments, and all type must be the same."); + } + return argumentTypes.get(0); } // builtin aggregation function @@ -884,6 +893,17 @@ public static boolean isTwoTypeComparable(List argumentTypes) { || ((isNumericType(left) || isCharType(left)) && isUnknownType(right)); } + public static boolean areAllTypesSameAndComparable(List argumentTypes) { + if (argumentTypes == null || argumentTypes.isEmpty()) { + return true; + } + Type firstType = argumentTypes.get(0); + if (!firstType.isComparable()) { + return false; + } + return argumentTypes.stream().allMatch(type -> type.equals(firstType)); + } + public static boolean isArithmeticType(Type type) { return INT32.equals(type) || INT64.equals(type) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/AbstractGreatestLeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/AbstractGreatestLeastColumnTransformer.java new file mode 100644 index 000000000000..f92c5fa2811e --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/AbstractGreatestLeastColumnTransformer.java @@ -0,0 +1,109 @@ +/* + * 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.transformation.dag.column.multi; + +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 org.apache.tsfile.read.common.type.TypeEnum; + +import java.util.List; + +public abstract class AbstractGreatestLeastColumnTransformer extends MultiColumnTransformer { + + protected AbstractGreatestLeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void doTransform( + List childrenColumns, ColumnBuilder builder, int positionCount) { + for (int i = 0; i < positionCount; i++) { + transform(builder, childrenColumns, i); + } + } + + @Override + protected void doTransform( + List childrenColumns, ColumnBuilder builder, int positionCount, boolean[] selection) { + for (int i = 0; i < positionCount; i++) { + if (selection[i]) { + transform(builder, childrenColumns, i); + } else { + builder.appendNull(); + } + } + } + + protected abstract void transform(ColumnBuilder builder, List childrenColumns, int index); + + public static ColumnTransformer getGreatestColumnTransformer( + Type type, List columnTransformers) { + TypeEnum typeEnum = type.getTypeEnum(); + switch (typeEnum) { + case BOOLEAN: + return new BooleanGreatestColumnTransformer(type, columnTransformers); + case INT32: + case DATE: + return new Int32GreatestColumnTransformer(type, columnTransformers); + case INT64: + case TIMESTAMP: + return new Int64GreatestColumnTransformer(type, columnTransformers); + case FLOAT: + return new FloatGreatestColumnTransformer(type, columnTransformers); + case DOUBLE: + return new DoubleGreatestColumnTransformer(type, columnTransformers); + case STRING: + case TEXT: + return new BinaryGreatestColumnTransformer(type, columnTransformers); + default: + throw new UnsupportedOperationException( + String.format("Unsupported data type: %s", typeEnum)); + } + } + + public static ColumnTransformer getLeastColumnTransformer( + Type type, List columnTransformers) { + TypeEnum typeEnum = type.getTypeEnum(); + switch (typeEnum) { + case BOOLEAN: + return new BooleanLeastColumnTransformer(type, columnTransformers); + case INT32: + case DATE: + return new Int32LeastColumnTransformer(type, columnTransformers); + case INT64: + case TIMESTAMP: + return new Int64LeastColumnTransformer(type, columnTransformers); + case FLOAT: + return new FloatLeastColumnTransformer(type, columnTransformers); + case DOUBLE: + return new DoubleLeastColumnTransformer(type, columnTransformers); + case STRING: + case TEXT: + return new BinaryLeastColumnTransformer(type, columnTransformers); + default: + throw new UnsupportedOperationException( + String.format("Unsupported data type: %s", typeEnum)); + } + } + + @Override + protected void checkType() { + // do nothing + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryGreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryGreatestColumnTransformer.java new file mode 100644 index 000000000000..e81487bbac3e --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryGreatestColumnTransformer.java @@ -0,0 +1,53 @@ +/* + * 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.transformation.dag.column.multi; + +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 org.apache.tsfile.utils.Binary; + +import java.util.List; + +public class BinaryGreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected BinaryGreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + Binary maxValue = firstColumn.getBinary(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + Binary value = column.getBinary(index); + if (allNull || value.compareTo(maxValue) > 0) { + allNull = false; + maxValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeBinary(builder, maxValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryLeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryLeastColumnTransformer.java new file mode 100644 index 000000000000..6cde29f4c845 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BinaryLeastColumnTransformer.java @@ -0,0 +1,53 @@ +/* + * 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.transformation.dag.column.multi; + +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 org.apache.tsfile.utils.Binary; + +import java.util.List; + +public class BinaryLeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected BinaryLeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + Binary minValue = firstColumn.getBinary(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + Binary value = column.getBinary(index); + if (allNull || value.compareTo(minValue) < 0) { + allNull = false; + minValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeBinary(builder, minValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanGreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanGreatestColumnTransformer.java new file mode 100644 index 000000000000..2bc56e6f5bc9 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanGreatestColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class BooleanGreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected BooleanGreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + boolean allNull = true; + for (Column column : childrenColumns) { + if (!column.isNull(index)) { + allNull = false; + if (column.getBoolean(index)) { + // find max value true + returnType.writeBoolean(builder, true); + break; + } + } + } + if (allNull) { + // all value are null return null + builder.appendNull(); + } else { + // do not have true, but have false + returnType.writeBoolean(builder, false); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanLeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanLeastColumnTransformer.java new file mode 100644 index 000000000000..4ea2b717092c --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/BooleanLeastColumnTransformer.java @@ -0,0 +1,49 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class BooleanLeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected BooleanLeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + boolean allNull = true; + for (Column column : childrenColumns) { + if (!column.isNull(index)) { + allNull = false; + if (!column.getBoolean(index)) { + returnType.writeBoolean(builder, false); + break; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeBoolean(builder, true); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleGreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleGreatestColumnTransformer.java new file mode 100644 index 000000000000..e09f0b6df4b2 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleGreatestColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class DoubleGreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected DoubleGreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + double maxValue = firstColumn.getDouble(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + double value = column.getDouble(index); + if (allNull || value > maxValue) { + allNull = false; + maxValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeDouble(builder, maxValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleLeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleLeastColumnTransformer.java new file mode 100644 index 000000000000..2dc19ec75e7a --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/DoubleLeastColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class DoubleLeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected DoubleLeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + double minValue = firstColumn.getDouble(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + double value = column.getDouble(index); + if (allNull || value < minValue) { + allNull = false; + minValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeDouble(builder, minValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatGreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatGreatestColumnTransformer.java new file mode 100644 index 000000000000..bc5bfc982f8c --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatGreatestColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class FloatGreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected FloatGreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + float maxValue = firstColumn.getFloat(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + float value = column.getFloat(index); + if (allNull || value > maxValue) { + allNull = false; + maxValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeFloat(builder, maxValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatLeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatLeastColumnTransformer.java new file mode 100644 index 000000000000..223f63673390 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/FloatLeastColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class FloatLeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected FloatLeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + float minValue = firstColumn.getFloat(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + float value = column.getFloat(index); + if (allNull || value < minValue) { + allNull = false; + minValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeFloat(builder, minValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32GreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32GreatestColumnTransformer.java new file mode 100644 index 000000000000..551970f470a6 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32GreatestColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class Int32GreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected Int32GreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + int maxValue = firstColumn.getInt(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + int value = column.getInt(index); + if (allNull || value > maxValue) { + allNull = false; + maxValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeInt(builder, maxValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32LeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32LeastColumnTransformer.java new file mode 100644 index 000000000000..26b64349fb4f --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int32LeastColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class Int32LeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected Int32LeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + int minValue = firstColumn.getInt(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + int value = column.getInt(index); + if (allNull || value < minValue) { + allNull = false; + minValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeInt(builder, minValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64GreatestColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64GreatestColumnTransformer.java new file mode 100644 index 000000000000..7818d217d0aa --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64GreatestColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class Int64GreatestColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected Int64GreatestColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + long maxValue = firstColumn.getLong(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + long value = column.getLong(index); + if (allNull || value > maxValue) { + allNull = false; + maxValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeLong(builder, maxValue); + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64LeastColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64LeastColumnTransformer.java new file mode 100644 index 000000000000..0efaccb37869 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/Int64LeastColumnTransformer.java @@ -0,0 +1,52 @@ +/* + * 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.transformation.dag.column.multi; + +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 java.util.List; + +public class Int64LeastColumnTransformer extends AbstractGreatestLeastColumnTransformer { + protected Int64LeastColumnTransformer( + Type returnType, List columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void transform(ColumnBuilder builder, List childrenColumns, int index) { + Column firstColumn = childrenColumns.get(0); + long minValue = firstColumn.getLong(index); + boolean allNull = firstColumn.isNull(index); + for (int i = 1; i < childrenColumns.size(); i++) { + Column column = childrenColumns.get(i); + if (!column.isNull(index)) { + long value = column.getLong(index); + if (allNull || value < minValue) { + allNull = false; + minValue = value; + } + } + } + if (allNull) { + builder.appendNull(); + } else { + returnType.writeLong(builder, minValue); + } + } +} diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/TableBuiltinScalarFunction.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/TableBuiltinScalarFunction.java index ee9b3d043b42..6d5b1ef4721a 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/TableBuiltinScalarFunction.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/builtin/relational/TableBuiltinScalarFunction.java @@ -65,6 +65,8 @@ public enum TableBuiltinScalarFunction { E("e"), DATE_BIN("date_bin"), FORMAT("format"), + GREATEST("greatest"), + LEAST("least"), ; private final String functionName;