This is an automated email from the ASF dual-hosted git repository. Caideyipi pushed a commit to branch codex/consensus-date-rowcount in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 5cb38ae089572da7a60c058aa4ad494419f653ef Author: Caideyipi <[email protected]> AuthorDate: Mon Oct 12 17:56:53 2026 +0800 Fix DATE conversion beyond tablet row count --- .../consensus/ConsensusLogToTabletConverter.java | 13 +++-- .../ConsensusLogToTabletConverterTest.java | 60 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverter.java index 882860cebbc..ab80b997061 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverter.java @@ -339,7 +339,8 @@ public class ConsensusLogToTabletConverter { convertColumnToTabletRepresentation( dataTypes[originalColIdx], columns[originalColIdx], - bitMaps != null ? bitMaps[originalColIdx] : null); + bitMaps != null ? bitMaps[originalColIdx] : null, + rowCount); if (bitMaps != null && bitMaps[originalColIdx] != null) { newBitMaps[i] = bitMaps[originalColIdx]; } @@ -529,6 +530,7 @@ public class ConsensusLogToTabletConverter { } final Object[] columns = node.getColumns(); final BitMap[] bitMaps = node.getBitMaps(); + final int rowCount = node.getRowCount(); final List<IMeasurementSchema> schemas = new ArrayList<>(measurements.length); final List<ColumnCategory> columnTypes = new ArrayList<>(measurements.length); final List<Object> validColumns = new ArrayList<>(measurements.length); @@ -551,7 +553,8 @@ public class ConsensusLogToTabletConverter { convertColumnToTabletRepresentation( dataTypes[i], columns[i], - Objects.nonNull(bitMaps) && i < bitMaps.length ? bitMaps[i] : null)); + Objects.nonNull(bitMaps) && i < bitMaps.length ? bitMaps[i] : null, + rowCount)); if (Objects.nonNull(validBitMaps)) { validBitMaps.add(i < bitMaps.length ? bitMaps[i] : null); } @@ -567,7 +570,7 @@ public class ConsensusLogToTabletConverter { node.getTimes(), validColumns.toArray(new Object[0]), Objects.nonNull(validBitMaps) ? validBitMaps.toArray(new BitMap[0]) : null, - node.getRowCount()); + rowCount); final Tablet prunedTablet = TabletColumnPruner.pruneTableModelTablet(tablet, databaseName, getColumnFilterMatcher()); @@ -748,14 +751,14 @@ public class ConsensusLogToTabletConverter { } private Object convertColumnToTabletRepresentation( - final TSDataType dataType, final Object column, final BitMap bitMap) { + final TSDataType dataType, final Object column, final BitMap bitMap, final int rowCount) { if (dataType != TSDataType.DATE || !(column instanceof int[])) { return column; } final int[] dateValues = (int[]) column; final LocalDate[] localDateValues = new LocalDate[dateValues.length]; - for (int i = 0; i < dateValues.length; i++) { + for (int i = 0; i < Math.min(rowCount, dateValues.length); i++) { if (Objects.isNull(bitMap) || !bitMap.isMarked(i)) { localDateValues[i] = DateUtils.parseIntToLocalDate(dateValues[i]); } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverterTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverterTest.java index c4af27f764c..e7c1f21cdb8 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverterTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/subscription/broker/consensus/ConsensusLogToTabletConverterTest.java @@ -198,6 +198,66 @@ public class ConsensusLogToTabletConverterTest { new LocalDate[] {date}, (LocalDate[]) deserializedTablet.getValues()[1]); } + @Test + public void testConvertRelationalInsertTabletNodeIgnoresDateCapacityBeyondRowCount() { + final ConsensusLogToTabletConverter converter = createConverter("value"); + final LocalDate date = LocalDate.of(2026, 2, 1); + final RelationalInsertTabletNode node = + new RelationalInsertTabletNode( + new PlanNodeId("date-capacity"), + new PartialPath(new String[] {StatementTestUtils.tableName()}), + true, + new String[] {"device_id", "value"}, + new TSDataType[] {TSDataType.STRING, TSDataType.DATE}, + new long[] {1L, 2L, 3L, 4L}, + null, + new Object[] { + new Binary[] { + new Binary("device_0".getBytes(StandardCharsets.UTF_8)), null, null, null + }, + new int[] {DateUtils.parseDateExpressionToInt(date), 0, 0, 0} + }, + 1, + new TsTableColumnCategory[] {TsTableColumnCategory.TAG, TsTableColumnCategory.FIELD}); + + final List<Tablet> tablets = converter.convert(node); + + Assert.assertEquals(1, tablets.size()); + final LocalDate[] convertedDates = (LocalDate[]) tablets.get(0).getValues()[1]; + Assert.assertEquals(date, convertedDates[0]); + Assert.assertNull(convertedDates[1]); + Assert.assertNull(convertedDates[2]); + Assert.assertNull(convertedDates[3]); + } + + @Test + public void testConvertTreeInsertTabletNodeIgnoresDateCapacityBeyondRowCount() + throws IllegalPathException { + final ConsensusLogToTabletConverter converter = createTreeConverter(); + final LocalDate date = LocalDate.of(2026, 2, 1); + final InsertTabletNode node = + new InsertTabletNode( + new PlanNodeId("tree-date-capacity"), + new PartialPath("root.sg.d1"), + false, + new String[] {"value"}, + new TSDataType[] {TSDataType.DATE}, + new MeasurementSchema[] {new MeasurementSchema("value", TSDataType.DATE)}, + new long[] {1L, 2L, 3L, 4L}, + null, + new Object[] {new int[] {DateUtils.parseDateExpressionToInt(date), 0, 0, 0}}, + 1); + + final List<Tablet> tablets = converter.convert(node); + + Assert.assertEquals(1, tablets.size()); + final LocalDate[] convertedDates = (LocalDate[]) tablets.get(0).getValues()[0]; + Assert.assertEquals(date, convertedDates[0]); + Assert.assertNull(convertedDates[1]); + Assert.assertNull(convertedDates[2]); + Assert.assertNull(convertedDates[3]); + } + @Test public void testConvertRelationalInsertTabletNodeKeepsNullMatchedFieldColumn() { final ConsensusLogToTabletConverter converter = createConverter("m1");
