Skip to content

Commit

Permalink
IGNITE-23873 Sql. Fix processing Infinite and NaN values after calcit…
Browse files Browse the repository at this point in the history
…e version was bumped
  • Loading branch information
zstan committed Jan 16, 2025
1 parent 7eb75ec commit 0667281
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;

/**
Expand Down Expand Up @@ -129,6 +130,34 @@ public void exactWithApproxComparison() {
assertQuery("SELECT '1.1'::float > 2").returns(false).check();
}

@ParameterizedTest
@CsvSource({"FLOAT", "REAL", "DOUBLE"})
public void nonFiniteNumerics(String type) {
Number positiveInfinity;
Number negativeInfinity;
Number nan;

if ("DOUBLE".equals(type)) {
positiveInfinity = Double.POSITIVE_INFINITY;
negativeInfinity = Double.NEGATIVE_INFINITY;
nan = Double.NaN;
} else {
positiveInfinity = Float.POSITIVE_INFINITY;
negativeInfinity = Float.NEGATIVE_INFINITY;
nan = Float.NaN;
}

assertQuery(format("select CAST('+Infinity' AS {})", type)).returns(positiveInfinity).check();
assertQuery(format("select CAST('Infinity' AS {})", type)).returns(positiveInfinity).check();
assertQuery(format("select CAST('-Infinity' AS {})", type)).returns(negativeInfinity).check();
assertQuery(format("select CAST('NaN' AS {})", type)).returns(nan).check();

assertQuery(format("SELECT * FROM (VALUES(0)) AS t(k) WHERE k < CAST('+Infinity' AS REAL)", type)).returns(0).check();
assertQuery(format("SELECT * FROM (VALUES(0)) AS t(k) WHERE k < CAST('Infinity' AS REAL)", type)).returns(0).check();
assertQuery(format("SELECT * FROM (VALUES(0)) AS t(k) WHERE k > CAST('-Infinity' AS REAL)", type)).returns(0).check();
assertQuery(format("SELECT * FROM (VALUES(0)) AS t(k) WHERE k <> CAST('NaN' AS REAL)", type)).returns(0).check();
}

@WithSystemProperty(key = "IMPLICIT_PK_ENABLED", value = "true")
@ParameterizedTest()
@MethodSource("exactDecimalTypes")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -881,12 +881,6 @@ RexNode toRex(RelInput relInput, Object o) {
literal = new BigDecimal(((Number) literal).longValue());
}

// Stub, it need to be fixed https://issues.apache.org/jira/browse/IGNITE-23873
if (type.getSqlTypeName() == SqlTypeName.DOUBLE && literal instanceof String
&& Double.isNaN(Double.parseDouble(literal.toString()))) {
literal = Double.NaN;
}

if (literal instanceof BigInteger) {
// If the literal is a BigInteger, RexBuilder assumes it represents a long value
// within the valid range and converts it without checking the bounds. If the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,37 @@ public RexNode makeLiteral(@Nullable Object value, RelDataType type, boolean all
// IgniteCustomType: Not comparable types are not supported.
assert value instanceof Comparable : "Not comparable IgniteCustomType:" + type + ". value: " + value;
return makeLiteral((Comparable<?>) value, type, type.getSqlTypeName());
} else if (value != null && type.getSqlTypeName() == SqlTypeName.CHAR) {
if (type.isNullable()) {
RelDataType typeNotNull =
typeFactory.createTypeWithNullability(type, false);
if (allowCast) {
RexNode literalNotNull = makeLiteral(value, typeNotNull, allowCast);
return makeAbstractCast(type, literalNotNull, false);
}

if (value != null) {
if (type.getSqlTypeName() == SqlTypeName.CHAR) {
if (type.isNullable()) {
RelDataType typeNotNull =
typeFactory.createTypeWithNullability(type, false);
if (allowCast) {
RexNode literalNotNull = makeLiteral(value, typeNotNull, allowCast);
return makeAbstractCast(type, literalNotNull, false);
}
}
}

NlsString string;
if (value instanceof NlsString) {
string = (NlsString) value;
} else {
assert type.getCharset() != null : type + ".getCharset() must not be null";
string = new NlsString((String) value, type.getCharset().name(), type.getCollation());
}
NlsString string;
if (value instanceof NlsString) {
string = (NlsString) value;
} else {
assert type.getCharset() != null : type + ".getCharset() must not be null";
string = new NlsString((String) value, type.getCharset().name(), type.getCollation());
}

return makeCharLiteral(string);
} else {
return super.makeLiteral(value, type, allowCast, trim);
return makeCharLiteral(string);
} else if (value instanceof String) {
if (type.getSqlTypeName() == SqlTypeName.DOUBLE) {
value = Double.parseDouble((String) value);
} else if (type.getSqlTypeName() == SqlTypeName.REAL || type.getSqlTypeName() == SqlTypeName.FLOAT) {
value = Float.parseFloat((String) value);
}
}
}

return super.makeLiteral(value, type, allowCast, trim);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ public static float convertToFloatExact(Number x) {
return value.floatValue();
} else {
double v = x.doubleValue();

if (!Double.isFinite(v)) {
return x.floatValue();
}

if (v > UPPER_FLOAT_DOUBLE || v < LOWER_FLOAT_DOUBLE) {
throw outOfRangeForTypeException(SqlTypeName.REAL);
}
Expand Down

0 comments on commit 0667281

Please sign in to comment.