This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git
The following commit(s) were added to refs/heads/develop by this push:
new dd27faf7a Fix/table model date query read (#738)
dd27faf7a is described below
commit dd27faf7a7077dc68f8f161f8181df81f3e9117b
Author: Hongzhi Gao <[email protected]>
AuthorDate: Fri Mar 6 11:34:07 2026 +0800
Fix/table model date query read (#738)
* fix readme logo
* fix readme logo
* fix readme badge
* fix table-model DATE query in Java reader
Handle DATE columns in SingleDeviceTsBlockReader projection paths and add a
regression test to prevent table query failures when reading DATE values.
* fix support TIMESTAMP STRING BLOB in table read path
Extend table-model query projection to handle TIMESTAMP/STRING/BLOB (and
aligned aliases) and update TsFileSequenceRead example decoding with matching
type coverage; add regression test for timestamp/string/blob query.
* mvn spotless:apply
* docs narrow TsFileSequenceRead type coverage
Remove OBJECT from the TsFileSequenceRead example switch so the sample only
demonstrates documented primitive and binary-like types.
---
.../java/org/apache/tsfile/TsFileSequenceRead.java | 4 +
.../reader/block/SingleDeviceTsBlockReader.java | 15 ++++
.../apache/tsfile/write/TsFileWriteApiTest.java | 86 ++++++++++++++++++++++
3 files changed, 105 insertions(+)
diff --git
a/java/examples/src/main/java/org/apache/tsfile/TsFileSequenceRead.java
b/java/examples/src/main/java/org/apache/tsfile/TsFileSequenceRead.java
index 5e708f1f0..e6000618f 100644
--- a/java/examples/src/main/java/org/apache/tsfile/TsFileSequenceRead.java
+++ b/java/examples/src/main/java/org/apache/tsfile/TsFileSequenceRead.java
@@ -155,9 +155,11 @@ public class TsFileSequenceRead {
value = valueDecoder.readBoolean(pageData);
break;
case INT32:
+ case DATE:
value = valueDecoder.readInt(pageData);
break;
case INT64:
+ case TIMESTAMP:
value = valueDecoder.readLong(pageData);
break;
case FLOAT:
@@ -167,6 +169,8 @@ public class TsFileSequenceRead {
value = valueDecoder.readDouble(pageData);
break;
case TEXT:
+ case STRING:
+ case BLOB:
value = valueDecoder.readBinary(pageData);
break;
default:
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/read/reader/block/SingleDeviceTsBlockReader.java
b/java/tsfile/src/main/java/org/apache/tsfile/read/reader/block/SingleDeviceTsBlockReader.java
index 174cdfd9a..f406252be 100644
---
a/java/tsfile/src/main/java/org/apache/tsfile/read/reader/block/SingleDeviceTsBlockReader.java
+++
b/java/tsfile/src/main/java/org/apache/tsfile/read/reader/block/SingleDeviceTsBlockReader.java
@@ -233,6 +233,9 @@ public class SingleDeviceTsBlockReader implements
TsBlockReader {
private void fillIdColumn(Column column, Object val, int startPos, int
endPos) {
switch (column.getDataType()) {
case TEXT:
+ case STRING:
+ case BLOB:
+ case OBJECT:
if (val instanceof String) {
val = new Binary(((String) val), StandardCharsets.UTF_8);
}
@@ -242,9 +245,11 @@ public class SingleDeviceTsBlockReader implements
TsBlockReader {
Arrays.fill(column.getBooleans(), startPos, endPos, ((boolean) val));
break;
case INT32:
+ case DATE:
Arrays.fill(column.getInts(), startPos, endPos, ((int) val));
break;
case INT64:
+ case TIMESTAMP:
Arrays.fill(column.getLongs(), startPos, endPos, ((long) val));
break;
case FLOAT:
@@ -271,12 +276,17 @@ public class SingleDeviceTsBlockReader implements
TsBlockReader {
column.getFloats()[pos] = batchData.getFloat();
break;
case INT32:
+ case DATE:
column.getInts()[pos] = batchData.getInt();
break;
case TEXT:
+ case STRING:
+ case BLOB:
+ case OBJECT:
column.getBinaries()[pos] = batchData.getBinary();
break;
case INT64:
+ case TIMESTAMP:
column.getLongs()[pos] = batchData.getLong();
break;
default:
@@ -372,12 +382,17 @@ public class SingleDeviceTsBlockReader implements
TsBlockReader {
if (value != null) {
switch (value.getDataType()) {
case TEXT:
+ case STRING:
+ case BLOB:
+ case OBJECT:
block.getColumn(pos).getBinaries()[blockRowNum] =
value.getBinary();
break;
case INT32:
+ case DATE:
block.getColumn(pos).getInts()[blockRowNum] = value.getInt();
break;
case INT64:
+ case TIMESTAMP:
block.getColumn(pos).getLongs()[blockRowNum] = value.getLong();
break;
case BOOLEAN:
diff --git
a/java/tsfile/src/test/java/org/apache/tsfile/write/TsFileWriteApiTest.java
b/java/tsfile/src/test/java/org/apache/tsfile/write/TsFileWriteApiTest.java
index dd6e74bc9..feaa27940 100644
--- a/java/tsfile/src/test/java/org/apache/tsfile/write/TsFileWriteApiTest.java
+++ b/java/tsfile/src/test/java/org/apache/tsfile/write/TsFileWriteApiTest.java
@@ -66,6 +66,7 @@ import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1151,6 +1152,91 @@ public class TsFileWriteApiTest {
}
}
+ @Test
+ public void queryDateColumnInTableModel()
+ throws IOException, WriteProcessException, ReadProcessException {
+ setEnv(100 * 1024 * 1024, 10 * 1024);
+ TableSchema tableSchema =
+ new TableSchema(
+ "Table1",
+ Arrays.asList(
+ new ColumnSchema("tag1", TSDataType.STRING,
ColumnCategory.TAG),
+ new ColumnSchema("s1", TSDataType.DATE, ColumnCategory.FIELD),
+ new ColumnSchema("s2", TSDataType.BOOLEAN,
ColumnCategory.FIELD)));
+ LocalDate date = LocalDate.parse("1970-01-01");
+ Tablet tablet =
+ new Tablet(
+ Arrays.asList("tag1", "s1", "s2"),
+ Arrays.asList(TSDataType.STRING, TSDataType.DATE,
TSDataType.BOOLEAN));
+ tablet.addTimestamp(0, 0);
+ tablet.addValue(0, "tag1", "d1");
+ tablet.addValue(0, "s1", date);
+ tablet.addValue(0, "s2", true);
+
+ try (ITsFileWriter writer =
+ new TsFileWriterBuilder().file(f).tableSchema(tableSchema).build()) {
+ writer.write(tablet);
+ }
+
+ try (ITsFileReader reader = new TsFileReaderBuilder().file(f).build();
+ ResultSet resultSet =
+ reader.query(
+ "table1", Arrays.asList("tag1", "s1", "s2"), Long.MIN_VALUE,
Long.MAX_VALUE)) {
+ Assert.assertTrue(resultSet.next());
+ Assert.assertEquals(0L, resultSet.getLong("Time"));
+ Assert.assertEquals("d1", resultSet.getString("tag1"));
+ Assert.assertEquals(date, resultSet.getDate("s1"));
+ Assert.assertTrue(resultSet.getBoolean("s2"));
+ }
+ }
+
+ @Test
+ public void queryTimestampStringBlobColumnsInTableModel()
+ throws IOException, WriteProcessException, ReadProcessException {
+ setEnv(100 * 1024 * 1024, 10 * 1024);
+ TableSchema tableSchema =
+ new TableSchema(
+ "Table1",
+ Arrays.asList(
+ new ColumnSchema("tag1", TSDataType.STRING,
ColumnCategory.TAG),
+ new ColumnSchema("s1", TSDataType.TIMESTAMP,
ColumnCategory.FIELD),
+ new ColumnSchema("s2", TSDataType.STRING,
ColumnCategory.FIELD),
+ new ColumnSchema("s3", TSDataType.BLOB,
ColumnCategory.FIELD)));
+ long timestampValue = 123456789L;
+ String stringValue = "hello-string";
+ byte[] blobValue = "hello-blob".getBytes(StandardCharsets.UTF_8);
+ Tablet tablet =
+ new Tablet(
+ Arrays.asList("tag1", "s1", "s2", "s3"),
+ Arrays.asList(
+ TSDataType.STRING, TSDataType.TIMESTAMP, TSDataType.STRING,
TSDataType.BLOB));
+ tablet.addTimestamp(0, 0);
+ tablet.addValue(0, "tag1", "d1");
+ tablet.addValue(0, "s1", timestampValue);
+ tablet.addValue(0, "s2", stringValue);
+ tablet.addValue(0, "s3", blobValue);
+
+ try (ITsFileWriter writer =
+ new TsFileWriterBuilder().file(f).tableSchema(tableSchema).build()) {
+ writer.write(tablet);
+ }
+
+ try (ITsFileReader reader = new TsFileReaderBuilder().file(f).build();
+ ResultSet resultSet =
+ reader.query(
+ "table1",
+ Arrays.asList("tag1", "s1", "s2", "s3"),
+ Long.MIN_VALUE,
+ Long.MAX_VALUE)) {
+ Assert.assertTrue(resultSet.next());
+ Assert.assertEquals(0L, resultSet.getLong("Time"));
+ Assert.assertEquals("d1", resultSet.getString("tag1"));
+ Assert.assertEquals(timestampValue, resultSet.getLong("s1"));
+ Assert.assertEquals(stringValue, resultSet.getString("s2"));
+ Assert.assertArrayEquals(blobValue, resultSet.getBinary("s3"));
+ }
+ }
+
@Test
public void calculateTableSize() throws IOException, WriteProcessException {
TableSchema tableSchema1 =