private List<Partition> getPartitionsByQuery(String catName, String dbName, String tblName,
      String queryText, Object[] params, boolean isAcidTable, GetPartitionsArgs args)
      throws MetaException {
    boolean doTrace = LOG.isDebugEnabled();

    // Read all the fields and create partitions, SDs and serdes.
    TreeMap<Long, Partition> partitions = new TreeMap<Long, Partition>();
    TreeMap<Long, StorageDescriptor> sds = new TreeMap<Long, StorageDescriptor>();
    TreeMap<Long, SerDeInfo> serdes = new TreeMap<Long, SerDeInfo>();
    TreeMap<Long, List<FieldSchema>> colss = new TreeMap<Long, List<FieldSchema>>();
    // Keep order by name, consistent with JDO.
    ArrayList<Partition> orderedResult;

    // Prepare StringBuilder-s for "in (...)" lists to use in one-to-many queries.
    StringBuilder sdSb = new StringBuilder(), serdeSb = new StringBuilder();
    StringBuilder colsSb = new StringBuilder(7); // We expect that there's only one field schema.
    tblName = tblName.toLowerCase();
    dbName = dbName.toLowerCase();
    catName = normalizeSpace(catName).toLowerCase();
    partitions.navigableKeySet();

    try (QueryWrapper query = new QueryWrapper(pm.newQuery("javax.jdo.query.SQL", queryText))) {
      long start = doTrace ? System.nanoTime() : 0;
      List<Object[]> sqlResult = executeWithArray(query.getInnerQuery(), params, queryText);
      long queryTime = doTrace ? System.nanoTime() : 0;
      Deadline.checkTimeout();
      orderedResult = new ArrayList<>(sqlResult.size());

      for (Object[] fields : sqlResult) {
        // Here comes the ugly part...
        long partitionId = MetastoreDirectSqlUtils.extractSqlLong(fields[0]);
        Long sdId = MetastoreDirectSqlUtils.extractSqlLong(fields[1]);
        Long colId = MetastoreDirectSqlUtils.extractSqlLong(fields[2]);
        Long serdeId = MetastoreDirectSqlUtils.extractSqlLong(fields[3]);

        Partition part = new Partition();
        orderedResult.add(part);
        // Set the collection fields; some code might not check presence before accessing them.
        part.setParameters(new HashMap<>());
        part.setValues(new ArrayList<String>());
        part.setCatName(catName);
        part.setDbName(dbName);
        part.setTableName(tblName);
        if (fields[4] != null) {
          part.setCreateTime(MetastoreDirectSqlUtils.extractSqlInt(fields[4]));
        }
        if (fields[5] != null) {
          part.setLastAccessTime(MetastoreDirectSqlUtils.extractSqlInt(fields[5]));
        }
        Long writeId = MetastoreDirectSqlUtils.extractSqlLong(fields[14]);
        if (writeId != null && writeId > 0) {
          part.setWriteId(writeId);
        } else {
          part.setWriteId(-1L);
        }
        partitions.put(partitionId, part);


        if (sdId == null) {
          continue; // Probably a view.
        }
        assert serdeId != null;

        // We assume each partition has an unique SD.
        StorageDescriptor sd = new StorageDescriptor();
        StorageDescriptor oldSd = sds.put(sdId, sd);
        if (oldSd != null) {
          throw new MetaException("Partitions reuse SDs; we don't expect that");
        }
        // Set the collection fields; some code might not check presence before accessing them.
        sd.setSortCols(new ArrayList<Order>());
        sd.setBucketCols(new ArrayList<String>());
        sd.setParameters(new HashMap<String, String>());
        sd.setSkewedInfo(new SkewedInfo(new ArrayList<String>(),
            new ArrayList<List<String>>(), new HashMap<List<String>, String>()));
        sd.setInputFormat((String) fields[6]);
        Boolean tmpBoolean = MetastoreDirectSqlUtils.extractSqlBoolean(fields[7]);
        if (tmpBoolean != null) {
          sd.setCompressed(tmpBoolean);
        }
        tmpBoolean = MetastoreDirectSqlUtils.extractSqlBoolean(fields[8]);
        if (tmpBoolean != null) {
          sd.setStoredAsSubDirectories(tmpBoolean);
        }
        sd.setLocation((String) fields[9]);
        if (fields[10] != null) {
          sd.setNumBuckets(MetastoreDirectSqlUtils.extractSqlInt(fields[10]));
        }
        sd.setOutputFormat((String) fields[11]);
        sdSb.append(sdId).append(",");
        part.setSd(sd);

        if (colId != null) {
          List<FieldSchema> cols = colss.get(colId);
          // We expect that colId will be the same for all (or many) SDs.
          if (cols == null) {
            cols = new ArrayList<FieldSchema>();
            colss.put(colId, cols);
            colsSb.append(colId).append(",");
          }
          sd.setCols(cols);
        }

        // We assume each SD has an unique serde.
        SerDeInfo serde = new SerDeInfo();
        SerDeInfo oldSerde = serdes.put(serdeId, serde);
        if (oldSerde != null) {
          throw new MetaException("SDs reuse serdes; we don't expect that");
        }
        serde.setParameters(new HashMap<String, String>());
        serde.setName((String) fields[12]);
        serde.setSerializationLib((String) fields[13]);
        serdeSb.append(serdeId).append(",");
        sd.setSerdeInfo(serde);

        Deadline.checkTimeout();
      }
      MetastoreDirectSqlUtils.timingTrace(doTrace, queryText, start, queryTime);
    }
    String partIds = getIdListForIn(partitions.keySet());

    if (partIds.isEmpty()) {
      return orderedResult;
    }

    // Now get all the one-to-many things. Start with partitions.
    MetastoreDirectSqlUtils
        .setPartitionParametersWithFilter(PARTITION_PARAMS, convertMapNullsToEmptyStrings, pm,
            partIds, partitions, args.getIncludeParamKeyPattern(), args.getExcludeParamKeyPattern());

    MetastoreDirectSqlUtils.setPartitionValues(PARTITION_KEY_VALS, pm, partIds, partitions);

    // Prepare IN (blah) lists for the following queries. Cut off the final ','s.
    if (sdSb.length() == 0) {
      assert serdeSb.length() == 0 && colsSb.length() == 0;
      return orderedResult; // No SDs, probably a view.
    }

    String sdIds = trimCommaList(sdSb);
    String serdeIds = trimCommaList(serdeSb);
    String colIds = trimCommaList(colsSb);

    if (!isAcidTable) {
      // Get all the stuff for SD. Don't do empty-list check - we expect partitions do have SDs.
      MetastoreDirectSqlUtils.setSDParameters(SD_PARAMS, convertMapNullsToEmptyStrings, pm, sds, sdIds);
    }

    boolean hasSkewedColumns = false;
    if (!isAcidTable) {
      MetastoreDirectSqlUtils.setSDSortCols(SORT_COLS, pm, sds, sdIds);
    }

    MetastoreDirectSqlUtils.setSDBucketCols(BUCKETING_COLS, pm, sds, sdIds);

    if (!isAcidTable) {
      // Skewed columns stuff.
      hasSkewedColumns = MetastoreDirectSqlUtils.setSkewedColNames(SKEWED_COL_NAMES, pm, sds, sdIds);
    }

    // Assume we don't need to fetch the rest of the skewed column data if we have no columns.
    if (hasSkewedColumns) {
      // We are skipping the SKEWED_STRING_LIST table here, as it seems to be totally useless.
      MetastoreDirectSqlUtils
          .setSkewedColValues(SKEWED_STRING_LIST_VALUES, SKEWED_VALUES, pm, sds, sdIds);

      // We are skipping the SKEWED_STRING_LIST table here, as it seems to be totally useless.
      MetastoreDirectSqlUtils
          .setSkewedColLocationMaps(SKEWED_COL_VALUE_LOC_MAP, SKEWED_STRING_LIST_VALUES, pm, sds, sdIds);
    } // if (hasSkewedColumns)

    // Get FieldSchema stuff if any.
    if (!colss.isEmpty() && !args.isSkipColumnSchemaForPartition()) {
      // We are skipping the CDS table here, as it seems to be totally useless.
      MetastoreDirectSqlUtils.setSDCols(COLUMNS_V2, pm, colss, colIds);
    }

    // Finally, get all the stuff for serdes - just the params.
    if (!isAcidTable) {
      MetastoreDirectSqlUtils.setSerdeParams(SERDE_PARAMS, convertMapNullsToEmptyStrings, pm, serdes, serdeIds);
    }

    return orderedResult;
  }
Should be called with the list short enough to not trip up Oracle/etc.
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java