diff --git a/fe/fe-core/src/main/java/com/starrocks/analysis/ModifyPartitionClause.java b/fe/fe-core/src/main/java/com/starrocks/analysis/ModifyPartitionClause.java index 1a73b4ea2c92f..a4d98d6a7a1a5 100644 --- a/fe/fe-core/src/main/java/com/starrocks/analysis/ModifyPartitionClause.java +++ b/fe/fe-core/src/main/java/com/starrocks/analysis/ModifyPartitionClause.java @@ -18,16 +18,10 @@ package com.starrocks.analysis; import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.starrocks.alter.AlterOpType; -import com.starrocks.catalog.DataProperty; -import com.starrocks.common.AnalysisException; -import com.starrocks.common.FeConstants; import com.starrocks.common.util.PrintableMap; -import com.starrocks.common.util.PropertyAnalyzer; +import com.starrocks.sql.ast.AstVisitor; import java.util.List; import java.util.Map; @@ -74,47 +68,6 @@ public static ModifyPartitionClause createStarClause(Map propert return new ModifyPartitionClause(properties); } - @Override - public void analyze(Analyzer analyzer) throws AnalysisException { - if (partitionNames == null || (!needExpand && partitionNames.isEmpty())) { - throw new AnalysisException("Partition names is not set or empty"); - } - - if (partitionNames.stream().anyMatch(entity -> Strings.isNullOrEmpty(entity))) { - throw new AnalysisException("there are empty partition name"); - } - - if (properties == null || properties.isEmpty()) { - throw new AnalysisException("Properties is not set"); - } - - // check properties here - checkProperties(Maps.newHashMap(properties)); - } - - // Check the following properties' legality before modifying partition. - // 1. replication_num - // 2. storage_medium && storage_cooldown_time - // 3. in_memory - // 4. tablet type - private void checkProperties(Map properties) throws AnalysisException { - // 1. data property - DataProperty newDataProperty = null; - newDataProperty = PropertyAnalyzer.analyzeDataProperty(properties, DataProperty.DEFAULT_DATA_PROPERTY); - Preconditions.checkNotNull(newDataProperty); - - // 2. replication num - short newReplicationNum = (short) -1; - newReplicationNum = PropertyAnalyzer.analyzeReplicationNum(properties, FeConstants.default_replication_num); - Preconditions.checkState(newReplicationNum != (short) -1); - - // 3. in memory - PropertyAnalyzer.analyzeBooleanProp(properties, PropertyAnalyzer.PROPERTIES_INMEMORY, false); - - // 4. tablet type - PropertyAnalyzer.analyzeTabletType(properties); - } - @Override public Map getProperties() { return this.properties; @@ -146,4 +99,14 @@ public String toSql() { public String toString() { return toSql(); } + + @Override + public boolean isSupportNewPlanner() { + return true; + } + + @Override + public R accept(AstVisitor visitor, C context) { + return visitor.visitModifyPartitionClause(this, context); + } } diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/AlterTableStatementAnalyzer.java b/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/AlterTableStatementAnalyzer.java index 6f4a9121f3e74..93bd7630601a4 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/AlterTableStatementAnalyzer.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/AlterTableStatementAnalyzer.java @@ -1,16 +1,20 @@ // This file is licensed under the Elastic License 2.0. Copyright 2021-present, StarRocks Limited. package com.starrocks.sql.analyzer; +import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.google.common.collect.Maps; import com.starrocks.alter.AlterOpType; import com.starrocks.analysis.AlterClause; import com.starrocks.analysis.AlterTableStmt; import com.starrocks.analysis.CreateIndexClause; import com.starrocks.analysis.IndexDef; +import com.starrocks.analysis.ModifyPartitionClause; import com.starrocks.analysis.ModifyTablePropertiesClause; import com.starrocks.analysis.TableName; import com.starrocks.analysis.TableRenameClause; import com.starrocks.catalog.CatalogUtils; +import com.starrocks.catalog.DataProperty; import com.starrocks.catalog.Index; import com.starrocks.catalog.MaterializedView; import com.starrocks.catalog.Table; @@ -18,6 +22,7 @@ import com.starrocks.common.AnalysisException; import com.starrocks.common.ErrorCode; import com.starrocks.common.ErrorReport; +import com.starrocks.common.FeConstants; import com.starrocks.common.FeNameFormat; import com.starrocks.common.util.DynamicPartitionUtil; import com.starrocks.common.util.PropertyAnalyzer; @@ -56,6 +61,7 @@ public static void analyze(AlterTableStmt statement, ConnectContext context) { } static class AlterTableClauseAnalyzerVisitor extends AstVisitor { + public void analyze(AlterClause statement, ConnectContext session) { visit(statement, session); } @@ -156,5 +162,54 @@ public Void visitModifyTablePropertiesClause(ModifyTablePropertiesClause clause, } return null; } + + @Override + public Void visitModifyPartitionClause(ModifyPartitionClause clause, ConnectContext context) { + final List partitionNames = clause.getPartitionNames(); + final boolean needExpand = clause.isNeedExpand(); + final Map properties = clause.getProperties(); + if (partitionNames == null || (!needExpand && partitionNames.isEmpty())) { + throw new SemanticException("Partition names is not set or empty"); + } + + if (partitionNames.stream().anyMatch(Strings::isNullOrEmpty)) { + throw new SemanticException("there are empty partition name"); + } + + if (properties == null || properties.isEmpty()) { + throw new SemanticException("Properties is not set"); + } + + // check properties here + try { + checkProperties(Maps.newHashMap(properties)); + } catch (AnalysisException e) { + throw new SemanticException("check properties error: %s", e.getMessage()); + } + return null; + } + + // Check the following properties' legality before modifying partition. + // 1. replication_num + // 2. storage_medium && storage_cooldown_time + // 3. in_memory + // 4. tablet type + private void checkProperties(Map properties) throws AnalysisException { + // 1. data property + DataProperty newDataProperty = null; + newDataProperty = PropertyAnalyzer.analyzeDataProperty(properties, DataProperty.DEFAULT_DATA_PROPERTY); + Preconditions.checkNotNull(newDataProperty); + + // 2. replication num + short newReplicationNum; + newReplicationNum = PropertyAnalyzer.analyzeReplicationNum(properties, FeConstants.default_replication_num); + Preconditions.checkState(newReplicationNum != (short) -1); + + // 3. in memory + PropertyAnalyzer.analyzeBooleanProp(properties, PropertyAnalyzer.PROPERTIES_INMEMORY, false); + + // 4. tablet type + PropertyAnalyzer.analyzeTabletType(properties); + } } } diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/ast/AstVisitor.java b/fe/fe-core/src/main/java/com/starrocks/sql/ast/AstVisitor.java index 1ba5044b4b958..0aab3c11ac731 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/ast/AstVisitor.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/ast/AstVisitor.java @@ -63,6 +63,7 @@ import com.starrocks.analysis.LiteralExpr; import com.starrocks.analysis.ModifyBackendAddressClause; import com.starrocks.analysis.ModifyFrontendAddressClause; +import com.starrocks.analysis.ModifyPartitionClause; import com.starrocks.analysis.ModifyTablePropertiesClause; import com.starrocks.analysis.OrderByElement; import com.starrocks.analysis.ParseNode; @@ -456,6 +457,10 @@ public R visitDropPartitionClause(DropPartitionClause clause, C context) { return visitNode(clause, context); } + public R visitModifyPartitionClause(ModifyPartitionClause clause, C context) { + return visitNode(clause, context); + } + public R visitAddPartitionClause(AddPartitionClause clause, C context) { return visitNode(clause, context); } diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/parser/AstBuilder.java b/fe/fe-core/src/main/java/com/starrocks/sql/parser/AstBuilder.java index 9bbdc66a1c94b..54d74516e01af 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/parser/AstBuilder.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/parser/AstBuilder.java @@ -89,6 +89,7 @@ import com.starrocks.analysis.LiteralExpr; import com.starrocks.analysis.ModifyBackendAddressClause; import com.starrocks.analysis.ModifyFrontendAddressClause; +import com.starrocks.analysis.ModifyPartitionClause; import com.starrocks.analysis.ModifyTablePropertiesClause; import com.starrocks.analysis.MultiItemListPartitionDesc; import com.starrocks.analysis.MultiRangePartitionDesc; @@ -230,6 +231,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -829,6 +831,29 @@ public ParseNode visitDropPartitionClause(StarRocksParser.DropPartitionClauseCon return new DropPartitionClause(exists, partitionName, temp, force); } + @Override + public ParseNode visitModifyPartitionClause(StarRocksParser.ModifyPartitionClauseContext context) { + Map properties = null; + if (context.propertyList() != null) { + properties = new HashMap<>(); + List propertyList = visit(context.propertyList().property(), Property.class); + for (Property property : propertyList) { + properties.put(property.getKey(), property.getValue()); + } + } + if (context.identifier() != null) { + final String partitionName = ((Identifier) visit(context.identifier())).getValue(); + return new ModifyPartitionClause(Collections.singletonList(partitionName), properties); + } else if (context.identifierList() != null) { + final List identifierList = visit(context.identifierList().identifier(), Identifier.class); + return new ModifyPartitionClause(identifierList.stream().map(Identifier::getValue).collect(toList()), + properties); + } else if (context.ASTERISK_SYMBOL() != null) { + return ModifyPartitionClause.createStarClause(properties); + } + return null; + } + // ------------------------------------------- View Statement ------------------------------------------------------ @Override diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/parser/StarRocks.g4 b/fe/fe-core/src/main/java/com/starrocks/sql/parser/StarRocks.g4 index ec5be533bc4a0..2d8d5b2065a10 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/parser/StarRocks.g4 +++ b/fe/fe-core/src/main/java/com/starrocks/sql/parser/StarRocks.g4 @@ -419,6 +419,7 @@ alterClause | dropPartitionClause | modifyTablePropertiesClause | addPartitionClause + | modifyPartitionClause ; addPartitionClause @@ -481,6 +482,10 @@ dropComputeNodeClause : DROP COMPUTE NODE string (',' string)* ; +modifyPartitionClause + : MODIFY PARTITION (identifier | identifierList | '(' ASTERISK_SYMBOL ')') SET propertyList + ; + // ------------------------------------------- DML Statement ----------------------------------------------------------- insertStatement diff --git a/fe/fe-core/src/test/java/com/starrocks/alter/AlterTest.java b/fe/fe-core/src/test/java/com/starrocks/alter/AlterTest.java index df526dcb12f26..533d0a5674e51 100644 --- a/fe/fe-core/src/test/java/com/starrocks/alter/AlterTest.java +++ b/fe/fe-core/src/test/java/com/starrocks/alter/AlterTest.java @@ -523,7 +523,7 @@ public void testConflictAlterOperations() throws Exception { Short.valueOf(tbl2.getPartitionInfo().getReplicationNum(partition.getId()))); Assert.assertEquals(Short.valueOf("2"), tbl2.getDefaultReplicationNum()); stmt = "alter table test.tbl2 modify partition tbl2 set ('replication_num' = '1');"; - alterTable(stmt, false); + alterTableWithNewParser(stmt, false); Assert.assertEquals(Short.valueOf("1"), Short.valueOf(tbl2.getPartitionInfo().getReplicationNum(partition.getId()))); Assert.assertEquals(Short.valueOf("1"), tbl2.getDefaultReplicationNum()); @@ -562,7 +562,7 @@ public void testBatchUpdatePartitionProperties() throws Exception { Assert.assertEquals(Short.valueOf("1"), Short.valueOf(tbl4.getPartitionInfo().getReplicationNum(partition.getId()))); } - alterTable(stmt, false); + alterTableWithNewParser(stmt, false); for (Partition partition : partitionList) { Assert.assertEquals(Short.valueOf("3"), Short.valueOf(tbl4.getPartitionInfo().getReplicationNum(partition.getId()))); @@ -575,7 +575,7 @@ public void testBatchUpdatePartitionProperties() throws Exception { for (Partition partition : partitionList) { Assert.assertEquals(false, tbl4.getPartitionInfo().getIsInMemory(partition.getId())); } - alterTable(stmt, false); + alterTableWithNewParser(stmt, false); for (Partition partition : partitionList) { Assert.assertEquals(true, tbl4.getPartitionInfo().getIsInMemory(partition.getId())); } @@ -590,7 +590,7 @@ public void testBatchUpdatePartitionProperties() throws Exception { for (Partition partition : partitionList) { Assert.assertEquals(oldDataProperty, tbl4.getPartitionInfo().getDataProperty(partition.getId())); } - alterTable(stmt, false); + alterTableWithNewParser(stmt, false); DataProperty newDataProperty = new DataProperty(TStorageMedium.HDD, DataProperty.MAX_COOLDOWN_TIME_MS); for (Partition partition : partitionList) { Assert.assertEquals(newDataProperty, tbl4.getPartitionInfo().getDataProperty(partition.getId())); @@ -600,7 +600,7 @@ public void testBatchUpdatePartitionProperties() throws Exception { // batch update range partitions' properties with * stmt = "alter table test.tbl4 modify partition (*) set ('replication_num' = '1')"; partitionList = Lists.newArrayList(p1, p2, p3, p4); - alterTable(stmt, false); + alterTableWithNewParser(stmt, false); for (Partition partition : partitionList) { Assert.assertEquals(Short.valueOf("1"), Short.valueOf(tbl4.getPartitionInfo().getReplicationNum(partition.getId())));