This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/dev/1.3 by this push:
new a55519b9291 [To dev/1.3] Fix timeseries alias display in last for
TreeModel #17117
a55519b9291 is described below
commit a55519b92919877e6287e1afa85c4f54ede64785
Author: Weihao Li <[email protected]>
AuthorDate: Fri Jan 30 11:55:09 2026 +0800
[To dev/1.3] Fix timeseries alias display in last for TreeModel #17117
(cherry picked from commit 5f641b262c33b160e6231adfe955342e8e3ca108)
---
.../db/it/aligned/IoTDBAlignedLastQueryIT.java | 114 ++++++++++++++
.../iotdb/db/it/last/IoTDBLastQueryAlias2IT.java | 60 ++++++++
.../iotdb/db/it/last/IoTDBLastQueryAliasIT.java | 164 +++++++++++++++++++++
.../AlignedUpdateViewPathLastCacheOperator.java | 25 +++-
.../process/last/UpdateLastCacheOperator.java | 2 +-
.../last/UpdateViewPathLastCacheOperator.java | 2 +-
.../queryengine/plan/analyze/AnalyzeVisitor.java | 6 +-
.../plan/planner/LogicalPlanBuilder.java | 47 +++++-
.../plan/planner/OperatorTreeGenerator.java | 23 ++-
.../plan/planner/plan/node/PlanGraphPrinter.java | 7 +-
.../plan/node/process/last/LastQueryNode.java | 11 +-
.../plan/node/source/LastQueryScanNode.java | 99 +++++++++----
.../plan/planner/distribution/LastQueryTest.java | 9 +-
.../logical/DataQueryLogicalPlannerTest.java | 11 +-
.../node/source/LastQueryScanNodeSerdeTest.java | 2 +
15 files changed, 517 insertions(+), 65 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedLastQueryIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedLastQueryIT.java
index a32572d4778..214a2c31806 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedLastQueryIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/aligned/IoTDBAlignedLastQueryIT.java
@@ -340,4 +340,118 @@ public class IoTDBAlignedLastQueryIT {
selectSomeAlignedLastWithTimeFilterTest();
selectSomeAlignedAndNonAlignedLastWithTimeFilterTest();
}
+
+ @Test
+ public void testLastAlias() {
+ String[] sqls =
+ new String[] {
+ "create aligned timeseries root.ln_1.tb_6141(fengjituichu_BOOLEAN
BOOLEAN encoding=RLE,`chushuiNH4-N_DOUBLE` DOUBLE
encoding=GORILLA,mochanshuizhuangtai_BOOLEAN BOOLEAN encoding=RLE,11_TEXT TEXT
encoding=PLAIN,chanshuijianxieyunxingshijianshezhi_DOUBLE DOUBLE
encoding=GORILLA,wenben_TEXT TEXT encoding=PLAIN, fengjitouru_BOOLEAN BOOLEAN
encoding=RLE,meiju_INT32 INT32 encoding=RLE,chushuiTP_DOUBLE DOUBLE
encoding=GORILLA,shuiguanliusu_DOUBLE DOUBLE encoding=GORILLA,CO2_DOUBLE DOU
[...]
+ "alter timeseries root.ln_1.tb_6141.fengjituichu_BOOLEAN upsert
alias=fengjituichu;",
+ "alter timeseries root.ln_1.tb_6141.shuiguanliusu_DOUBLE upsert
alias=shuiguanliusu;",
+ "alter timeseries root.ln_1.tb_6141.CO2_DOUBLE upsert alias=CO2;",
+ "alter timeseries root.ln_1.tb_6141.fengjitouru_BOOLEAN upsert
alias=fengjitouru;",
+ "alter timeseries
root.ln_1.tb_6141.chanshuijianxieyunxingshijianshezhi_DOUBLE upsert
alias=chanshuijianxieyunxingshijianshezhi;",
+ "alter timeseries root.ln_1.tb_6141.mochanshuizhuangtai_BOOLEAN
upsert alias=mochanshuizhuangtai;",
+ "alter timeseries root.ln_1.tb_6141.meiju_INT32 upsert alias=meiju;",
+ "alter timeseries root.ln_1.tb_6141.chushuiTP_DOUBLE upsert
alias=chushuiTP;",
+ "alter timeseries root.ln_1.tb_6141.wenben_TEXT upsert
alias=wenben;",
+ "alter timeseries root.ln_1.tb_6141.`chushuiNH4-N_DOUBLE` upsert
alias=`chushuiNH4-N`;",
+ "alter timeseries root.ln_1.tb_6141.gongnengma_DOUBLE upsert
alias=gongnengma;",
+ "alter timeseries root.ln_1.tb_6141.11_TEXT upsert alias=`11`;",
+ "alter timeseries root.ln_1.tb_6141.`kaiguanliang-yunxing_BOOLEAN`
upsert alias=`kaiguanliang-yunxing`;",
+ "insert into
root.ln_1.tb_6141(time,chanshuijianxieyunxingshijianshezhi_DOUBLE) aligned
values(1679365910000,10.0);",
+ "insert into root.ln_1.tb_6141(time,chushuiTP_DOUBLE) aligned
values(1679365910000,15.0);",
+ "insert into root.ln_1.tb_6141(time,gongnengma_DOUBLE) aligned
values(1679477545000,2.0);",
+ "insert into root.ln_1.tb_6141(time,wenben_TEXT) aligned
values(1675995566000,52);",
+ "insert into root.ln_1.tb_6141(time,meiju_INT32) aligned
values(1675995566000,2);",
+ "insert into root.ln_1.tb_6141(time,shuiguanliusu_DOUBLE) aligned
values(1679365910000,15.0);",
+ "insert into root.ln_1.tb_6141(time,mochanshuizhuangtai_BOOLEAN)
aligned values(1677033625000,true);",
+ "insert into root.ln_1.tb_6141(time,fengjitouru_BOOLEAN) aligned
values(1675995566000,true);",
+ "insert into root.ln_1.tb_6141(time,fengjituichu_BOOLEAN) aligned
values(1675995566000,false);",
+ "insert into root.ln_1.tb_6141(time,11_TEXT) aligned
values(1679365910000,13);",
+ "insert into root.ln_1.tb_6141(time,CO2_DOUBLE) aligned
values(1679365910000,12.0);",
+ "insert into root.ln_1.tb_6141(time,`chushuiNH4-N_DOUBLE`) aligned
values(1679365910000,12.0);",
+ "insert into root.ln_1.tb_6141(time,`kaiguanliang-yunxing_BOOLEAN`)
aligned values(1675995566000,false);",
+ };
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ // create aligned and non-aligned time series
+ for (String sql : sqls) {
+ statement.addBatch(sql);
+ }
+ statement.executeBatch();
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ Set<String> retSet =
+ new HashSet<>(
+ Arrays.asList(
+ "1679477545000,root.ln_1.tb_6141.gongnengma,2.0,DOUBLE",
+ "1675995566000,root.ln_1.tb_6141.wenben,52,TEXT"));
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ try (ResultSet resultSet =
+ statement.executeQuery(
+ "select last gongnengma,wenben from root.ln_1.tb_6141 order by
timeseries asc;")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(TIMESERIES_STR)
+ + ","
+ + resultSet.getString(VALUE_STR)
+ + ","
+ + resultSet.getString(DATA_TYPE_STR);
+ assertTrue(ans, retSet.contains(ans));
+ cnt++;
+ }
+ assertEquals(retSet.size(), cnt);
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ retSet =
+ new HashSet<>(
+ Arrays.asList(
+ "1679477545000,root.ln_1.tb_6141.gongnengma,2.0,DOUBLE",
+
"1677033625000,root.ln_1.tb_6141.mochanshuizhuangtai,true,BOOLEAN",
+ "1675995566000,root.ln_1.tb_6141.wenben,52,TEXT"));
+
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ try (ResultSet resultSet =
+ statement.executeQuery(
+ "select last gongnengma,mochanshuizhuangtai,wenben from
root.ln_1.tb_6141 order by timeseries asc;")) {
+ int cnt = 0;
+ while (resultSet.next()) {
+ String ans =
+ resultSet.getString(TIMESTAMP_STR)
+ + ","
+ + resultSet.getString(TIMESERIES_STR)
+ + ","
+ + resultSet.getString(VALUE_STR)
+ + ","
+ + resultSet.getString(DATA_TYPE_STR);
+ assertTrue(ans, retSet.contains(ans));
+ cnt++;
+ }
+ assertEquals(retSet.size(), cnt);
+ }
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAlias2IT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAlias2IT.java
new file mode 100644
index 00000000000..6e8f2753fa8
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAlias2IT.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.last;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.apache.iotdb.db.it.utils.TestUtils.prepareData;
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBLastQueryAlias2IT extends IoTDBLastQueryAliasIT {
+ @BeforeClass
+ public static void setUp() throws Exception {
+ // with lastCache
+ EnvFactory.getEnv().getConfig().getCommonConfig().setEnableLastCache(true);
+ EnvFactory.getEnv().initClusterEnvironment();
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ prepareData(SQLs);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAliasIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAliasIT.java
new file mode 100644
index 00000000000..4772804f384
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/last/IoTDBLastQueryAliasIT.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.it.last;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.apache.iotdb.db.it.utils.TestUtils.prepareData;
+import static org.apache.iotdb.db.it.utils.TestUtils.resultSetEqualTest;
+import static org.apache.iotdb.itbase.constant.TestConstant.DATA_TYPE_STR;
+import static org.apache.iotdb.itbase.constant.TestConstant.TIMESERIES_STR;
+import static org.apache.iotdb.itbase.constant.TestConstant.TIMESTAMP_STR;
+import static org.apache.iotdb.itbase.constant.TestConstant.VALUE_STR;
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBLastQueryAliasIT {
+ protected static final String[] SQLs =
+ new String[] {
+ "create timeseries root.test.d1.s1(alias3) with dataType= int32",
+ "create timeseries root.test.d1.s2(alias2) with dataType= int32",
+ "create timeseries root.test.d1.s3(alias1) with dataType= int32",
+ "insert into root.test.d1(timestamp,s1,s2,s3) values(1,1,2,3)",
+ "create aligned timeseries root.test.d2 (s1 (alias3) int32,s2 (alias2)
int32,s3 (alias1) int32)",
+ "insert into root.test.d2(timestamp,s1,s2,s3) values(2,2,3,4)",
+ };
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ // without lastCache
+
EnvFactory.getEnv().getConfig().getCommonConfig().setEnableLastCache(false);
+ EnvFactory.getEnv().initClusterEnvironment();
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ prepareData(SQLs);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ @Test
+ public void nonAlignedTest() {
+ String[] expectedHeader =
+ new String[] {TIMESTAMP_STR, TIMESERIES_STR, VALUE_STR, DATA_TYPE_STR};
+
+ String[] retArray =
+ new String[] {
+ "1,root.test.d1.alias3,1,INT32,",
+ };
+ resultSetEqualTest("select last alias3 from root.test.d1", expectedHeader,
retArray);
+
+ retArray =
+ new String[] {
+ "1,root.test.d1.alias3,1,INT32,",
+ "1,root.test.d1.alias2,2,INT32,",
+ "1,root.test.d1.alias1,3,INT32,",
+ };
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d1", expectedHeader,
retArray);
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d1", expectedHeader,
retArray);
+
+ retArray =
+ new String[] {
+ "1,root.test.d1.alias1,3,INT32,",
+ "1,root.test.d1.alias2,2,INT32,",
+ "1,root.test.d1.alias3,1,INT32,",
+ };
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d1 order by
timeseries",
+ expectedHeader,
+ retArray);
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d1 order by
timeseries",
+ expectedHeader,
+ retArray);
+ }
+
+ @Test
+ public void alignedTest() {
+ String[] expectedHeader =
+ new String[] {TIMESTAMP_STR, TIMESERIES_STR, VALUE_STR, DATA_TYPE_STR};
+ String[] retArray =
+ new String[] {
+ "2,root.test.d2.alias3,2,INT32,",
+ "2,root.test.d2.alias2,3,INT32,",
+ "2,root.test.d2.alias1,4,INT32,",
+ };
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d2", expectedHeader,
retArray);
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d2", expectedHeader,
retArray);
+
+ retArray =
+ new String[] {
+ "2,root.test.d2.alias1,4,INT32,",
+ "2,root.test.d2.alias2,3,INT32,",
+ "2,root.test.d2.alias3,2,INT32,",
+ };
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d2 order by
timeseries",
+ expectedHeader,
+ retArray);
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.d2 order by
timeseries",
+ expectedHeader,
+ retArray);
+ }
+
+ @Test
+ public void mixedTest() {
+ String[] expectedHeader =
+ new String[] {TIMESTAMP_STR, TIMESERIES_STR, VALUE_STR, DATA_TYPE_STR};
+ String[] retArray =
+ new String[] {
+ "1,root.test.d1.alias1,3,INT32,",
+ "1,root.test.d1.alias2,2,INT32,",
+ "1,root.test.d1.alias3,1,INT32,",
+ "2,root.test.d2.alias1,4,INT32,",
+ "2,root.test.d2.alias2,3,INT32,",
+ "2,root.test.d2.alias3,2,INT32,",
+ };
+ resultSetEqualTest(
+ "select last alias3,alias2,alias1 from root.test.* order by
timeseries",
+ expectedHeader,
+ retArray);
+ }
+}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/AlignedUpdateViewPathLastCacheOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/AlignedUpdateViewPathLastCacheOperator.java
index 3fc9f0412bc..5d5afbedb5b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/AlignedUpdateViewPathLastCacheOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/AlignedUpdateViewPathLastCacheOperator.java
@@ -28,11 +28,15 @@ import
org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.DataNodeSchemaC
import org.apache.tsfile.utils.RamUsageEstimator;
import org.apache.tsfile.utils.TsPrimitiveType;
+import java.util.List;
+
import static com.google.common.base.Preconditions.checkArgument;
public class AlignedUpdateViewPathLastCacheOperator extends
AlignedUpdateLastCacheOperator {
-
- private final String outputViewPath;
+ // Now not only a view path will be set here, but also the measurement path
with alias will be set
+ // .e.g last query path: root.test.d1(s1(alias1), s2), outputPaths:
[root.test.d1.alias1, null]
+ private final List<String> outputPaths;
+ private int outputPathIndex = 0;
public AlignedUpdateViewPathLastCacheOperator(
OperatorContext operatorContext,
@@ -41,7 +45,7 @@ public class AlignedUpdateViewPathLastCacheOperator extends
AlignedUpdateLastCac
DataNodeSchemaCache dataNodeSchemaCache,
boolean needUpdateCache,
boolean needUpdateNullEntry,
- String outputViewPath,
+ List<String> outputPaths,
boolean deviceInMultiRegion) {
super(
operatorContext,
@@ -51,19 +55,26 @@ public class AlignedUpdateViewPathLastCacheOperator extends
AlignedUpdateLastCac
needUpdateCache,
needUpdateNullEntry,
deviceInMultiRegion);
- checkArgument(seriesPath.getMeasurementList().size() == 1);
- this.outputViewPath = outputViewPath;
+ checkArgument(outputPaths != null, "outputPaths shouldn't be null");
+ this.outputPaths = outputPaths;
}
@Override
protected void appendLastValueToTsBlockBuilder(
long lastTime, TsPrimitiveType lastValue, MeasurementPath
measurementPath, String type) {
+ String outputPath = outputPaths.get(outputPathIndex);
LastQueryUtil.appendLastValue(
- tsBlockBuilder, lastTime, outputViewPath, lastValue.getStringValue(),
type);
+ tsBlockBuilder,
+ lastTime,
+ outputPath == null ? measurementPath.getFullPath() : outputPath,
+ lastValue.getStringValue(),
+ type);
+ outputPathIndex++;
}
@Override
public long ramBytesUsed() {
- return super.ramBytesUsed() + RamUsageEstimator.sizeOf(outputViewPath);
+ return super.ramBytesUsed()
+ + outputPaths.stream().mapToLong(path ->
RamUsageEstimator.sizeOf(path)).sum();
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateLastCacheOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateLastCacheOperator.java
index d55f1d9fd4e..3e8a92ded26 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateLastCacheOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateLastCacheOperator.java
@@ -40,7 +40,7 @@ public class UpdateLastCacheOperator extends
AbstractUpdateLastCacheOperator {
// fullPath for queried time series
// It should be exact PartialPath, neither MeasurementPath nor AlignedPath,
because lastCache only
// accept PartialPath
- private final MeasurementPath fullPath;
+ protected final MeasurementPath fullPath;
// type for queried time series
protected final String dataType;
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateViewPathLastCacheOperator.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateViewPathLastCacheOperator.java
index dcc83bddfbd..d3ed5b2a7b1 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateViewPathLastCacheOperator.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/last/UpdateViewPathLastCacheOperator.java
@@ -29,7 +29,7 @@ import org.apache.tsfile.utils.RamUsageEstimator;
import org.apache.tsfile.utils.TsPrimitiveType;
public class UpdateViewPathLastCacheOperator extends UpdateLastCacheOperator {
-
+ // Now not only a view path will be set here, but also the measurement path
with alias will be set
private final String outputViewPath;
public UpdateViewPathLastCacheOperator(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
index e79fe9e3f40..a28ca79c956 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
@@ -657,7 +657,11 @@ public class AnalyzeVisitor extends
StatementVisitor<Analysis, MPPQueryContext>
timeseriesOrdering != null
? new
TreeMap<>(timeseriesOrdering.getStringComparator())
: new LinkedHashMap<>())
- .put(outputPath.getMeasurement(), timeSeriesOperand);
+ .put(
+ outputPath.isMeasurementAliasExists()
+ ? outputPath.getMeasurementAlias()
+ : outputPath.getMeasurement(),
+ timeSeriesOperand);
} else {
lastQueryNonWritableViewSourceExpressionMap =
lastQueryNonWritableViewSourceExpressionMap == null
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 1d206b03ca1..81afda469c3 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
@@ -252,10 +252,24 @@ public class LogicalPlanBuilder {
for (Expression sourceExpression :
measurementToExpressionsOfDevice.values()) {
MeasurementPath selectedPath =
(MeasurementPath) ((TimeSeriesOperand)
sourceExpression).getPath();
- String outputViewPath =
- sourceExpression.isViewExpression()
- ? sourceExpression.getViewPath().getFullPath()
- : null;
+
+ String outputPath;
+ TSDataType outputViewPathType = null;
+ // the path is view, use the view path as the output path
+ if (sourceExpression.isViewExpression()) {
+ outputPath = sourceExpression.getViewPath().getFullPath();
+ outputViewPathType = selectedPath.getSeriesType();
+ } else {
+ outputPath = selectedPath.getFullPath();
+ }
+ // the path has alias, use alias as the output path
+ if (selectedPath.isMeasurementAliasExists()) {
+ outputPath =
+ selectedPath
+ .getDevicePath()
+
.concatAsMeasurementPath(selectedPath.getMeasurementAlias())
+ .toString();
+ }
PartialPath devicePath = selectedPath.getDevicePath();
// For expression with view path, we do not use the deviceId in
Map.Entry because it is a
@@ -267,7 +281,8 @@ public class LogicalPlanBuilder {
devicePath,
selectedPath.isUnderAlignedEntity(),
Collections.singletonList(selectedPath.getMeasurementSchema()),
- outputViewPath);
+ Collections.singletonList(outputPath),
+ outputViewPathType != null);
this.context.reserveMemoryForFrontEnd(memCost);
}
} else {
@@ -275,12 +290,31 @@ public class LogicalPlanBuilder {
List<IMeasurementSchema> measurementSchemas =
new ArrayList<>(measurementToExpressionsOfDevice.size());
PartialPath devicePath = null;
+ List<String> outputPaths = null;
+ int i = 0;
for (Expression sourceExpression :
measurementToExpressionsOfDevice.values()) {
MeasurementPath selectedPath =
(MeasurementPath) ((TimeSeriesOperand)
sourceExpression).getPath();
aligned = selectedPath.isUnderAlignedEntity();
devicePath = devicePath == null ? selectedPath.getDevicePath() :
devicePath;
measurementSchemas.add(selectedPath.getMeasurementSchema());
+
+ // series has alias and use alias to SELECT
+ if (selectedPath.isMeasurementAliasExists()) {
+ if (outputPaths == null) {
+ // fill null as default value
+ outputPaths =
+ new ArrayList<>(
+
Collections.nCopies(measurementToExpressionsOfDevice.size(), null));
+ }
+ outputPaths.set(
+ i,
+ selectedPath
+ .getDevicePath()
+
.concatAsMeasurementPath(selectedPath.getMeasurementAlias())
+ .toString());
+ }
+ i++;
}
// DeviceId is needed in the distribution plan stage
devicePath.setIDeviceID(deviceId);
@@ -290,7 +324,8 @@ public class LogicalPlanBuilder {
devicePath,
aligned,
measurementSchemas,
- null);
+ outputPaths,
+ false);
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 8aad87866b8..e0aeacb7f56 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
@@ -2789,7 +2789,7 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
fullPath);
}
- return Objects.isNull(node.getOutputViewPath())
+ return Objects.isNull(node.getOutputPaths())
? new UpdateLastCacheOperator(
operatorContext,
lastQueryScan,
@@ -2806,11 +2806,11 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
DATA_NODE_SCHEMA_CACHE,
context.isNeedUpdateLastCache(),
context.isNeedUpdateNullEntry(),
- node.getOutputViewPath());
+ node.getOutputPaths().get(idx));
}
private AlignedUpdateLastCacheOperator createAlignedUpdateLastCacheOperator(
- final String outputViewPath,
+ final List<String> outputPaths,
final PlanNodeId planNodeId,
final AlignedPath unCachedPath,
final LocalExecutionPlanContext context,
@@ -2846,7 +2846,7 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
}
}
- return Objects.isNull(outputViewPath)
+ return Objects.isNull(outputPaths)
? new AlignedUpdateLastCacheOperator(
operatorContext,
lastQueryScan,
@@ -2862,7 +2862,7 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
DATA_NODE_SCHEMA_CACHE,
context.isNeedUpdateLastCache(),
context.isNeedUpdateNullEntry(),
- outputViewPath,
+ outputPaths,
deviceInMultiRegion);
}
@@ -2964,6 +2964,7 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
updateFilterUsingTTL(
context.getGlobalTimeFilter(),
DataNodeTTLCache.getInstance().getTTL(devicePath.getNodes()));
+ boolean hasOutputPath = node.getOutputPaths() != null;
for (int i = 0; i < idxOfMeasurementSchemas.size(); i++) {
IMeasurementSchema measurementSchema = node.getMeasurementSchema(i);
final PartialPath measurementPath =
@@ -2994,8 +2995,9 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
unCachedMeasurementIndexes.add(i);
}
} else { // cached last value is satisfied, put it into
LastCacheScanOperator
- if (node.getOutputViewPath() != null) {
- context.addCachedLastValue(timeValuePair, node.getOutputViewPath());
+ String outputPath = hasOutputPath ? node.getOutputPaths().get(i) :
null;
+ if (outputPath != null) {
+ context.addCachedLastValue(timeValuePair,
node.getOutputPaths().get(i));
} else {
context.addCachedLastValue(timeValuePair,
measurementPath.getFullPath());
}
@@ -3006,12 +3008,17 @@ public class OperatorTreeGenerator extends
PlanVisitor<Operator, LocalExecutionP
}
if (node.isAligned()) {
AlignedPath unCachedPath = new AlignedPath(node.getDevicePath());
+ // select output paths for uncached measurements
+ List<String> newOutputPaths = hasOutputPath ? new ArrayList<>() : null;
for (int i : unCachedMeasurementIndexes) {
IMeasurementSchema measurementSchema = node.getMeasurementSchema(i);
unCachedPath.addMeasurement(measurementSchema.getMeasurementId(),
measurementSchema);
+ if (hasOutputPath) {
+ newOutputPaths.add(node.getOutputPaths().get(i));
+ }
}
return createAlignedUpdateLastCacheOperator(
- node.getOutputViewPath(),
+ newOutputPaths,
node.getPlanNodeId(),
unCachedPath,
context,
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
index b8fefee7201..5a03015d781 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
@@ -68,7 +68,6 @@ import
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.IntoPathDescr
import org.apache.commons.lang3.Validate;
import org.apache.tsfile.utils.Pair;
-import org.eclipse.jetty.util.StringUtil;
import java.util.ArrayList;
import java.util.HashMap;
@@ -520,8 +519,10 @@ public class PlanGraphPrinter extends
PlanVisitor<List<String>, PlanGraphPrinter
boxValue.add(
String.format(
"Series: %s%s", node.getDevicePath().getIDeviceID(),
node.getMeasurementSchemas()));
- if (StringUtil.isNotBlank(node.getOutputViewPath())) {
- boxValue.add(String.format("ViewPath: %s", node.getOutputViewPath()));
+
+ List<String> outputPaths = node.getOutputPaths();
+ if (outputPaths != null) {
+ boxValue.add(String.format("OutputPaths: %s", outputPaths));
}
boxValue.add(printRegion(node.getRegionReplicaSet()));
return render(node, boxValue, context);
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..32af69eb476 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
@@ -89,7 +89,8 @@ public class LastQueryNode extends MultiChildProcessNode {
PartialPath devicePath,
boolean aligned,
List<IMeasurementSchema> measurementSchemas,
- String outputViewPath) {
+ List<String> outputPaths,
+ boolean isOutputPathForView) {
List<Integer> idxList = new ArrayList<>(measurementSchemas.size());
for (IMeasurementSchema measurementSchema : measurementSchemas) {
int idx =
@@ -103,7 +104,13 @@ public class LastQueryNode extends MultiChildProcessNode {
}
LastQueryScanNode scanNode =
new LastQueryScanNode(
- id, devicePath, aligned, idxList, outputViewPath,
globalMeasurementSchemaList);
+ id,
+ devicePath,
+ aligned,
+ idxList,
+ outputPaths,
+ isOutputPathForView,
+ 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 a16aeb779f4..1969357a7ac 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
@@ -34,7 +34,6 @@ import com.google.common.collect.ImmutableList;
import org.apache.tsfile.utils.RamUsageEstimator;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.apache.tsfile.write.schema.IMeasurementSchema;
-import org.eclipse.jetty.util.StringUtil;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -63,7 +62,10 @@ public class LastQueryScanNode extends LastSeriesSourceNode {
// It will be set when the current Node is added to the child by the upper
LastQueryNode.
private List<IMeasurementSchema> globalMeasurementSchemaList;
- private final String outputViewPath;
+ // Store alias of paths or viewPath in this field.
+ private final List<String> outputPaths;
+ // Indicate if there is viewPath stored in outputPaths.
+ private final boolean isOutputPathForView;
// The id of DataRegion where the node will run
private TRegionReplicaSet regionReplicaSet;
@@ -74,14 +76,16 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
PartialPath devicePath,
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
- String outputViewPath,
+ List<String> outputPaths,
+ boolean isOutputPathForView,
List<IMeasurementSchema> globalMeasurementSchemaList) {
super(id, new AtomicInteger(1));
this.aligned = aligned;
this.devicePath = devicePath;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
- this.outputViewPath = outputViewPath;
+ this.outputPaths = outputPaths;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
+ this.isOutputPathForView = isOutputPathForView;
}
public LastQueryScanNode(
@@ -90,14 +94,16 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
- String outputViewPath) {
+ List<String> outputPaths,
+ boolean isOutputPathForView) {
this(
id,
devicePath,
aligned,
indexOfMeasurementSchemas,
dataNodeSeriesScanNum,
- outputViewPath,
+ outputPaths,
+ isOutputPathForView,
null);
}
@@ -107,13 +113,15 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
- String outputViewPath,
+ List<String> outputPaths,
+ boolean isOutputPathForView,
List<IMeasurementSchema> globalMeasurementSchemaList) {
super(id, dataNodeSeriesScanNum);
this.aligned = aligned;
this.devicePath = devicePath;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
- this.outputViewPath = outputViewPath;
+ this.outputPaths = outputPaths;
+ this.isOutputPathForView = isOutputPathForView;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
}
@@ -123,7 +131,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
boolean aligned,
List<Integer> indexOfMeasurementSchemas,
AtomicInteger dataNodeSeriesScanNum,
- String outputViewPath,
+ List<String> outputPaths,
+ boolean isOutputPathForView,
TRegionReplicaSet regionReplicaSet,
boolean deviceInMultiRegion,
List<IMeasurementSchema> globalMeasurementSchemaList) {
@@ -131,7 +140,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
this.devicePath = devicePath;
this.aligned = aligned;
this.indexOfMeasurementSchemas = indexOfMeasurementSchemas;
- this.outputViewPath = outputViewPath;
+ this.outputPaths = outputPaths;
+ this.isOutputPathForView = isOutputPathForView;
this.regionReplicaSet = regionReplicaSet;
this.deviceInMultiRegion = deviceInMultiRegion;
this.globalMeasurementSchemaList = globalMeasurementSchemaList;
@@ -158,14 +168,21 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
return this.aligned;
}
- public String getOutputViewPath() {
- return outputViewPath;
+ public List<String> getOutputPaths() {
+ return outputPaths;
+ }
+
+ public boolean isOutputPathForView() {
+ return isOutputPathForView;
}
public String getOutputSymbolForSort() {
- if (outputViewPath != null) {
- return outputViewPath;
+ if (outputPaths != null && outputPaths.size() == 1) {
+ return outputPaths.get(0);
}
+ // If outputPaths is null or size > 1, it means there is no view and no
alias, just return the
+ // device name is ok,
+ // because the measurements have been sorted in AnalyzeVisitor if needed.
return devicePath.toString();
}
@@ -195,7 +212,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
aligned,
indexOfMeasurementSchemas,
getDataNodeSeriesScanNum(),
- outputViewPath,
+ outputPaths,
+ isOutputPathForView,
regionReplicaSet,
deviceInMultiRegion,
globalMeasurementSchemaList);
@@ -225,7 +243,7 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
return Objects.equals(devicePath, that.devicePath)
&& Objects.equals(aligned, that.aligned)
&& Objects.equals(indexOfMeasurementSchemas,
that.indexOfMeasurementSchemas)
- && Objects.equals(outputViewPath, that.outputViewPath)
+ && Objects.equals(outputPaths, that.outputPaths)
&& Objects.equals(regionReplicaSet, that.regionReplicaSet);
}
@@ -236,20 +254,21 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
devicePath,
aligned,
indexOfMeasurementSchemas,
- outputViewPath,
+ outputPaths,
regionReplicaSet);
}
@Override
public String toString() {
- if (StringUtil.isNotBlank(outputViewPath)) {
+
+ if (outputPaths != null) {
return String.format(
- "LastQueryScanNode-%s:[Device: %s, Aligned: %s, Measurements: %s,
ViewPath: %s, DataRegion: %s]",
+ "LastQueryScanNode-%s:[Device: %s, Aligned: %s, Measurements: %s,
OutputPaths: %s, DataRegion: %s]",
this.getPlanNodeId(),
this.getDevicePath(),
this.aligned,
this.getMeasurementSchemas(),
- this.getOutputViewPath(),
+ this.getOutputPaths(),
PlanNodeUtil.printRegionReplicaSet(getRegionReplicaSet()));
} else {
return String.format(
@@ -272,10 +291,15 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
ReadWriteIOUtils.write(measurementSchema, byteBuffer);
}
ReadWriteIOUtils.write(getDataNodeSeriesScanNum().get(), byteBuffer);
- ReadWriteIOUtils.write(outputViewPath == null, byteBuffer);
- if (outputViewPath != null) {
- ReadWriteIOUtils.write(outputViewPath, byteBuffer);
+ ReadWriteIOUtils.write(outputPaths == null, byteBuffer);
+ if (outputPaths != null) {
+ int size = outputPaths.size();
+ ReadWriteIOUtils.write(size, byteBuffer);
+ for (int i = 0; i < size; i++) {
+ ReadWriteIOUtils.write(outputPaths.get(i), byteBuffer);
+ }
}
+ ReadWriteIOUtils.write(isOutputPathForView, byteBuffer);
ReadWriteIOUtils.write(deviceInMultiRegion, byteBuffer);
}
@@ -289,10 +313,15 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
ReadWriteIOUtils.write(measurementSchema, stream);
}
ReadWriteIOUtils.write(getDataNodeSeriesScanNum().get(), stream);
- ReadWriteIOUtils.write(outputViewPath == null, stream);
- if (outputViewPath != null) {
- ReadWriteIOUtils.write(outputViewPath, stream);
+ ReadWriteIOUtils.write(outputPaths == null, stream);
+ if (outputPaths != null) {
+ int size = outputPaths.size();
+ ReadWriteIOUtils.write(size, stream);
+ for (int i = 0; i < size; i++) {
+ ReadWriteIOUtils.write(outputPaths.get(i), stream);
+ }
}
+ ReadWriteIOUtils.write(isOutputPathForView, stream);
ReadWriteIOUtils.write(deviceInMultiRegion, stream);
}
@@ -307,7 +336,16 @@ public class LastQueryScanNode extends
LastSeriesSourceNode {
int dataNodeSeriesScanNum = ReadWriteIOUtils.readInt(byteBuffer);
boolean isNull = ReadWriteIOUtils.readBool(byteBuffer);
- String outputPathSymbol = isNull ? null :
ReadWriteIOUtils.readString(byteBuffer);
+ List<String> outputPaths = null;
+ if (!isNull) {
+ int size = ReadWriteIOUtils.readInt(byteBuffer);
+ outputPaths = new ArrayList<>(size);
+ while (size > 0) {
+ outputPaths.add(ReadWriteIOUtils.readString(byteBuffer));
+ size--;
+ }
+ }
+ boolean isOutputPathForView = ReadWriteIOUtils.readBool(byteBuffer);
boolean deviceInMultiRegion = ReadWriteIOUtils.readBool(byteBuffer);
PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
return new LastQueryScanNode(
@@ -316,7 +354,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
aligned,
measurementSchemas,
new AtomicInteger(dataNodeSeriesScanNum),
- outputPathSymbol,
+ outputPaths,
+ isOutputPathForView,
null,
deviceInMultiRegion,
null);
@@ -369,6 +408,8 @@ public class LastQueryScanNode extends LastSeriesSourceNode
{
// The memory of each String has been calculated before
+
MemoryEstimationHelper.getEstimatedSizeOfCopiedPartialPath(devicePath)
+
MemoryEstimationHelper.getEstimatedSizeOfIntegerArrayList(indexOfMeasurementSchemas)
- + RamUsageEstimator.sizeOf(outputViewPath);
+ + (outputPaths == null
+ ? 0L
+ : outputPaths.stream().mapToLong(path ->
RamUsageEstimator.sizeOf(path)).sum());
}
}
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 2a30129bbd5..930ba4bcc7d 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
@@ -59,13 +59,15 @@ public class LastQueryTest {
new MeasurementSchema("s3", TSDataType.INT32),
new MeasurementSchema("s1", TSDataType.BOOLEAN),
new MeasurementSchema("s2", TSDataType.INT32)),
- null);
+ null,
+ false);
lastQueryNode.addDeviceLastQueryScanNode(
new PlanNodeId("test_last_query_scan2"),
new PartialPath("root.test.d0"),
false,
Collections.singletonList(new MeasurementSchema("s0",
TSDataType.BOOLEAN)),
- null);
+ null,
+ false);
Analysis analysis = Util.constructAnalysis();
SourceRewriter sourceRewriter = new SourceRewriter(analysis);
@@ -255,7 +257,8 @@ public class LastQueryTest {
devicePath,
selectPath.isUnderAlignedEntity(),
Collections.singletonList(selectPath.getMeasurementSchema()),
- null);
+ null,
+ false);
}
return new LogicalQueryPlan(context, root);
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 2e51898a1f4..3ca25ab5ff8 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
@@ -88,7 +88,8 @@ public class DataQueryLogicalPlannerTest {
d1s1Path.getDevicePath(),
d1s1Path.isUnderAlignedEntity(),
measurementSchemas,
- null);
+ null,
+ false);
measurementSchemas =
Arrays.asList(
@@ -101,11 +102,12 @@ public class DataQueryLogicalPlannerTest {
d2s1Path.getDevicePath(),
d2s1Path.isUnderAlignedEntity(),
measurementSchemas,
- null);
+ null,
+ false);
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, false);
PlanNode actualPlan = parseSQLToPlanNode(sql);
Assert.assertEquals(actualPlan, lastQueryNode);
@@ -131,7 +133,8 @@ public class DataQueryLogicalPlannerTest {
s3Path.getDevicePath(),
s3Path.isUnderAlignedEntity(),
measurementSchemas,
- null);
+ null,
+ false);
SortNode sortNode =
new 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..3a0d8952e2d 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,
+ false,
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,
+ false,
Arrays.asList(
new MeasurementSchema("s1", TSDataType.INT32),
new MeasurementSchema("s0", TSDataType.BOOLEAN)));