protected TableMeta getMixedTableMeta(TableIdentifier identifier) {
    org.apache.hadoop.hive.metastore.api.Table hiveTable = null;
    identifier = identifier.toLowCaseIdentifier();
    try {
      hiveTable = HiveTableUtil.loadHmsTable(this.hiveClientPool, identifier);
    } catch (RuntimeException e) {
      throw new IllegalStateException(String.format("failed load hive table %s.", identifier), e);
    }
    if (hiveTable == null) {
      throw new NoSuchTableException("load table failed %s.", identifier);
    }

    Map<String, String> hiveParameters = hiveTable.getParameters();

    String mixedTableRootLocation = hiveParameters.get(MIXED_TABLE_ROOT_LOCATION);
    if (mixedTableRootLocation == null) {
      // if hive location ends with /hive, then it's a mixed-hive table. we need to remove /hive to
      // get root location.
      // if hive location doesn't end with /hive, then it's a pure-hive table. we can use the
      // location as root location.
      String hiveRootLocation = hiveTable.getSd().getLocation();
      if (hiveRootLocation.endsWith("/hive")) {
        mixedTableRootLocation = hiveRootLocation.substring(0, hiveRootLocation.length() - 5);
      } else {
        mixedTableRootLocation = hiveRootLocation;
      }
    }

    // full path of base, change and root location
    String baseLocation = mixedTableRootLocation + "/base";
    String changeLocation = mixedTableRootLocation + "/change";
    // load base table for get table properties
    Table baseIcebergTable = getTables().loadHadoopTableByLocation(baseLocation);
    if (baseIcebergTable == null) {
      throw new NoSuchTableException("load table failed %s, base table not found.", identifier);
    }
    Map<String, String> properties = baseIcebergTable.properties();
    // start to construct TableMeta
    TableMeta tableMeta = new TableMeta();
    tableMeta.setTableIdentifier(identifier.buildTableIdentifier());

    Map<String, String> locations = new HashMap<>();
    putNotNullProperties(locations, MetaTableProperties.LOCATION_KEY_TABLE, mixedTableRootLocation);
    putNotNullProperties(locations, MetaTableProperties.LOCATION_KEY_CHANGE, changeLocation);
    putNotNullProperties(locations, MetaTableProperties.LOCATION_KEY_BASE, baseLocation);
    // set table location
    tableMeta.setLocations(locations);

    // set table properties
    Map<String, String> newProperties = new HashMap<>(properties);
    tableMeta.setProperties(newProperties);

    // set table's primary key when needed
    if (hiveParameters != null) {
      String primaryKey = hiveParameters.get(MIXED_TABLE_PRIMARY_KEYS);
      // primary key info come from hive properties
      if (StringUtils.isNotBlank(primaryKey)) {
        org.apache.amoro.api.PrimaryKeySpec keySpec = new org.apache.amoro.api.PrimaryKeySpec();
        List<String> fields =
            Arrays.stream(primaryKey.split(PRIMARY_KEY_COLUMN_JOIN_DELIMITER))
                .collect(Collectors.toList());
        keySpec.setFields(fields);
        tableMeta.setKeySpec(keySpec);
      }
    }
    // set table format to mixed-hive format
    tableMeta.setFormat(TableFormat.MIXED_HIVE.name());
    return tableMeta;
  }
HMS is case-insensitive for table name and database
amoro-format-mixed/amoro-mixed-hive/src/main/java/org/apache/amoro/hive/catalog/MixedHiveCatalog.java