private List<Partition> setSingleValuedFields(List<Long> partitionIds,
      final TreeMap<Long, Partition> partitions, final TreeMap<Long, StorageDescriptor> sdIds,
      final TreeMap<Long, SerDeInfo> serdeIds, final TreeMap<Long, List<FieldSchema>> cdIds)
      throws MetaException {

    StringBuilder queryTextBuilder = new StringBuilder();
    int numColumns = buildQueryForSingleValuedFields(partitionIds, queryTextBuilder);
    String queryText = queryTextBuilder.toString();

    Query<?> query = pm.newQuery("javax.jdo.query.SQL", queryText);
    try {
      long start = LOG.isDebugEnabled() ? System.nanoTime() : 0;
      List<Object> sqlResult = MetastoreDirectSqlUtils.executeWithArray(query, null, queryText);
      long queryTime = LOG.isDebugEnabled() ? System.nanoTime() : 0;
      MetastoreDirectSqlUtils.timingTrace(LOG.isDebugEnabled(), queryText, start, queryTime);
      Deadline.checkTimeout();
      final Long[] ids = new Long[4];
      Object[] rowVals = new Object[1];
      // Keep order by name, consistent with JDO.
      ArrayList<Partition> orderedResult = new ArrayList<Partition>(partitionIds.size());
      for (Object row : sqlResult) {
        if (numColumns > 1) {
          rowVals = (Object[])row;
        } else {
          // only one column is selected by query. The result class will be Object
          rowVals[0] = row;
        }
        Partition part = new Partition();
        for (PartitionFieldNode root : roots) {
          traverseAndSetValues(part, root, rowVals, new PartitionFieldValueSetter() {
            @Override
            public void setValue(Object partition, PartitionFieldNode node, Object value)
                throws MetaException {
              if (!node.isMultiValued) {
                // in case of serdeid and sdId node we just collect the sdIds for further processing
                if (node.equals(sdIdNode)) {
                  ids[SD_INDEX] = extractSqlLong(value);
                } else if (node.equals(serdeIdNode)) {
                  ids[SERDE_INDEX] = extractSqlLong(value);
                } else if (node.equals(cdIdNode)) {
                  ids[CD_INDEX] = extractSqlLong(value);
                } else if (node.equals(partIdNode)) {
                  ids[PART_INDEX] = extractSqlLong(value);
                } else {
                  // incase of sd.compressed and sd.storedAsSubDirectories we need special code to convert
                  // string to a boolean value
                  if (node.fieldName.equals("sd.compressed") || node.fieldName.equals("sd.storedAsSubDirectories")) {
                    value = MetastoreDirectSqlUtils.extractSqlBoolean(value);
                  } else if (node.fieldName.equals("lastAccessTime") || node.fieldName.equals("createTime")) {
                    value = MetastoreDirectSqlUtils.extractSqlInt(value);
                  }
                  MetaStoreServerUtils.setNestedProperty(partition, node.fieldName, value, true);
                }
              }
            }
          });
        }
        // PART_ID is always queried
        if (ids[PART_INDEX] == null) {
          throw new MetaException("Could not find PART_ID for partition " + part);
        }
        partitions.put(ids[PART_INDEX], part);
        orderedResult.add(part);
        ids[PART_INDEX] = null;

        if (ids[SD_INDEX] != null) {
          // sd object is initialized if any of the sd single-valued fields are in the projection
          if (part.getSd() == null) {
            part.setSd(new StorageDescriptor());
          }
          sdIds.put(ids[SD_INDEX], part.getSd());
          ids[SD_INDEX] = null;
        }

        if (ids[SERDE_INDEX] != null) {
          // serde object must have already been intialized above in MetaStoreUtils.setNestedProperty call
          if (part.getSd().getSerdeInfo() == null) {
            part.getSd().setSerdeInfo(new SerDeInfo());
          }
          serdeIds.put(ids[SERDE_INDEX], part.getSd().getSerdeInfo());
          ids[SERDE_INDEX] = null;
        }

        if (ids[CD_INDEX] != null) {
          // common case is all the SDs will reuse the same CD
          // allocate List<FieldSchema> only when you see a new CD_ID
          cdIds.putIfAbsent(ids[CD_INDEX], new ArrayList<>(5));
          if (part.getSd().getCols() == null) {
            part.getSd().setCols(cdIds.get(ids[CD_INDEX]));
          }
          ids[CD_INDEX] = null;
        }
        Deadline.checkTimeout();
      }
      return orderedResult;
    } catch (Exception e) {
      LOG.error("Exception received while getting partitions using projected fields", e);
      throw new MetaException(e.getMessage());
    } finally {
      query.closeAll();
    }
  }
Given a list of partition ids, returns the List of partially filled partitions based on the
projection list used to instantiate this PartitionProjectionEvaluator
@param partitionIds List of partition ids corresponding to the Partitions objects which are requested
@return Partitions where each partition has only the projected fields set
@throws MetaException
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PartitionProjectionEvaluator.java