This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 772bab4abe0 Fix display of Blob type in last query
772bab4abe0 is described below
commit 772bab4abe078b1f843736df1c57369c18416c50
Author: Weihao Li <[email protected]>
AuthorDate: Wed Jul 16 06:41:26 2025 +0800
Fix display of Blob type in last query
---
.../db/it/last/IoTDBLastQueryLastCacheIT.java | 2 +-
.../plan/planner/LocalExecutionPlanContext.java | 13 ++++++++-----
.../plan/planner/LogicalPlanBuilder.java | 6 +++++-
.../plan/planner/OperatorTreeGenerator.java | 19 +++++++++++--------
.../plan/node/process/last/LastQueryNode.java | 12 ++++++++++--
.../plan/node/source/LastQueryScanNode.java | 22 +++++++++++++++++++++-
.../plan/planner/distribution/LastQueryTest.java | 1 +
.../logical/DataQueryLogicalPlannerTest.java | 5 ++++-
.../node/source/LastQueryScanNodeSerdeTest.java | 2 ++
9 files changed, 63 insertions(+), 19 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
index c4584f22fab..1c69857a3c5 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryLastCacheIT.java
@@ -183,7 +183,7 @@ public class IoTDBLastQueryLastCacheIT {
}
@Test
- public void testLastQuerySortWithBlobType() {
+ public void testLastQueryWithBlobType() {
String[] expectedHeader =
new String[] {TIMESTAMP_STR, TIMESERIES_STR, VALUE_STR, DATA_TYPE_STR};
String[] retArray =
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanContext.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanContext.java
index de4f99ff089..6c9d52dbe8c 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanContext.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanContext.java
@@ -83,8 +83,8 @@ public class LocalExecutionPlanContext {
private List<TSDataType> cachedDataTypes;
// left is cached last value in last query
- // right is full path for each cached last value
- private List<Pair<TimeValuePair, Binary>> cachedLastValueAndPathList;
+ // right is full path and DataType for each cached last value
+ private List<Pair<TimeValuePair, Pair<Binary, TSDataType>>>
cachedLastValueAndPathList;
// whether we need to update last cache
private boolean needUpdateLastCache;
@@ -274,15 +274,18 @@ public class LocalExecutionPlanContext {
this.needUpdateLastCache = needUpdateLastCache;
}
- public void addCachedLastValue(TimeValuePair timeValuePair, String fullPath)
{
+ public void addCachedLastValue(
+ TimeValuePair timeValuePair, String fullPath, TSDataType dataType) {
if (cachedLastValueAndPathList == null) {
cachedLastValueAndPathList = new ArrayList<>();
}
cachedLastValueAndPathList.add(
- new Pair<>(timeValuePair, new Binary(fullPath,
TSFileConfig.STRING_CHARSET)));
+ new Pair<>(
+ timeValuePair,
+ new Pair<>(new Binary(fullPath, TSFileConfig.STRING_CHARSET),
dataType)));
}
- public List<Pair<TimeValuePair, Binary>> getCachedLastValueAndPathList() {
+ public List<Pair<TimeValuePair, Pair<Binary, TSDataType>>>
getCachedLastValueAndPathList() {
return cachedLastValueAndPathList;
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
index 84d0d84224d..9dbb0b8274d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
@@ -257,6 +257,8 @@ public class LogicalPlanBuilder {
sourceExpression.isViewExpression()
? sourceExpression.getViewPath().getFullPath()
: null;
+ TSDataType outputViewPathType =
+ outputViewPath == null ? null : selectedPath.getSeriesType();
PartialPath devicePath = selectedPath.getDevicePath();
// For expression with view path, we do not use the deviceId in
Map.Entry because it is a
@@ -268,7 +270,8 @@ public class LogicalPlanBuilder {
devicePath,
selectedPath.isUnderAlignedEntity(),
Collections.singletonList(selectedPath.getMeasurementSchema()),
- outputViewPath);
+ outputViewPath,
+ outputViewPathType);
this.context.reserveMemoryForFrontEnd(memCost);
}
} else {
@@ -291,6 +294,7 @@ public class LogicalPlanBuilder {
devicePath,
aligned,
measurementSchemas,
+ null,
null);
this.context.reserveMemoryForFrontEnd(memCost);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
index 505af22ffc7..55b2defa543 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
@@ -3047,9 +3047,11 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
}
} else { // cached last value is satisfied, put it into
LastCacheScanOperator
if (node.getOutputViewPath() != null) {
- context.addCachedLastValue(timeValuePair, node.getOutputViewPath());
+ context.addCachedLastValue(
+ timeValuePair, node.getOutputViewPath(),
node.getOutputViewPathType());
} else {
- context.addCachedLastValue(timeValuePair,
measurementPath.getFullPath());
+ context.addCachedLastValue(
+ timeValuePair, measurementPath.getFullPath(),
measurementSchema.getType());
}
}
}
@@ -3097,7 +3099,7 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
.filter(Objects::nonNull)
.collect(Collectors.toList());
- List<Pair<TimeValuePair, Binary>> cachedLastValueAndPathList =
+ List<Pair<TimeValuePair, Pair<Binary, TSDataType>>>
cachedLastValueAndPathList =
context.getCachedLastValueAndPathList();
int initSize = cachedLastValueAndPathList != null ?
cachedLastValueAndPathList.size() : 0;
@@ -3109,9 +3111,9 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
LastQueryUtil.appendLastValueRespectBlob(
builder,
timeValuePair.getTimestamp(),
- cachedLastValueAndPathList.get(i).right,
+ cachedLastValueAndPathList.get(i).right.getLeft(),
timeValuePair.getValue(),
- timeValuePair.getValue().getDataType().name());
+ cachedLastValueAndPathList.get(i).right.getRight().name());
}
OperatorContext operatorContext =
context
@@ -3127,7 +3129,8 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
node.getTimeseriesOrdering() == ASC ? ASC_BINARY_COMPARATOR :
DESC_BINARY_COMPARATOR;
// sort values from last cache
if (initSize > 0) {
- cachedLastValueAndPathList.sort(Comparator.comparing(Pair::getRight,
comparator));
+ cachedLastValueAndPathList.sort(
+ Comparator.comparing(pair -> pair.getRight().getLeft(),
comparator));
}
TsBlockBuilder builder = LastQueryUtil.createTsBlockBuilder(initSize);
@@ -3136,9 +3139,9 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
LastQueryUtil.appendLastValueRespectBlob(
builder,
timeValuePair.getTimestamp(),
- cachedLastValueAndPathList.get(i).right,
+ cachedLastValueAndPathList.get(i).right.getLeft(),
timeValuePair.getValue(),
- timeValuePair.getValue().getDataType().name());
+ cachedLastValueAndPathList.get(i).right.getRight().name());
}
OperatorContext operatorContext =
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
index 4ce3f29750c..cbae6e9abd9 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/last/LastQueryNode.java
@@ -29,6 +29,7 @@ import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.source.LastQuerySc
import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.source.SourceNode;
import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
+import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.utils.RamUsageEstimator;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.apache.tsfile.write.schema.IMeasurementSchema;
@@ -89,7 +90,8 @@ public class LastQueryNode extends MultiChildProcessNode {
PartialPath devicePath,
boolean aligned,
List<IMeasurementSchema> measurementSchemas,
- String outputViewPath) {
+ String outputViewPath,
+ TSDataType outputViewPathType) {
List<Integer> idxList = new ArrayList<>(measurementSchemas.size());
for (IMeasurementSchema measurementSchema : measurementSchemas) {
int idx =
@@ -103,7 +105,13 @@ public class LastQueryNode extends MultiChildProcessNode {
}
LastQueryScanNode scanNode =
new LastQueryScanNode(
- id, devicePath, aligned, idxList, outputViewPath,
globalMeasurementSchemaList);
+ id,
+ devicePath,
+ aligned,
+ idxList,
+ outputViewPath,
+ outputViewPathType,
+ globalMeasurementSchemaList);
children.add(scanNode);
return scanNode.ramBytesUsed();
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/LastQueryScanNode.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/LastQueryScanNode.java
index 30b10f51014..1d40c1457a2 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/LastQueryScanNode.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/source/LastQueryScanNode.java
@@ -31,6 +31,7 @@ import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeUtil;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
import com.google.common.collect.ImmutableList;
+import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.utils.RamUsageEstimator;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.apache.tsfile.write.schema.IMeasurementSchema;
@@ -64,6 +65,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode {
private List<IMeasurementSchema> globalMeasurementSchemaList;
private final String outputViewPath;
+ private final TSDataType outputViewPathType;
// The id of DataRegion where the node will run
private TRegionReplicaSet regionReplicaSet;
@@ -75,12 +77,14 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
String outputViewPath,
+ TSDataType outputViewPathType,
List<IMeasurementSchema> globalMeasurementSchemaList) {
super(id, new AtomicInteger(1));
this.aligned = aligned;
this.devicePath = devicePath;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
this.outputViewPath = outputViewPath;
+ this.outputViewPathType = outputViewPathType;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
}
@@ -90,7 +94,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode {
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
- String outputViewPath) {
+ String outputViewPath,
+ TSDataType outputViewPathType) {
this(
id,
devicePath,
@@ -98,6 +103,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode {
indexOfMeasurementSchemas,
dataNodeSeriesScanNum,
outputViewPath,
+ outputViewPathType,
null);
}
@@ -108,12 +114,14 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
String outputViewPath,
+ TSDataType outputViewPathType,
List<IMeasurementSchema> globalMeasurementSchemaList) {
super(id, dataNodeSeriesScanNum);
this.aligned = aligned;
this.devicePath = devicePath;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
this.outputViewPath = outputViewPath;
+ this.outputViewPathType = outputViewPathType;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
}
@@ -124,6 +132,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
String outputViewPath,
+ TSDataType outputViewPathType,
TRegionReplicaSet regionReplicaSet,
boolean deviceInMultiRegion,
List<IMeasurementSchema> globalMeasurementSchemaList) {
@@ -132,6 +141,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
this.aligned = aligned;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
this.outputViewPath = outputViewPath;
+ this.outputViewPathType = outputViewPathType;
this.regionReplicaSet = regionReplicaSet;
this.deviceInMultiRegion = deviceInMultiRegion;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
@@ -162,6 +172,10 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
return outputViewPath;
}
+ public TSDataType getOutputViewPathType() {
+ return outputViewPathType;
+ }
+
public String getOutputSymbolForSort() {
if (outputViewPath != null) {
return outputViewPath;
@@ -196,6 +210,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
indexOfMeasurementSchemas,
getDataNodeSeriesScanNum(),
outputViewPath,
+ outputViewPathType,
regionReplicaSet,
deviceInMultiRegion,
globalMeasurementSchemaList);
@@ -226,6 +241,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
&& Objects.equals(aligned, that.aligned)
&& Objects.equals(indexOfMeasurementSchemas,
that.indexOfMeasurementSchemas)
&& Objects.equals(outputViewPath, that.outputViewPath)
+ && Objects.equals(outputViewPathType, that.outputViewPathType)
&& Objects.equals(regionReplicaSet, that.regionReplicaSet);
}
@@ -275,6 +291,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
ReadWriteIOUtils.write(outputViewPath == null, byteBuffer);
if (outputViewPath != null) {
ReadWriteIOUtils.write(outputViewPath, byteBuffer);
+ ReadWriteIOUtils.write(outputViewPathType, byteBuffer);
}
ReadWriteIOUtils.write(deviceInMultiRegion, byteBuffer);
}
@@ -292,6 +309,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
ReadWriteIOUtils.write(outputViewPath == null, stream);
if (outputViewPath != null) {
ReadWriteIOUtils.write(outputViewPath, stream);
+ ReadWriteIOUtils.write(outputViewPathType, stream);
}
ReadWriteIOUtils.write(deviceInMultiRegion, stream);
}
@@ -308,6 +326,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
int dataNodeSeriesScanNum = ReadWriteIOUtils.readInt(byteBuffer);
boolean isNull = ReadWriteIOUtils.readBool(byteBuffer);
String outputPathSymbol = isNull ? null :
ReadWriteIOUtils.readString(byteBuffer);
+ TSDataType dataType = isNull ? null :
ReadWriteIOUtils.readDataType(byteBuffer);
boolean deviceInMultiRegion = ReadWriteIOUtils.readBool(byteBuffer);
PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
return new LastQueryScanNode(
@@ -317,6 +336,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
measurementSchemas,
new AtomicInteger(dataNodeSeriesScanNum),
outputPathSymbol,
+ dataType,
null,
deviceInMultiRegion,
null);
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/LastQueryTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/LastQueryTest.java
index e1893916d9e..86eb189680f 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/LastQueryTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/LastQueryTest.java
@@ -198,6 +198,7 @@ public class LastQueryTest {
selectPath.getDevicePath(),
selectPath.isUnderAlignedEntity(),
Collections.singletonList(selectPath.getMeasurementSchema()),
+ null,
null);
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
index b92ef232d3d..2298b6ab631 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/logical/DataQueryLogicalPlannerTest.java
@@ -89,6 +89,7 @@ public class DataQueryLogicalPlannerTest {
d1s1Path.getDevicePath(),
d1s1Path.isUnderAlignedEntity(),
measurementSchemas,
+ null,
null);
measurementSchemas =
@@ -102,11 +103,12 @@ public class DataQueryLogicalPlannerTest {
d2s1Path.getDevicePath(),
d2s1Path.isUnderAlignedEntity(),
measurementSchemas,
+ null,
null);
AlignedPath aPath = (AlignedPath) schemaMap.get("root.sg.d2.a");
lastQueryNode.addDeviceLastQueryScanNode(
- queryId.genPlanNodeId(), aPath.getDevicePath(), true,
aPath.getSchemaList(), null);
+ queryId.genPlanNodeId(), aPath.getDevicePath(), true,
aPath.getSchemaList(), null, null);
PlanNode actualPlan = parseSQLToPlanNode(sql);
Assert.assertEquals(actualPlan, lastQueryNode);
@@ -132,6 +134,7 @@ public class DataQueryLogicalPlannerTest {
s3Path.getDevicePath(),
s3Path.isUnderAlignedEntity(),
measurementSchemas,
+ null,
null);
SortNode sortNode =
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/source/LastQueryScanNodeSerdeTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/source/LastQueryScanNodeSerdeTest.java
index 270411f3f51..68a7fa0df0d 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/source/LastQueryScanNodeSerdeTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/node/source/LastQueryScanNodeSerdeTest.java
@@ -44,6 +44,7 @@ public class LastQueryScanNodeSerdeTest {
true,
Arrays.asList(0, 1),
null,
+ null,
Arrays.asList(
new MeasurementSchema("s1", TSDataType.INT32),
new MeasurementSchema("s0", TSDataType.BOOLEAN)));
@@ -59,6 +60,7 @@ public class LastQueryScanNodeSerdeTest {
false,
Arrays.asList(0, 1),
null,
+ null,
Arrays.asList(
new MeasurementSchema("s1", TSDataType.INT32),
new MeasurementSchema("s0", TSDataType.BOOLEAN)));