You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2023/07/24 08:38:04 UTC

[iotdb] branch rel/1.2 updated: [To rel/1.2][IOTDB-6076] Add duplicate checking when upsert alias

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

jackietien 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 7c256485042 [To rel/1.2][IOTDB-6076] Add duplicate checking when upsert alias
7c256485042 is described below

commit 7c25648504260fa34f528c39e14b6417d9efe3d7
Author: Chen YZ <43...@users.noreply.github.com>
AuthorDate: Mon Jul 24 16:37:57 2023 +0800

    [To rel/1.2][IOTDB-6076] Add duplicate checking when upsert alias
---
 .../apache/iotdb/db/it/schema/IoTDBTagAlterIT.java | 29 ++++++++++++++
 .../schemaregion/impl/SchemaRegionMemoryImpl.java  | 43 +++-----------------
 .../schemaregion/impl/SchemaRegionPBTreeImpl.java  | 46 +++-------------------
 .../mtree/impl/mem/MTreeBelowSGMemoryImpl.java     | 23 +++++++++++
 .../mtree/impl/pbtree/MTreeBelowSGCachedImpl.java  | 27 +++++++++++++
 .../schemaRegion/SchemaRegionAliasAndTagTest.java  | 19 +++++++++
 6 files changed, 110 insertions(+), 77 deletions(-)

diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBTagAlterIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBTagAlterIT.java
index 90f2b61cf30..116d767ab8f 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBTagAlterIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBTagAlterIT.java
@@ -607,4 +607,33 @@ public class IoTDBTagAlterIT extends AbstractSchemaIT {
       fail();
     }
   }
+
+  @Test
+  public void alterDuplicateAliasTest() {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute(
+          "create timeseries root.turbine.d1.s1(a1) with datatype=FLOAT, encoding=RLE, compression=SNAPPY;");
+      statement.execute("create timeseries root.turbine.d1.s2 with datatype=INT32, encoding=RLE;");
+      try {
+        statement.execute("alter timeseries root.turbine.d1.s2 upsert alias=s1;");
+        fail();
+      } catch (Exception e) {
+        assertTrue(
+            e.getMessage()
+                .contains("The alias is duplicated with the name or alias of other measurement."));
+      }
+      try {
+        statement.execute("alter timeseries root.turbine.d1.s2 upsert alias=a1;");
+        fail();
+      } catch (Exception e) {
+        assertTrue(
+            e.getMessage()
+                .contains("The alias is duplicated with the name or alias of other measurement."));
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      fail();
+    }
+  }
 }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
index 3eea90bfdb3..3a49f596f9e 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
@@ -28,7 +28,6 @@ import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.schema.ClusterSchemaQuotaLevel;
 import org.apache.iotdb.commons.schema.filter.SchemaFilterType;
-import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
 import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
 import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
 import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
@@ -943,22 +942,6 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
     }
   }
 
