diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 index 97876c231fec69f..15597af4279d1a6 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 @@ -510,6 +510,8 @@ supportedAdminStatement (ON LEFT_PAREN backends+=STRING_LITERAL (COMMA backends+=STRING_LITERAL)* RIGHT_PAREN)? #adminCleanTrash | ADMIN SET TABLE name=multipartIdentifier STATUS properties=propertyClause? #adminSetTableStatus + | ADMIN SET TABLE name=multipartIdentifier + PARTITION VERSION properties=propertyClause? #adminSetPartitionVersion ; supportedRecoverStatement @@ -527,8 +529,6 @@ unsupportedAdminStatement | ADMIN CANCEL REPAIR TABLE baseTableRef #adminCancelRepairTable | ADMIN SET (FRONTEND | (ALL FRONTENDS)) CONFIG (LEFT_PAREN propertyItemList RIGHT_PAREN)? ALL? #adminSetFrontendConfig - | ADMIN SET TABLE name=multipartIdentifier - PARTITION VERSION properties=propertyClause? #adminSetPartitionVersion | ADMIN COPY TABLET tabletId=INTEGER_VALUE properties=propertyClause? #adminCopyTablet ; diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index bb344e1b376deb0..fe5cf70e6648119 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -495,6 +495,7 @@ import org.apache.doris.nereids.trees.plans.commands.AdminCleanTrashCommand; import org.apache.doris.nereids.trees.plans.commands.AdminCompactTableCommand; import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand; +import org.apache.doris.nereids.trees.plans.commands.AdminSetPartitionVersionCommand; import org.apache.doris.nereids.trees.plans.commands.AdminSetTableStatusCommand; import org.apache.doris.nereids.trees.plans.commands.AdminShowReplicaStatusCommand; import org.apache.doris.nereids.trees.plans.commands.AlterCatalogCommentCommand; @@ -5185,5 +5186,17 @@ public Object visitSwitchCatalog(SwitchCatalogContext ctx) { } throw new AnalysisException("catalog name can not be null"); } + + @Override + public LogicalPlan visitAdminSetPartitionVersion(DorisParser.AdminSetPartitionVersionContext ctx) { + + List nameParts = visitMultipartIdentifier(ctx.name); + + Map properties = ctx.properties != null + ? Maps.newHashMap(visitPropertyClause(ctx.properties)) + : Maps.newHashMap(); + return new AdminSetPartitionVersionCommand(new TableNameInfo(nameParts), properties); + } + } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java index dfc129f10b0fd6d..63cc385384c8b10 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java @@ -266,5 +266,6 @@ public enum PlanType { CREATE_ROUTINE_LOAD_COMMAND, SHOW_TABLE_CREATION_COMMAND, SHOW_QUERY_PROFILE_COMMAND, - SWITCH_COMMAND + SWITCH_COMMAND, + ADMIN_SET_PARTITION_VERSION } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetPartitionVersionCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetPartitionVersionCommand.java new file mode 100644 index 000000000000000..9854ee9c0245f44 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminSetPartitionVersionCommand.java @@ -0,0 +1,98 @@ +// 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.doris.nereids.trees.plans.commands; + +import org.apache.doris.catalog.Env; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.common.util.PropertyAnalyzer; +import org.apache.doris.common.util.Util; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.nereids.trees.plans.PlanType; +import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo; +import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.qe.ConnectContext; +import org.apache.doris.qe.StmtExecutor; + +import java.util.Map; + +/** + * admin set partition version command + */ +public class AdminSetPartitionVersionCommand extends Command implements ForwardNoSync { + long partitionId = -1; + long visibleVersion = -1; + private final TableNameInfo tableName; + private final Map properties; + + /** + * constructor + */ + public AdminSetPartitionVersionCommand(TableNameInfo tableName, Map properties) { + super(PlanType.ADMIN_SET_PARTITION_VERSION); + this.tableName = tableName; + this.properties = properties; + } + + @Override + public void run(ConnectContext ctx, StmtExecutor executor) throws Exception { + + tableName.analyze(ctx); + + // check auth + if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) { + ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ADMIN"); + } + + Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName()); + + checkProperties(); + + String database = tableName.getDb(); + String table = tableName.getTbl(); + + int setSuccess = Env.getCurrentEnv().setPartitionVersionInternal(database, table, partitionId, visibleVersion, + false); + if (setSuccess == -1) { + throw new DdlException("Failed to set partition visible version to " + visibleVersion + ". " + "Partition " + + partitionId + " not exists. Database " + database + ", Table " + table + "."); + } + + } + + private void checkProperties() throws AnalysisException { + partitionId = PropertyAnalyzer.analyzePartitionId(properties); + if (partitionId == -1) { + throw new AnalysisException("Should specify 'partition_id' property."); + } + visibleVersion = PropertyAnalyzer.analyzeVisibleVersion(properties); + if (visibleVersion == -1) { + throw new AnalysisException("Should specify 'visible_version' property."); + } + if (properties != null && !properties.isEmpty()) { + throw new AnalysisException("Unknown properties: " + properties.keySet()); + } + } + + @Override + public R accept(PlanVisitor visitor, C context) { + return visitor.visitAdminSetPartitionVersionCommand(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java index d3749e94d57d0f0..cc702f35164379f 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java @@ -23,6 +23,7 @@ import org.apache.doris.nereids.trees.plans.commands.AdminCleanTrashCommand; import org.apache.doris.nereids.trees.plans.commands.AdminCompactTableCommand; import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand; +import org.apache.doris.nereids.trees.plans.commands.AdminSetPartitionVersionCommand; import org.apache.doris.nereids.trees.plans.commands.AdminSetTableStatusCommand; import org.apache.doris.nereids.trees.plans.commands.AdminShowReplicaStatusCommand; import org.apache.doris.nereids.trees.plans.commands.AlterCatalogCommentCommand; @@ -697,4 +698,9 @@ default R visitShowQueryProfileCommand(ShowQueryProfileCommand showQueryProfileC default R visitSwitchCommand(SwitchCommand switchCommand, C context) { return visitCommand(switchCommand, context); } + + default R visitAdminSetPartitionVersionCommand(AdminSetPartitionVersionCommand adminSetPartitionVersionCommand, + C context) { + return visitCommand(adminSetPartitionVersionCommand, context); + } } diff --git a/regression-test/suites/nereids_p0/select_tablets/test_nereids_admin_set_partition_version.groovy b/regression-test/suites/nereids_p0/select_tablets/test_nereids_admin_set_partition_version.groovy new file mode 100644 index 000000000000000..bd6a9177055e0c9 --- /dev/null +++ b/regression-test/suites/nereids_p0/select_tablets/test_nereids_admin_set_partition_version.groovy @@ -0,0 +1,75 @@ +package select_tablets +// 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. + + +suite("test_nereids_admin_set_partition_version") { + def table = "test_nereids_admin_set_partition_version" + + // create table and insert data + String dbName = 'test_nereids_admin_set_partition_version' + try_sql """drop database if exists ${dbName}""" + sql """create database ${dbName}""" + sql """ drop table if exists ${dbName}.${table} force""" + + sql """ + create table ${dbName}.${table} ( + `id` int(11), + `name` varchar(128), + `da` date + ) + engine=olap + duplicate key(id) + partition by range(da)( + PARTITION p3 VALUES LESS THAN ('2023-01-01'), + PARTITION p4 VALUES LESS THAN ('2024-01-01'), + PARTITION p5 VALUES LESS THAN ('2025-01-01') + ) + distributed by hash(id) buckets 2 + properties( + "replication_num"="1", + "light_schema_change"="true" + ); + """ + + def result = sql_return_maparray "show partitions from ${dbName}.${table}" + logger.info("${result}") + def partitionId; + for (def partition : result) { + //get any partition ID. + partitionId = partition.PartitionId; + break; + } + + checkNereidsExecute("ADMIN SET TABLE ${dbName}.${table} PARTITION VERSION PROPERTIES ('partition_id' = '${partitionId}', 'visible_version' = '100');") + sql """ use ${dbName}""" + checkNereidsExecute("ADMIN SET TABLE ${table} PARTITION VERSION PROPERTIES ('partition_id' = '${partitionId}', 'visible_version' = '100');") + + String catalog_name = "es" + + sql """drop catalog if exists ${catalog_name}""" + sql """create catalog if not exists ${catalog_name} properties ( + "type"="es", + "hosts"="http://127.0.0.1:9200" + );""" + + sql """switch ${catalog_name};""" + + checkNereidsExecute("ADMIN SET TABLE ${dbName}.${table} PARTITION VERSION PROPERTIES ('partition_id' = '${partitionId}', 'visible_version' = '100');") + +} +