This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch force_ci/object_type in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 38033d5bc78011427306ea9218ae77001ecda80c Author: JackieTien97 <[email protected]> AuthorDate: Wed Nov 5 11:09:50 2025 +0800 Support In UDF Record --- .../main/java/org/apache/iotdb/ObjectExample.java | 148 --------------------- .../java/org/apache/iotdb/ObjectReadExample.java | 114 ---------------- .../org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java | 2 +- .../relational/metadata/TableMetadataImpl.java | 18 ++- .../iotdb/commons/udf/access/RecordIterator.java | 19 ++- 5 files changed, 29 insertions(+), 272 deletions(-) diff --git a/example/session/src/main/java/org/apache/iotdb/ObjectExample.java b/example/session/src/main/java/org/apache/iotdb/ObjectExample.java deleted file mode 100644 index 3339d3aae5a..00000000000 --- a/example/session/src/main/java/org/apache/iotdb/ObjectExample.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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; - -import org.apache.iotdb.isession.ITableSession; -import org.apache.iotdb.rpc.IoTDBConnectionException; -import org.apache.iotdb.rpc.StatementExecutionException; -import org.apache.iotdb.session.TableSessionBuilder; - -import org.apache.tsfile.enums.ColumnCategory; -import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.write.record.Tablet; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class ObjectExample { - private static final String LOCAL_URL = "127.0.0.1:6667"; - - public static void main(String[] args) { - - // don't specify database in constructor - try (ITableSession session = - new TableSessionBuilder() - .nodeUrls(Collections.singletonList(LOCAL_URL)) - .username("root") - .password("root") - .build()) { - session.executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS test1"); - session.executeNonQueryStatement("use test1"); - - // insert table data by tablet - List<String> columnNameList = - Arrays.asList("region_id", "plant_id", "device_id", "temperature", "file"); - List<TSDataType> dataTypeList = - Arrays.asList( - TSDataType.STRING, - TSDataType.STRING, - TSDataType.STRING, - TSDataType.FLOAT, - TSDataType.OBJECT); - List<ColumnCategory> columnTypeList = - new ArrayList<>( - Arrays.asList( - ColumnCategory.TAG, - ColumnCategory.TAG, - ColumnCategory.TAG, - ColumnCategory.FIELD, - ColumnCategory.FIELD)); - Tablet tablet = new Tablet("tsfile_table", columnNameList, dataTypeList, columnTypeList, 1); - int rowIndex = tablet.getRowSize(); - tablet.addTimestamp(rowIndex, 1); - tablet.addValue(rowIndex, 0, "1"); - tablet.addValue(rowIndex, 1, "5"); - tablet.addValue(rowIndex, 2, "3"); - tablet.addValue(rowIndex, 3, 37.6F); - tablet.addValue( - rowIndex, - 4, - true, - 0, - Files.readAllBytes( - Paths.get( - "/Users/jackietien/Downloads/2_1746622362350_fa24aa15233f4e76bcda789a5771f43f"))); - session.insert(tablet); - tablet.reset(); - - tablet = new Tablet("tsfile_table", columnNameList, dataTypeList, columnTypeList, 1); - rowIndex = tablet.getRowSize(); - tablet.addTimestamp(rowIndex, 2); - tablet.addValue(rowIndex, 0, "1"); - tablet.addValue(rowIndex, 1, "5"); - tablet.addValue(rowIndex, 2, "3"); - tablet.addValue(rowIndex, 3, 37.6F); - tablet.addValue( - rowIndex, - 4, - true, - 0, - Files.readAllBytes( - Paths.get( - "/Users/jackietien/Downloads/2_1746622367063_8fb5ac8e21724140874195b60b878664"))); - session.insert(tablet); - tablet.reset(); - - tablet = new Tablet("tiff_table", columnNameList, dataTypeList, columnTypeList, 1); - rowIndex = tablet.getRowSize(); - tablet.addTimestamp(rowIndex, 1); - tablet.addValue(rowIndex, 0, "1"); - tablet.addValue(rowIndex, 1, "5"); - tablet.addValue(rowIndex, 2, "3"); - tablet.addValue(rowIndex, 3, 37.6F); - tablet.addValue( - rowIndex, - 4, - true, - 0, - Files.readAllBytes(Paths.get("/Users/jackietien/Downloads/1751891240130.tiff"))); - session.insert(tablet); - tablet.reset(); - - tablet = new Tablet("tiff_table", columnNameList, dataTypeList, columnTypeList, 1); - rowIndex = tablet.getRowSize(); - tablet.addTimestamp(rowIndex, 2); - tablet.addValue(rowIndex, 0, "1"); - tablet.addValue(rowIndex, 1, "5"); - tablet.addValue(rowIndex, 2, "4"); - tablet.addValue(rowIndex, 3, 37.6F); - tablet.addValue( - rowIndex, - 4, - true, - 0, - Files.readAllBytes(Paths.get("/Users/jackietien/Downloads/1751891242743.tiff"))); - session.insert(tablet); - tablet.reset(); - - } catch (IoTDBConnectionException e) { - e.printStackTrace(); - } catch (StatementExecutionException e) { - e.printStackTrace(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/example/session/src/main/java/org/apache/iotdb/ObjectReadExample.java b/example/session/src/main/java/org/apache/iotdb/ObjectReadExample.java deleted file mode 100644 index 344939175db..00000000000 --- a/example/session/src/main/java/org/apache/iotdb/ObjectReadExample.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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; - -import org.apache.iotdb.isession.ITableSession; -import org.apache.iotdb.isession.SessionDataSet; -import org.apache.iotdb.rpc.IoTDBConnectionException; -import org.apache.iotdb.rpc.StatementExecutionException; -import org.apache.iotdb.session.TableSessionBuilder; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.tsfile.utils.Binary; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collections; - -public class ObjectReadExample { - private static final String LOCAL_URL = "127.0.0.1:6667"; - - public static void main(String[] args) { - - // don't specify database in constructor - try (ITableSession session = - new TableSessionBuilder() - .nodeUrls(Collections.singletonList(LOCAL_URL)) - .username("root") - .password("root") - .database("test1") - .thriftMaxFrameSize(256 * 1024 * 1024) - .build()) { - try (SessionDataSet dataSet = - session.executeQueryStatement( - "select READ_OBJECT(file) from tsfile_table where time = 1")) { - SessionDataSet.DataIterator iterator = dataSet.iterator(); - while (iterator.next()) { - Binary binary = iterator.getBlob(1); - System.out.println(DigestUtils.md5Hex(binary.getValues())); - } - } - - try (SessionDataSet dataSet = - session.executeQueryStatement( - "select READ_OBJECT(file) from tsfile_table where time = 2")) { - SessionDataSet.DataIterator iterator = dataSet.iterator(); - while (iterator.next()) { - Binary binary = iterator.getBlob(1); - System.out.println(DigestUtils.md5Hex(binary.getValues())); - } - } - - try (SessionDataSet dataSet = - session.executeQueryStatement("select READ_OBJECT(file) from tsfile_table")) { - SessionDataSet.DataIterator iterator = dataSet.iterator(); - while (iterator.next()) { - Binary binary = iterator.getBlob(1); - System.out.println(DigestUtils.md5Hex(binary.getValues())); - } - } - - try (SessionDataSet dataSet = - session.executeQueryStatement( - "select geo_penetrate(file, '0,3,7501,7504') from tsfile_table")) { - SessionDataSet.DataIterator iterator = dataSet.iterator(); - while (iterator.next()) { - Binary binary = iterator.getBlob(1); - ByteBuffer byteBuffer = ByteBuffer.wrap(binary.getValues()); - float[] res = new float[byteBuffer.limit() / Float.BYTES]; - for (int i = 0; i < res.length; i++) { - res[i] = byteBuffer.getFloat(); - } - System.out.println(Arrays.toString(res)); - } - } - - try (SessionDataSet dataSet = - session.executeQueryStatement( - "select geo_penetrate(file, '0,3,7501,7504', 'UNCOMPRESSED_TIFF') from tiff_table")) { - SessionDataSet.DataIterator iterator = dataSet.iterator(); - while (iterator.next()) { - Binary binary = iterator.getBlob(1); - ByteBuffer byteBuffer = ByteBuffer.wrap(binary.getValues()); - float[] res = new float[byteBuffer.limit() / Float.BYTES]; - for (int i = 0; i < res.length; i++) { - res[i] = byteBuffer.getFloat(); - } - System.out.println(Arrays.toString(res)); - } - } - - } catch (IoTDBConnectionException e) { - e.printStackTrace(); - } catch (StatementExecutionException e) { - e.printStackTrace(); - } - } -} diff --git a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java index 3157b6c98c4..77ae98d4887 100644 --- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java +++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java @@ -360,7 +360,7 @@ public class IoTDBJDBCResultSet implements ResultSet { return null; } - if (dataType.equals(TSDataType.BLOB)) { + if (dataType.equals(TSDataType.BLOB) || dataType.equals(TSDataType.OBJECT)) { Binary binary = ioTDBRpcDataSet.getBinary(columnIndex); return binary == null ? null : binary.getValues(); } else { 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 ec41311635e..60190d4b287 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 @@ -1333,8 +1333,13 @@ public class TableMetadataImpl implements Metadata { Collections.emptyMap()); try { ScalarFunctionAnalysis scalarFunctionAnalysis = scalarFunction.analyze(functionArguments); - return UDFDataTypeTransformer.transformUDFDataTypeToReadType( - scalarFunctionAnalysis.getOutputDataType()); + Type returnType = + UDFDataTypeTransformer.transformUDFDataTypeToReadType( + scalarFunctionAnalysis.getOutputDataType()); + if (returnType == ObjectType.OBJECT) { + throw new SemanticException("OBJECT type is not supported as return type"); + } + return returnType; } catch (Exception e) { throw new SemanticException("Invalid function parameters: " + e.getMessage()); } finally { @@ -1351,8 +1356,13 @@ public class TableMetadataImpl implements Metadata { try { AggregateFunctionAnalysis aggregateFunctionAnalysis = aggregateFunction.analyze(functionArguments); - return UDFDataTypeTransformer.transformUDFDataTypeToReadType( - aggregateFunctionAnalysis.getOutputDataType()); + Type returnType = + UDFDataTypeTransformer.transformUDFDataTypeToReadType( + aggregateFunctionAnalysis.getOutputDataType()); + if (returnType == ObjectType.OBJECT) { + throw new SemanticException("OBJECT type is not supported as return type"); + } + return returnType; } catch (Exception e) { throw new SemanticException("Invalid function parameters: " + e.getMessage()); } finally { diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/access/RecordIterator.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/access/RecordIterator.java index 3c38383f0b0..6f5813955dd 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/access/RecordIterator.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/udf/access/RecordIterator.java @@ -25,13 +25,17 @@ import org.apache.iotdb.udf.api.type.Type; import org.apache.tsfile.block.column.Column; import org.apache.tsfile.common.conf.TSFileConfig; +import org.apache.tsfile.read.common.type.ObjectType; import org.apache.tsfile.utils.Binary; +import org.apache.tsfile.utils.BytesUtils; import org.apache.tsfile.utils.DateUtils; import java.time.LocalDate; import java.util.Iterator; import java.util.List; +import static org.apache.tsfile.read.common.type.BlobType.BLOB; + public class RecordIterator implements Iterator<Record> { private final List<Column> childrenColumns; @@ -70,7 +74,7 @@ public class RecordIterator implements Iterator<Record> { private final List<Column> childrenColumns; private final List<org.apache.tsfile.read.common.type.Type> dataTypes; - private int index; + private final int index; private RecordImpl( List<Column> childrenColumns, @@ -113,10 +117,15 @@ public class RecordIterator implements Iterator<Record> { @Override public String getString(int columnIndex) { - return childrenColumns - .get(columnIndex) - .getBinary(index) - .getStringValue(TSFileConfig.STRING_CHARSET); + Binary binary = childrenColumns.get(columnIndex).getBinary(index); + org.apache.tsfile.read.common.type.Type type = dataTypes.get(columnIndex); + if (type == ObjectType.OBJECT) { + return BytesUtils.parseObjectByteArrayToString(binary.getValues()); + } else if (type == BLOB) { + return BytesUtils.parseBlobByteArrayToString(binary.getValues()); + } else { + return binary.getStringValue(TSFileConfig.STRING_CHARSET); + } } @Override
