You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@olingo.apache.org by "Patel, Yesha" <ye...@sap.com> on 2022/09/29 17:33:55 UTC

OLingo v4.0 deserializer double value running into exception.

Hi,
There is odata service which has a table that has edm.double datatype column with value 0.020000000004074536 and when olingo api tries to deserialize it runs into below exception.

java.io.IOException: org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException: The literal '0.020000000004074536' has illegal content.

It is not matching the regex in PATTERN and throws this.

Any idea why it is rejecting this particular value?


Thanks,
Yesha




In Olingo v4.0
Olingo-OData-4.6.0\src\org\apache\olingo\commons\core\edm\primitivetype\EdmDouble.java

private static final Pattern PATTERN = Pattern.compile(
      "(?:\\+|-)?\\p{Digit}{1,17}(?:\\.\\p{Digit}{1,17})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,3})?");


@Override
  protected <T> T internalValueOfString(final String value,
      final Boolean isNullable, final Integer maxLength, final Integer precision,
      final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {

    Double result = null;
    BigDecimal bigDecimalValue = null;
    // Handle special values first.
    if (value.equals(NEGATIVE_INFINITY)) {
      result = Double.NEGATIVE_INFINITY;
    } else if (value.equals(POSITIVE_INFINITY)) {
      result = Double.POSITIVE_INFINITY;
    } else if (value.equals(NaN)) {
      result = Double.NaN;
    } else {
      // Now only "normal" numbers remain.
      if (!PATTERN.matcher(value).matches()) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }

      // The number format is checked above, so we don't have to catch NumberFormatException.
      bigDecimalValue = new BigDecimal(value);
      result = bigDecimalValue.doubleValue();
      // "Real" infinite values have been treated already above, so we can throw an exception
      // if the conversion to a double results in an infinite value.
      if (result.isInfinite() || BigDecimal.valueOf(result).compareTo(bigDecimalValue) != 0) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }
    }

    if (returnType.isAssignableFrom(Double.class)) {
      return returnType.cast(result);
    } else if (result.isInfinite() || result.isNaN()) {
      if (returnType.isAssignableFrom(Float.class)) {
        return returnType.cast(result.floatValue());
      } else {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".");
      }
    } else {
      try {
        return EdmDecimal.convertDecimal(bigDecimalValue, returnType);
      } catch (final IllegalArgumentException e) {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".", e);
      } catch (final ClassCastException e) {
        throw new EdmPrimitiveTypeException("The value type " + returnType + " is not supported.", e);
      }
    }
  }

RE: OLingo v4.0 deserializer double value running into exception.

Posted by "Patel, Yesha" <ye...@sap.com>.
Hi Carsten,
Thanks you for explaining.
Regards,
Yesha

From: Carsten Milkau <Ca...@prologa.de>
Sent: Friday, September 30, 2022 4:03 AM
To: user@olingo.apache.org
Subject: AW: OLingo v4.0 deserializer double value running into exception.

You don't often get email from carsten.milkau@prologa.de<ma...@prologa.de>. Learn why this is important<https://aka.ms/LearnAboutSenderIdentification>
Hi Yesha,

18 digits is one too many fort he regex.

0.020000000004074536
(?:\+|-)?\\p{Digit}{1,17}(?:\.\p{Digit}{1,17})?(?:(?:E|e)(?:\+|-)?\p{Digit}{1,3})?

Best Regards,
Carsten

Von: Patel, Yesha <ye...@sap.com>>
Gesendet: Donnerstag, 29. September 2022 19:34
An: user@olingo.apache.org<ma...@olingo.apache.org>
Betreff: OLingo v4.0 deserializer double value running into exception.

Hi,
There is odata service which has a table that has edm.double datatype column with value 0.020000000004074536 and when olingo api tries to deserialize it runs into below exception.

java.io.IOException: org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException: The literal '0.020000000004074536' has illegal content.

It is not matching the regex in PATTERN and throws this.

Any idea why it is rejecting this particular value?


Thanks,
Yesha




In Olingo v4.0
Olingo-OData-4.6.0\src\org\apache\olingo\commons\core\edm\primitivetype\EdmDouble.java

private static final Pattern PATTERN = Pattern.compile(
      "(?:\\+|-)?\\p{Digit}{1,17}(?:\\.\\p{Digit}{1,17})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,3})?");


