未验证 提交 7c256485 编写于 作者: C Chen YZ 提交者: GitHub

[To rel/1.2][IOTDB-6076] Add duplicate checking when upsert alias

上级 43601d7f
......@@ -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();
}
}
}
......@@ -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);
}
}
......
......@@ -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);
}
}
......
......@@ -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
*
......
......@@ -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;
......
......@@ -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>() {
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册