SQL: Fix string to boolean conversion (elastic/x-pack-elasticsearch#2728)
This commit also adds tests for conversion to boolean Original commit: elastic/x-pack-elasticsearch@d7740929a2
This commit is contained in:
parent
06b4c043b9
commit
7f0c44f138
|
@ -10,6 +10,7 @@ import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
import org.joda.time.format.ISODateTimeFormat;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.function.DoubleFunction;
|
import java.util.function.DoubleFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.LongFunction;
|
import java.util.function.LongFunction;
|
||||||
|
@ -292,6 +293,13 @@ public abstract class DataTypeConversion {
|
||||||
return Math.round(x);
|
return Math.round(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean convertToBoolean(String val) {
|
||||||
|
String lowVal = val.toLowerCase(Locale.ROOT);
|
||||||
|
if (Booleans.isBoolean(lowVal) == false) {
|
||||||
|
throw new SqlIllegalArgumentException("cannot cast [" + val + "] to [Boolean]");
|
||||||
|
}
|
||||||
|
return Booleans.parseBoolean(lowVal);
|
||||||
|
}
|
||||||
public static Object convert(Object value, DataType dataType) {
|
public static Object convert(Object value, DataType dataType) {
|
||||||
DataType detectedType = DataTypes.fromJava(value);
|
DataType detectedType = DataTypes.fromJava(value);
|
||||||
if (detectedType.equals(dataType)) {
|
if (detectedType.equals(dataType)) {
|
||||||
|
@ -333,7 +341,7 @@ public abstract class DataTypeConversion {
|
||||||
STRING_TO_DOUBLE(fromString(Double::valueOf, "Double")),
|
STRING_TO_DOUBLE(fromString(Double::valueOf, "Double")),
|
||||||
STRING_TO_DATE(fromString(UTC_DATE_FORMATTER::parseMillis, "Date")),
|
STRING_TO_DATE(fromString(UTC_DATE_FORMATTER::parseMillis, "Date")),
|
||||||
NUMERIC_TO_BOOLEAN(fromLong(value -> value != 0)),
|
NUMERIC_TO_BOOLEAN(fromLong(value -> value != 0)),
|
||||||
STRING_TO_BOOLEAN(fromString(Booleans::isBoolean, "Boolean")), // NOCOMMIT probably wrong
|
STRING_TO_BOOLEAN(fromString(DataTypeConversion::convertToBoolean, "Boolean")),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final Function<Object, Object> converter;
|
private final Function<Object, Object> converter;
|
||||||
|
|
|
@ -93,4 +93,50 @@ public class DataTypeConversionTests extends ESTestCase {
|
||||||
assertEquals("cannot cast [0xff] to [Double]", e.getMessage());
|
assertEquals("cannot cast [0xff] to [Double]", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testConversionToBoolean() {
|
||||||
|
{
|
||||||
|
Conversion conversion = DataTypeConversion.conversionFor(new FloatType(true), new BooleanType(true));
|
||||||
|
assertNull(conversion.convert(null));
|
||||||
|
assertEquals(true, conversion.convert(10.0f));
|
||||||
|
assertEquals(true, conversion.convert(-10.0f));
|
||||||
|
assertEquals(false, conversion.convert(0.0f));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Conversion conversion = DataTypeConversion.conversionFor(new IntegerType(true), new BooleanType(true));
|
||||||
|
assertNull(conversion.convert(null));
|
||||||
|
assertEquals(true, conversion.convert(10));
|
||||||
|
assertEquals(true, conversion.convert(-10));
|
||||||
|
assertEquals(false, conversion.convert(0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Conversion conversion = DataTypeConversion.conversionFor(new DoubleType(true), new BooleanType(true));
|
||||||
|
assertNull(conversion.convert(null));
|
||||||
|
assertEquals(true, conversion.convert(10.0));
|
||||||
|
assertEquals(true, conversion.convert(-10.0));
|
||||||
|
assertEquals(false, conversion.convert(0.0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Conversion conversion = DataTypeConversion.conversionFor(KeywordType.DEFAULT, new BooleanType(true));
|
||||||
|
assertNull(conversion.convert(null));
|
||||||
|
// We only handled upper and lower case true and false
|
||||||
|
assertEquals(true, conversion.convert("true"));
|
||||||
|
assertEquals(false, conversion.convert("false"));
|
||||||
|
assertEquals(true, conversion.convert("True"));
|
||||||
|
assertEquals(false, conversion.convert("fAlSe"));
|
||||||
|
// Everything else should fail
|
||||||
|
Exception e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("10"));
|
||||||
|
assertEquals("cannot cast [10] to [Boolean]", e.getMessage());
|
||||||
|
e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("-1"));
|
||||||
|
assertEquals("cannot cast [-1] to [Boolean]", e.getMessage());
|
||||||
|
e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("0"));
|
||||||
|
assertEquals("cannot cast [0] to [Boolean]", e.getMessage());
|
||||||
|
e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("blah"));
|
||||||
|
assertEquals("cannot cast [blah] to [Boolean]", e.getMessage());
|
||||||
|
e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("Yes"));
|
||||||
|
assertEquals("cannot cast [Yes] to [Boolean]", e.getMessage());
|
||||||
|
e = expectThrows(SqlIllegalArgumentException.class, () -> conversion.convert("nO"));
|
||||||
|
assertEquals("cannot cast [nO] to [Boolean]", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue