private void checkAndMergeColStats(List<ColumnStatistics> statsNew, Table tbl) throws InvalidObjectException {
    Long previousSnapshotId = tbl.currentSnapshot().parentId();
    if (previousSnapshotId != null && canProvideColStats(tbl, previousSnapshotId)) {
      List<ColumnStatistics> statsOld = IcebergTableUtil.getColStatsPath(tbl, previousSnapshotId)
          .map(statsPath -> readColStats(tbl, statsPath, null))
          .orElse(Collections.emptyList());

      boolean isTblLevel = statsNew.get(0).getStatsDesc().isIsTblLevel();
      Map<String, ColumnStatistics> oldStatsMap = Maps.newHashMap();

      if (!isTblLevel) {
        for (ColumnStatistics statsObjOld : statsOld) {
          oldStatsMap.put(statsObjOld.getStatsDesc().getPartName(), statsObjOld);
        }
      }
      for (ColumnStatistics statsObjNew : statsNew) {
        String partitionKey = statsObjNew.getStatsDesc().getPartName();
        ColumnStatistics statsObjOld = isTblLevel ?
            statsOld.get(0) : oldStatsMap.get(partitionKey);

        if (statsObjOld != null && statsObjOld.getStatsObjSize() != 0 && !statsObjNew.getStatsObj().isEmpty()) {
          MetaStoreServerUtils.mergeColStats(statsObjNew, statsObjOld);
          if (!isTblLevel) {
            oldStatsMap.remove(partitionKey);
          }
        }
      }
      if (!isTblLevel) {
        statsNew.addAll(oldStatsMap.values());
      }
    }
  }
@param jobConf Job configuration for InputFormat to access
@param deserializer Deserializer
@param exprNodeDesc Filter expression extracted by Hive
@return Entire filter to take advantage of Hive's pruning as well as Iceberg's pruning.
iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java