-  private void changeAlias(PartialPath path, String alias) throws MetadataException {
-    IMeasurementMNode<IMemMNode> leafMNode = mtree.getMeasurementMNode(path);
-    IDeviceMNode<IMemMNode> device = leafMNode.getParent().getAsDeviceMNode();
-    if (leafMNode.getAlias() != null) {
-      device.deleteAliasChild(leafMNode.getAlias());
-    }
-    device.addAlias(alias, leafMNode);
-    mtree.setAlias(leafMNode, alias);
-
-    try {
-      writeToMLog(SchemaRegionWritePlanFactory.getChangeAliasPlan(path, alias));
-    } catch (IOException e) {
-      throw new MetadataException(e);
-    }
-  }
-
   /**
    * Upsert tags and attributes key-value for the timeseries if the key has existed, just use the
    * new value to update it.
@@ -976,11 +959,9 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
       Map<String, String> attributesMap,
       PartialPath fullPath)
       throws MetadataException, IOException {
-    IMeasurementMNode<IMemMNode> leafMNode = mtree.getMeasurementMNode(fullPath);
-
     // upsert alias
-    upsertAlias(alias, fullPath, leafMNode);
-
+    upsertAlias(alias, fullPath);
+    IMeasurementMNode<IMemMNode> leafMNode = mtree.getMeasurementMNode(fullPath);
     if (tagsMap == null && attributesMap == null) {
       return;
     }
@@ -1000,21 +981,9 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
     tagManager.updateTagsAndAttributes(tagsMap, attributesMap, leafMNode);
   }
 
-  private void upsertAlias(
-      String alias, PartialPath fullPath, IMeasurementMNode<IMemMNode> leafMNode)
+  private void upsertAlias(String alias, PartialPath fullPath)
       throws MetadataException, IOException {
-    // upsert alias
-    if (alias != null && !alias.equals(leafMNode.getAlias())) {
-      IDeviceMNode<IMemMNode> deviceMNode = leafMNode.getParent().getAsDeviceMNode();
-      if (!deviceMNode.addAlias(alias, leafMNode)) {
-        throw new MetadataException("The alias already exists.");
-      }
-
-      if (leafMNode.getAlias() != null) {
-        deviceMNode.deleteAliasChild(leafMNode.getAlias());
-      }
-
-      mtree.setAlias(leafMNode, alias);
+    if (mtree.changeAlias(alias, fullPath)) {
       // persist to WAL
       writeToMLog(SchemaRegionWritePlanFactory.getChangeAliasPlan(fullPath, alias));
     }
@@ -1315,9 +1284,9 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
     public RecoverOperationResult visitChangeAlias(
         IChangeAliasPlan changeAliasPlan, SchemaRegionMemoryImpl context) {
       try {
-        changeAlias(changeAliasPlan.getPath(), changeAliasPlan.getAlias());
+        upsertAlias(changeAliasPlan.getAlias(), changeAliasPlan.getPath());
         return RecoverOperationResult.SUCCESS;
-      } catch (MetadataException e) {
+      } catch (MetadataException | IOException e) {
         return new RecoverOperationResult(e);
       }
     }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
index 91a94b80688..d7f008ab59d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
@@ -954,26 +954,6 @@ public class SchemaRegionPBTreeImpl implements ISchemaRegion {
     }
   }
 
-  private void changeAlias(PartialPath path, String alias) throws MetadataException {
-    IMeasurementMNode<ICachedMNode> leafMNode = mtree.getMeasurementMNode(path);
-    try {
-      IDeviceMNode<ICachedMNode> device = leafMNode.getParent().getAsDeviceMNode();
-      if (leafMNode.getAlias() != null) {
-        device.deleteAliasChild(leafMNode.getAlias());
-      }
-      device.addAlias(alias, leafMNode);
-      mtree.setAlias(leafMNode, alias);
-    } finally {
-      mtree.unPinMNode(leafMNode.getAsMNode());
-    }
-
-    try {
-      writeToMLog(SchemaRegionWritePlanFactory.getChangeAliasPlan(path, alias));
-    } catch (IOException e) {
-      throw new MetadataException(e);
-    }
-  }
-
   /**
    * Upsert tags and attributes key-value for the timeseries if the key has existed, just use the
    * new value to update it.
@@ -991,15 +971,13 @@ public class SchemaRegionPBTreeImpl implements ISchemaRegion {
       Map<String, String> attributesMap,
       PartialPath fullPath)
       throws MetadataException, IOException {
+    // upsert alias
+    upsertAlias(alias, fullPath);
     IMeasurementMNode<ICachedMNode> leafMNode = mtree.getMeasurementMNode(fullPath);
     try {
-      // upsert alias
-      upsertAlias(alias, fullPath, leafMNode);
-
       if (tagsMap == null && attributesMap == null) {
         return;
       }
-
       // no tag or attribute, we need to add a new record in log
       if (leafMNode.getOffset() < 0) {
         long offset = tagManager.writeTagFile(tagsMap, attributesMap);
@@ -1020,21 +998,9 @@ public class SchemaRegionPBTreeImpl implements ISchemaRegion {
     }
   }
 
-  private void upsertAlias(
-      String alias, PartialPath fullPath, IMeasurementMNode<ICachedMNode> leafMNode)
+  private void upsertAlias(String alias, PartialPath fullPath)
       throws MetadataException, IOException {
-    // upsert alias
-    if (alias != null && !alias.equals(leafMNode.getAlias())) {
-      IDeviceMNode<ICachedMNode> device = leafMNode.getParent().getAsDeviceMNode();
-      if (!device.addAlias(alias, leafMNode)) {
-        throw new MetadataException("The alias already exists.");
-      }
-
-      if (leafMNode.getAlias() != null) {
-        device.deleteAliasChild(leafMNode.getAlias());
-      }
-
-      mtree.setAlias(leafMNode, alias);
+    if (mtree.changeAlias(alias, fullPath)) {
       // persist to WAL
       writeToMLog(SchemaRegionWritePlanFactory.getChangeAliasPlan(fullPath, alias));
     }
@@ -1357,9 +1323,9 @@ public class SchemaRegionPBTreeImpl implements ISchemaRegion {
     public RecoverOperationResult visitChangeAlias(
         IChangeAliasPlan changeAliasPlan, SchemaRegionPBTreeImpl context) {
       try {
-        changeAlias(changeAliasPlan.getPath(), changeAliasPlan.getAlias());
+        upsertAlias(changeAliasPlan.getAlias(), changeAliasPlan.getPath());
         return RecoverOperationResult.SUCCESS;
-      } catch (MetadataException e) {
+      } catch (MetadataException | IOException e) {
         return new RecoverOperationResult(e);
       }
     }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
index 1422c17e0af..07ba7ce7801 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
@@ -479,6 +479,29 @@ public class MTreeBelowSGMemoryImpl {
     }
     return failingMeasurementMap;
   }
+
+  public boolean changeAlias(String alias, PartialPath fullPath) throws MetadataException {
+    IMeasurementMNode<IMemMNode> measurementMNode = getMeasurementMNode(fullPath);
+    // upsert alias
+    if (alias != null && !alias.equals(measurementMNode.getAlias())) {
+      synchronized (this) {
+        IDeviceMNode<IMemMNode> device = measurementMNode.getParent().getAsDeviceMNode();
+        IMemMNode memMNode = store.getChild(device.getAsMNode(), alias);
+        if (memMNode != null) {
+          throw new MetadataException(
+              "The alias is duplicated with the name or alias of other measurement.");
+        }
+        if (measurementMNode.getAlias() != null) {
+          device.deleteAliasChild(measurementMNode.getAlias());
+        }
+        device.addAlias(alias, measurementMNode);
+        setAlias(measurementMNode, alias);
+      }
+      return true;
+    }
+    return false;
+  }
+
   /**
    * Delete path. The path should be a full path from root to leaf node
    *
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
index eb25926970b..07ad7d435f3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
@@ -422,6 +422,33 @@ public class MTreeBelowSGCachedImpl {
     }
   }
 
+  public boolean changeAlias(String alias, PartialPath fullPath) throws MetadataException {
+    IMeasurementMNode<ICachedMNode> measurementMNode = getMeasurementMNode(fullPath);
+    try {
+      // upsert alias
+      if (alias != null && !alias.equals(measurementMNode.getAlias())) {
+        synchronized (this) {
+          IDeviceMNode<ICachedMNode> device = measurementMNode.getParent().getAsDeviceMNode();
+          ICachedMNode cachedMNode = store.getChild(device.getAsMNode(), alias);
+          if (cachedMNode != null) {
+            unPinMNode(cachedMNode);
+            throw new MetadataException(
+                "The alias is duplicated with the name or alias of other measurement.");
+          }
+          if (measurementMNode.getAlias() != null) {
+            device.deleteAliasChild(measurementMNode.getAlias());
+          }
+          device.addAlias(alias, measurementMNode);
+          setAlias(measurementMNode, alias);
+        }
+        return true;
+      }
+      return false;
+    } finally {
+      unPinMNode(measurementMNode.getAsMNode());
+    }
+  }
+
   public Map<Integer, MetadataException> checkMeasurementExistence(
       PartialPath devicePath, List<String> measurementList, List<String> aliasList) {
     ICachedMNode device;
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionAliasAndTagTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionAliasAndTagTest.java
index c3f14ccc9cb..567d6ca73b5 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionAliasAndTagTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionAliasAndTagTest.java
@@ -245,6 +245,25 @@ public class SchemaRegionAliasAndTagTest extends AbstractSchemaRegionTest {
   public void testUpsertAliasAndTagsAndAttributes() {
     try {
       prepareTimeseries();
+      try {
+        schemaRegion.upsertAliasAndTagsAndAttributes(
+            "s2", null, null, new PartialPath("root.sg.wf01.wt01.v1.s1"));
+        Assert.fail();
+      } catch (Exception e) {
+        Assert.assertTrue(
+            e.getMessage()
+                .contains("The alias is duplicated with the name or alias of other measurement."));
+      }
+      try {
+        schemaRegion.upsertAliasAndTagsAndAttributes(
+            "temp", null, null, new PartialPath("root.sg.wf01.wt01.v1.s1"));
+        Assert.fail();
+      } catch (Exception e) {
+        Assert.assertTrue(
+            e.getMessage()
+                .contains("The alias is duplicated with the name or alias of other measurement."));
+      }
+
       Map<String, String> newTags =
           new HashMap<String, String>() {
             {