Code review comment: **1. For a partitioned table:**  `create table testsparkstats (id int, name string) partitioned by(dt string) tored as orc;`  **2. insert two partition dt=2024 and dt=2025**  `insert into testsparkstats values(1243,'ttetw','2024'),(8945,'erw','2024'),(456,'df','2025'),(568,'tom','2025');`  **3. analyze column statistics against the partitioned table**  **For `column `level statistics, spark will store all the column statistics in the table properties whether the table is partitioned or not, that is to say, the two statements have same effect (spark will treat partitioned table as unpartitioned table when doing `column `statistics)** 1) analyze the partition column statistics dt=2024, and this will get all table's statistics and stored in the table properties `analyze table testsparkstats partition (dt='2024') compute statistics for all columns;` 2) analyze partitoned table's level statistics  `analyze table testsparkstats compute statistics for all columns;`  **4. Check the table properties from hms metadata**  mysql> select * from TABLE_PARAMS where TBL_ID=1082; +--------+--------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | TBL_ID | PARAM_KEY                                        | PARAM_VALUE                                                                                                                                                                                                         | +--------+--------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |   1082 | spark.sql.create.version                         | 3.3.1                                                                                                                                                                                                               | |   1082 | spark.sql.sources.schema                         | {"type":"struct","fields":[{"name":"id","type":"integer","nullable":true,"metadata":{}},{"name":"name","type":"string","nullable":true,"metadata":{}},{"name":"dt","type":"string","nullable":true,"metadata":{}}]} | |   1082 | spark.sql.sources.schema.numPartCols             | 1                                                                                                                                                                                                                   | |   1082 | spark.sql.sources.schema.partCol.0               | dt                                                                                                                                                                                                                  | |   1082 | spark.sql.statistics.colStats.dt.avgLen          | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.dt.distinctCount   | 2                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.dt.maxLen          | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.dt.nullCount       | 0                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.dt.version         | 2                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.id.avgLen          | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.id.distinctCount   | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.id.max             | 8945                                                                                                                                                                                                                | |   1082 | spark.sql.statistics.colStats.id.maxLen          | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.id.min             | 456                                                                                                                                                                                                                 | |   1082 | spark.sql.statistics.colStats.id.nullCount       | 0                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.id.version         | 2                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.name.avgLen        | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.name.distinctCount | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.name.maxLen        | 5                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.name.nullCount     | 0                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.colStats.name.version       | 2                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.numRows                     | 4                                                                                                                                                                                                                   | |   1082 | spark.sql.statistics.totalSize                   | 762                                                                                                                                                                                                                 | |   1082 | transient_lastDdlTime                            | 1706411426                                                                                                                                                                                                          | +--------+--------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 24 rows in set (0.00 sec) ` 

Code before review:
public HivePartitionStats getTableStatistics(String dbName, String tblName) {
org.apache.hadoop.hive.metastore.api.Table table = client.getTable(dbName, tblName);
HiveCommonStats commonStats = toHiveCommonStats(table.getParameters());
long totalRowNums = commonStats.getRowNums();
if (totalRowNums == -1) {
return HivePartitionStats.empty();
}
List<String> dataColumns = table.getSd().getCols().stream()
.map(FieldSchema::getName)
.collect(toImmutableList());
List<ColumnStatisticsObj> statisticsObjs = client.getTableColumnStats(dbName, tblName, dataColumns);
if (statisticsObjs.isEmpty()) {
statisticsObjs = HiveMetastoreApiConverter.getColStatsFromSparkParams(table);
}
Map<String, HiveColumnStats> columnStatistics =
HiveMetastoreApiConverter.toSinglePartitionColumnStats(statisticsObjs, totalRowNums);
return new HivePartitionStats(commonStats, columnStatistics);
}

Line under review: if (statisticsObjs.isEmpty()) {

Code after addressing the review:
public HivePartitionStats getTableStatistics(String dbName, String tblName) {
org.apache.hadoop.hive.metastore.api.Table table = client.getTable(dbName, tblName);
HiveCommonStats commonStats = toHiveCommonStats(table.getParameters());
long totalRowNums = commonStats.getRowNums();
if (totalRowNums == -1) {
return HivePartitionStats.empty();
}
List<String> dataColumns = table.getSd().getCols().stream()
.map(FieldSchema::getName)
.collect(toImmutableList());
List<ColumnStatisticsObj> statisticsObjs = client.getTableColumnStats(dbName, tblName, dataColumns);
if (statisticsObjs.isEmpty() && Config.enable_reuse_spark_column_statistics) {
try {
if (table.getParameters().keySet().stream().anyMatch(k -> k.startsWith("spark.sql.statistics.colStats."))) {
statisticsObjs = HiveMetastoreApiConverter.getColStatsFromSparkParams(table);
}
} catch (Exception e) {
LOG.warn("Failed to get column stats from table [{}.{}]", dbName, tblName);
}
}
Map<String, HiveColumnStats> columnStatistics =
HiveMetastoreApiConverter.toSinglePartitionColumnStats(statisticsObjs, totalRowNums);
return new HivePartitionStats(commonStats, columnStatistics);
}