This is an automated email from the ASF dual-hosted git repository. caogaofei pushed a commit to branch add_coalesce in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit ed85c44817ba64f4e73e1b76ef94c07c70ffaa2d Author: Beyyes <[email protected]> AuthorDate: Tue Sep 24 20:29:01 2024 +0800 add coalesce --- .../db/it/IoTDBMultiIDsWithAttributesTableIT.java | 19 ++++++++ .../relational/ColumnTransformerBuilder.java | 23 ++++++++- .../column/multi/CoalesceColumnTransformer.java | 57 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) 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 348aebc6b5b..75793e62998 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 @@ -389,6 +389,25 @@ public class IoTDBMultiIDsWithAttributesTableIT { DATABASE_NAME); } + @Test + public void coalesceTest() { + String[] expectedHeader = new String[] {"time", "level", "coalesce_attr2", "str"}; + String[] retArray = + new String[] { + "1970-01-01T00:00:00.040Z,l3,a,apricot,", + "1970-01-01T00:00:00.040Z,l3,CCC,apricot,", + "1970-01-01T00:00:00.020Z,l2,CCC,pineapple,", + "1970-01-01T00:00:00.020Z,l2,zz,pineapple,", + "1970-01-01T00:00:00.000Z,l1,d,coconut,", + "1970-01-01T00:00:00.000Z,l1,c,coconut,", + }; + tableResultSetEqualTest( + "select time,level,coalesce(attr2, 'CCC', 'DDD') as coalesce_attr2,str from table0 order by num+1,attr1 limit 6", + expectedHeader, + retArray, + DATABASE_NAME); + } + // ========== SubQuery Test ========= @Test public void subQueryTest1() { 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 f6b8099928f..5c449af0790 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 @@ -79,6 +79,7 @@ import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.IdentityCo 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.CoalesceColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBinaryMultiColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InBooleanMultiColumnTransformer; import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.InDoubleMultiColumnTransformer; @@ -1283,7 +1284,27 @@ public class ColumnTransformerBuilder @Override protected ColumnTransformer visitCoalesceExpression(CoalesceExpression node, Context context) { - throw new UnsupportedOperationException(String.format(UNSUPPORTED_EXPRESSION, node)); + if (!context.cache.containsKey(node)) { + if (context.hasSeen.containsKey(node)) { + ColumnTransformer columnTransformer = context.hasSeen.get(node); + IdentityColumnTransformer identity = + new IdentityColumnTransformer( + columnTransformer.getType(), + context.originSize + context.commonTransformerList.size()); + columnTransformer.addReferenceCount(); + context.commonTransformerList.add(columnTransformer); + context.leafList.add(identity); + context.inputDataTypes.add(getTSDataType(columnTransformer.getType())); + context.cache.put(node, identity); + } else { + List<ColumnTransformer> children = + node.getChildren().stream().map(c -> process(c, context)).collect(Collectors.toList()); + context.cache.put(node, new CoalesceColumnTransformer(children.get(0).getType(), children)); + } + } + ColumnTransformer res = context.cache.get(node); + res.addReferenceCount(); + return res; } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/CoalesceColumnTransformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/CoalesceColumnTransformer.java new file mode 100644 index 00000000000..c6f84fd8eef --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/transformation/dag/column/multi/CoalesceColumnTransformer.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.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 CoalesceColumnTransformer extends MultiColumnTransformer { + + public CoalesceColumnTransformer(Type returnType, List<ColumnTransformer> columnTransformerList) { + super(returnType, columnTransformerList); + } + + @Override + protected void doTransform( + List<Column> childrenColumns, ColumnBuilder builder, int positionCount) { + for (int i = 0; i < positionCount; i++) { + boolean allNull = true; + for (Column column : childrenColumns) { + if (!column.isNull(i)) { + allNull = false; + builder.write(column, i); + } + } + if (allNull) { + builder.appendNull(); + } + } + } + + @Override + protected void checkType() { + // do nothing, has checked in FE + } +}
