class SelectValueMapper implements ValueMapper<GenericRow, GenericRow> {

  @Override
  public GenericRow apply(final GenericRow row) {
    if (row == null) {
      return row;
    }
    final List<Object> newColumns = new ArrayList<>();
    for (int i = 0; i < expressionPairList.size(); i++) {
      try {
        final int[] parameterIndexes = expressionEvaluators.get(i).getIndexes();
        final Kudf[] kudfs = expressionEvaluators.get(i).getUdfs();
        final Object[] parameterObjects = new Object[parameterIndexes.length];
        for (int j = 0; j < parameterIndexes.length; j++) {
          if (parameterIndexes[j] < 0) {
            parameterObjects[j] = kudfs[j];
          } else {
            parameterObjects[j] =
                typeEnforcer.enforceFieldType(parameterIndexes[j],
                    row.getColumns()
                        .get(parameterIndexes[j]));
          }
        }
        newColumns.add(
            expressionEvaluators.get(i).getExpressionEvaluator().evaluate(parameterObjects)
        );
      } catch (Exception e) {
        log.error(
            "Error calculating column with index {} : {}",
            i,
            expressionPairList.get(i).getLeft(),
            e
        );
        newColumns.add(null);
      }
    }
    return new GenericRow(newColumns);
  }

    SelectValueMapper(
      final GenericRowValueTypeEnforcer typeEnforcer,
      final List<Pair<String, Expression>> expressionPairList,
      final List<ExpressionMetadata> expressionEvaluators
  );

}