diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeNormalIT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeNormalIT.java index bf0a6ce55272c..01eae1fb25d24 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeNormalIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeNormalIT.java @@ -157,13 +157,6 @@ public void success1C4DIoTTestUseTableSQL() throws Exception { successTest(2, 3, 1, 4, 1, 2, true, SQLModel.TABLE_MODEL_SQL, ConsensusFactory.IOT_CONSENSUS); } - @Test - public void success1C5DRemoveTwoDataNodesUseSQL() throws Exception { - // Setup 1C5D, and remove 2D in a single "remove datanode a, b" statement; 3 DataNodes remain - // which is enough to keep both the data (factor 2) and schema (factor 3) replicas. - successTest(2, 3, 1, 5, 2, 2, true, SQLModel.TREE_MODEL_SQL, ConsensusFactory.IOT_CONSENSUS); - } - // @Test public void success1C4DIoTV2TestUseTableSQL() throws Exception { // Setup 1C4D, and remove 1D, this test should success diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 index 5353535ad344e..e2ae5144caf0b 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 @@ -598,7 +598,7 @@ verifyConnection // ---- Remove DataNode removeDataNode - : REMOVE DATANODE dataNodeIds+=INTEGER_LITERAL (COMMA dataNodeIds+=INTEGER_LITERAL)* + : REMOVE DATANODE dataNodeId=INTEGER_LITERAL ; // ---- Remove ConfigNode diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index 6ddd95593a1ec..e1ef66774f9f1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -4704,8 +4704,7 @@ public Statement visitRemoveRegion(IoTDBSqlParser.RemoveRegionContext ctx) { @Override public Statement visitRemoveDataNode(IoTDBSqlParser.RemoveDataNodeContext ctx) { - List nodeIds = - ctx.dataNodeIds.stream().map(token -> Integer.parseInt(token.getText())).collect(toList()); + List nodeIds = Collections.singletonList(Integer.parseInt(ctx.dataNodeId.getText())); return new RemoveDataNodeStatement(nodeIds); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java index 13ee006af768c..7db81826ab6fa 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java @@ -1608,8 +1608,7 @@ public Node visitRemoveRegionStatement(RelationalSqlParser.RemoveRegionStatement @Override public Node visitRemoveDataNodeStatement(RelationalSqlParser.RemoveDataNodeStatementContext ctx) { - List nodeIds = - ctx.dataNodeIds.stream().map(token -> Integer.parseInt(token.getText())).collect(toList()); + List nodeIds = Collections.singletonList(Integer.parseInt(ctx.dataNodeId.getText())); return new RemoveDataNode(nodeIds); } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveDataNodeMultiNodeParseTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveNodeSingleNodeParseTest.java similarity index 66% rename from iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveDataNodeMultiNodeParseTest.java rename to iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveNodeSingleNodeParseTest.java index d71e443904575..ea67dcc48cf7e 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveDataNodeMultiNodeParseTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/RemoveNodeSingleNodeParseTest.java @@ -20,22 +20,21 @@ package org.apache.iotdb.db.queryengine.plan.parser; import org.apache.iotdb.db.queryengine.plan.statement.Statement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.RemoveConfigNodeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.RemoveDataNodeStatement; +import org.antlr.v4.runtime.misc.ParseCancellationException; import org.junit.Test; import java.time.ZoneId; -import java.util.Arrays; import java.util.Collections; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -/** - * Parsing tests for the tree-model SQL that lets REMOVE DATANODE remove multiple DataNodes in a - * single statement. - */ -public class RemoveDataNodeMultiNodeParseTest { +/** Parsing tests for tree-model REMOVE DATANODE and REMOVE CONFIGNODE statements. */ +public class RemoveNodeSingleNodeParseTest { private static Statement parse(String sql) { return StatementGenerator.createStatement(sql, ZoneId.systemDefault()); @@ -49,11 +48,15 @@ public void testRemoveSingleDataNode() { } @Test - public void testRemoveMultipleDataNodes() { - Statement statement = parse("remove datanode 3, 4, 5"); - assertTrue(statement instanceof RemoveDataNodeStatement); - RemoveDataNodeStatement removeDataNodeStatement = (RemoveDataNodeStatement) statement; - assertEquals(3, removeDataNodeStatement.getNodeIds().size()); - assertTrue(removeDataNodeStatement.getNodeIds().containsAll(Arrays.asList(3, 4, 5))); + public void testRemoveSingleConfigNode() { + Statement statement = parse("remove confignode 3"); + assertTrue(statement instanceof RemoveConfigNodeStatement); + assertEquals(3, ((RemoveConfigNodeStatement) statement).getNodeId().intValue()); + } + + @Test + public void testRejectRemovingMultipleNodes() { + assertThrows(ParseCancellationException.class, () -> parse("remove datanode 3, 4")); + assertThrows(ParseCancellationException.class, () -> parse("remove confignode 3, 4")); } } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveDataNodeMultiNodeStatementTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveNodeSingleNodeStatementTest.java similarity index 70% rename from iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveDataNodeMultiNodeStatementTest.java rename to iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveNodeSingleNodeStatementTest.java index 06a794f2bdbdd..105457c4fca7e 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveDataNodeMultiNodeStatementTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/RemoveNodeSingleNodeStatementTest.java @@ -20,25 +20,24 @@ package org.apache.iotdb.db.queryengine.plan.relational.sql.parser; import org.apache.iotdb.commons.queryengine.plan.relational.sql.ast.Statement; +import org.apache.iotdb.commons.queryengine.plan.relational.sql.parser.ParsingException; import org.apache.iotdb.db.protocol.session.IClientSession; import org.apache.iotdb.db.protocol.session.InternalClientSession; +import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.RemoveConfigNode; import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.RemoveDataNode; import org.junit.Before; import org.junit.Test; import java.time.ZoneId; -import java.util.Arrays; import java.util.Collections; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -/** - * Parsing tests for the table-model SQL that lets REMOVE DATANODE remove multiple DataNodes in a - * single statement. - */ -public class RemoveDataNodeMultiNodeStatementTest { +/** Parsing tests for table-model REMOVE DATANODE and REMOVE CONFIGNODE statements. */ +public class RemoveNodeSingleNodeStatementTest { private SqlParser sqlParser; private IClientSession clientSession; @@ -61,9 +60,15 @@ public void testRemoveSingleDataNode() { } @Test - public void testRemoveMultipleDataNodes() { - Statement statement = parse("remove datanode 3, 4, 5"); - assertTrue(statement instanceof RemoveDataNode); - assertEquals(Arrays.asList(3, 4, 5), ((RemoveDataNode) statement).getNodeIds()); + public void testRemoveSingleConfigNode() { + Statement statement = parse("remove confignode 3"); + assertTrue(statement instanceof RemoveConfigNode); + assertEquals(3, ((RemoveConfigNode) statement).getNodeId().intValue()); + } + + @Test + public void testRejectRemovingMultipleNodes() { + assertThrows(ParsingException.class, () -> parse("remove datanode 3, 4")); + assertThrows(ParsingException.class, () -> parse("remove confignode 3, 4")); } } diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 index 6bebd2bc08eee..e8e3c1937a7a5 100644 --- a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 @@ -660,7 +660,7 @@ removeRegionStatement ; removeDataNodeStatement - : REMOVE DATANODE dataNodeIds+=INTEGER_VALUE (',' dataNodeIds+=INTEGER_VALUE)* + : REMOVE DATANODE dataNodeId=INTEGER_VALUE ; removeConfigNodeStatement