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

dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new c04a8da75bc branch-3.0: [fix](vault) Fix bugs about altering storage 
vault name #45685 (#45963)
c04a8da75bc is described below

commit c04a8da75bcb39c387a9ac8465813bdfa5260a0b
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Dec 26 09:26:40 2024 +0800

    branch-3.0: [fix](vault) Fix bugs about altering storage vault name #45685 
(#45963)
    
    Cherry-picked from #45685
    
    Co-authored-by: Lei Zhang <zhang...@selectdb.com>
---
 cloud/src/meta-service/meta_service_resource.cpp   |  55 +++--
 cloud/test/meta_service_test.cpp                   |  39 ++++
 .../main/java/org/apache/doris/catalog/Env.java    |   5 +-
 .../java/org/apache/doris/catalog/OlapTable.java   |  20 +-
 .../org/apache/doris/catalog/StorageVault.java     |   3 +-
 .../org/apache/doris/catalog/StorageVaultMgr.java  |  52 ++++-
 .../org/apache/doris/catalog/TableProperty.java    |   4 -
 .../cloud/datasource/CloudInternalCatalog.java     |  36 +---
 .../apache/doris/datasource/InternalCatalog.java   |   1 -
 .../plans/commands/AlterStorageVaultCommand.java   |  10 +
 .../org/apache/doris/regression/suite/Suite.groovy |   4 +-
 .../vault_p0/alter/test_alter_vault_name.groovy    | 232 +++++++++++++++++++++
 12 files changed, 386 insertions(+), 75 deletions(-)

diff --git a/cloud/src/meta-service/meta_service_resource.cpp 
b/cloud/src/meta-service/meta_service_resource.cpp
index 4fa8cc5a132..d873dec7b21 100644
--- a/cloud/src/meta-service/meta_service_resource.cpp
+++ b/cloud/src/meta-service/meta_service_resource.cpp
@@ -523,9 +523,18 @@ static void set_default_vault_log_helper(const 
InstanceInfoPB& instance,
     LOG(INFO) << vault_msg;
 }
 
-static int alter_hdfs_storage_vault(InstanceInfoPB& instance, 
std::unique_ptr<Transaction> txn,
+static bool vault_exist(const InstanceInfoPB& instance, const std::string& 
new_vault_name) {
+    for (auto& name : instance.storage_vault_names()) {
+        if (new_vault_name == name) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static int alter_hdfs_storage_vault(InstanceInfoPB& instance, 
std::unique_ptr<Transaction>& txn,
                                     const StorageVaultPB& vault, 
MetaServiceCode& code,
-                                    std::string& msg) {
+                                    std::string& msg, 
AlterObjStoreInfoResponse* response) {
     if (!vault.has_hdfs_info()) {
         code = MetaServiceCode::INVALID_ARGUMENT;
         std::stringstream ss;
@@ -591,6 +600,13 @@ static int alter_hdfs_storage_vault(InstanceInfoPB& 
instance, std::unique_ptr<Tr
             msg = ss.str();
             return -1;
         }
+
+        if (vault_exist(instance, vault.alter_name())) {
+            code = MetaServiceCode::ALREADY_EXISTED;
+            msg = fmt::format("vault_name={} already existed", 
vault.alter_name());
+            return -1;
+        }
+
         new_vault.set_name(vault.alter_name());
         *name_itr = vault.alter_name();
     }
@@ -623,19 +639,15 @@ static int alter_hdfs_storage_vault(InstanceInfoPB& 
instance, std::unique_ptr<Tr
     txn->put(vault_key, val);
     LOG(INFO) << "put vault_id=" << vault_id << ", vault_key=" << 
hex(vault_key)
               << ", origin vault=" << origin_vault_info << ", new_vault=" << 
new_vault_info;
-    err = txn->commit();
-    if (err != TxnErrorCode::TXN_OK) {
-        code = cast_as<ErrCategory::COMMIT>(err);
-        msg = fmt::format("failed to commit kv txn, err={}", err);
-        LOG(WARNING) << msg;
-    }
 
+    DCHECK_EQ(new_vault.id(), vault_id);
+    response->set_storage_vault_id(new_vault.id());
     return 0;
 }
 
-static int alter_s3_storage_vault(InstanceInfoPB& instance, 
std::unique_ptr<Transaction> txn,
+static int alter_s3_storage_vault(InstanceInfoPB& instance, 
std::unique_ptr<Transaction>& txn,
                                   const StorageVaultPB& vault, 
MetaServiceCode& code,
-                                  std::string& msg) {
+                                  std::string& msg, AlterObjStoreInfoResponse* 
response) {
     if (!vault.has_obj_info()) {
         code = MetaServiceCode::INVALID_ARGUMENT;
         std::stringstream ss;
@@ -708,6 +720,13 @@ static int alter_s3_storage_vault(InstanceInfoPB& 
instance, std::unique_ptr<Tran
             msg = ss.str();
             return -1;
         }
+
+        if (vault_exist(instance, vault.alter_name())) {
+            code = MetaServiceCode::ALREADY_EXISTED;
+            msg = fmt::format("vault_name={} already existed", 
vault.alter_name());
+            return -1;
+        }
+
         new_vault.set_name(vault.alter_name());
         *name_itr = vault.alter_name();
     }
@@ -747,13 +766,9 @@ static int alter_s3_storage_vault(InstanceInfoPB& 
instance, std::unique_ptr<Tran
     txn->put(vault_key, val);
     LOG(INFO) << "put vault_id=" << vault_id << ", vault_key=" << 
hex(vault_key)
               << ", origin vault=" << origin_vault_info << ", new vault=" << 
new_vault_info;
-    err = txn->commit();
-    if (err != TxnErrorCode::TXN_OK) {
-        code = cast_as<ErrCategory::COMMIT>(err);
-        msg = fmt::format("failed to commit kv txn, err={}", err);
-        LOG(WARNING) << msg;
-    }
 
+    DCHECK_EQ(new_vault.id(), vault_id);
+    response->set_storage_vault_id(new_vault.id());
     return 0;
 }
 
@@ -1100,12 +1115,12 @@ void 
MetaServiceImpl::alter_storage_vault(google::protobuf::RpcController* contr
         break;
     }
     case AlterObjStoreInfoRequest::ALTER_S3_VAULT: {
-        alter_s3_storage_vault(instance, std::move(txn), request->vault(), 
code, msg);
-        return;
+        alter_s3_storage_vault(instance, txn, request->vault(), code, msg, 
response);
+        break;
     }
     case AlterObjStoreInfoRequest::ALTER_HDFS_VAULT: {
-        alter_hdfs_storage_vault(instance, std::move(txn), request->vault(), 
code, msg);
-        return;
+        alter_hdfs_storage_vault(instance, txn, request->vault(), code, msg, 
response);
+        break;
     }
     case AlterObjStoreInfoRequest::DROP_S3_VAULT:
         [[fallthrough]];
diff --git a/cloud/test/meta_service_test.cpp b/cloud/test/meta_service_test.cpp
index 3bf20facca1..777c7419b70 100644
--- a/cloud/test/meta_service_test.cpp
+++ b/cloud/test/meta_service_test.cpp
@@ -637,6 +637,25 @@ TEST(MetaServiceTest, AlterS3StorageVaultTest) {
         meta_service->alter_storage_vault(
                 reinterpret_cast<::google::protobuf::RpcController*>(&cntl), 
&req, &res, nullptr);
         ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << 
res.status().msg();
+
+        {
+            AlterObjStoreInfoRequest req;
+            req.set_cloud_unique_id("test_cloud_unique_id");
+            req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
+            StorageVaultPB vault;
+            vault.set_alter_name(new_vault_name);
+            ObjectStoreInfoPB obj;
+            obj_info.set_ak("new_ak");
+            obj_info.set_sk("new_sk");
+            vault.mutable_obj_info()->MergeFrom(obj);
+            vault.set_name(new_vault_name);
+            req.mutable_vault()->CopyFrom(vault);
+            meta_service->alter_storage_vault(
+                    
reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
+                    nullptr);
+            ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) 
<< res.status().msg();
+        }
+
         InstanceInfoPB instance;
         get_test_instance(instance);
 
@@ -726,6 +745,7 @@ TEST(MetaServiceTest, AlterHdfsStorageVaultTest) {
         meta_service->alter_storage_vault(
                 reinterpret_cast<::google::protobuf::RpcController*>(&cntl), 
&req, &res, nullptr);
         ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << 
res.status().msg();
+
         InstanceInfoPB instance;
         get_test_instance(instance);
 
@@ -793,6 +813,25 @@ TEST(MetaServiceTest, AlterHdfsStorageVaultTest) {
         meta_service->alter_storage_vault(
                 reinterpret_cast<::google::protobuf::RpcController*>(&cntl), 
&req, &res, nullptr);
         ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << 
res.status().msg();
+
+        {
+            AlterObjStoreInfoRequest req;
+            req.set_cloud_unique_id("test_cloud_unique_id");
+            req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
+            StorageVaultPB vault;
+            
vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
+            vault.set_name(new_vault_name);
+            vault.set_alter_name(new_vault_name);
+            req.mutable_vault()->CopyFrom(vault);
+
+            brpc::Controller cntl;
+            AlterObjStoreInfoResponse res;
+            meta_service->alter_storage_vault(
+                    
reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
+                    nullptr);
+            ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) 
<< res.status().msg();
+        }
+
         InstanceInfoPB instance;
         get_test_instance(instance);
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index 91a45bb71b0..f703fa0926a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -3693,7 +3693,10 @@ public class Env {
         }
 
         // Storage Vault
-        if (!olapTable.getStorageVaultName().isEmpty()) {
+        if (!Strings.isNullOrEmpty(olapTable.getStorageVaultId())) {
+            sb.append(",\n\"").append(PropertyAnalyzer
+                    .PROPERTIES_STORAGE_VAULT_ID).append("\" = \"");
+            sb.append(olapTable.getStorageVaultId()).append("\"");
             sb.append(",\n\"").append(PropertyAnalyzer
                     .PROPERTIES_STORAGE_VAULT_NAME).append("\" = \"");
             sb.append(olapTable.getStorageVaultName()).append("\"");
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index ef20b93053c..205702db632 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -263,22 +263,18 @@ public class OlapTable extends Table implements 
MTMVRelatedTableIf, GsonPostProc
                 String.valueOf(isBeingSynced));
     }
 
-    public void setStorageVaultName(String storageVaultName) throws 
DdlException {
-        if (storageVaultName == null || storageVaultName.isEmpty()) {
-            return;
-        }
-        getOrCreatTableProperty().setStorageVaultName(storageVaultName);
-    }
-
     public String getStorageVaultName() {
-        return getOrCreatTableProperty().getStorageVaultName();
+        if (Strings.isNullOrEmpty(getStorageVaultId())) {
+            return "";
+        }
+        return 
Env.getCurrentEnv().getStorageVaultMgr().getVaultNameById(getStorageVaultId());
     }
 
-    public void setStorageVaultId(String setStorageVaultId) throws 
DdlException {
-        if (setStorageVaultId == null || setStorageVaultId.isEmpty()) {
-            throw new DdlException("Invalid Storage Vault, please set one 
useful storage vault");
+    public void setStorageVaultId(String storageVaultId) throws DdlException {
+        if (Strings.isNullOrEmpty(storageVaultId)) {
+            throw new DdlException("Invalid storage vault id, please set an 
available storage vault");
         }
-        getOrCreatTableProperty().setStorageVaultId(setStorageVaultId);
+        getOrCreatTableProperty().setStorageVaultId(storageVaultId);
     }
 
     public String getStorageVaultId() {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
index 9d45ce7bdd8..c1a22430d50 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
@@ -45,6 +45,8 @@ public abstract class StorageVault {
     public static final String LOWER_CASE_META_NAMES = "lower_case_meta_names";
     public static final String META_NAMES_MAPPING = "meta_names_mapping";
 
+    public static final String VAULT_NAME = "VAULT_NAME";
+
     public enum StorageVaultType {
         UNKNOWN,
         S3,
@@ -60,7 +62,6 @@ public abstract class StorageVault {
         }
     }
 
-    protected static final String VAULT_NAME = "VAULT_NAME";
     protected String name;
     protected StorageVaultType type;
     protected String id;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
index cd97c92fb72..e48adad47ff 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
@@ -36,6 +36,8 @@ import org.apache.doris.system.SystemInfoService;
 import org.apache.doris.thrift.TNetworkAddress;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -82,12 +84,42 @@ public class StorageVaultMgr {
         rwLock.writeLock().unlock();
     }
 
-    public String getVaultIdByName(String name) {
-        String vaultId;
-        rwLock.readLock().lock();
-        vaultId = vaultNameToVaultId.getOrDefault(name, "");
-        rwLock.readLock().unlock();
-        return vaultId;
+    public String getVaultIdByName(String vaultName) {
+        try {
+            rwLock.readLock().lock();
+            return vaultNameToVaultId.getOrDefault(vaultName, "");
+        } finally {
+            rwLock.readLock().unlock();
+        }
+    }
+
+    public String getVaultNameById(String vaultId) {
+        try {
+            rwLock.readLock().lock();
+            for (Map.Entry<String, String> entry : 
vaultNameToVaultId.entrySet()) {
+                if (entry.getValue().equals(vaultId)) {
+                    return entry.getKey();
+                }
+            }
+            return "";
+        } finally {
+            rwLock.readLock().unlock();
+        }
+    }
+
+    private void updateVaultNameToIdCache(String oldVaultName, String 
newVaultName, String vaultId) {
+        try {
+            rwLock.writeLock().lock();
+            String cachedVaultId = vaultNameToVaultId.get(oldVaultName);
+            vaultNameToVaultId.remove(oldVaultName);
+            Preconditions.checkArgument(!Strings.isNullOrEmpty(cachedVaultId), 
cachedVaultId,
+                    "Cached vault id is null or empty");
+            Preconditions.checkArgument(cachedVaultId.equals(vaultId),
+                    "Cached vault id not equal to remote storage." + 
cachedVaultId + " - " + vaultId);
+            vaultNameToVaultId.put(newVaultName, vaultId);
+        } finally {
+            rwLock.writeLock().unlock();
+        }
     }
 
     private Cloud.StorageVaultPB.Builder buildAlterS3VaultRequest(Map<String, 
String> properties, String name)
@@ -168,8 +200,12 @@ public class StorageVaultMgr {
                 LOG.warn("failed to alter storage vault response: {} ", 
response);
                 throw new DdlException(response.getStatus().getMsg());
             }
-            LOG.info("Succeed to alter storage vault {}, id {}, origin default 
vault replaced {}",
-                    name, response.getStorageVaultId(), 
response.getDefaultStorageVaultReplaced());
+
+            if (request.hasVault() && request.getVault().hasAlterName()) {
+                updateVaultNameToIdCache(name, 
request.getVault().getAlterName(), response.getStorageVaultId());
+                LOG.info("Succeed to alter storage vault, old name:{} new 
name: {} id:{}", name,
+                        request.getVault().getAlterName(), 
response.getStorageVaultId());
+            }
 
             // Make BE eagerly fetch the storage vault info from Meta Service
             ALTER_BE_SYNC_THREAD_POOL.execute(() -> alterSyncVaultTask());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
index 3229d5dad72..a52477e66eb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
@@ -770,10 +770,6 @@ public class TableProperty implements Writable, 
GsonPostProcessable {
         return 
properties.getOrDefault(PropertyAnalyzer.PROPERTIES_STORAGE_VAULT_NAME, "");
     }
 
-    public void setStorageVaultName(String storageVaultName) {
-        properties.put(PropertyAnalyzer.PROPERTIES_STORAGE_VAULT_NAME, 
storageVaultName);
-    }
-
     public String getPropertiesString() throws IOException {
         ObjectMapper objectMapper = new ObjectMapper();
         try {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
 
b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
index c20d971cc30..8fc912d57df 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
@@ -55,7 +55,6 @@ import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.MetaNotFoundException;
-import org.apache.doris.common.Pair;
 import org.apache.doris.datasource.InternalCatalog;
 import org.apache.doris.proto.OlapCommon;
 import org.apache.doris.proto.OlapFile;
@@ -105,6 +104,12 @@ public class CloudInternalCatalog extends InternalCatalog {
             throws DdlException {
         // create base index first.
         Preconditions.checkArgument(tbl.getBaseIndexId() != -1);
+
+        if (((CloudEnv) Env.getCurrentEnv()).getEnableStorageVault()) {
+            
Preconditions.checkArgument(!Strings.isNullOrEmpty(tbl.getStorageVaultId()),
+                    "Storage vault id is null or empty");
+        }
+
         MaterializedIndex baseIndex = new 
MaterializedIndex(tbl.getBaseIndexId(), IndexState.NORMAL);
 
         LOG.info("begin create cloud partition");
@@ -128,9 +133,6 @@ public class CloudInternalCatalog extends InternalCatalog {
 
         long version = partition.getVisibleVersion();
 
-        final String storageVaultName = tbl.getStorageVaultName();
-        boolean storageVaultIdSet = tbl.getStorageVaultId().isEmpty();
-
         // short totalReplicaNum = replicaAlloc.getTotalReplicaNum();
         for (Map.Entry<Long, MaterializedIndex> entry : indexMap.entrySet()) {
             long indexId = entry.getKey();
@@ -177,29 +179,11 @@ public class CloudInternalCatalog extends InternalCatalog 
{
                         tbl.variantEnableFlattenNested());
                 requestBuilder.addTabletMetas(builder);
             }
-            if (!storageVaultIdSet && ((CloudEnv) 
Env.getCurrentEnv()).getEnableStorageVault()) {
-                requestBuilder.setStorageVaultName(storageVaultName);
-            }
             requestBuilder.setDbId(dbId);
-
-            LOG.info("create tablets, dbId: {}, tableId: {}, tableName: {}, 
partitionId: {}, partitionName: {}, "
-                    + "indexId: {}, vault name: {}",
-                    dbId, tbl.getId(), tbl.getName(), partitionId, 
partitionName, indexId, storageVaultName);
-            Cloud.CreateTabletsResponse resp = 
sendCreateTabletsRpc(requestBuilder);
-            // If the resp has no vault id set, it means the MS is running 
with enable_storage_vault false
-            if (resp.hasStorageVaultId() && !storageVaultIdSet) {
-                tbl.setStorageVaultId(resp.getStorageVaultId());
-                storageVaultIdSet = true;
-                if (storageVaultName.isEmpty()) {
-                    // If user doesn't specify the vault name for this table, 
we should set it
-                    // to make the show create table stmt return correct stmt
-                    // TODO(ByteYue): setDefaultStorageVault for vaultMgr 
might override user's
-                    // defualt vault, maybe we should set it using show 
default storage vault stmt
-                    tbl.setStorageVaultName(resp.getStorageVaultName());
-                    
Env.getCurrentEnv().getStorageVaultMgr().setDefaultStorageVault(
-                            Pair.of(resp.getStorageVaultName(), 
resp.getStorageVaultId()));
-                }
-            }
+            LOG.info("create tablets dbId: {} tableId: {} tableName: {} 
partitionId: {} partitionName: {} "
+                    + "indexId: {} vaultId: {}",
+                    dbId, tbl.getId(), tbl.getName(), partitionId, 
partitionName, indexId, tbl.getStorageVaultId());
+            sendCreateTabletsRpc(requestBuilder);
             if (index.getId() != tbl.getBaseIndexId()) {
                 // add rollup index to partition
                 partition.createRollupIndex(index);
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index aa14905c705..c5b2243aef2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -2746,7 +2746,6 @@ public class InternalCatalog implements 
CatalogIf<Database> {
                         + "' for storage vault '" + storageVaultName + "'");
             }
 
-            olapTable.setStorageVaultName(storageVaultName);
             storageVaultId = 
env.getStorageVaultMgr().getVaultIdByName(storageVaultName);
             if (Strings.isNullOrEmpty(storageVaultId)) {
                 throw new DdlException("Storage vault '" + storageVaultName + 
"' does not exist. "
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
index cbdc5765839..0766d236439 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
@@ -21,11 +21,14 @@ import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.StorageVault;
 import org.apache.doris.catalog.StorageVault.StorageVaultType;
 import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.FeNameFormat;
 import org.apache.doris.nereids.trees.plans.PlanType;
 import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.qe.StmtExecutor;
 
+import com.google.common.base.Preconditions;
+
 import java.util.Map;
 
 /**
@@ -48,6 +51,13 @@ public class AlterStorageVaultCommand extends Command 
implements ForwardWithSync
         if (vaultType == StorageVault.StorageVaultType.UNKNOWN) {
             throw new AnalysisException("Unsupported Storage Vault type: " + 
type);
         }
+
+        FeNameFormat.checkStorageVaultName(name);
+        if (properties.containsKey(StorageVault.VAULT_NAME)) {
+            String newName = properties.get(StorageVault.VAULT_NAME);
+            FeNameFormat.checkStorageVaultName(newName);
+            Preconditions.checkArgument(!name.equalsIgnoreCase(newName), 
"vault name no change");
+        }
         Env.getCurrentEnv().getStorageVaultMgr().alterStorageVault(vaultType, 
properties, name);
     }
 
diff --git 
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
 
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
index ee9a87251fd..a7b8421635e 100644
--- 
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
+++ 
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
@@ -783,11 +783,11 @@ class Suite implements GroovyInterceptable {
         return randomBoolean ? "true" : "false"
     }
 
-    void expectExceptionLike(Closure userFunction, String errorMessage = null) 
{
+    void expectExceptionLike(Closure userFunction, String errMsg = null) {
         try {
             userFunction()
         } catch (Exception e) {
-            if (!e.getMessage().contains(errorMessage)) {
+            if (!Strings.isNullOrEmpty(errMsg) && 
!e.getMessage().contains(errMsg)) {
                 throw e
             }
         }
diff --git a/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy 
b/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy
new file mode 100644
index 00000000000..4592e72292a
--- /dev/null
+++ b/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy
@@ -0,0 +1,232 @@
+// 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_alter_vault_name", "nonConcurrent") {
+    def suiteName = name;
+    if (!isCloudMode()) {
+        logger.info("skip ${suiteName} case, because not cloud mode")
+        return
+    }
+
+    if (!enableStoragevault()) {
+        logger.info("skip ${suiteName} case, because storage vault not 
enabled")
+        return
+    }
+
+    def vaultName = UUID.randomUUID().toString().replace("-", "")
+    def hdfsVaultName = "hdfs_" + vaultName
+    sql """
+        CREATE STORAGE VAULT ${hdfsVaultName}
+        PROPERTIES (
+            "type" = "HDFS",
+            "fs.defaultFS" = "${getHdfsFs()}",
+            "path_prefix" = "${hdfsVaultName}",
+            "hadoop.username" = "${getHdfsUser()}"
+        );
+    """
+
+    def s3VaultName = "s3_" + vaultName
+    sql """
+        CREATE STORAGE VAULT ${s3VaultName}
+        PROPERTIES (
+            "type" = "S3",
+            "s3.endpoint" = "${getS3Endpoint()}",
+            "s3.region" = "${getS3Region()}",
+            "s3.access_key" = "${getS3AK()}",
+            "s3.secret_key" = "${getS3SK()}",
+            "s3.root.path" = "${s3VaultName}",
+            "s3.bucket" = "${getS3BucketName()}",
+            "s3.external_endpoint" = "",
+            "provider" = "${getS3Provider()}",
+            "use_path_style" = "false"
+        );
+    """
+
+    // case1
+    expectExceptionLike({
+        sql """
+            ALTER STORAGE VAULT ${hdfsVaultName}
+            PROPERTIES (
+                "type" = "hdfs",
+                "VAULT_NAME" = "${hdfsVaultName}"
+            );
+        """
+    }, "vault name no change")
+
+    // case2
+    expectExceptionLike({
+        sql """
+            ALTER STORAGE VAULT ${hdfsVaultName}
+            PROPERTIES (
+                "type" = "hdfs",
+                "VAULT_NAME" = "${s3VaultName}"
+            );
+        """
+    }, "already existed")
+
+    // case3
+    expectExceptionLike({
+        sql """
+            ALTER STORAGE VAULT ${s3VaultName}
+            PROPERTIES (
+                "type" = "s3",
+                "VAULT_NAME" = "${s3VaultName}"
+            );
+        """
+    }, "vault name no change")
+
+    // case4
+    expectExceptionLike({
+        sql """
+            ALTER STORAGE VAULT ${s3VaultName}
+            PROPERTIES (
+                "type" = "s3",
+                "VAULT_NAME" = "${hdfsVaultName}"
+            );
+        """
+    }, "already existed")
+
+    // case5
+    sql """
+        CREATE TABLE ${hdfsVaultName} (
+            C_CUSTKEY     INTEGER NOT NULL,
+            C_NAME        INTEGER NOT NULL
+        )
+        DUPLICATE KEY(C_CUSTKEY, C_NAME)
+        DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "storage_vault_name" = ${hdfsVaultName}
+        )
+    """
+    sql """ insert into ${hdfsVaultName} values(1, 1); """
+    sql """ sync;"""
+    def result = sql """ select * from ${hdfsVaultName}; """
+    assertEquals(result.size(), 1);
+
+    sql """
+        ALTER STORAGE VAULT ${hdfsVaultName}
+        PROPERTIES (
+            "type" = "hdfs",
+            "VAULT_NAME" = "${hdfsVaultName}_new"
+        );
+        """
+    sql """ insert into ${hdfsVaultName} values(2, 2); """
+    sql """ sync;"""
+    result = sql """ select * from ${hdfsVaultName}; """
+    assertEquals(result.size(), 2);
+
+    // case6
+    expectExceptionLike({
+        sql """
+            CREATE TABLE ${hdfsVaultName}_new (
+                C_CUSTKEY     INTEGER NOT NULL,
+                C_NAME        INTEGER NOT NULL
+            )
+            DUPLICATE KEY(C_CUSTKEY, C_NAME)
+            DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+            PROPERTIES (
+                "replication_num" = "1",
+                "storage_vault_name" = ${hdfsVaultName}
+            )
+        """
+    }, "does not exis")
+
+    // case7
+    sql """
+        CREATE TABLE ${hdfsVaultName}_new (
+            C_CUSTKEY     INTEGER NOT NULL,
+            C_NAME        INTEGER NOT NULL
+        )
+        DUPLICATE KEY(C_CUSTKEY, C_NAME)
+        DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "storage_vault_name" = ${hdfsVaultName}_new
+        )
+    """
+
+    sql """ insert into ${hdfsVaultName}_new values(1, 1); """
+    sql """ sync;"""
+    result = sql """ select * from ${hdfsVaultName}_new; """
+    assertEquals(result.size(), 1);
+
+    // case8
+    sql """
+        CREATE TABLE ${s3VaultName} (
+            C_CUSTKEY     INTEGER NOT NULL,
+            C_NAME        INTEGER NOT NULL
+        )
+        DUPLICATE KEY(C_CUSTKEY, C_NAME)
+        DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "storage_vault_name" = ${s3VaultName}
+        )
+    """
+    sql """ insert into ${s3VaultName} values(1, 1); """
+    sql """ sync;"""
+    result = sql """ select * from ${s3VaultName}; """
+    assertEquals(result.size(), 1);
+
+    sql """
+        ALTER STORAGE VAULT ${s3VaultName}
+        PROPERTIES (
+            "type" = "s3",
+            "VAULT_NAME" = "${s3VaultName}_new"
+        );
+        """
+    sql """ insert into ${s3VaultName} values(2, 2); """
+    sql """ sync;"""
+    result = sql """ select * from ${s3VaultName}; """
+    assertEquals(result.size(), 2);
+
+    // case9
+    expectExceptionLike({
+        sql """
+            CREATE TABLE ${s3VaultName}_new (
+                C_CUSTKEY     INTEGER NOT NULL,
+                C_NAME        INTEGER NOT NULL
+            )
+            DUPLICATE KEY(C_CUSTKEY, C_NAME)
+            DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+            PROPERTIES (
+                "replication_num" = "1",
+                "storage_vault_name" = ${s3VaultName}
+            )
+        """
+    }, "does not exis")
+
+    // case10
+    sql """
+        CREATE TABLE ${s3VaultName}_new (
+            C_CUSTKEY     INTEGER NOT NULL,
+            C_NAME        INTEGER NOT NULL
+        )
+        DUPLICATE KEY(C_CUSTKEY, C_NAME)
+        DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+        PROPERTIES (
+            "replication_num" = "1",
+            "storage_vault_name" = ${s3VaultName}_new
+        )
+    """
+
+    sql """ insert into ${s3VaultName}_new values(1, 1); """
+    sql """ sync;"""
+    result = sql """ select * from ${s3VaultName}_new; """
+    assertEquals(result.size(), 1);
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to