diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/io/CompactionTsFileWriter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/io/CompactionTsFileWriter.java index 1f822e3b9345d..45adb94cf8f2e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/io/CompactionTsFileWriter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/io/CompactionTsFileWriter.java @@ -47,6 +47,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; public class CompactionTsFileWriter extends TsFileIOWriter { CompactionType type; @@ -181,15 +182,21 @@ public boolean isEmptyTargetFile() { } private void removeUnusedTableSchema() { - Map tableSchemaMap = getSchema().getTableSchemaMap(); - Iterator> iterator = tableSchemaMap.entrySet().iterator(); + final Map tableSchemaMap = getSchema().getTableSchemaMap(); + final Iterator> iterator = tableSchemaMap.entrySet().iterator(); while (iterator.hasNext()) { - Map.Entry entry = iterator.next(); - List columnTypes = entry.getValue().getColumnTypes(); - if (columnTypes.contains(ColumnCategory.FIELD)) { + final Map.Entry entry = iterator.next(); + final List columnTypes = entry.getValue().getColumnTypes(); + if (hasFieldOrTimeColumn(columnTypes)) { continue; } iterator.remove(); } } + + private boolean hasFieldOrTimeColumn(final List columnTypes) { + return Objects.nonNull(columnTypes) + && (columnTypes.contains(ColumnCategory.FIELD) + || columnTypes.contains(ColumnCategory.TIME)); + } } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/CompactionTableModelTestFileWriter.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/CompactionTableModelTestFileWriter.java index f586f6a547333..39f0b909856ed 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/CompactionTableModelTestFileWriter.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/CompactionTableModelTestFileWriter.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.tablemodel; +import org.apache.iotdb.commons.utils.TestOnly; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionTableSchema; import org.apache.iotdb.db.storageengine.dataregion.compaction.utils.CompactionTestFileWriter; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; @@ -30,12 +31,15 @@ import org.apache.tsfile.file.metadata.TableSchema; import org.apache.tsfile.file.metadata.enums.CompressionType; import org.apache.tsfile.file.metadata.enums.TSEncoding; +import org.apache.tsfile.read.common.TimeRange; +import org.apache.tsfile.write.chunk.AlignedChunkWriterImpl; import org.apache.tsfile.write.schema.IMeasurementSchema; import org.apache.tsfile.write.schema.MeasurementSchema; import org.apache.tsfile.write.schema.Schema; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class CompactionTableModelTestFileWriter extends CompactionTestFileWriter { @@ -61,6 +65,22 @@ public void registerTableSchema(String tableName, List idColumnNames) { schema.registerTableSchema(tableSchema); } + public void registerTableSchemaWithTagAndTime(String tableName, List idColumnNames) { + List measurementSchemas = new ArrayList<>(); + List columnTypes = new ArrayList<>(); + for (String idColumnName : idColumnNames) { + measurementSchemas.add( + new MeasurementSchema( + idColumnName, TSDataType.STRING, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED)); + columnTypes.add(ColumnCategory.TAG); + } + measurementSchemas.add( + new MeasurementSchema( + "time", TSDataType.INT64, TSEncoding.PLAIN, CompressionType.UNCOMPRESSED)); + columnTypes.add(ColumnCategory.TIME); + schema.registerTableSchema(new TableSchema(tableName, measurementSchemas, columnTypes)); + } + public void registerTableSchemaWithTagField(String tableName, List columnNames) { List measurementSchemas = new ArrayList<>(); List columnTypes = new ArrayList<>(); @@ -75,6 +95,19 @@ public void registerTableSchemaWithTagField(String tableName, List colum schema.registerTableSchema(new TableSchema(tableName, measurementSchemas, columnTypes)); } + @TestOnly + public void generateTimeOnlyDataToCurrentDevice(TimeRange[] timeRanges) throws IOException { + for (TimeRange timeRange : timeRanges) { + AlignedChunkWriterImpl chunkWriter = new AlignedChunkWriterImpl(Collections.emptyList()); + currentDeviceStartTime = Math.min(timeRange.getMin(), currentDeviceStartTime); + currentDeviceEndTime = Math.max(timeRange.getMax(), currentDeviceEndTime); + for (long time = timeRange.getMin(); time <= timeRange.getMax(); time++) { + chunkWriter.getTimeChunkWriter().write(time); + } + chunkWriter.writeToFileWriter(fileWriter); + } + } + public IDeviceID startChunkGroup(String tableName, List idColumnFields) throws IOException { int idx = 0; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionTestFileWriterTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionTestFileWriterTest.java index 70431d61f0744..05f345b7bbc3a 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionTestFileWriterTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionTestFileWriterTest.java @@ -22,11 +22,14 @@ import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.db.exception.StorageEngineException; import org.apache.iotdb.db.storageengine.dataregion.compaction.AbstractCompactionTest; +import org.apache.iotdb.db.storageengine.dataregion.compaction.tablemodel.CompactionTableModelTestFileWriter; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; +import org.apache.tsfile.enums.ColumnCategory; import org.apache.tsfile.exception.write.WriteProcessException; import org.apache.tsfile.file.metadata.enums.CompressionType; import org.apache.tsfile.file.metadata.enums.TSEncoding; +import org.apache.tsfile.read.TsFileSequenceReader; import org.apache.tsfile.read.common.TimeRange; import org.junit.After; import org.junit.Assert; @@ -35,6 +38,7 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Collections; public class CompactionTestFileWriterTest extends AbstractCompactionTest { @Before @@ -196,4 +200,23 @@ public void testGenerateAlignedSeriesWithPoints() throws IOException { Assert.fail(); } } + + @Test + public void testFieldlessTableSchemaWithTimeDataIsRetained() throws IOException { + final TsFileResource resource = createEmptyFileAndResource(true); + try (final CompactionTableModelTestFileWriter writer = + new CompactionTableModelTestFileWriter(resource)) { + writer.registerTableSchemaWithTagAndTime("table1", Collections.singletonList("tag1")); + writer.startChunkGroup("table1", Collections.singletonList("tag1_value")); + writer.generateTimeOnlyDataToCurrentDevice(new TimeRange[] {new TimeRange(1, 3)}); + writer.endChunkGroup(); + writer.endFile(); + } + try (final TsFileSequenceReader reader = + new TsFileSequenceReader(resource.getTsFile().getAbsolutePath())) { + Assert.assertTrue(reader.getTableSchemaMap().containsKey("table1")); + Assert.assertFalse( + reader.getTableSchemaMap().get("table1").getColumnTypes().contains(ColumnCategory.FIELD)); + } + } }