@Override
  protected <T> T internalValueOfString(final String value,
      final Boolean isNullable, final Integer maxLength, final Integer precision,
      final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {

    Double result = null;
    BigDecimal bigDecimalValue = null;
    // Handle special values first.
    if (value.equals(NEGATIVE_INFINITY)) {
      result = Double.NEGATIVE_INFINITY;
    } else if (value.equals(POSITIVE_INFINITY)) {
      result = Double.POSITIVE_INFINITY;
    } else if (value.equals(NaN)) {
      result = Double.NaN;
    } else {
      // Now only "normal" numbers remain.
      if (!PATTERN.matcher(value).matches()) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }

      // The number format is checked above, so we don't have to catch NumberFormatException.
      bigDecimalValue = new BigDecimal(value);
      result = bigDecimalValue.doubleValue();
      // "Real" infinite values have been treated already above, so we can throw an exception
      // if the conversion to a double results in an infinite value.
      if (result.isInfinite() || BigDecimal.valueOf(result).compareTo(bigDecimalValue) != 0) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }
    }

    if (returnType.isAssignableFrom(Double.class)) {
      return returnType.cast(result);
    } else if (result.isInfinite() || result.isNaN()) {
      if (returnType.isAssignableFrom(Float.class)) {
        return returnType.cast(result.floatValue());
      } else {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".");
      }
    } else {
      try {
        return EdmDecimal.convertDecimal(bigDecimalValue, returnType);
      } catch (final IllegalArgumentException e) {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".", e);
      } catch (final ClassCastException e) {
        throw new EdmPrimitiveTypeException("The value type " + returnType + " is not supported.", e);
      }
    }
  }

AW: OLingo v4.0 deserializer double value running into exception.

Posted by Carsten Milkau <Ca...@prologa.de>.
Hi Yesha,

18 digits is one too many fort he regex.

0.020000000004074536
(?:\+|-)?\\p{Digit}{1,17}(?:\.\p{Digit}{1,17})?(?:(?:E|e)(?:\+|-)?\p{Digit}{1,3})?

Best Regards,
Carsten

Von: Patel, Yesha <ye...@sap.com>
Gesendet: Donnerstag, 29. September 2022 19:34
An: user@olingo.apache.org
Betreff: OLingo v4.0 deserializer double value running into exception.

Hi,
There is odata service which has a table that has edm.double datatype column with value 0.020000000004074536 and when olingo api tries to deserialize it runs into below exception.

java.io.IOException: org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException: The literal '0.020000000004074536' has illegal content.

It is not matching the regex in PATTERN and throws this.

Any idea why it is rejecting this particular value?


Thanks,
Yesha




In Olingo v4.0
Olingo-OData-4.6.0\src\org\apache\olingo\commons\core\edm\primitivetype\EdmDouble.java

private static final Pattern PATTERN = Pattern.compile(
      "(?:\\+|-)?\\p{Digit}{1,17}(?:\\.\\p{Digit}{1,17})?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,3})?");


@Override
  protected <T> T internalValueOfString(final String value,
      final Boolean isNullable, final Integer maxLength, final Integer precision,
      final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {

    Double result = null;
    BigDecimal bigDecimalValue = null;
    // Handle special values first.
    if (value.equals(NEGATIVE_INFINITY)) {
      result = Double.NEGATIVE_INFINITY;
    } else if (value.equals(POSITIVE_INFINITY)) {
      result = Double.POSITIVE_INFINITY;
    } else if (value.equals(NaN)) {
      result = Double.NaN;
    } else {
      // Now only "normal" numbers remain.
      if (!PATTERN.matcher(value).matches()) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }

      // The number format is checked above, so we don't have to catch NumberFormatException.
      bigDecimalValue = new BigDecimal(value);
      result = bigDecimalValue.doubleValue();
      // "Real" infinite values have been treated already above, so we can throw an exception
      // if the conversion to a double results in an infinite value.
      if (result.isInfinite() || BigDecimal.valueOf(result).compareTo(bigDecimalValue) != 0) {
        throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content.");
      }
    }

    if (returnType.isAssignableFrom(Double.class)) {
      return returnType.cast(result);
    } else if (result.isInfinite() || result.isNaN()) {
      if (returnType.isAssignableFrom(Float.class)) {
        return returnType.cast(result.floatValue());
      } else {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".");
      }
    } else {
      try {
        return EdmDecimal.convertDecimal(bigDecimalValue, returnType);
      } catch (final IllegalArgumentException e) {
        throw new EdmPrimitiveTypeException("The literal '" + value
            + "' cannot be converted to value type " + returnType + ".", e);
      } catch (final ClassCastException e) {
        throw new EdmPrimitiveTypeException("The value type " + returnType + " is not supported.", e);
      }
    }
  }