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

deniskuzZ 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 1516fb91e8a HIVE-29604: DESCRIBE column fails with an execution error 
for partition columns (#6472)
1516fb91e8a is described below

commit 1516fb91e8a622b4655b0e07a37fb449634c1637
Author: Tanishq Chugh <[email protected]>
AuthorDate: Fri May 15 12:27:05 2026 +0530

    HIVE-29604: DESCRIBE column fails with an execution error for partition 
columns (#6472)
---
 .../ql/ddl/table/info/desc/DescTableOperation.java |  59 ++++++++----
 .../test/queries/clientpositive/describe_syntax.q  |  18 ++++
 .../clientpositive/llap/desc_cols_formatted.q.out  |   6 +-
 .../clientpositive/llap/describe_syntax.q.out      | 105 +++++++++++++++++++++
 4 files changed, 165 insertions(+), 23 deletions(-)

diff --git 
a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/info/desc/DescTableOperation.java
 
b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/info/desc/DescTableOperation.java
index b60126a8db1..9086ad90c67 100644
--- 
a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/info/desc/DescTableOperation.java
+++ 
b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/info/desc/DescTableOperation.java
@@ -21,6 +21,7 @@
 import java.io.DataOutputStream;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -88,11 +89,7 @@ public int execute() throws Exception {
       if (desc.getColumnPath() == null) {
         getColumnsNoColumnPath(table, part, cols);
       } else {
-        if (desc.isFormatted()) {
-          getColumnDataColPathSpecified(table, part, cols, colStats, 
deserializer);
-        } else {
-          cols.addAll(Hive.getFieldsFromDeserializer(desc.getColumnPath(), 
deserializer, context.getConf()));
-        }
+        getColumnDataColPathSpecified(table, part, cols, colStats, 
deserializer);
       }
       fixDecimalColumnTypeName(cols);
 
@@ -191,28 +188,31 @@ private void getColumnDataColPathSpecified(Table table, 
Partition part, List<Fie
       throws HiveException, MetaException {
     // when column name is specified in describe table DDL, colPath will be 
db_name.table_name.column_name
     String colName = desc.getColumnPath().split("\\.")[2];
+    FieldSchema partitionCol = resolveColumnSchema(table, deserializer, 
colName, cols);
+
+    if (!desc.isFormatted()) {
+      return;
+    }
+
     List<String> colNames = Lists.newArrayList(colName.toLowerCase());
 
     if (part == null) {
       if (table.isPartitioned() && 
StatsUtils.checkCanProvideColumnStats(table)) {
         Map<String, String> tableProps = table.getParameters() == null ?
             new HashMap<>() : table.getParameters();
-        if (table.isPartitionKey(colNames.getFirst())) {
-          getColumnDataForPartitionKeyColumn(table, cols, colStats, colNames, 
tableProps);
+        if (partitionCol != null) {
+          addStatsForPartitionKeyColumn(table, colStats, colNames, tableProps, 
partitionCol);
         } else {
-          getColumnsForNotPartitionKeyColumn(table, cols, colStats, 
deserializer, colName,
-              tableProps);
+          addStatsForRegularColumn(table, colStats, colName, tableProps);
         }
         table.setParameters(tableProps);
       } else {
-        cols.addAll(getFilteredFieldsFromDeserializer(table, deserializer, 
colName));
         colStats.addAll(context.getDb().getTableColumnStatistics(table, 
colNames, false));
       }
     } else {
       List<String> partitions = new ArrayList<>();
       String partName = part.getName();
       partitions.add(partName);
-      cols.addAll(getFilteredFieldsFromDeserializer(table, deserializer, 
colName));
       Map<String, List<ColumnStatisticsObj>> partitionColumnStatistics = 
context.getDb().getPartitionColumnStatistics(
           table.getDbName(), table.getTableName(), partitions, colNames, 
false);
       List<ColumnStatisticsObj> partitionColStat = 
partitionColumnStatistics.get(partName);
@@ -222,6 +222,31 @@ private void getColumnDataColPathSpecified(Table table, 
Partition part, List<Fie
     }
   }
 
+  /**
+   * Adds the resolved FieldSchema(s) for {@code desc.getColumnPath()} to 
{@code cols}:
+   * partition column, nested xpath traversal (e.g. {@code struct.field}, 
{@code array.$elem$},
+   * {@code map.$key$}/{@code $value$}), or top-level deserializer field.
+   *
+   * @return the partition FieldSchema if the path is a partition key, 
otherwise null
+   */
+  private FieldSchema resolveColumnSchema(Table table, Deserializer 
deserializer, String colName,
+      List<FieldSchema> cols) throws HiveException {
+    FieldSchema partitionCol = table.getPartColByName(colName.toLowerCase());
+    if (partitionCol != null) {
+      cols.add(partitionCol);
+      return partitionCol;
+    }
+    List<FieldSchema> resolved = (desc.getColumnPath().split("\\.").length == 
3)
+        ? getFilteredFieldsFromDeserializer(table, deserializer, colName)
+        : Collections.emptyList();
+    if (resolved.isEmpty()) {
+      // xpath path OR invalid top-level name — path-traversal handles both
+      resolved = Hive.getFieldsFromDeserializer(desc.getColumnPath(), 
deserializer, context.getConf());
+    }
+    cols.addAll(resolved);
+    return null;
+  }
+
   private List<FieldSchema> getFilteredFieldsFromDeserializer(Table table, 
Deserializer deserializer,
       String targetColName) throws HiveException {
     List<FieldSchema> allFields = 
Hive.getFieldsFromDeserializer(table.getTableName(), deserializer, 
context.getConf());
@@ -239,11 +264,9 @@ private List<FieldSchema> 
getFilteredFieldsFromDeserializer(Table table, Deseria
     return filteredFields;
   }
 
-  private void getColumnDataForPartitionKeyColumn(Table table, 
List<FieldSchema> cols,
-      List<ColumnStatisticsObj> colStats, List<String> colNames, Map<String, 
String> tableProps)
+  private void addStatsForPartitionKeyColumn(Table table, 
List<ColumnStatisticsObj> colStats,
+      List<String> colNames, Map<String, String> tableProps, FieldSchema 
partCol)
       throws HiveException, MetaException {
-    FieldSchema partCol = table.getPartColByName(colNames.getFirst());
-    cols.add(partCol);
     PartitionIterable parts = new PartitionIterable(context.getDb(), table, 
null,
         MetastoreConf.getIntVar(context.getConf(), 
MetastoreConf.ConfVars.BATCH_RETRIEVE_MAX));
     ColumnInfo ci = new ColumnInfo(partCol.getName(),
@@ -256,10 +279,8 @@ private void getColumnDataForPartitionKeyColumn(Table 
table, List<FieldSchema> c
     StatsSetupConst.setColumnStatsState(tableProps, colNames);
   }
 
-  private void getColumnsForNotPartitionKeyColumn(Table table, 
List<FieldSchema> cols, List<ColumnStatisticsObj> colStats,
-      Deserializer deserializer, String colName, Map<String, String> 
tableProps)
-      throws HiveException {
-    cols.addAll(getFilteredFieldsFromDeserializer(table, deserializer, 
colName));
+  private void addStatsForRegularColumn(Table table, List<ColumnStatisticsObj> 
colStats,
+      String colName, Map<String, String> tableProps) throws HiveException {
     List<String> parts = context.getDb().getPartitionNames(table, (short) -1);
     AggrStats aggrStats = context.getDb().getAggrColStatsFor(table, 
Lists.newArrayList(colName.toLowerCase()),
         parts, false);
diff --git a/ql/src/test/queries/clientpositive/describe_syntax.q 
b/ql/src/test/queries/clientpositive/describe_syntax.q
index 3f9db316b27..d5295412c81 100644
--- a/ql/src/test/queries/clientpositive/describe_syntax.q
+++ b/ql/src/test/queries/clientpositive/describe_syntax.q
@@ -34,6 +34,19 @@ DESCRIBE t1 key1;
 DESCRIBE EXTENDED t1 key1;
 DESCRIBE FORMATTED t1 key1;
 
+-- describe table partition column
+DESCRIBE t1 ds;
+DESCRIBE EXTENDED t1 ds;
+DESCRIBE FORMATTED t1 ds;
+
+-- describe database.table partition column
+DESCRIBE db1.t1 ds;
+DESCRIBE EXTENDED db1.t1 ds;
+DESCRIBE FORMATTED db1.t1 ds;
+
+-- describe table case-insensitive partition column
+DESCRIBE t1 PART;
+
 -- describe table partition
 DESCRIBE t1 PARTITION(ds='4', part='5');
 DESCRIBE EXTENDED t1 PARTITION(ds='4', part='5');
@@ -43,3 +56,8 @@ DESCRIBE FORMATTED t1 PARTITION(ds='4', part='5');
 DESCRIBE db1.t1 PARTITION(ds='4', part='5');
 DESCRIBE EXTENDED db1.t1 PARTITION(ds='4', part='5');
 DESCRIBE FORMATTED db1.t1 PARTITION(ds='4', part='5');
+
+-- describe table partition column with partition spec
+DESCRIBE t1 PARTITION(ds='3', part='3') ds;
+DESCRIBE EXTENDED t1 PARTITION(ds='4', part='5') part;
+DESCRIBE FORMATTED t1 PARTITION(ds='3', part='3') ds;
diff --git a/ql/src/test/results/clientpositive/llap/desc_cols_formatted.q.out 
b/ql/src/test/results/clientpositive/llap/desc_cols_formatted.q.out
index 375576b1479..80c753707a2 100644
--- a/ql/src/test/results/clientpositive/llap/desc_cols_formatted.q.out
+++ b/ql/src/test/results/clientpositive/llap/desc_cols_formatted.q.out
@@ -93,8 +93,7 @@ PREHOOK: Input: default@tbl_t
 POSTHOOK: query: DESCRIBE tbl_t Point
 POSTHOOK: type: DESCTABLE
 POSTHOOK: Input: default@tbl_t
-x                      int                     from deserializer   
-y                      int                     from deserializer   
+Point                  struct<x:int,y:int>     from deserializer   
 COLUMN_STATS_ACCURATE  
{\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"id\":\"true\",\"point\":\"true\"}}
         
 PREHOOK: query: CREATE TABLE tbl_part(id int, Point STRUCT<x:INT, y:INT>) 
PARTITIONED BY (name string)
 PREHOOK: type: CREATETABLE
@@ -195,5 +194,4 @@ PREHOOK: Input: default@tbl_part
 POSTHOOK: query: DESCRIBE tbl_part Point
 POSTHOOK: type: DESCTABLE
 POSTHOOK: Input: default@tbl_part
-x                      int                     from deserializer   
-y                      int                     from deserializer   
+Point                  struct<x:int,y:int>     from deserializer   
diff --git a/ql/src/test/results/clientpositive/llap/describe_syntax.q.out 
b/ql/src/test/results/clientpositive/llap/describe_syntax.q.out
index e1c9dfb6318..f722036cc0e 100644
--- a/ql/src/test/results/clientpositive/llap/describe_syntax.q.out
+++ b/ql/src/test/results/clientpositive/llap/describe_syntax.q.out
@@ -284,6 +284,79 @@ num_falses
 bit_vector                                 
 comment                from deserializer   
 COLUMN_STATS_ACCURATE  {}                  
+PREHOOK: query: DESCRIBE t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+ds                     string                                      
+PREHOOK: query: DESCRIBE EXTENDED t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE EXTENDED t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+ds                     string                                      
+PREHOOK: query: DESCRIBE FORMATTED t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE FORMATTED t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+col_name               ds                  
+data_type              string              
+min                                        
+max                                        
+num_nulls              0                   
+distinct_count         2                   
+avg_col_len            100.0               
+max_col_len            100                 
+num_trues                                  
+num_falses                                 
+bit_vector                                 
+comment                                    
+COLUMN_STATS_ACCURATE  {\"COLUMN_STATS\":{\"ds\":\"true\"}}
+PREHOOK: query: DESCRIBE db1.t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE db1.t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+ds                     string                                      
+PREHOOK: query: DESCRIBE EXTENDED db1.t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE EXTENDED db1.t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+ds                     string                                      
+PREHOOK: query: DESCRIBE FORMATTED db1.t1 ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE FORMATTED db1.t1 ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+col_name               ds                  
+data_type              string              
+min                                        
+max                                        
+num_nulls              0                   
+distinct_count         2                   
+avg_col_len            100.0               
+max_col_len            100                 
+num_trues                                  
+num_falses                                 
+bit_vector                                 
+comment                                    
+COLUMN_STATS_ACCURATE  {\"COLUMN_STATS\":{\"ds\":\"true\"}}
+PREHOOK: query: DESCRIBE t1 PART
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE t1 PART
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+part                   string                                      
 PREHOOK: query: DESCRIBE t1 PARTITION(ds='4', part='5')
 PREHOOK: type: DESCTABLE
 PREHOOK: Input: db1@t1
@@ -424,3 +497,35 @@ Bucket Columns:            []
 Sort Columns:          []                       
 Storage Desc Params:            
        serialization.format    1                   
+PREHOOK: query: DESCRIBE t1 PARTITION(ds='3', part='3') ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE t1 PARTITION(ds='3', part='3') ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+ds                     string                                      
+PREHOOK: query: DESCRIBE EXTENDED t1 PARTITION(ds='4', part='5') part
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE EXTENDED t1 PARTITION(ds='4', part='5') part
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+part                   string                                      
+PREHOOK: query: DESCRIBE FORMATTED t1 PARTITION(ds='3', part='3') ds
+PREHOOK: type: DESCTABLE
+PREHOOK: Input: db1@t1
+POSTHOOK: query: DESCRIBE FORMATTED t1 PARTITION(ds='3', part='3') ds
+POSTHOOK: type: DESCTABLE
+POSTHOOK: Input: db1@t1
+col_name               ds                  
+data_type              string              
+min                                        
+max                                        
+num_nulls                                  
+distinct_count                             
+avg_col_len                                
+max_col_len                                
+num_trues                                  
+num_falses                                 
+bit_vector                                 
+comment                                    

Reply via email to