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

dkuzmenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new 02f0553eb85 HIVE-29066: PARTITION_NAME_WHITELIST_PATTERN is not 
honoring session level configuration (#5943)
02f0553eb85 is described below

commit 02f0553eb85deb55e94fd881fc2faec917326656
Author: Raghav Aggarwal <[email protected]>
AuthorDate: Sat Aug 2 13:51:19 2025 +0530

    HIVE-29066: PARTITION_NAME_WHITELIST_PATTERN is not honoring session level 
configuration (#5943)
---
 .../apache/hive/common/util/HiveStringUtils.java   | 25 ++++---
 .../hadoop/hive/ql/exec/FileSinkOperator.java      | 35 ++++++----
 .../hadoop/hive/ql/plan/DynamicPartitionCtx.java   |  4 +-
 .../dynamic_partitions_with_whitelist.q            |  2 +-
 .../session_partition_with_whitelist.q             |  9 +++
 .../add_partition_with_whitelist.q.out             |  2 +-
 .../alter_partition_with_whitelist.q.out           |  2 +-
 .../dynamic_partitions_with_whitelist.q.out        |  8 +--
 .../session_partition_with_whitelist.q.out         | 20 ++++++
 .../apache/hadoop/hive/metastore/HMSHandler.java   | 38 +++++------
 .../apache/hadoop/hive/metastore/ObjectStore.java  | 14 +---
 .../hive/metastore/utils/MetaStoreServerUtils.java | 77 ++++++++++++----------
 12 files changed, 130 insertions(+), 106 deletions(-)

diff --git a/common/src/java/org/apache/hive/common/util/HiveStringUtils.java 
b/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
index d703f9f41f7..1b4b34f1a82 100644
--- a/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
+++ b/common/src/java/org/apache/hive/common/util/HiveStringUtils.java
@@ -18,6 +18,7 @@
 
 package org.apache.hive.common.util;
 
+import com.google.common.base.Splitter;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.InetAddress;
@@ -38,8 +39,6 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;
-
-import com.google.common.base.Splitter;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.text.translate.CharSequenceTranslator;
 import org.apache.commons.lang3.text.translate.EntityArrays;
@@ -1080,19 +1079,17 @@ public static boolean commentProvided(char[] chars) {
     return false;
   }
 
-  public static String getPartitionValWithInvalidCharacter(List<String> 
partVals,
-      Pattern partitionValidationPattern) {
-    if (partitionValidationPattern == null) {
-      return null;
+  public static String getPartitionValWithInvalidCharacter(
+      List<String> partVals, Pattern partitionValidationPattern) {
+    String result = null;
+    if (partitionValidationPattern != null) {
+      result =
+          partVals.stream()
+              .filter(partVal -> 
!partitionValidationPattern.matcher(partVal).matches())
+              .findFirst()
+              .orElse(null);
     }
-  
-    for (String partVal : partVals) {
-      if (!partitionValidationPattern.matcher(partVal).matches()) {
-        return partVal;
-      }
-    }
-  
-    return null;
+    return result;
   }
 
   /**
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java 
b/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java
index cfa2608a93c..6a57672207f 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java
@@ -24,6 +24,7 @@
 import static 
org.apache.hadoop.hive.ql.security.authorization.HiveCustomStorageHandlerUtils.setWriteOperation;
 import static 
org.apache.hadoop.hive.ql.security.authorization.HiveCustomStorageHandlerUtils.setWriteOperationIsSorted;
 
+import com.google.common.collect.Lists;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -38,20 +39,17 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.function.BiFunction;
-
-import com.google.common.collect.Lists;
-
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-
 import org.apache.hadoop.hive.common.FileUtils;
 import org.apache.hadoop.hive.common.StatsSetupConst;
 import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.conf.HiveConfUtil;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.hive.conf.HiveConfUtil;
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
 import org.apache.hadoop.hive.ql.CompilationOpContext;
 import org.apache.hadoop.hive.ql.ErrorMsg;
 import org.apache.hadoop.hive.ql.exec.Utilities.MissingBucketsContext;
@@ -81,7 +79,11 @@
 import org.apache.hadoop.hive.ql.plan.api.OperatorType;
 import org.apache.hadoop.hive.ql.stats.StatsCollectionContext;
 import org.apache.hadoop.hive.ql.stats.StatsPublisher;
-import org.apache.hadoop.hive.serde2.*;
+import org.apache.hadoop.hive.serde2.AbstractSerDe;
+import org.apache.hadoop.hive.serde2.ColumnProjectionUtils;
+import org.apache.hadoop.hive.serde2.SerDeException;
+import org.apache.hadoop.hive.serde2.SerDeStats;
+import org.apache.hadoop.hive.serde2.Serializer;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
 import 
org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils.ObjectInspectorCopyOption;
@@ -92,13 +94,11 @@
 import org.apache.hadoop.hive.shims.HadoopShims.StoragePolicyShim;
 import org.apache.hadoop.hive.shims.HadoopShims.StoragePolicyValue;
 import org.apache.hadoop.hive.shims.ShimLoader;
-
 import org.apache.hadoop.io.IntWritable;
 import org.apache.hadoop.io.LongWritable;
 import org.apache.hadoop.io.Writable;
 import org.apache.hadoop.mapred.JobConf;
 import org.apache.hadoop.util.ReflectionUtils;
-
 import org.apache.hive.common.util.HiveStringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1125,12 +1125,19 @@ public void process(Object row, int tag) throws 
HiveException {
           }
         }
 
-        String invalidPartitionVal;
-        if((invalidPartitionVal = 
HiveStringUtils.getPartitionValWithInvalidCharacter(dpVals, 
dpCtx.getWhiteListPattern()))!=null) {
-          throw new HiveFatalException("Partition value '" + 
invalidPartitionVal +
-              "' contains a character not matched by whitelist pattern '" +
-              dpCtx.getWhiteListPattern().toString() + "'.  " + "(configure 
with " +
-              
HiveConf.ConfVars.METASTORE_PARTITION_NAME_WHITELIST_PATTERN.varname + ")");
+        String invalidPartitionVal =
+            HiveStringUtils.getPartitionValWithInvalidCharacter(
+                dpVals, dpCtx.getWhiteListPattern());
+
+        if (invalidPartitionVal != null) {
+          String errorMsg =
+              ("Partition value '%s' contains a character not matched by 
whitelist pattern '%s'. Configure with %s")
+                  .formatted(
+                      invalidPartitionVal,
+                      dpCtx.getWhiteListPattern().toString(),
+                      
MetastoreConf.ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getVarname());
+
+          throw new HiveFatalException(errorMsg);
         }
         fpaths = getDynOutPaths(dpVals, lbDirName);
         dynamicPartitionSpecs.add(fpaths.dpDirForCounters);
diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/plan/DynamicPartitionCtx.java 
b/ql/src/java/org/apache/hadoop/hive/ql/plan/DynamicPartitionCtx.java
index c90f6dfb491..a83f91f2f42 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/DynamicPartitionCtx.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/DynamicPartitionCtx.java
@@ -91,7 +91,7 @@ public DynamicPartitionCtx(List<String> partColNames, String 
defaultPartName,
     this.spPath = null;
     String confVal;
     try {
-      confVal = 
Hive.get().getMetaConf(ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getHiveName());
+      confVal = 
Hive.get().getMetaConf(ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getVarname());
     } catch (HiveException e) {
       throw new SemanticException(e);
     }
@@ -126,7 +126,7 @@ public DynamicPartitionCtx(Map<String, String> partSpec, 
String defaultPartName,
     }
     String confVal;
     try {
-      confVal = 
Hive.get().getMetaConf(ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getHiveName());
+      confVal = 
Hive.get().getMetaConf(ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getVarname());
     } catch (HiveException e) {
       throw new SemanticException(e);
     }
diff --git 
a/ql/src/test/queries/clientnegative/dynamic_partitions_with_whitelist.q 
b/ql/src/test/queries/clientnegative/dynamic_partitions_with_whitelist.q
index 8b126c6d71a..4d324f5c77b 100644
--- a/ql/src/test/queries/clientnegative/dynamic_partitions_with_whitelist.q
+++ b/ql/src/test/queries/clientnegative/dynamic_partitions_with_whitelist.q
@@ -2,7 +2,6 @@
 set hive.strict.checks.bucketing=false;
 
 set hive.mapred.mode=nonstrict;
-SET hive.metastore.partition.name.whitelist.pattern=[^9]*;
 set 
hive.exec.failure.hooks=org.apache.hadoop.hive.ql.hooks.VerifyTableDirectoryIsEmptyHook;
 
 set hive.exec.dynamic.partition=true;
@@ -17,4 +16,5 @@ load data local inpath '../../data/files/bmj/000000_0' INTO 
TABLE source_table p
 -- If the directory is not empty the hook will throw an error, instead the 
error should come from the metastore
 -- This shows that no dynamic partitions were created and left behind or had 
directories created
 
+SET metaconf:metastore.partition.name.whitelist.pattern=[^9]*;
 insert overwrite table dest_table partition (ds, hr) select key, hr, ds, value 
from source_table where ds='2008-04-08' and value='val_129' order by value asc;
diff --git 
a/ql/src/test/queries/clientnegative/session_partition_with_whitelist.q 
b/ql/src/test/queries/clientnegative/session_partition_with_whitelist.q
new file mode 100644
index 00000000000..fd6073b0603
--- /dev/null
+++ b/ql/src/test/queries/clientnegative/session_partition_with_whitelist.q
@@ -0,0 +1,9 @@
+set metaconf:metastore.partition.name.whitelist.pattern;
+
+create table t1 (id int) partitioned by (pcol string);
+alter table t1 add partition (pCol='2025-06-09');
+
+set metaconf:metastore.partition.name.whitelist.pattern=[^9]*;
+alter table t1 add partition (pCol='2025-06-19');
+show partitions t1;
+
diff --git 
a/ql/src/test/results/clientnegative/add_partition_with_whitelist.q.out 
b/ql/src/test/results/clientnegative/add_partition_with_whitelist.q.out
index 6aa789b6f72..dfacd50fcd2 100644
--- a/ql/src/test/results/clientnegative/add_partition_with_whitelist.q.out
+++ b/ql/src/test/results/clientnegative/add_partition_with_whitelist.q.out
@@ -15,4 +15,4 @@ POSTHOOK: Input: default@part_whitelist_test
 PREHOOK: query: ALTER TABLE part_whitelist_test ADD PARTITION (ds='1,2,3,4')
 PREHOOK: type: ALTERTABLE_ADDPARTS
 PREHOOK: Output: default@part_whitelist_test
-FAILED: Execution Error, return code 40000 from 
org.apache.hadoop.hive.ql.ddl.DDLTask. MetaException(message:Partition value 
'1,2,3,4' contains a character not matched by whitelist pattern 
'[\\x20-\\x7E&&[^,]]*'.  (configure with 
metastore.partition.name.whitelist.pattern))
+FAILED: Execution Error, return code 40000 from 
org.apache.hadoop.hive.ql.ddl.DDLTask. MetaException(message:Partition value 
'1,2,3,4' contains a character not matched by whitelist pattern 
'[\\x20-\\x7E&&[^,]]*'. Configure with 
metastore.partition.name.whitelist.pattern)
diff --git 
a/ql/src/test/results/clientnegative/alter_partition_with_whitelist.q.out 
b/ql/src/test/results/clientnegative/alter_partition_with_whitelist.q.out
index 8a7857ee821..0ae9cf8e01e 100644
--- a/ql/src/test/results/clientnegative/alter_partition_with_whitelist.q.out
+++ b/ql/src/test/results/clientnegative/alter_partition_with_whitelist.q.out
@@ -23,4 +23,4 @@ PREHOOK: query: ALTER TABLE part_whitelist_test PARTITION 
(ds='1') rename to par
 PREHOOK: type: ALTERTABLE_RENAMEPART
 PREHOOK: Input: default@part_whitelist_test
 PREHOOK: Output: default@part_whitelist_test@ds=1
-FAILED: Execution Error, return code 40000 from 
org.apache.hadoop.hive.ql.ddl.DDLTask. Unable to rename partition. Partition 
value '1,2,3' contains a character not matched by whitelist pattern 
'[\\x20-\\x7E&&[^,]]*'.  (configure with 
metastore.partition.name.whitelist.pattern)
+FAILED: Execution Error, return code 40000 from 
org.apache.hadoop.hive.ql.ddl.DDLTask. Unable to rename partition. Partition 
value '1,2,3' contains a character not matched by whitelist pattern 
'[\\x20-\\x7E&&[^,]]*'. Configure with 
metastore.partition.name.whitelist.pattern
diff --git 
a/ql/src/test/results/clientnegative/dynamic_partitions_with_whitelist.q.out 
b/ql/src/test/results/clientnegative/dynamic_partitions_with_whitelist.q.out
index a9ca39db8c7..e2d004e4e2a 100644
--- a/ql/src/test/results/clientnegative/dynamic_partitions_with_whitelist.q.out
+++ b/ql/src/test/results/clientnegative/dynamic_partitions_with_whitelist.q.out
@@ -33,13 +33,13 @@ Vertex failed, vertexName=Map 1, vertexId=vertex_#ID#, 
diagnostics=[Task failed,
 #### A masked pattern was here ####
 Caused by: java.lang.RuntimeException: Hive Runtime Error while closing 
operators
 #### A masked pattern was here ####
-Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'.  
(configure with hive.metastore.partition.name.whitelist.pattern)
+Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'. 
Configure with metastore.partition.name.whitelist.pattern
 #### A masked pattern was here ####
 ], TaskAttempt 1 failed, info=[Error: Error while running task ( failure ) : 
attempt_#ID#:java.lang.RuntimeException: java.lang.RuntimeException: Hive 
Runtime Error while closing operators
 #### A masked pattern was here ####
 Caused by: java.lang.RuntimeException: Hive Runtime Error while closing 
operators
 #### A masked pattern was here ####
-Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'.  
(configure with hive.metastore.partition.name.whitelist.pattern)
+Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'. 
Configure with metastore.partition.name.whitelist.pattern
 #### A masked pattern was here ####
 ]], Vertex did not succeed due to OWN_TASK_FAILURE, failedTasks:1 
killedTasks:0, Vertex vertex_#ID# [Map 1] killed/failed due to:OWN_TASK_FAILURE]
 [Masked Vertex killed due to OTHER_VERTEX_FAILURE]
@@ -48,12 +48,12 @@ FAILED: Execution Error, return code 2 from 
org.apache.hadoop.hive.ql.exec.tez.T
 #### A masked pattern was here ####
 Caused by: java.lang.RuntimeException: Hive Runtime Error while closing 
operators
 #### A masked pattern was here ####
-Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'.  
(configure with hive.metastore.partition.name.whitelist.pattern)
+Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'. 
Configure with metastore.partition.name.whitelist.pattern
 #### A masked pattern was here ####
 ], TaskAttempt 1 failed, info=[Error: Error while running task ( failure ) : 
attempt_#ID#:java.lang.RuntimeException: java.lang.RuntimeException: Hive 
Runtime Error while closing operators
 #### A masked pattern was here ####
 Caused by: java.lang.RuntimeException: Hive Runtime Error while closing 
operators
 #### A masked pattern was here ####
-Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'.  
(configure with hive.metastore.partition.name.whitelist.pattern)
+Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: Partition 
value 'val_129' contains a character not matched by whitelist pattern '[^9]*'. 
Configure with metastore.partition.name.whitelist.pattern
 #### A masked pattern was here ####
 ]], Vertex did not succeed due to OWN_TASK_FAILURE, failedTasks:1 
killedTasks:0, Vertex vertex_#ID# [Map 1] killed/failed due 
to:OWN_TASK_FAILURE][Masked Vertex killed due to OTHER_VERTEX_FAILURE]DAG did 
not succeed due to VERTEX_FAILURE. failedVertices:1 killedVertices:1
diff --git 
a/ql/src/test/results/clientnegative/session_partition_with_whitelist.q.out 
b/ql/src/test/results/clientnegative/session_partition_with_whitelist.q.out
new file mode 100644
index 00000000000..197600e99fd
--- /dev/null
+++ b/ql/src/test/results/clientnegative/session_partition_with_whitelist.q.out
@@ -0,0 +1,20 @@
+metaconf:metastore.partition.name.whitelist.pattern=
+PREHOOK: query: create table t1 (id int) partitioned by (pcol string)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@t1
+POSTHOOK: query: create table t1 (id int) partitioned by (pcol string)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@t1
+PREHOOK: query: alter table t1 add partition (pCol='2025-06-09')
+PREHOOK: type: ALTERTABLE_ADDPARTS
+PREHOOK: Output: default@t1
+POSTHOOK: query: alter table t1 add partition (pCol='2025-06-09')
+POSTHOOK: type: ALTERTABLE_ADDPARTS
+POSTHOOK: Output: default@t1
+POSTHOOK: Output: default@t1@pcol=2025-06-09
+PREHOOK: query: alter table t1 add partition (pCol='2025-06-19')
+PREHOOK: type: ALTERTABLE_ADDPARTS
+PREHOOK: Output: default@t1
+FAILED: Execution Error, return code 40000 from 
org.apache.hadoop.hive.ql.ddl.DDLTask. MetaException(message:Partition value 
'2025-06-19' contains a character not matched by whitelist pattern '[^9]*'. 
Configure with metastore.partition.name.whitelist.pattern)
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
index e4bcb21d6a4..086766de41b 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java
@@ -296,7 +296,6 @@ public Configuration getHiveConf() {
   private MetaStoreFilterHook filterHook;
   private boolean isServerFilterEnabled = false;
 
-  private Pattern partitionValidationPattern;
   private final boolean isInTest;
 
   @Override
@@ -371,11 +370,7 @@ public void init(Warehouse wh) throws MetaException {
     endFunctionListeners = MetaStoreServerUtils.getMetaStoreListeners(
         MetaStoreEndFunctionListener.class, conf, MetastoreConf.getVar(conf, 
ConfVars.END_FUNCTION_LISTENERS));
 
-    String partitionValidationRegex =
-        MetastoreConf.getVar(conf, ConfVars.PARTITION_NAME_WHITELIST_PATTERN);
-    if (partitionValidationRegex != null && 
!partitionValidationRegex.isEmpty()) {
-      partitionValidationPattern = Pattern.compile(partitionValidationRegex);
-    }
+
 
     expressionProxy = PartFilterExprUtil.createExpressionProxy(conf);
     fileMetadataManager = new FileMetadataManager(this.getMS(), conf);
@@ -472,13 +467,13 @@ public void setConf(Configuration conf) {
 
   @Override
   public Configuration getConf() {
-    Configuration conf = HMSHandlerContext.getConfiguration()
-        .orElseGet(() -> {
-          Configuration configuration = new Configuration(this.conf);
-          HMSHandlerContext.setConfiguration(configuration);
-          return configuration;
-        });
-    return conf;
+    return HMSHandlerContext.getConfiguration()
+        .orElseGet(
+            () -> {
+              Configuration configuration = new Configuration(this.conf);
+              HMSHandlerContext.setConfiguration(configuration);
+              return configuration;
+            });
   }
 
   @Override
@@ -4052,7 +4047,7 @@ private Partition append_partition_common(RawStore ms, 
String catName, String db
       part.setTableName(tableName);
       part.setValues(part_vals);
 
-      MetaStoreServerUtils.validatePartitionNameCharacters(part_vals, 
partitionValidationPattern);
+      MetaStoreServerUtils.validatePartitionNameCharacters(part_vals, 
getConf());
 
       tbl = ms.getTable(part.getCatName(), part.getDbName(), 
part.getTableName(), null);
       if (tbl == null) {
@@ -4465,8 +4460,7 @@ private void cleanupPartitionFolders(final 
Map<PartValEqWrapperLite, Boolean> ad
   private void validatePartition(final Partition part, final String catName,
                                     final String tblName, final String dbName, 
final Set<PartValEqWrapperLite> partsToAdd)
       throws MetaException, TException {
-    MetaStoreServerUtils.validatePartitionNameCharacters(part.getValues(),
-        partitionValidationPattern);
+    MetaStoreServerUtils.validatePartitionNameCharacters(part.getValues(), 
getConf());
     if (part.getDbName() == null || part.getTableName() == null) {
       throw new MetaException("The database and table name must be set in the 
partition.");
     }
@@ -6015,8 +6009,7 @@ private void alter_partition_core(String catName, String 
db_name, String tbl_nam
 
       firePreEvent(new PreAlterPartitionEvent(db_name, tbl_name, table, 
part_vals, new_part, this));
       if (part_vals != null && !part_vals.isEmpty()) {
-        
MetaStoreServerUtils.validatePartitionNameCharacters(new_part.getValues(),
-            partitionValidationPattern);
+        
MetaStoreServerUtils.validatePartitionNameCharacters(new_part.getValues(), 
getConf());
       }
 
       oldPart = alterHandler.alterPartition(getMS(), wh, catName, db_name, 
tbl_name,
@@ -8654,18 +8647,17 @@ public List<String> set_ugi(String username, 
List<String> groupNames) throws TEx
   }
 
   @Override
-  public boolean partition_name_has_valid_characters(List<String> part_vals,
-                                                     boolean throw_exception) 
throws TException {
+  public boolean partition_name_has_valid_characters(
+      List<String> part_vals, boolean throw_exception) throws TException {
     startFunction("partition_name_has_valid_characters");
     boolean ret;
     Exception ex = null;
     try {
       if (throw_exception) {
-        MetaStoreServerUtils.validatePartitionNameCharacters(part_vals, 
partitionValidationPattern);
+        MetaStoreServerUtils.validatePartitionNameCharacters(part_vals, 
getConf());
         ret = true;
       } else {
-        ret = MetaStoreServerUtils.partitionNameHasValidCharacters(part_vals,
-            partitionValidationPattern);
+        ret = MetaStoreServerUtils.partitionNameHasValidCharacters(part_vals, 
getConf());
       }
     } catch (Exception e) {
       ex = e;
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index c1ca07678fb..7836ad0f0fb 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -343,7 +343,6 @@ private enum TXN_STATUS {
   private volatile int openTrasactionCalls = 0;
   private Transaction currentTransaction = null;
   private TXN_STATUS transactionStatus = TXN_STATUS.NO_STATE;
-  private Pattern partitionValidationPattern;
   private Counter directSqlErrors;
   private boolean areTxnStatsSupported = false;
   private PropertyStore propertyStore;
@@ -384,15 +383,7 @@ public void setConf(Configuration conf) {
     transactionStatus = TXN_STATUS.NO_STATE;
 
     initialize();
-
-    String partitionValidationRegex =
-        MetastoreConf.getVar(this.conf, 
ConfVars.PARTITION_NAME_WHITELIST_PATTERN);
-    if (partitionValidationRegex != null && 
!partitionValidationRegex.isEmpty()) {
-      partitionValidationPattern = Pattern.compile(partitionValidationRegex);
-    } else {
-      partitionValidationPattern = null;
-    }
-
+    
     // Note, if metrics have not been initialized this will return null, which 
means we aren't
     // using metrics.  Thus we should always check whether this is non-null 
before using.
     MetricRegistry registry = Metrics.getRegistry();
@@ -2773,8 +2764,7 @@ protected String describeResult() {
 
   private boolean isValidPartition(
       Partition part, List<FieldSchema> partitionKeys, boolean ifNotExists) 
throws MetaException {
-    MetaStoreServerUtils.validatePartitionNameCharacters(part.getValues(),
-        partitionValidationPattern);
+    MetaStoreServerUtils.validatePartitionNameCharacters(part.getValues(), 
conf);
     boolean doesExist = doesPartitionExist(part.getCatName(),
         part.getDbName(), part.getTableName(), partitionKeys, 
part.getValues());
     if (doesExist && !ifNotExists) {
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/MetaStoreServerUtils.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/MetaStoreServerUtils.java
index 69ec400017a..fd2e1926e43 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/MetaStoreServerUtils.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/utils/MetaStoreServerUtils.java
@@ -17,6 +17,13 @@
  */
 package org.apache.hadoop.hive.metastore.utils;
 
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimaps;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import java.beans.PropertyDescriptor;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
@@ -51,14 +58,7 @@
 import java.util.concurrent.Future;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimaps;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import javax.annotation.Nullable;
 import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.ListUtils;
@@ -114,8 +114,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.annotation.Nullable;
-
 /**
  * Utility methods used by Hive standalone metastore server.
  */
@@ -132,7 +130,7 @@ public class MetaStoreServerUtils {
       = new com.google.common.base.Function<String, String>() {
     @Override
     public String apply(@Nullable String string) {
-      return org.apache.commons.lang3.StringUtils.defaultString(string);
+      return StringUtils.defaultString(string);
     }
   };
 
@@ -255,31 +253,43 @@ public static double decimalToDouble(Decimal decimal) {
     return new BigDecimal(new BigInteger(decimal.getUnscaled()), 
decimal.getScale()).doubleValue();
   }
 
-  public static void validatePartitionNameCharacters(List<String> partVals,
-                                                     Pattern 
partitionValidationPattern) throws MetaException {
+  private static Pattern getPartitionValidationRegex(Configuration conf) {
+    return Optional.ofNullable(
+            MetastoreConf.getVar(conf, 
MetastoreConf.ConfVars.PARTITION_NAME_WHITELIST_PATTERN))
+        .filter(StringUtils::isNotBlank)
+        .map(Pattern::compile)
+        .orElse(null);
+  }
+
+  public static void validatePartitionNameCharacters(List<String> partVals, 
Configuration conf)
+      throws MetaException {
 
+    Pattern partitionValidationPattern = getPartitionValidationRegex(conf);
     String invalidPartitionVal = getPartitionValWithInvalidCharacter(partVals, 
partitionValidationPattern);
+
     if (invalidPartitionVal != null) {
-      throw new MetaException("Partition value '" + invalidPartitionVal +
-          "' contains a character " + "not matched by whitelist pattern '" +
-          partitionValidationPattern.toString() + "'.  " + "(configure with " +
-          MetastoreConf.ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getVarname() 
+ ")");
-    }
-  }
+      String errorMsg =
+          ("Partition value '%s' contains a character not matched by whitelist 
pattern '%s'. Configure with %s")
+              .formatted(
+                  invalidPartitionVal,
+                  partitionValidationPattern.toString(),
+                  
MetastoreConf.ConfVars.PARTITION_NAME_WHITELIST_PATTERN.getVarname());
 
-  private static String getPartitionValWithInvalidCharacter(List<String> 
partVals,
-                                                            Pattern 
partitionValidationPattern) {
-    if (partitionValidationPattern == null) {
-      return null;
+      throw new MetaException(errorMsg);
     }
+  }
 
-    for (String partVal : partVals) {
-      if (!partitionValidationPattern.matcher(partVal).matches()) {
-        return partVal;
-      }
+  private static String getPartitionValWithInvalidCharacter(
+      List<String> partVals, Pattern partitionValidationPattern) {
+    String result = null;
+    if (partitionValidationPattern != null) {
+      result =
+          partVals.stream()
+              .filter(partVal -> 
!partitionValidationPattern.matcher(partVal).matches())
+              .findFirst()
+              .orElse(null);
     }
-
-    return null;
+    return result;
   }
 
   /**
@@ -351,7 +361,7 @@ public static synchronized byte[] 
hashStorageDescriptor(StorageDescriptor sd, Me
         SortedSet<String> sortedOuterList = new TreeSet<>();
         for (List<String> innerList : skewed.getSkewedColValues()) {
           SortedSet<String> sortedInnerList = new TreeSet<>(innerList);
-          
sortedOuterList.add(org.apache.commons.lang3.StringUtils.join(sortedInnerList, 
"."));
+          sortedOuterList.add(StringUtils.join(sortedInnerList, "."));
         }
         for (String colval : sortedOuterList) {
           md.update(colval.getBytes(ENCODING));
@@ -361,7 +371,7 @@ public static synchronized byte[] 
hashStorageDescriptor(StorageDescriptor sd, Me
         SortedMap<String, String> sortedMap = new TreeMap<>();
         for (Map.Entry<List<String>, String> smap : 
skewed.getSkewedColValueLocationMaps().entrySet()) {
           SortedSet<String> sortedKey = new TreeSet<>(smap.getKey());
-          sortedMap.put(org.apache.commons.lang3.StringUtils.join(sortedKey, 
"."), smap.getValue());
+          sortedMap.put(StringUtils.join(sortedKey, "."), smap.getValue());
         }
         for (Map.Entry<String, String> e : sortedMap.entrySet()) {
           md.update(e.getKey().getBytes(ENCODING));
@@ -775,9 +785,8 @@ public static String 
validateSkewedColNamesSubsetCol(List<String> skewedColNames
     return copySkewedColNames.toString();
   }
 
-  public static boolean partitionNameHasValidCharacters(List<String> partVals,
-                                                        Pattern 
partitionValidationPattern) {
-    return getPartitionValWithInvalidCharacter(partVals, 
partitionValidationPattern) == null;
+  public static boolean partitionNameHasValidCharacters(List<String> partVals, 
Configuration conf) {
+    return getPartitionValWithInvalidCharacter(partVals, 
getPartitionValidationRegex(conf)) == null;
   }
 
   public static void getMergableCols(ColumnStatistics csNew, Map<String, 
String> parameters) {

Reply via email to