This is an automated email from the ASF dual-hosted git repository.

zyk pushed a commit to branch rel/1.2
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/rel/1.2 by this push:
     new d84a6eecf11 [To rel/1.2] use Boolean for isAligned (#10198)
d84a6eecf11 is described below

commit d84a6eecf117325c93da6a675a6de6c4ceec47e2
Author: 橘子 <[email protected]>
AuthorDate: Sun Jun 18 17:38:03 2023 +0800

    [To rel/1.2] use Boolean for isAligned (#10198)
    
    * use Boolean for isAligned
    
    修改了isAligned属性的存储方式,由原本的boolean改为Boolean,因此可以存储空值。
    注意事项如下:
    1. 
尽可能减少了对原有系统的冲击,Measurement获取isUnderAlignedEntity时使用的函数返回值依旧为boolean,不可能为空,因为返回前做了判断;IDeviceMNode的isAligned接口保持不变,返回值依旧为boolean,同样是在返回前做了费控判断。**注意,为空时默认返回false**,这和原有系统行为一致,原本的纯视图设备isAligned返回false。
    2. 
修改了序列化方法。新增readBoolObject用于读取Boolean类,写入则使用的是原有接口write。为了保证兼容性,true序列化为1,false序列化为0,空值序列化为2.需要注意的是,序列化Boolean时没有使用readObject或者write
 object这种接口,这是为了兼容旧系统。
    **没能找到对DeviceNode的反序列化方法,这里可能该漏了**,但实际测试时,重启时发现null值的保存是成功的。
    3. 关于isAligned的状态的转化。
    不使用视图时,isAligned只可能为true或者false;
    
创建视图并且自动创建了设备时,说明该设备之前没有measurement作为孩子,所以这个视图是第一个作为孩子的measurement,因此它的isAligned是null;删除一个设备下所有非视图序列并且保留视图时,isAligned自动转换为null。
    
    * use -1 for serializing null
    
    * add ITs. IoTDBShowDevicesContainedViewIT
    
    * Update IoTDBShowDevicesContainedViewIT.java
---
 .../view/IoTDBShowDevicesContainedViewIT.java      | 226 +++++++++++++++++++++
 .../apache/iotdb/commons/path/MeasurementPath.java |  11 +-
 .../node/common/AbstractDatabaseDeviceMNode.java   |  11 +-
 .../schema/node/common/AbstractDeviceMNode.java    |  11 +-
 .../node/common/AbstractMeasurementMNode.java      |   2 +-
 .../commons/schema/node/info/IDeviceInfo.java      |   4 +-
 .../commons/schema/node/role/IDeviceMNode.java     |   4 +-
 .../db/metadata/mnode/mem/info/DeviceInfo.java     |   6 +-
 .../db/metadata/mtree/MTreeBelowSGCachedImpl.java  |   2 +-
 .../db/metadata/mtree/MTreeBelowSGMemoryImpl.java  |  32 ++-
 .../mtree/snapshot/MemMTreeSnapshotUtil.java       |   4 +-
 .../store/disk/schemafile/MockSchemaFile.java      |   4 +-
 .../traverser/collector/MeasurementCollector.java  |   2 +-
 .../schemaregion/result/ShowDevicesResult.java     |   6 +-
 .../db/metadata/query/info/IDeviceSchemaInfo.java  |   2 +-
 .../iotdb/tsfile/utils/ReadWriteIOUtils.java       |  19 +-
 16 files changed, 317 insertions(+), 29 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBShowDevicesContainedViewIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBShowDevicesContainedViewIT.java
new file mode 100644
index 00000000000..b5f51a55cfb
--- /dev/null
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBShowDevicesContainedViewIT.java
@@ -0,0 +1,226 @@
+/*
+ * 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.schema.view;
+
+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.Assert;
+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.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBShowDevicesContainedViewIT {
+
+  private static final String showDevicesSQL = "show devices;";
+  private static final String deleteAllTimeSeriesSQL = "delete timeseries 
root.**;";
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    EnvFactory.getEnv().initClusterEnvironment();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    EnvFactory.getEnv().cleanClusterEnvironment();
+  }
+
+  private void validateResultSetAndStandard(ResultSet resultSet, Set<String> 
standard)
+      throws SQLException {
+    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+    while (resultSet.next()) {
+      StringBuilder builder = new StringBuilder();
+      for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+        builder.append(resultSet.getString(i)).append(",");
+      }
+      String string = builder.toString();
+      Assert.assertTrue(standard.contains(string));
+      standard.remove(string);
+    }
+  }
+
+  @Test
+  public void testShowDevicesContainedView01() throws SQLException {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      // step 1. create normal time series and the alignment is true or false
+      String[] sqls =
+          new String[] {
+            "create timeseries root.db.d01.s01 INT32 encoding=RLE;",
+            "create timeseries root.db.d01.s02 INT32 encoding=RLE;",
+            "create aligned timeseries root.db.d02(s01 INT32 encoding=RLE, s02 
INT32 encoding=RLE);"
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      Set<String> standard =
+          new HashSet<>(Arrays.asList("root.db.d01,false,", 
"root.db.d02,true,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 2. create views under these devices and the alignment remain 
unchanged
+      sqls =
+          new String[] {
+            "create VIEW root.db.d01.s_view AS root.db.d01.s01",
+            "create VIEW root.db.d02.s_view AS root.db.d02.s01",
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard = new HashSet<>(Arrays.asList("root.db.d01,false,", 
"root.db.d02,true,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 3. create view and auto create device, the alignment of these 
devices are null
+      sqls =
+          new String[] {
+            "create VIEW root.db.d03.s_view AS root.db.d01.s01",
+            "create VIEW root.db.d04.s_view AS root.db.d01.s01",
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList(
+                  "root.db.d01,false,",
+                  "root.db.d02,true,",
+                  "root.db.d03,null,",
+                  "root.db.d04,null,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 4. create time series under those devices who just have views, 
and alignment should be
+      // true or false
+      sqls =
+          new String[] {
+            "create timeseries root.db.d03.s01 INT32 encoding=RLE;",
+            "create aligned timeseries root.db.d04(s01 INT32 encoding=RLE, s02 
INT32 encoding=RLE);"
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList(
+                  "root.db.d01,false,",
+                  "root.db.d02,true,",
+                  "root.db.d03,false,",
+                  "root.db.d04,true,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 5. delete all non-view time series created at last step, and the 
alignment of devices
+      // should be null
+      sqls =
+          new String[] {
+            "delete timeseries root.db.d03.s01;",
+            "delete timeseries root.db.d04.s01;",
+            "delete timeseries root.db.d04.s02;"
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList(
+                  "root.db.d01,false,",
+                  "root.db.d02,true,",
+                  "root.db.d03,null,",
+                  "root.db.d04,null,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // clean environment
+      statement.execute(deleteAllTimeSeriesSQL);
+    } // end of try
+  }
+
+  @Test
+  public void testShowDevicesContainedView02() throws SQLException {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      // step 1. create normal time series (prepared for views)
+      String[] sqls =
+          new String[] {
+            "create timeseries root.db.d01.s01 INT32 encoding=RLE;",
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      Set<String> standard = new 
HashSet<>(Collections.singletonList("root.db.d01,false,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 2. create view and auto create device, the alignment of these 
devices are null
+      sqls =
+          new String[] {
+            "create VIEW root.db.d05.s_view AS root.db.d01.s01",
+            "create VIEW root.db.d06.s_view AS root.db.d01.s01",
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList("root.db.d01,false,", "root.db.d05,null,", 
"root.db.d06,null,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 3. insert data under those devices who have only views, the 
alignment should be true
+      // or false
+      sqls =
+          new String[] {
+            "insert into root.db.d05(time,s01) values(1, 36);",
+            "insert into root.db.d06(time,s01) aligned values(1, 36);"
+          };
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList("root.db.d01,false,", "root.db.d05,false,", 
"root.db.d06,true,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // step 4. delete all auto created timeseries at last step, and the 
alignment of devices
+      // should be null
+      sqls =
+          new String[] {"delete timeseries root.db.d05.s01;", "delete 
timeseries root.db.d06.s01;"};
+      for (String sql : sqls) {
+        statement.execute(sql);
+      }
+      standard =
+          new HashSet<>(
+              Arrays.asList("root.db.d01,false,", "root.db.d05,null,", 
"root.db.d06,null,"));
+      validateResultSetAndStandard(statement.executeQuery(showDevicesSQL), 
standard);
+
+      // clean environment
+      statement.execute(deleteAllTimeSeriesSQL);
+    } // end of try
+  }
+}
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java 
b/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
index f1ce572ecd9..e1872e928bf 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/path/MeasurementPath.java
@@ -49,7 +49,7 @@ public class MeasurementPath extends PartialPath {
 
   private Map<String, String> tagMap;
 
-  private boolean isUnderAlignedEntity = false;
+  private Boolean isUnderAlignedEntity = false;
 
   // alias of measurement, null pointer cannot be serialized in thrift so 
empty string is instead
   private String measurementAlias = "";
@@ -76,7 +76,7 @@ public class MeasurementPath extends PartialPath {
   public MeasurementPath(
       PartialPath measurementPath,
       IMeasurementSchema measurementSchema,
-      boolean isUnderAlignedEntity) {
+      Boolean isUnderAlignedEntity) {
     super(measurementPath.getNodes());
     this.measurementSchema = measurementSchema;
     this.isUnderAlignedEntity = isUnderAlignedEntity;
@@ -149,10 +149,13 @@ public class MeasurementPath extends PartialPath {
   }
 
   public boolean isUnderAlignedEntity() {
+    if (isUnderAlignedEntity == null) {
+      return false;
+    }
     return isUnderAlignedEntity;
   }
 
-  public void setUnderAlignedEntity(boolean underAlignedEntity) {
+  public void setUnderAlignedEntity(Boolean underAlignedEntity) {
     isUnderAlignedEntity = underAlignedEntity;
   }
 
@@ -264,7 +267,7 @@ public class MeasurementPath extends PartialPath {
     if (isNull == 1) {
       measurementPath.tagMap = ReadWriteIOUtils.readMap(byteBuffer);
     }
-    measurementPath.isUnderAlignedEntity = 
ReadWriteIOUtils.readBool(byteBuffer);
+    measurementPath.isUnderAlignedEntity = 
ReadWriteIOUtils.readBoolObject(byteBuffer);
     measurementPath.measurementAlias = ReadWriteIOUtils.readString(byteBuffer);
     measurementPath.nodes = partialPath.getNodes();
     measurementPath.device = partialPath.getDevice();
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDatabaseDeviceMNode.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDatabaseDeviceMNode.java
index 2577a426a46..b0f78219064 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDatabaseDeviceMNode.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDatabaseDeviceMNode.java
@@ -262,11 +262,20 @@ public abstract class AbstractDatabaseDeviceMNode<N 
extends IMNode<N>, BasicNode
 
   @Override
   public boolean isAligned() {
+    Boolean align = databaseDeviceInfo.isAligned();
+    if (align == null) {
+      return false;
+    }
+    return align;
+  }
+
+  @Override
+  public Boolean isAlignedNullable() {
     return databaseDeviceInfo.isAligned();
   }
 
   @Override
-  public void setAligned(boolean isAligned) {
+  public void setAligned(Boolean isAligned) {
     databaseDeviceInfo.setAligned(isAligned);
   }
 
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDeviceMNode.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDeviceMNode.java
index 093eaaf4e63..49c1e111c89 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDeviceMNode.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractDeviceMNode.java
@@ -252,11 +252,20 @@ public abstract class AbstractDeviceMNode<N extends 
IMNode<N>, BasicNode extends
 
   @Override
   public boolean isAligned() {
+    Boolean align = deviceInfo.isAligned();
+    if (align == null) {
+      return false;
+    }
+    return align;
+  }
+
+  @Override
+  public Boolean isAlignedNullable() {
     return deviceInfo.isAligned();
   }
 
   @Override
-  public void setAligned(boolean isAligned) {
+  public void setAligned(Boolean isAligned) {
     deviceInfo.setAligned(isAligned);
   }
 
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
index c8338deeadd..3d55200c27a 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/common/AbstractMeasurementMNode.java
@@ -82,7 +82,7 @@ public abstract class AbstractMeasurementMNode<N extends 
IMNode<N>, BasicNode ex
   @Override
   public MeasurementPath getMeasurementPath() {
     MeasurementPath result = new MeasurementPath(getPartialPath(), 
getSchema());
-    result.setUnderAlignedEntity(getParent().getAsDeviceMNode().isAligned());
+    
result.setUnderAlignedEntity(getParent().getAsDeviceMNode().isAlignedNullable());
     return result;
   }
 
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/info/IDeviceInfo.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/info/IDeviceInfo.java
index bc625833d5b..6e79544e3f9 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/info/IDeviceInfo.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/info/IDeviceInfo.java
@@ -60,9 +60,9 @@ public interface IDeviceInfo<N extends IMNode<N>> {
 
   void deactivateTemplate();
 
-  boolean isAligned();
+  Boolean isAligned();
 
-  void setAligned(boolean isAligned);
+  void setAligned(Boolean isAligned);
 
   int estimateSize();
 }
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IDeviceMNode.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IDeviceMNode.java
index 8713933d5eb..a2ab8dd0773 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IDeviceMNode.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/schema/node/role/IDeviceMNode.java
@@ -53,5 +53,7 @@ public interface IDeviceMNode<N extends IMNode<N>> extends 
IMNode<N> {
 
   boolean isAligned();
 
-  void setAligned(boolean isAligned);
+  Boolean isAlignedNullable();
+
+  void setAligned(Boolean isAligned);
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/DeviceInfo.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/DeviceInfo.java
index 34182996465..63ee1fb6568 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/DeviceInfo.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/mem/info/DeviceInfo.java
@@ -49,7 +49,7 @@ public class DeviceInfo<N extends IMNode<N>> implements 
IDeviceInfo<N> {
   @SuppressWarnings("squid:S3077")
   private transient volatile Map<String, IMeasurementMNode<N>> aliasChildren = 
null;
 
-  private volatile boolean isAligned = false;
+  private volatile Boolean isAligned = false;
 
   @Override
   public void moveDataToNewMNode(IDeviceMNode<N> newMNode) {
@@ -168,12 +168,12 @@ public class DeviceInfo<N extends IMNode<N>> implements 
IDeviceInfo<N> {
   }
 
   @Override
-  public boolean isAligned() {
+  public Boolean isAligned() {
     return isAligned;
   }
 
   @Override
-  public void setAligned(boolean isAligned) {
+  public void setAligned(Boolean isAligned) {
     this.isAligned = isAligned;
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
index e3a1ebcb7b8..6d5d9cdd841 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
@@ -1024,7 +1024,7 @@ public class MTreeBelowSGCachedImpl {
 
           protected IDeviceSchemaInfo collectEntity(IDeviceMNode<ICachedMNode> 
node) {
             PartialPath device = 
getPartialPathFromRootToNode(node.getAsMNode());
-            return new ShowDevicesResult(device.getFullPath(), 
node.isAligned());
+            return new ShowDevicesResult(device.getFullPath(), 
node.isAlignedNullable());
           }
         };
     if (showDevicesPlan.usingSchemaTemplate()) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
index f7d6a3d8062..dedebbdbfb8 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
@@ -236,7 +236,9 @@ public class MTreeBelowSGMemoryImpl {
         }
       }
 
-      if (device.isDevice() && device.getAsDeviceMNode().isAligned()) {
+      if (device.isDevice()
+          && device.getAsDeviceMNode().isAlignedNullable() != null
+          && device.getAsDeviceMNode().isAligned()) {
         throw new AlignedTimeseriesException(
             "timeseries under this device is aligned, please use 
createAlignedTimeseries or change device.",
             device.getFullPath());
@@ -252,6 +254,11 @@ public class MTreeBelowSGMemoryImpl {
         }
       }
 
+      // create a non-aligned timeseries
+      if (entityMNode.isAlignedNullable() == null) {
+        entityMNode.setAligned(false);
+      }
+
       IMeasurementMNode<IMemMNode> measurementMNode =
           nodeFactory.createMeasurementMNode(
               entityMNode,
@@ -316,7 +323,9 @@ public class MTreeBelowSGMemoryImpl {
         }
       }
 
-      if (device.isDevice() && !device.getAsDeviceMNode().isAligned()) {
+      if (device.isDevice()
+          && device.getAsDeviceMNode().isAlignedNullable() != null
+          && !device.getAsDeviceMNode().isAligned()) {
         throw new AlignedTimeseriesException(
             "Timeseries under this device is not aligned, please use 
createTimeseries or change device.",
             devicePath.getFullPath());
@@ -333,6 +342,11 @@ public class MTreeBelowSGMemoryImpl {
         }
       }
 
+      // create a non-aligned timeseries
+      if (entityMNode.isAlignedNullable() == null) {
+        entityMNode.setAligned(true);
+      }
+
       for (int i = 0; i < measurements.size(); i++) {
         IMeasurementMNode<IMemMNode> measurementMNode =
             nodeFactory.createMeasurementMNode(
@@ -486,13 +500,17 @@ public class MTreeBelowSGMemoryImpl {
     IMemMNode curNode = entityMNode.getAsMNode();
     if (!entityMNode.isUseTemplate()) {
       boolean hasMeasurement = false;
+      boolean hasNonViewMeasurement = false;
       IMemMNode child;
       IMNodeIterator<IMemMNode> iterator = store.getChildrenIterator(curNode);
       while (iterator.hasNext()) {
         child = iterator.next();
         if (child.isMeasurement()) {
           hasMeasurement = true;
-          break;
+          if (!child.getAsMeasurementMNode().isLogicalView()) {
+            hasNonViewMeasurement = true;
+            break;
+          }
         }
       }
 
@@ -503,6 +521,9 @@ public class MTreeBelowSGMemoryImpl {
             replaceStorageGroupMNode(curNode.getAsDatabaseMNode());
           }
         }
+      } else if (!hasNonViewMeasurement) {
+        // has some measurement but they are all logical view
+        entityMNode.setAligned(null);
       }
     }
 
@@ -863,7 +884,7 @@ public class MTreeBelowSGMemoryImpl {
 
           protected IDeviceSchemaInfo collectEntity(IDeviceMNode<IMemMNode> 
node) {
             PartialPath device = 
getPartialPathFromRootToNode(node.getAsMNode());
-            return new ShowDevicesResult(device.getFullPath(), 
node.isAligned());
+            return new ShowDevicesResult(device.getFullPath(), 
node.isAlignedNullable());
           }
         };
     if (showDevicesPlan.usingSchemaTemplate()) {
@@ -1062,6 +1083,9 @@ public class MTreeBelowSGMemoryImpl {
         if (entityMNode.isDatabase()) {
           replaceStorageGroupMNode(entityMNode.getAsDatabaseMNode());
         }
+        // this parent has no measurement before. The leafName is his first 
child who is a logical
+        // view.
+        entityMNode.setAligned(null);
       }
 
       IMeasurementMNode<IMemMNode> measurementMNode =
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
index 224bb2692e2..a4a4a4be3eb 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/snapshot/MemMTreeSnapshotUtil.java
@@ -312,7 +312,7 @@ public class MemMTreeSnapshotUtil {
         serializeBasicMNode(node.getBasicMNode(), outputStream);
         ReadWriteIOUtils.write(node.getSchemaTemplateIdWithState(), 
outputStream);
         ReadWriteIOUtils.write(node.isUseTemplate(), outputStream);
-        ReadWriteIOUtils.write(node.isAligned(), outputStream);
+        ReadWriteIOUtils.write(node.isAlignedNullable(), outputStream);
         // database node in schemaRegion doesn't store any database schema
         return true;
       } catch (IOException e) {
@@ -329,7 +329,7 @@ public class MemMTreeSnapshotUtil {
         serializeBasicMNode(node.getBasicMNode(), outputStream);
         ReadWriteIOUtils.write(node.getSchemaTemplateIdWithState(), 
outputStream);
         ReadWriteIOUtils.write(node.isUseTemplate(), outputStream);
-        ReadWriteIOUtils.write(node.isAligned(), outputStream);
+        ReadWriteIOUtils.write(node.isAlignedNullable(), outputStream);
         return true;
       } catch (IOException e) {
         logger.error(SERIALIZE_ERROR_INFO, e);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/disk/schemafile/MockSchemaFile.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/disk/schemafile/MockSchemaFile.java
index 6674745fd4a..13ed4aeb29b 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/disk/schemafile/MockSchemaFile.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/disk/schemafile/MockSchemaFile.java
@@ -189,12 +189,12 @@ public class MockSchemaFile implements ISchemaFile {
       ICachedMNode result =
           nodeFactory.createDatabaseDeviceMNode(
               null, node.getName(), node.getAsDatabaseMNode().getDataTTL());
-      
result.getAsDeviceMNode().setAligned(node.getAsDeviceMNode().isAligned());
+      
result.getAsDeviceMNode().setAligned(node.getAsDeviceMNode().isAlignedNullable());
       cloneInternalMNodeData(node, result);
       return result;
     } else if (node.isDevice()) {
       ICachedMNode result = nodeFactory.createDeviceMNode(null, 
node.getName()).getAsMNode();
-      
result.getAsDeviceMNode().setAligned(node.getAsDeviceMNode().isAligned());
+      
result.getAsDeviceMNode().setAligned(node.getAsDeviceMNode().isAlignedNullable());
       cloneInternalMNodeData(node, result);
       return result;
     } else if (node.isDatabase()) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
index 2c42161abb0..4c2eda5446e 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
@@ -59,7 +59,7 @@ public abstract class MeasurementCollector<R, N extends 
IMNode<N>>
     MeasurementPath retPath =
         new MeasurementPath(
             getPartialPathFromRootToNode(currentNode.getAsMNode()), 
currentNode.getSchema());
-    retPath.setUnderAlignedEntity(par.getAsDeviceMNode().isAligned());
+    retPath.setUnderAlignedEntity(par.getAsDeviceMNode().isAlignedNullable());
     return retPath;
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowDevicesResult.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowDevicesResult.java
index 5a6a4b4dd86..c7cf9ad9a6f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowDevicesResult.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/plan/schemaregion/result/ShowDevicesResult.java
@@ -23,14 +23,14 @@ import 
org.apache.iotdb.db.metadata.query.info.IDeviceSchemaInfo;
 import java.util.Objects;
 
 public class ShowDevicesResult extends ShowSchemaResult implements 
IDeviceSchemaInfo {
-  private boolean isAligned;
+  private Boolean isAligned;
 
-  public ShowDevicesResult(String name, boolean isAligned) {
+  public ShowDevicesResult(String name, Boolean isAligned) {
     super(name);
     this.isAligned = isAligned;
   }
 
-  public boolean isAligned() {
+  public Boolean isAligned() {
     return isAligned;
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/IDeviceSchemaInfo.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/query/info/IDeviceSchemaInfo.java
index 92f4b6bd998..80bb67fdc47 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/query/info/IDeviceSchemaInfo.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/query/info/IDeviceSchemaInfo.java
@@ -21,5 +21,5 @@ package org.apache.iotdb.db.metadata.query.info;
 
 public interface IDeviceSchemaInfo extends ISchemaInfo {
 
-  boolean isAligned();
+  Boolean isAligned();
 }
diff --git 
a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java 
b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
index febda38bc5d..cb9bc523512 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
@@ -95,6 +95,17 @@ public class ReadWriteIOUtils {
     return a == 1;
   }
 
+  /** read a Boolean from byteBuffer. */
+  public static Boolean readBoolObject(ByteBuffer buffer) {
+    byte a = buffer.get();
+    if (a == 1) {
+      return true;
+    } else if (a == 0) {
+      return false;
+    }
+    return null;
+  }
+
   /** read a byte from byteBuffer. */
   public static byte readByte(ByteBuffer buffer) {
     return buffer.get();
@@ -185,7 +196,9 @@ public class ReadWriteIOUtils {
    * write a int value to outputStream according to flag. If flag is true, 
write 1, else write 0.
    */
   public static int write(Boolean flag, OutputStream outputStream) throws 
IOException {
-    if (Boolean.TRUE.equals(flag)) {
+    if (flag == null) {
+      outputStream.write(-1);
+    } else if (Boolean.TRUE.equals(flag)) {
       outputStream.write(1);
     } else {
       outputStream.write(0);
@@ -196,7 +209,9 @@ public class ReadWriteIOUtils {
   /** write a byte to byteBuffer according to flag. If flag is true, write 1, 
else write 0. */
   public static int write(Boolean flag, ByteBuffer buffer) {
     byte a;
-    if (Boolean.TRUE.equals(flag)) {
+    if (flag == null) {
+      a = -1;
+    } else if (Boolean.TRUE.equals(flag)) {
       a = 1;
     } else {
       a = 0;

Reply via email to