@Override
  public List<TableMeta> getTableMeta(String catName, String dbNames, String tableNames,
                                      List<String> tableTypes) throws MetaException {

    boolean commited = false;
    Query query = null;
    List<TableMeta> metas = new ArrayList<>();
    try {
      openTransaction();
      // Take the pattern and split it on the | to get all the composing
      // patterns
      StringBuilder filterBuilder = new StringBuilder();
      List<String> parameterVals = new ArrayList<>();
      appendSimpleCondition(filterBuilder, "database.catalogName", new String[] {catName}, parameterVals);
      if (dbNames != null && !dbNames.equals("*")) {
        appendPatternCondition(filterBuilder, "database.name", dbNames, parameterVals);
      }
      if (tableNames != null && !tableNames.equals("*")) {
        appendPatternCondition(filterBuilder, "tableName", tableNames, parameterVals);
      }
      if (tableTypes != null && !tableTypes.isEmpty()) {
        appendSimpleCondition(filterBuilder, "tableType", tableTypes.toArray(new String[0]), parameterVals);
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug("getTableMeta with filter " + filterBuilder + " params: " +
            StringUtils.join(parameterVals, ", "));
      }
      // Add the fetch group here which retrieves the database object along with the MTable
      // objects. If we don't prefetch the database object, we could end up in a situation where
      // the database gets dropped while we are looping through the tables throwing a
      // JDOObjectNotFoundException. This causes HMS to go into a retry loop which greatly degrades
      // performance of this function when called with dbNames="*" and tableNames="*" (fetch all
      // tables in all databases, essentially a full dump)
      pm.getFetchPlan().addGroup(FetchGroups.FETCH_DATABASE_ON_MTABLE);
      query = pm.newQuery(MTable.class, filterBuilder.toString()) ;
      query.setResult("database.name, tableName, tableType, parameters.get(\"comment\"), owner, ownerType");
      List<Object[]> tables = (List<Object[]>) query.executeWithArray(parameterVals.toArray(new String[0]));
      for (Object[] table : tables) {
        TableMeta metaData = new TableMeta(table[0].toString(), table[1].toString(), table[2].toString());
        metaData.setCatName(catName);
        if (table[3] != null) {
          metaData.setComments(table[3].toString());
        }
        if (table[4] != null) {
          metaData.setOwnerName(table[4].toString());
        }
        if (table[5] != null) {
          metaData.setOwnerType(getPrincipalTypeFromStr(table[5].toString()));
        }
        metas.add(metaData);
      }
      commited = commitTransaction();
    } finally {
      pm.getFetchPlan().removeGroup(FetchGroups.FETCH_DATABASE_ON_MTABLE);
      rollbackAndCleanup(commited, query);
    }
    return metas;
  }
Convert PrivilegeGrantInfo from privMap to MTablePrivilege, and add all of
them to the toPersistPrivObjs. These privilege objects will be persisted as
part of createTable.
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java