This is an automated email from the ASF dual-hosted git repository. jt2594838 pushed a commit to branch remove_swtich_type in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 954731b1a5132c714c26656bb0042c730d53b6b3 Author: Tian Jiang <[email protected]> AuthorDate: Wed Aug 26 17:51:37 2026 +0800 multiple refactors --- .../org/apache/iotdb/rpc/IoTDBJDBCDataSet.java | 177 +++++---------------- .../java/org/apache/iotdb/rpc/TypeServices.java | 68 ++++++++ .../org/apache/iotdb/rpc/IoTDBJDBCDataSetTest.java | 106 ++++++++++++ 3 files changed, 216 insertions(+), 135 deletions(-) diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java index 000ab5a2799..a578f6e4a81 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/IoTDBJDBCDataSet.java @@ -29,14 +29,12 @@ import org.apache.iotdb.service.rpc.thrift.TSQueryDataSet; import org.apache.thrift.TException; import org.apache.tsfile.enums.TSDataType; -import org.apache.tsfile.utils.Binary; +import org.apache.tsfile.read.common.type.Type; import org.apache.tsfile.utils.BytesUtils; -import org.apache.tsfile.utils.DateUtils; import org.apache.tsfile.utils.ReadWriteIOUtils; import org.apache.tsfile.write.UnSupportedDataTypeException; import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.sql.Timestamp; import java.time.ZoneId; import java.util.ArrayList; @@ -156,38 +154,7 @@ public class IoTDBJDBCDataSet { time = new byte[Long.BYTES]; currentBitmap = new byte[columnTypeDeduplicatedList.size()]; - values = new byte[columnTypeDeduplicatedList.size()][]; - for (int i = 0; i < values.length; i++) { - TSDataType dataType = columnTypeDeduplicatedList.get(i); - switch (dataType) { - case BOOLEAN: - values[i] = new byte[1]; - break; - case INT32: - case DATE: - values[i] = new byte[Integer.BYTES]; - break; - case INT64: - case TIMESTAMP: - values[i] = new byte[Long.BYTES]; - break; - case FLOAT: - values[i] = new byte[Float.BYTES]; - break; - case DOUBLE: - values[i] = new byte[Double.BYTES]; - break; - case TEXT: - case BLOB: - case STRING: - case OBJECT: - values[i] = null; - break; - default: - throw new UnSupportedDataTypeException( - String.format(DATA_TYPE_NOT_SUPPORTED, columnTypeDeduplicatedList.get(i))); - } - } + values = initializeValueBuffers(columnTypeDeduplicatedList); this.tsQueryDataSet = queryDataSet; this.emptyResultSet = (queryDataSet == null || !queryDataSet.time.hasRemaining()); } @@ -275,38 +242,7 @@ public class IoTDBJDBCDataSet { time = new byte[Long.BYTES]; currentBitmap = new byte[columnTypeDeduplicatedList.size()]; - values = new byte[columnTypeDeduplicatedList.size()][]; - for (int i = 0; i < values.length; i++) { - TSDataType dataType = columnTypeDeduplicatedList.get(i); - switch (dataType) { - case BOOLEAN: - values[i] = new byte[1]; - break; - case INT32: - case DATE: - values[i] = new byte[Integer.BYTES]; - break; - case INT64: - case TIMESTAMP: - values[i] = new byte[Long.BYTES]; - break; - case FLOAT: - values[i] = new byte[Float.BYTES]; - break; - case DOUBLE: - values[i] = new byte[Double.BYTES]; - break; - case TEXT: - case BLOB: - case STRING: - case OBJECT: - values[i] = null; - break; - default: - throw new UnSupportedDataTypeException( - String.format(DATA_TYPE_NOT_SUPPORTED, columnTypeDeduplicatedList.get(i))); - } - } + values = initializeValueBuffers(columnTypeDeduplicatedList); this.tsQueryDataSet = queryDataSet; this.emptyResultSet = (queryDataSet == null || !queryDataSet.time.hasRemaining()); } @@ -420,26 +356,11 @@ public class IoTDBJDBCDataSet { if (!isNull(i, rowsIndex)) { ByteBuffer valueBuffer = tsQueryDataSet.valueList.get(i); TSDataType dataType = columnTypeDeduplicatedList.get(i); - switch (dataType) { - case BOOLEAN: - case INT32: - case INT64: - case FLOAT: - case DOUBLE: - case DATE: - case TIMESTAMP: - valueBuffer.get(values[i]); - break; - case TEXT: - case BLOB: - case STRING: - case OBJECT: - int length = valueBuffer.getInt(); - values[i] = ReadWriteIOUtils.readBytes(valueBuffer, length); - break; - default: - throw new UnSupportedDataTypeException( - String.format(DATA_TYPE_NOT_SUPPORTED, columnTypeDeduplicatedList.get(i))); + if (dataType.isBinary()) { + int length = valueBuffer.getInt(); + values[i] = ReadWriteIOUtils.readBytes(valueBuffer, length); + } else { + valueBuffer.get(values[i]); } } } @@ -447,6 +368,34 @@ public class IoTDBJDBCDataSet { hasCachedRecord = true; } + static byte[][] initializeValueBuffers(List<TSDataType> dataTypes) { + byte[][] valueBuffers = new byte[dataTypes.size()][]; + for (int i = 0; i < dataTypes.size(); i++) { + TSDataType dataType = dataTypes.get(i); + if (dataType == TSDataType.VECTOR || dataType == TSDataType.UNKNOWN) { + throw unsupportedDataType(dataType); + } + if (dataType.isBinary()) { + continue; + } + final int dataTypeSize; + try { + dataTypeSize = dataType.getDataTypeSize(); + } catch (UnSupportedDataTypeException e) { + throw unsupportedDataType(dataType); + } + if (dataTypeSize == 0) { + throw unsupportedDataType(dataType); + } + valueBuffers[i] = new byte[dataTypeSize]; + } + return valueBuffers; + } + + private static UnSupportedDataTypeException unsupportedDataType(TSDataType dataType) { + return new UnSupportedDataTypeException(String.format(DATA_TYPE_NOT_SUPPORTED, dataType)); + } + public boolean isNull(int columnIndex) throws StatementExecutionException { int index = columnOrdinalMap.get(findColumnNameByIndex(columnIndex)) - START_INDEX; // time column will never be null @@ -597,30 +546,9 @@ public class IoTDBJDBCDataSet { } public String getString(int index, TSDataType tsDataType, byte[][] values) { - switch (tsDataType) { - case BOOLEAN: - return String.valueOf(BytesUtils.bytesToBool(values[index])); - case INT32: - return String.valueOf(BytesUtils.bytesToInt(values[index])); - case INT64: - case TIMESTAMP: - return String.valueOf(BytesUtils.bytesToLong(values[index])); - case FLOAT: - return String.valueOf(BytesUtils.bytesToFloat(values[index])); - case DOUBLE: - return String.valueOf(BytesUtils.bytesToDouble(values[index])); - case TEXT: - case STRING: - return new String(values[index], StandardCharsets.UTF_8); - case OBJECT: - return BytesUtils.parseObjectByteArrayToString(values[index]); - case BLOB: - return BytesUtils.parseBlobByteArrayToString(values[index]); - case DATE: - return DateUtils.formatDate(BytesUtils.bytesToInt(values[index])); - default: - return null; - } + return TypeServices.JDBC_STRING_READER_SERVICE + .call(Type.fromTsDataType(tsDataType)) + .apply(values[index]); } public Object getObjectByName(String columnName) throws StatementExecutionException { @@ -638,30 +566,9 @@ public class IoTDBJDBCDataSet { } public Object getObject(int index, TSDataType tsDataType, byte[][] values) { - switch (tsDataType) { - case BOOLEAN: - return BytesUtils.bytesToBool(values[index]); - case INT32: - return BytesUtils.bytesToInt(values[index]); - case INT64: - return BytesUtils.bytesToLong(values[index]); - case FLOAT: - return BytesUtils.bytesToFloat(values[index]); - case DOUBLE: - return BytesUtils.bytesToDouble(values[index]); - case TEXT: - case STRING: - return new String(values[index], StandardCharsets.UTF_8); - case OBJECT: - case BLOB: - return new Binary(values[index]); - case TIMESTAMP: - return new Timestamp(BytesUtils.bytesToLong(values[index])); - case DATE: - return DateUtils.parseIntToDate(BytesUtils.bytesToInt(values[index])); - default: - return null; - } + return TypeServices.JDBC_OBJECT_READER_SERVICE + .call(Type.fromTsDataType(tsDataType)) + .apply(values[index]); } public String findColumnNameByIndex(int columnIndex) throws StatementExecutionException { diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TypeServices.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TypeServices.java new file mode 100644 index 00000000000..4e1cec95c6f --- /dev/null +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TypeServices.java @@ -0,0 +1,68 @@ +/* + * 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.rpc; + +import org.apache.tsfile.read.common.type.service.TypeService; +import org.apache.tsfile.utils.Binary; +import org.apache.tsfile.utils.BytesUtils; +import org.apache.tsfile.utils.DateUtils; + +import java.nio.charset.StandardCharsets; +import java.sql.Timestamp; +import java.util.function.Function; + +final class TypeServices { + + static final TypeService<Function<byte[], String>> JDBC_STRING_READER_SERVICE = + type -> + switch (type.getTypeEnum()) { + case BOOLEAN -> value -> String.valueOf(BytesUtils.bytesToBool(value)); + case INT32 -> value -> String.valueOf(BytesUtils.bytesToInt(value)); + case INT64, TIMESTAMP -> value -> String.valueOf(BytesUtils.bytesToLong(value)); + case FLOAT -> value -> String.valueOf(BytesUtils.bytesToFloat(value)); + case DOUBLE -> value -> String.valueOf(BytesUtils.bytesToDouble(value)); + case TEXT, STRING -> value -> new String(value, StandardCharsets.UTF_8); + case OBJECT -> BytesUtils::parseObjectByteArrayToString; + case BLOB -> BytesUtils::parseBlobByteArrayToString; + case DATE -> value -> DateUtils.formatDate(BytesUtils.bytesToInt(value)); + case ROW, UNKNOWN, VECTOR -> ignored -> null; + }; + + static final TypeService<Function<byte[], Object>> JDBC_OBJECT_READER_SERVICE = + type -> + switch (type.getTypeEnum()) { + case BOOLEAN -> BytesUtils::bytesToBool; + case INT32 -> BytesUtils::bytesToInt; + case INT64 -> BytesUtils::bytesToLong; + case FLOAT -> BytesUtils::bytesToFloat; + case DOUBLE -> BytesUtils::bytesToDouble; + case TEXT, STRING -> value -> new String(value, StandardCharsets.UTF_8); + case OBJECT, BLOB -> Binary::new; + case TIMESTAMP -> value -> new Timestamp(BytesUtils.bytesToLong(value)); + case DATE -> value -> DateUtils.parseIntToDate(BytesUtils.bytesToInt(value)); + case ROW, UNKNOWN, VECTOR -> ignored -> null; + }; + + static { + JDBC_STRING_READER_SERVICE.check(); + JDBC_OBJECT_READER_SERVICE.check(); + } + + private TypeServices() {} +} diff --git a/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/IoTDBJDBCDataSetTest.java b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/IoTDBJDBCDataSetTest.java new file mode 100644 index 00000000000..af98f2a60ec --- /dev/null +++ b/iotdb-client/service-rpc/src/test/java/org/apache/iotdb/rpc/IoTDBJDBCDataSetTest.java @@ -0,0 +1,106 @@ +/* + * 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.rpc; + +import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.read.common.type.Type; +import org.apache.tsfile.read.common.type.UnknownType; +import org.apache.tsfile.utils.Binary; +import org.apache.tsfile.utils.BytesUtils; +import org.apache.tsfile.write.UnSupportedDataTypeException; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +public class IoTDBJDBCDataSetTest { + + @Test + public void testInitializeValueBuffersUsesDataTypeInterfaces() { + byte[][] buffers = + IoTDBJDBCDataSet.initializeValueBuffers( + Arrays.asList( + TSDataType.BOOLEAN, + TSDataType.INT32, + TSDataType.INT64, + TSDataType.FLOAT, + TSDataType.DOUBLE, + TSDataType.DATE, + TSDataType.TIMESTAMP, + TSDataType.TEXT, + TSDataType.STRING, + TSDataType.BLOB, + TSDataType.OBJECT)); + + Assert.assertEquals(Byte.BYTES, buffers[0].length); + Assert.assertEquals(Integer.BYTES, buffers[1].length); + Assert.assertEquals(Long.BYTES, buffers[2].length); + Assert.assertEquals(Float.BYTES, buffers[3].length); + Assert.assertEquals(Double.BYTES, buffers[4].length); + Assert.assertEquals(Integer.BYTES, buffers[5].length); + Assert.assertEquals(Long.BYTES, buffers[6].length); + Assert.assertNull(buffers[7]); + Assert.assertNull(buffers[8]); + Assert.assertNull(buffers[9]); + Assert.assertNull(buffers[10]); + } + + @Test + public void testInitializeValueBuffersRejectsInternalTypes() { + assertUnsupported(TSDataType.UNKNOWN); + assertUnsupported(TSDataType.VECTOR); + } + + @Test + public void testJdbcValueReadersUseTypeServices() { + Assert.assertEquals( + "42", + TypeServices.JDBC_STRING_READER_SERVICE + .call(Type.fromTsDataType(TSDataType.INT32)) + .apply(BytesUtils.intToBytes(42))); + Assert.assertEquals( + 42, + TypeServices.JDBC_OBJECT_READER_SERVICE + .call(Type.fromTsDataType(TSDataType.INT32)) + .apply(BytesUtils.intToBytes(42))); + + byte[] binary = new byte[] {1, 2, 3}; + Assert.assertEquals( + new Binary(binary), + TypeServices.JDBC_OBJECT_READER_SERVICE + .call(Type.fromTsDataType(TSDataType.BLOB)) + .apply(binary)); + + Assert.assertNull( + TypeServices.JDBC_STRING_READER_SERVICE.call(UnknownType.UNKNOWN).apply(new byte[0])); + Assert.assertNull( + TypeServices.JDBC_OBJECT_READER_SERVICE.call(UnknownType.UNKNOWN).apply(new byte[0])); + } + + private static void assertUnsupported(TSDataType dataType) { + UnSupportedDataTypeException exception = + Assert.assertThrows( + UnSupportedDataTypeException.class, + () -> IoTDBJDBCDataSet.initializeValueBuffers(Arrays.asList(dataType))); + Assert.assertTrue( + exception + .getMessage() + .endsWith(String.format(IoTDBJDBCDataSet.DATA_TYPE_NOT_SUPPORTED, dataType))); + } +}
