public static Object coerce()

in sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java [53:157]


  public static Object coerce(
      final ObjectMapper jsonMapper,
      final Context context,
      final Object value,
      final SqlTypeName sqlTypeName,
      final String fieldName
  )
  {
    final Object coercedValue;

    if (SqlTypeName.CHAR_TYPES.contains(sqlTypeName)) {
      if (value == null || value instanceof String) {
        coercedValue = value;
      } else if (value instanceof NlsString) {
        coercedValue = ((NlsString) value).getValue();
      } else if (value instanceof Number) {
        coercedValue = String.valueOf(value);
      } else if (value instanceof Boolean) {
        coercedValue = String.valueOf(value);
      } else {
        final Object maybeList = coerceArrayToList(value, false);

        // Check if "maybeList" was originally a Collection of some kind, or was able to be coerced to one.
        // Then Iterate through the collection, coercing each value. Useful for handling multi-value dimensions.
        if (maybeList instanceof Collection) {
          final List<String> valueStrings =
              ((Collection<?>) maybeList)
                  .stream()
                  .map(v -> (String) coerce(jsonMapper, context, v, sqlTypeName, fieldName))
                  .collect(Collectors.toList());

          // Must stringify since the caller is expecting CHAR_TYPES.
          coercedValue = coerceUsingObjectMapper(jsonMapper, valueStrings, sqlTypeName, fieldName);
        } else {
          throw cannotCoerce(value, sqlTypeName, fieldName);
        }
      }
    } else if (value == null) {
      coercedValue = null;
    } else if (sqlTypeName == SqlTypeName.DATE) {
      return Calcites.jodaToCalciteDate(coerceDateTime(value, sqlTypeName, fieldName), context.getTimeZone());
    } else if (sqlTypeName == SqlTypeName.TIMESTAMP) {
      return Calcites.jodaToCalciteTimestamp(coerceDateTime(value, sqlTypeName, fieldName), context.getTimeZone());
    } else if (sqlTypeName == SqlTypeName.BOOLEAN) {
      if (value instanceof Boolean) {
        coercedValue = value;
      } else if (value instanceof String) {
        coercedValue = Evals.asBoolean(((String) value));
      } else if (value instanceof Number) {
        coercedValue = Evals.asBoolean(((Number) value).longValue());
      } else {
        throw cannotCoerce(value, sqlTypeName, fieldName);
      }
    } else if (sqlTypeName == SqlTypeName.INTEGER) {
      if (value instanceof String) {
        coercedValue = Ints.tryParse((String) value);
      } else if (value instanceof Number) {
        coercedValue = ((Number) value).intValue();
      } else {
        throw cannotCoerce(value, sqlTypeName, fieldName);
      }
    } else if (sqlTypeName == SqlTypeName.BIGINT) {
      try {
        coercedValue = DimensionHandlerUtils.convertObjectToLong(value, fieldName);
      }
      catch (Exception e) {
        throw cannotCoerce(value, sqlTypeName, fieldName);
      }
    } else if (sqlTypeName == SqlTypeName.FLOAT) {
      try {
        coercedValue = DimensionHandlerUtils.convertObjectToFloat(value, fieldName);
      }
      catch (Exception e) {
        throw cannotCoerce(value, sqlTypeName, fieldName);
      }
    } else if (SqlTypeName.FRACTIONAL_TYPES.contains(sqlTypeName)) {
      try {
        coercedValue = DimensionHandlerUtils.convertObjectToDouble(value, fieldName);
      }
      catch (Exception e) {
        throw cannotCoerce(value, sqlTypeName, fieldName);
      }
    } else if (sqlTypeName == SqlTypeName.OTHER) {
      coercedValue = coerceUsingObjectMapper(jsonMapper, value, sqlTypeName, fieldName);
    } else if (sqlTypeName == SqlTypeName.ARRAY) {
      if (context.isStringifyArrays()) {
        if (value instanceof String) {
          coercedValue = value;
        } else if (value instanceof NlsString) {
          coercedValue = ((NlsString) value).getValue();
        } else {
          coercedValue = coerceUsingObjectMapper(jsonMapper, value, sqlTypeName, fieldName);
        }
      } else {
        // the protobuf jdbc handler prefers lists (it actually can't handle java arrays as sql arrays, only java lists)
        // the json handler could handle this just fine, but it handles lists as sql arrays as well so just convert
        // here if needed
        coercedValue = coerceArrayToList(value, true);
      }
    } else {
      throw cannotCoerce(value, sqlTypeName, fieldName);
    }

    return coercedValue;
  }