private Function<ResultSet, Val[]> buildResultSetMapper(
            final FieldIndex fieldIndex,
            final StatisticStoreDoc statisticStoreEntity) {

        LAMBDA_LOGGER.debug(() -> String.format("Building mapper for fieldIndexMap %s, entity %s",
                fieldIndex, statisticStoreEntity.getUuid()));

        // construct a list of field extractors that can populate the appropriate bit of the data arr
        // when given a resultSet row
        List<ValueExtractor> valueExtractors = fieldIndex.stream()
                .map(entry -> {
                    final int idx = entry.getValue();
                    final String fieldName = entry.getKey();
                    final ValueExtractor extractor;
                    if (fieldName.equals(StatisticStoreDoc.FIELD_NAME_DATE_TIME)) {
                        extractor = buildDateValueExtractor(SQLStatisticNames.TIME_MS, idx);
                    } else if (fieldName.equals(StatisticStoreDoc.FIELD_NAME_COUNT)) {
                        extractor = buildLongValueExtractor(SQLStatisticNames.COUNT, idx);
                    } else if (fieldName.equals(StatisticStoreDoc.FIELD_NAME_PRECISION_MS)) {
                        extractor = buildPrecisionMsExtractor(idx);
                    } else if (fieldName.equals(StatisticStoreDoc.FIELD_NAME_VALUE)) {
                        final StatisticType statisticType = statisticStoreEntity.getStatisticType();
                        if (statisticType.equals(StatisticType.COUNT)) {
                            extractor = buildLongValueExtractor(SQLStatisticNames.COUNT, idx);
                        } else if (statisticType.equals(StatisticType.VALUE)) {
                            // value stat
                            extractor = buildStatValueExtractor(idx);
                        } else {
                            throw new RuntimeException(String.format("Unexpected type %s", statisticType));
                        }
                    } else if (statisticStoreEntity.getFieldNames().contains(fieldName)) {
                        // this is a tag field so need to extract the tags/values from the NAME col.
                        // We only want to do this extraction once so we cache the values
                        extractor = buildTagFieldValueExtractor(fieldName, idx);
                    } else {
                        extractor = null;
//                        throw new RuntimeException(String.format("Unexpected fieldName %s", fieldName));
                    }
                    LAMBDA_LOGGER.debug(() ->
                            String.format("Adding extraction function for field %s, idx %s", fieldName, idx));
                    return extractor;
                })
                .toList();

        final int arrSize = valueExtractors.size();

        //the mapping function that will be used on each row in the resultSet, that makes use of the ValueExtractors
        //created above
        return rs -> {
            Preconditions.checkNotNull(rs);
            try {
                if (rs.isClosed()) {
                    throw new RuntimeException("ResultSet is closed");
                }
            } catch (SQLException e) {
                throw new RuntimeException("Error testing closed state of resultSet", e);
            }
            //the data array we are populating
            final Val[] data = new Val[arrSize];
            //state to hold while mapping this row, used to save parsing the NAME col multiple times
            final Map<String, Val> fieldValueCache = new HashMap<>();

            //run each of our field value extractors against the resultSet to fill up the data arr
            valueExtractors.forEach(valueExtractor -> {
                if (valueExtractor != null) {
                    valueExtractor.extract(rs, data, fieldValueCache);
                }
            });

            LAMBDA_LOGGER.trace(() -> {
                try {
                    return String.format("Mapped resultSet row %s to %s", rs.getRow(), Arrays.toString(data));
                } catch (SQLException e) {
                    throw new RuntimeException(String.format("Error getting current row number: %s", e.getMessage()),
                            e);
                }
            });
            return Val.of(data);
        };
    }
Build a mapper function that will only extract the columns of interest from the resultSet row.
Assumes something external to the returned function will advance the resultSet
stroom-statistics/stroom-statistics-impl-sql/src/main/java/stroom/statistics/impl/sql/search/StatisticsSearchServiceImpl.java