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

dengzhhu653 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 9384d27dfc9 HIVE-30096: HiveAlterHandler forces a full file listing to 
recompute stats on every table-level alter (#6822)
9384d27dfc9 is described below

commit 9384d27dfc990d5ec88c3a2e3764dcfc63cc2f39
Author: neatHyperTxt-meesho <[email protected]>
AuthorDate: Mon Oct 12 12:56:49 2026 +0530

    HIVE-30096: HiveAlterHandler forces a full file listing to recompute stats 
on every table-level alter (#6822)
---
 .../results/clientpositive/llap/acid_stats5.q.out  |  2 +-
 .../llap/alter_table_stats_status.q.out            |  1 +
 .../llap/alter_tableprops_numeric.q.out            |  4 ++-
 .../clientpositive/llap/default_constraint.q.out   | 10 +++---
 .../llap/drop_stats_for_columns.q.out              | 16 +++++-----
 .../llap/materialized_view_create_rewrite_10.q.out |  2 +-
 .../results/clientpositive/llap/schq_analyze.q.out |  2 +-
 .../clientpositive/llap/stats_unset_hilo.q.out     | 36 +++++++++++-----------
 .../hadoop/hive/metastore/HiveAlterHandler.java    | 19 ++++++++++--
 .../hive/metastore/utils/MetaStoreServerUtils.java |  6 ++++
 .../hive/metastore/TestHiveAlterHandler.java       | 35 +++++++++++++++++++++
 11 files changed, 96 insertions(+), 37 deletions(-)

diff --git a/ql/src/test/results/clientpositive/llap/acid_stats5.q.out 
b/ql/src/test/results/clientpositive/llap/acid_stats5.q.out
index 343c9e57bb4..5d4ed975abf 100644
--- a/ql/src/test/results/clientpositive/llap/acid_stats5.q.out
+++ b/ql/src/test/results/clientpositive/llap/acid_stats5.q.out
@@ -90,7 +90,7 @@ Retention:            0
 Table Type:            MANAGED_TABLE            
 Table Parameters:               
        bucketing_version       2                   
-       numFiles                3                   
+       numFiles                2                   
        numRows                 2                   
        rawDataSize             10                  
        totalSize               #Masked#
diff --git 
a/ql/src/test/results/clientpositive/llap/alter_table_stats_status.q.out 
b/ql/src/test/results/clientpositive/llap/alter_table_stats_status.q.out
index 42979305967..8efa55354c2 100644
--- a/ql/src/test/results/clientpositive/llap/alter_table_stats_status.q.out
+++ b/ql/src/test/results/clientpositive/llap/alter_table_stats_status.q.out
@@ -177,6 +177,7 @@ Retention:                  0
 #### A masked pattern was here ####
 Table Type:            MANAGED_TABLE            
 Table Parameters:               
+       COLUMN_STATS_ACCURATE   {\"BASIC_STATS\":\"true\"}
        bucketing_version       2                   
 #### A masked pattern was here ####
        numFiles                1                   
diff --git 
a/ql/src/test/results/clientpositive/llap/alter_tableprops_numeric.q.out 
b/ql/src/test/results/clientpositive/llap/alter_tableprops_numeric.q.out
index d2ab5bf2b5b..93507727898 100644
--- a/ql/src/test/results/clientpositive/llap/alter_tableprops_numeric.q.out
+++ b/ql/src/test/results/clientpositive/llap/alter_tableprops_numeric.q.out
@@ -30,11 +30,13 @@ Retention:                  0
 #### A masked pattern was here ####
 Table Type:            EXTERNAL_TABLE           
 Table Parameters:               
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"a\":\"true\"}}
        EXTERNAL                TRUE                
        STATS_GENERATED_VIA_STATS_TASK  true                
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                0                   
+       numFiles                1                   
+       numFilesErasureCoded    5                   
        numRows                 2                   
        rawDataSize             4                   
        totalSize               #Masked#
diff --git a/ql/src/test/results/clientpositive/llap/default_constraint.q.out 
b/ql/src/test/results/clientpositive/llap/default_constraint.q.out
index a9e78172112..750ba4f9165 100644
--- a/ql/src/test/results/clientpositive/llap/default_constraint.q.out
+++ b/ql/src/test/results/clientpositive/llap/default_constraint.q.out
@@ -1739,7 +1739,7 @@ Table Type:               MANAGED_TABLE
 Table Parameters:               
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                2                   
+       numFiles                1                   
        totalSize               #Masked#
        transactional           true                
        transactional_properties        default             
@@ -1817,7 +1817,7 @@ Table Type:               MANAGED_TABLE
 Table Parameters:               
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                2                   
+       numFiles                1                   
        totalSize               #Masked#
        transactional           true                
        transactional_properties        default             
@@ -1998,7 +1998,7 @@ Table Type:               MANAGED_TABLE
 Table Parameters:               
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                3                   
+       numFiles                1                   
        totalSize               #Masked#
        transactional           true                
        transactional_properties        default             
@@ -2079,7 +2079,7 @@ Table Type:               MANAGED_TABLE
 Table Parameters:               
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                3                   
+       numFiles                1                   
        totalSize               #Masked#
        transactional           true                
        transactional_properties        default             
@@ -2157,7 +2157,7 @@ Table Type:               MANAGED_TABLE
 Table Parameters:               
        bucketing_version       2                   
 #### A masked pattern was here ####
-       numFiles                3                   
+       numFiles                1                   
        totalSize               #Masked#
        transactional           true                
        transactional_properties        default             
diff --git 
a/ql/src/test/results/clientpositive/llap/drop_stats_for_columns.q.out 
b/ql/src/test/results/clientpositive/llap/drop_stats_for_columns.q.out
index a480caa6cd5..8ec32401053 100644
--- a/ql/src/test/results/clientpositive/llap/drop_stats_for_columns.q.out
+++ b/ql/src/test/results/clientpositive/llap/drop_stats_for_columns.q.out
@@ -56,7 +56,7 @@ Retention:            0
 #### A masked pattern was here ####
 Table Type:            MANAGED_TABLE            
 Table Parameters:               
-       COLUMN_STATS_ACCURATE   
{\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
+       COLUMN_STATS_ACCURATE   
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
        bucketing_version       2                   
 #### A masked pattern was here ####
        numFiles                0                   
@@ -93,7 +93,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
 PREHOOK: query: describe formatted t1 j
 PREHOOK: type: DESCTABLE
 PREHOOK: Input: default@t1
@@ -112,7 +112,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
 PREHOOK: query: describe formatted t1 k
 PREHOOK: type: DESCTABLE
 PREHOOK: Input: default@t1
@@ -131,7 +131,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"i\":\"true\",\"j\":\"true\",\"k\":\"true\"}}
 PREHOOK: query: alter table t1 drop statistics for columns
 PREHOOK: type: ALTERTABLE_DROP_COL_STATS
 PREHOOK: Input: default@t1
@@ -158,7 +158,7 @@ Retention:                  0
 #### A masked pattern was here ####
 Table Type:            MANAGED_TABLE            
 Table Parameters:               
-       COLUMN_STATS_ACCURATE   {}                  
+       COLUMN_STATS_ACCURATE   {\"BASIC_STATS\":\"true\"}
        bucketing_version       2                   
 #### A masked pattern was here ####
        numFiles                0                   
@@ -195,7 +195,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  {}                  
+COLUMN_STATS_ACCURATE  {\"BASIC_STATS\":\"true\"}
 PREHOOK: query: describe formatted t1 j
 PREHOOK: type: DESCTABLE
 PREHOOK: Input: default@t1
@@ -214,7 +214,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  {}                  
+COLUMN_STATS_ACCURATE  {\"BASIC_STATS\":\"true\"}
 PREHOOK: query: describe formatted t1 k
 PREHOOK: type: DESCTABLE
 PREHOOK: Input: default@t1
@@ -233,4 +233,4 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  {}                  
+COLUMN_STATS_ACCURATE  {\"BASIC_STATS\":\"true\"}
diff --git 
a/ql/src/test/results/clientpositive/llap/materialized_view_create_rewrite_10.q.out
 
b/ql/src/test/results/clientpositive/llap/materialized_view_create_rewrite_10.q.out
index 62742a9e463..305271f4458 100644
--- 
a/ql/src/test/results/clientpositive/llap/materialized_view_create_rewrite_10.q.out
+++ 
b/ql/src/test/results/clientpositive/llap/materialized_view_create_rewrite_10.q.out
@@ -79,7 +79,7 @@ STAGE PLANS:
                 TableScan
                   alias: t1
                   filterExpr: (b = 1) (type: boolean)
-                  Statistics: Num rows: 70 Data size: #Masked# Basic stats: 
COMPLETE Column stats: NONE
+                  Statistics: Num rows: 35 Data size: #Masked# Basic stats: 
COMPLETE Column stats: NONE
                   Filter Operator
                     predicate: (b = 1) (type: boolean)
                     Statistics: Num rows: 1 Data size: #Masked# Basic stats: 
COMPLETE Column stats: NONE
diff --git a/ql/src/test/results/clientpositive/llap/schq_analyze.q.out 
b/ql/src/test/results/clientpositive/llap/schq_analyze.q.out
index ba2bf0fa370..5457a88ead4 100644
--- a/ql/src/test/results/clientpositive/llap/schq_analyze.q.out
+++ b/ql/src/test/results/clientpositive/llap/schq_analyze.q.out
@@ -37,7 +37,7 @@ Table Type:           EXTERNAL_TABLE
 Table Parameters:               
        EXTERNAL                TRUE                
        bucketing_version       2                   
-       numFiles                1                   
+       numFiles                0                   
        numRows                 0                   
        rawDataSize             0                   
        totalSize               #Masked#
diff --git a/ql/src/test/results/clientpositive/llap/stats_unset_hilo.q.out 
b/ql/src/test/results/clientpositive/llap/stats_unset_hilo.q.out
index f2a6f4b8b8c..ae2f9974973 100644
--- a/ql/src/test/results/clientpositive/llap/stats_unset_hilo.q.out
+++ b/ql/src/test/results/clientpositive/llap/stats_unset_hilo.q.out
@@ -250,7 +250,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_tinyint > 50
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -399,7 +399,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_smallint < 500
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -548,7 +548,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_int BETWEEN 100 AND 500
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -697,7 +697,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_bigint = 999
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -846,7 +846,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_float > 50.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -995,7 +995,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_both_unset WHERE 
col_double < 500.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_both_unset
@@ -1144,7 +1144,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_tinyint > 50
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -1293,7 +1293,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_smallint > 200
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -1442,7 +1442,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_int > 2000
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -1591,7 +1591,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_bigint > 20000
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -1740,7 +1740,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_float > 50.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -1889,7 +1889,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_min_only WHERE 
col_double > 200.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_min_only
@@ -2038,7 +2038,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_tinyint < 50
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
@@ -2187,7 +2187,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_smallint < 500
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
@@ -2336,7 +2336,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_int < 5000
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
@@ -2485,7 +2485,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_bigint < 50000
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
@@ -2634,7 +2634,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_float < 50.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
@@ -2783,7 +2783,7 @@ num_trues
 num_falses                                 
 bit_vector                                 
 comment                from deserializer   
-COLUMN_STATS_ACCURATE  
{\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
+COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"col_bigint\":\"true\",\"col_double\":\"true\",\"col_float\":\"true\",\"col_int\":\"true\",\"col_smallint\":\"true\",\"col_tinyint\":\"true\"}}
 PREHOOK: query: EXPLAIN EXTENDED SELECT count(1) FROM stats_max_only WHERE 
col_double < 500.0
 PREHOOK: type: QUERY
 PREHOOK: Input: default@stats_max_only
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java
index aa0e691b750..4fe70e19bf3 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java
@@ -65,6 +65,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 import java.util.LinkedList;
 import java.util.Optional;
@@ -396,8 +397,14 @@ public List<Void> run(List<Partition> input) throws 
Exception {
         if (MetaStoreServerUtils.requireCalStats(null, null, newt, 
environmentContext) &&
             !isPartitionedTable) {
           assert(isReplicated == isDbReplicationTarget(db));
-          // Update table stats. For partitioned table, we update stats in 
alterPartition()
-          MetaStoreServerUtils.updateTableStatsSlow(db, newt, wh, false, true, 
environmentContext);
+          // Update table stats. For partitioned table, we update stats in 
alterPartition().
+          // Force a recompute, which lists every file under the table 
location, only when the
+          // location actually changed: for a metadata-only alter the fast 
stats already present
+          // on the table are still valid, and relisting can be prohibitively 
expensive for
+          // formats that keep their partitioning in a transaction log (Delta, 
Iceberg, Hudi) and
+          // register as unpartitioned tables with millions of files under a 
single directory.
+          MetaStoreServerUtils.updateTableStatsSlow(db, newt, wh, false, 
isTableLocationChanged(oldt, newt),
+              environmentContext);
         }
 
         if (isPartitionedTable) {
@@ -1064,4 +1071,12 @@ public static void updateOrGetPartitionColumnStats(
       throw new InvalidObjectException("Invalid input to delete partition 
column stats." + iie);
     }
   }
+
+  /** Whether an alter moved the table to a different data location. */
+  @VisibleForTesting
+  static boolean isTableLocationChanged(Table oldTable, Table newTable) {
+    return !Objects.equals(
+        oldTable.getSd() == null ? null : oldTable.getSd().getLocation(),
+        newTable.getSd() == null ? null : newTable.getSd().getLocation());
+  }
 }
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 a9c54a1186c..0dc9070a996 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
@@ -1066,6 +1066,12 @@ public static boolean requireCalStats(Partition oldPart,
       return false;
     }
 
+    // Data of a non-native table is managed by its storage handler, so 
filesystem based stats
+    // computed from the table location are not meaningful for it
+    if (MetaStoreUtils.isNonNativeTable(tbl)) {
+      return false;
+    }
+
     if  (oldPart == null && newPart == null) {
       return true;
     }
diff --git 
a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java
 
b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java
index 223023906b5..14d0c0d8589 100644
--- 
a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java
+++ 
b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestHiveAlterHandler.java
@@ -123,4 +123,39 @@ public void testAlterTableChangePosNotUpdateStats() throws 
MetaException, Invali
     handler.deleteTableColumnStats(msdb, oldTable, newTable);
   }
 
+  /**
+   * HIVE-30096: a table level alter forces a stats recompute, which lists 
every file under the
+   * table location, only when the alter changed the location. A metadata-only 
alter must reuse
+   * the fast stats already present on the table instead of relisting a 
potentially huge
+   * directory (formats like Delta/Iceberg/Hudi register as unpartitioned 
tables with millions
+   * of files).
+   */
+  @Test
+  public void testTableLocationChangeDetection() {
+    StorageDescriptor oldSd = new StorageDescriptor();
+    oldSd.setLocation("gs://bucket/warehouse/t1");
+    Table oldTable = new Table();
+    oldTable.setDbName("default");
+    oldTable.setTableName("test_table");
+    oldTable.setSd(oldSd);
+
+    // same location: metadata-only alter, no recompute
+    StorageDescriptor newSd = new StorageDescriptor(oldSd);
+    Table newTable = new Table(oldTable);
+    newTable.setSd(newSd);
+    
org.junit.Assert.assertFalse(HiveAlterHandler.isTableLocationChanged(oldTable, 
newTable));
+
+    // changed location: stats must be recomputed
+    StorageDescriptor movedSd = new StorageDescriptor(oldSd);
+    movedSd.setLocation("gs://bucket/warehouse/t1_moved");
+    Table movedTable = new Table(oldTable);
+    movedTable.setSd(movedSd);
+    
org.junit.Assert.assertTrue(HiveAlterHandler.isTableLocationChanged(oldTable, 
movedTable));
+
+    // location set where there was none before
+    Table noLocTable = new Table(oldTable);
+    noLocTable.setSd(new StorageDescriptor());
+    
org.junit.Assert.assertTrue(HiveAlterHandler.isTableLocationChanged(noLocTable, 
newTable));
+  }
+
 }

Reply via email to