SQL: Fix issue with common type resolution (#46565)

Many scalar functions try to find out the common type between their
arguments in order to set it as their return time, e.g.:
for `float + double` the common type which is set as the return type
of the + operation is `double`.

Previously, for data types TEXT and KEYWORD (string data types) there
was no common data type found and null was returned causing NPEs when
the function was trying to resolve the return data type.

Fixes: #46551
(cherry picked from commit 291017d69dfc810707c3c7c692f5a50af431b790)
This commit is contained in:
Marios Trivyzas 2019-09-11 18:27:04 +03:00
parent 043471c643
commit 0963e78164
2 changed files with 11 additions and 1 deletions

View File

@ -23,6 +23,7 @@ import static org.elasticsearch.xpack.sql.type.DataType.DATE;
import static org.elasticsearch.xpack.sql.type.DataType.DATETIME;
import static org.elasticsearch.xpack.sql.type.DataType.LONG;
import static org.elasticsearch.xpack.sql.type.DataType.NULL;
import static org.elasticsearch.xpack.sql.type.DataType.TEXT;
import static org.elasticsearch.xpack.sql.type.DataType.TIME;
/**
@ -50,6 +51,12 @@ public abstract class DataTypeConversion {
if (DataTypes.isNull(right)) {
return left;
}
if (left.isString() && right.isString()) {
if (left == TEXT) {
return TEXT;
}
return right;
}
if (left.isNumeric() && right.isNumeric()) {
// if one is int
if (left.isInteger()) {

View File

@ -621,12 +621,15 @@ public class DataTypeConversionTests extends ESTestCase {
assertEquals(NULL, commonType(NULL, NULL));
assertEquals(INTEGER, commonType(INTEGER, KEYWORD));
assertEquals(LONG, commonType(TEXT, LONG));
assertNull(commonType(TEXT, KEYWORD));
assertEquals(SHORT, commonType(SHORT, BYTE));
assertEquals(FLOAT, commonType(BYTE, FLOAT));
assertEquals(FLOAT, commonType(FLOAT, INTEGER));
assertEquals(DOUBLE, commonType(DOUBLE, FLOAT));
// strings
assertEquals(TEXT, commonType(TEXT, KEYWORD));
assertEquals(TEXT, commonType(KEYWORD, TEXT));
// numeric and intervals
assertEquals(INTERVAL_YEAR_TO_MONTH, commonType(INTERVAL_YEAR_TO_MONTH, LONG));
assertEquals(INTERVAL_HOUR_TO_MINUTE, commonType(INTEGER, INTERVAL_HOUR_TO_MINUTE));