Skip to content

Commit

Permalink
Fix error message for invalid real cast
Browse files Browse the repository at this point in the history
The error message for invalid cast from REAL ->
BIGINT/INTEGER/SMALLINT/TINYINT was previously returning the integer
bits underlying the float instead of the float value itself. This fixes
that to use the float value in the error message. For example, casting
a NaN value to bigint that was represented as 0xFFC00000 would fail
with the message "Unable to cast -4194304 to bigint".  Now the error
message will say "Unable to cast NaN to bigint".
  • Loading branch information
rschlussel committed Aug 1, 2024
1 parent 97eed74 commit 8e95218
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public static long castToLong(@SqlType(StandardTypes.REAL) long value)
return DoubleMath.roundToLong(intBitsToFloat((int) value), HALF_UP);
}
catch (ArithmeticException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to bigint", value), e);
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to bigint", intBitsToFloat((int) value)), e);
}
}

Expand All @@ -136,7 +136,7 @@ public static long castToInteger(@SqlType(StandardTypes.REAL) long value)
return DoubleMath.roundToInt(intBitsToFloat((int) value), HALF_UP);
}
catch (ArithmeticException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to integer", value), e);
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to integer", intBitsToFloat((int) value)), e);
}
}

Expand All @@ -148,7 +148,7 @@ public static long castToSmallint(@SqlType(StandardTypes.REAL) long value)
return Shorts.checkedCast(DoubleMath.roundToInt(intBitsToFloat((int) value), HALF_UP));
}
catch (ArithmeticException | IllegalArgumentException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to smallint", value), e);
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to smallint", intBitsToFloat((int) value)), e);
}
}

Expand All @@ -160,7 +160,7 @@ public static long castToTinyint(@SqlType(StandardTypes.REAL) long value)
return SignedBytes.checkedCast(DoubleMath.roundToInt(intBitsToFloat((int) value), HALF_UP));
}
catch (ArithmeticException | IllegalArgumentException e) {
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to tinyint", value), e);
throw new PrestoException(INVALID_CAST_ARGUMENT, format("Unable to cast %s to tinyint", intBitsToFloat((int) value)), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ public void testCastToBigInt()
assertFunction("CAST(REAL'1.98' as BIGINT)", BIGINT, 2L);
assertFunction("CAST(REAL'-0.0' as BIGINT)", BIGINT, 0L);

assertInvalidFunction("CAST(cast(nan() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(infinity() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(REAL '" + Float.MAX_VALUE + "' as BIGINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(nan() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT, "Unable to cast NaN to bigint");
assertInvalidFunction("CAST(cast(infinity() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT, "Unable to cast Infinity to bigint");
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as BIGINT)", INVALID_CAST_ARGUMENT, "Unable to cast -Infinity to bigint");
assertInvalidFunction("CAST(REAL '" + Float.MAX_VALUE + "' as BIGINT)", INVALID_CAST_ARGUMENT, "Unable to cast 3.4028235E38 to bigint");
}

@Test
Expand All @@ -217,12 +217,12 @@ public void testCastToInteger()
assertFunction("cast(REAL '" + -0x1.0p31 + "' as integer)", INTEGER, (int) -0x1.0p31);
assertFunction("cast(REAL '" + Math.nextUp(-0x1.0p31f) + "' as integer)", INTEGER, (int) Math.nextUp(-0x1.0p31f));

assertInvalidFunction("cast(9.3E9 as integer)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("cast(-9.3E9 as integer)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(nan() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(infinity() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(REAL '" + (Integer.MAX_VALUE + 0.6) + "' as INTEGER)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("cast(9.3E9 as integer)", INVALID_CAST_ARGUMENT, "Unable to cast 9.3E9 to integer");
assertInvalidFunction("cast(-9.3E9 as integer)", INVALID_CAST_ARGUMENT, "Unable to cast -9.3E9 to integer");
assertInvalidFunction("CAST(cast(nan() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT, "Unable to cast NaN to integer");
assertInvalidFunction("CAST(cast(infinity() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT, "Unable to cast Infinity to integer");
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as INTEGER)", INVALID_CAST_ARGUMENT, "Unable to cast -Infinity to integer");
assertInvalidFunction("CAST(REAL '" + (Integer.MAX_VALUE + 0.6) + "' as INTEGER)", INVALID_CAST_ARGUMENT, "Unable to cast 2.14748365E9 to integer");
}

@Test
Expand All @@ -232,10 +232,10 @@ public void testCastToSmallint()
assertFunction("CAST(REAL'-754.1985' AS SMALLINT)", SMALLINT, (short) -754);
assertFunction("CAST(REAL'9.99' AS SMALLINT)", SMALLINT, (short) 10);
assertFunction("CAST(REAL'-0.0' AS SMALLINT)", SMALLINT, (short) 0);
assertInvalidFunction("CAST(cast(nan() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(infinity() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(REAL '" + (Short.MAX_VALUE + 0.6) + "' as SMALLINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(nan() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT, "Unable to cast NaN to smallint");
assertInvalidFunction("CAST(cast(infinity() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT, "Unable to cast Infinity to smallint");
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as SMALLINT)", INVALID_CAST_ARGUMENT, "Unable to cast -Infinity to smallint");
assertInvalidFunction("CAST(REAL '" + (Short.MAX_VALUE + 0.6) + "' as SMALLINT)", INVALID_CAST_ARGUMENT, "Unable to cast 32767.6 to smallint");
}

@Test
Expand All @@ -245,10 +245,10 @@ public void testCastToTinyint()
assertFunction("CAST(REAL'-128.234' AS TINYINT)", TINYINT, (byte) -128);
assertFunction("CAST(REAL'9.99' AS TINYINT)", TINYINT, (byte) 10);
assertFunction("CAST(REAL'-0.0' AS TINYINT)", TINYINT, (byte) 0);
assertInvalidFunction("CAST(cast(nan() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(infinity() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(REAL '" + (Byte.MAX_VALUE + 0.6) + "' as TINYINT)", INVALID_CAST_ARGUMENT);
assertInvalidFunction("CAST(cast(nan() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT, "Unable to cast NaN to tinyint");
assertInvalidFunction("CAST(cast(infinity() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT, "Unable to cast Infinity to tinyint");
assertInvalidFunction("CAST(cast(-infinity() AS REAL) as TINYINT)", INVALID_CAST_ARGUMENT, "Unable to cast -Infinity to tinyint");
assertInvalidFunction("CAST(REAL '" + (Byte.MAX_VALUE + 0.6) + "' as TINYINT)", INVALID_CAST_ARGUMENT, "Unable to cast 127.6 to tinyint");
}

@Test
Expand Down

0 comments on commit 8e95218

Please sign in to comment.