This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch rc/1.3.5 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 7336c1444db4dd7758f17276cd7f498ff94dcf16 Author: Jiang Tian <[email protected]> AuthorDate: Wed Aug 20 18:40:52 2025 +0800 Print measurement for putting buffer exceptions (#15873) (#16213) --- .../iotdb/session/it/IoTDBSessionSimpleIT.java | 16 +++ .../java/org/apache/iotdb/session/Session.java | 17 ++- .../apache/iotdb/session/util/SessionUtils.java | 139 ++++++++++++++------- .../iotdb/session/util/SessionUtilsTest.java | 29 ++++- .../metrics/IoTDBInternalLocalReporter.java | 2 +- 5 files changed, 146 insertions(+), 57 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSimpleIT.java b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSimpleIT.java index 536bab31171..a4b84bab7d3 100644 --- a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSimpleIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSimpleIT.java @@ -79,6 +79,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -2130,4 +2131,19 @@ public class IoTDBSessionSimpleIT { } } } + + @Test + public void testInsertWrongTypeRecord() throws IoTDBConnectionException { + try (ISession session = EnvFactory.getEnv().getSessionConnection()) { + assertThrows( + ClassCastException.class, + () -> + session.insertRecord( + "root.db1.d1", + 0, + Collections.singletonList("s1"), + Collections.singletonList(TSDataType.INT32), + Collections.singletonList(1L))); + } + } } diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java index b7bf5daac0c..7d76cedee63 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/Session.java @@ -1430,7 +1430,7 @@ public class Session implements ISession { request.setPrefixPath(prefixPath); request.setTimestamp(time); request.setMeasurements(measurements); - ByteBuffer buffer = SessionUtils.getValueBuffer(types, values); + ByteBuffer buffer = SessionUtils.getValueBuffer(types, values, measurements); request.setValues(buffer); request.setIsAligned(isAligned); return request; @@ -2395,7 +2395,8 @@ public class Session implements ISession { request.setPrefixPath(prefixPath); request.setTimestamps(times); request.setMeasurementsList(measurementsList); - List<ByteBuffer> buffersList = objectValuesListToByteBufferList(valuesList, typesList); + List<ByteBuffer> buffersList = + objectValuesListToByteBufferList(valuesList, typesList, measurementsList); request.setValuesList(buffersList); request.setIsAligned(isAligned); return request; @@ -2469,11 +2470,14 @@ public class Session implements ISession { } private List<ByteBuffer> objectValuesListToByteBufferList( - List<List<Object>> valuesList, List<List<TSDataType>> typesList) + List<List<Object>> valuesList, + List<List<TSDataType>> typesList, + List<List<String>> measurementsList) throws IoTDBConnectionException { List<ByteBuffer> buffersList = new ArrayList<>(); for (int i = 0; i < valuesList.size(); i++) { - ByteBuffer buffer = SessionUtils.getValueBuffer(typesList.get(i), valuesList.get(i)); + ByteBuffer buffer = + SessionUtils.getValueBuffer(typesList.get(i), valuesList.get(i), measurementsList.get(i)); buffersList.add(buffer); } return buffersList; @@ -2545,7 +2549,8 @@ public class Session implements ISession { request.setTimestamps(times); request.setMeasurementsList(measurementsList); request.setIsAligned(isAligned); - List<ByteBuffer> buffersList = objectValuesListToByteBufferList(valuesList, typesList); + List<ByteBuffer> buffersList = + objectValuesListToByteBufferList(valuesList, typesList, measurementsList); request.setValuesList(buffersList); return request; } @@ -2582,7 +2587,7 @@ public class Session implements ISession { request.addToPrefixPaths(deviceId); request.addToTimestamps(time); request.addToMeasurementsList(measurements); - ByteBuffer buffer = SessionUtils.getValueBuffer(types, values); + ByteBuffer buffer = SessionUtils.getValueBuffer(types, values, measurements); request.addToValuesList(buffer); } diff --git a/iotdb-client/session/src/main/java/org/apache/iotdb/session/util/SessionUtils.java b/iotdb-client/session/src/main/java/org/apache/iotdb/session/util/SessionUtils.java index 88ecda05248..31ca44aa3ff 100644 --- a/iotdb-client/session/src/main/java/org/apache/iotdb/session/util/SessionUtils.java +++ b/iotdb-client/session/src/main/java/org/apache/iotdb/session/util/SessionUtils.java @@ -33,6 +33,8 @@ import org.apache.tsfile.utils.ReadWriteIOUtils; import org.apache.tsfile.write.UnSupportedDataTypeException; import org.apache.tsfile.write.record.Tablet; import org.apache.tsfile.write.schema.MeasurementSchema; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; import java.time.LocalDate; @@ -43,6 +45,7 @@ import static org.apache.iotdb.session.Session.MSG_UNSUPPORTED_DATA_TYPE; public class SessionUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(SessionUtils.class); private static final byte TYPE_NULL = -2; public static ByteBuffer getTimeBuffer(Tablet tablet) { @@ -77,10 +80,47 @@ public class SessionUtils { return valueBuffer; } - public static ByteBuffer getValueBuffer(List<TSDataType> types, List<Object> values) + private static int calOccupationOfOneColumn( + TSDataType dataType, Object[] values, int columnIndex, int rowSize) { + int valueOccupation = 0; + switch (dataType) { + case BOOLEAN: + valueOccupation += rowSize; + break; + case INT32: + case FLOAT: + case DATE: + valueOccupation += rowSize * 4; + break; + case INT64: + case DOUBLE: + case TIMESTAMP: + valueOccupation += rowSize * 8; + break; + case TEXT: + case BLOB: + case STRING: + valueOccupation += rowSize * 4; + Binary[] binaries = (Binary[]) values[columnIndex]; + for (int rowIndex = 0; rowIndex < rowSize; rowIndex++) { + valueOccupation += + binaries[rowIndex] != null + ? binaries[rowIndex].getLength() + : Binary.EMPTY_VALUE.getLength(); + } + break; + default: + throw new UnSupportedDataTypeException( + String.format("Data type %s is not supported.", dataType)); + } + return valueOccupation; + } + + public static ByteBuffer getValueBuffer( + List<TSDataType> types, List<Object> values, List<String> measurements) throws IoTDBConnectionException { ByteBuffer buffer = ByteBuffer.allocate(SessionUtils.calculateLength(types, values)); - SessionUtils.putValues(types, values, buffer); + SessionUtils.putValues(types, values, buffer, measurements); return buffer; } @@ -136,53 +176,60 @@ public class SessionUtils { * @param buffer buffer to insert * @throws IoTDBConnectionException */ - private static void putValues(List<TSDataType> types, List<Object> values, ByteBuffer buffer) + private static void putValues( + List<TSDataType> types, List<Object> values, ByteBuffer buffer, List<String> measurements) throws IoTDBConnectionException { for (int i = 0; i < values.size(); i++) { - if (values.get(i) == null) { - ReadWriteIOUtils.write(TYPE_NULL, buffer); - continue; - } - ReadWriteIOUtils.write(types.get(i), buffer); - switch (types.get(i)) { - case BOOLEAN: - ReadWriteIOUtils.write((Boolean) values.get(i), buffer); - break; - case INT32: - ReadWriteIOUtils.write((Integer) values.get(i), buffer); - break; - case DATE: - ReadWriteIOUtils.write( - DateUtils.parseDateExpressionToInt((LocalDate) values.get(i)), buffer); - break; - case INT64: - case TIMESTAMP: - ReadWriteIOUtils.write((Long) values.get(i), buffer); - break; - case FLOAT: - ReadWriteIOUtils.write((Float) values.get(i), buffer); - break; - case DOUBLE: - ReadWriteIOUtils.write((Double) values.get(i), buffer); - break; - case TEXT: - case STRING: - byte[] bytes; - if (values.get(i) instanceof Binary) { + try { + if (values.get(i) == null) { + ReadWriteIOUtils.write(TYPE_NULL, buffer); + continue; + } + ReadWriteIOUtils.write(types.get(i), buffer); + switch (types.get(i)) { + case BOOLEAN: + ReadWriteIOUtils.write((Boolean) values.get(i), buffer); + break; + case INT32: + ReadWriteIOUtils.write((Integer) values.get(i), buffer); + break; + case DATE: + ReadWriteIOUtils.write( + DateUtils.parseDateExpressionToInt((LocalDate) values.get(i)), buffer); + break; + case INT64: + case TIMESTAMP: + ReadWriteIOUtils.write((Long) values.get(i), buffer); + break; + case FLOAT: + ReadWriteIOUtils.write((Float) values.get(i), buffer); + break; + case DOUBLE: + ReadWriteIOUtils.write((Double) values.get(i), buffer); + break; + case TEXT: + case STRING: + byte[] bytes; + if (values.get(i) instanceof Binary) { + bytes = ((Binary) values.get(i)).getValues(); + } else { + bytes = ((String) values.get(i)).getBytes(TSFileConfig.STRING_CHARSET); + } + ReadWriteIOUtils.write(bytes.length, buffer); + buffer.put(bytes); + break; + case BLOB: bytes = ((Binary) values.get(i)).getValues(); - } else { - bytes = ((String) values.get(i)).getBytes(TSFileConfig.STRING_CHARSET); - } - ReadWriteIOUtils.write(bytes.length, buffer); - buffer.put(bytes); - break; - case BLOB: - bytes = ((Binary) values.get(i)).getValues(); - ReadWriteIOUtils.write(bytes.length, buffer); - buffer.put(bytes); - break; - default: - throw new IoTDBConnectionException(MSG_UNSUPPORTED_DATA_TYPE + types.get(i)); + ReadWriteIOUtils.write(bytes.length, buffer); + buffer.put(bytes); + break; + default: + throw new IoTDBConnectionException(MSG_UNSUPPORTED_DATA_TYPE + types.get(i)); + } + } catch (Throwable e) { + LOGGER.error( + "Cannot put values for measurement {}, type={}", measurements.get(i), types.get(i), e); + throw e; } } buffer.flip(); diff --git a/iotdb-client/session/src/test/java/org/apache/iotdb/session/util/SessionUtilsTest.java b/iotdb-client/session/src/test/java/org/apache/iotdb/session/util/SessionUtilsTest.java index 7fb93e49a23..82f19d3d332 100644 --- a/iotdb-client/session/src/test/java/org/apache/iotdb/session/util/SessionUtilsTest.java +++ b/iotdb-client/session/src/test/java/org/apache/iotdb/session/util/SessionUtilsTest.java @@ -35,8 +35,11 @@ import org.junit.Test; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import static org.junit.Assert.assertThrows; + public class SessionUtilsTest { @Test @@ -122,24 +125,42 @@ public class SessionUtilsTest { TSDataType.DOUBLE, TSDataType.TEXT, TSDataType.BOOLEAN); - ByteBuffer timeBuffer = SessionUtils.getValueBuffer(typeList, valueList); + List<String> measurements = Arrays.asList("s1", "s2", "s3", "s4", "s5", "s6"); + ByteBuffer timeBuffer = SessionUtils.getValueBuffer(typeList, valueList, measurements); Assert.assertNotNull(timeBuffer); valueList = new ArrayList<>(); valueList.add(null); - typeList = Arrays.asList(TSDataType.INT32); - timeBuffer = SessionUtils.getValueBuffer(typeList, valueList); + typeList = Collections.singletonList(TSDataType.INT32); + timeBuffer = SessionUtils.getValueBuffer(typeList, valueList, measurements); Assert.assertNotNull(timeBuffer); valueList = Arrays.asList(false); typeList = Arrays.asList(TSDataType.UNKNOWN); try { - timeBuffer = SessionUtils.getValueBuffer(typeList, valueList); + SessionUtils.getValueBuffer(typeList, valueList, measurements); } catch (Exception e) { Assert.assertTrue(e instanceof IoTDBConnectionException); } } + @Test + public void testGetValueBufferWithWrongType() { + List<Object> valueList = Arrays.asList(12L, 13, 1.2, 0.707f, false, "false"); + List<TSDataType> typeList = + Arrays.asList( + TSDataType.INT32, + TSDataType.INT64, + TSDataType.FLOAT, + TSDataType.DOUBLE, + TSDataType.TEXT, + TSDataType.BOOLEAN); + List<String> measurements = Arrays.asList("s1", "s2", "s3", "s4", "s5", "s6"); + assertThrows( + ClassCastException.class, + () -> SessionUtils.getValueBuffer(typeList, valueList, measurements)); + } + @Test public void testParseSeedNodeUrls() { List<String> nodeUrls = Arrays.asList("127.0.0.1:1234"); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java index bd8ca1e8654..2dc54e564f2 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java @@ -194,7 +194,7 @@ public class IoTDBInternalLocalReporter extends IoTDBInternalReporter { types.add(inferType(value)); values.add(value); } - ByteBuffer buffer = SessionUtils.getValueBuffer(types, values); + ByteBuffer buffer = SessionUtils.getValueBuffer(types, values, measurements); request.setPrefixPath(prefix); request.setTimestamp(time);
