QL: constant_keyword support (#53241) (#53602)

(cherry picked from commit d6cd4ce7849ba215407c8c5fa815c9b373fb8480)
This commit is contained in:
Andrei Stefan 2020-03-16 18:06:31 +02:00 committed by GitHub
parent dc2edc97f0
commit 91ca9c5c33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 497 additions and 127 deletions

View File

@ -13,21 +13,22 @@ s|SQL precision
4+h| Core types
| <<null-value, `null`>> | null | NULL | 0
| <<boolean, `boolean`>> | boolean | BOOLEAN | 1
| <<number, `byte`>> | byte | TINYINT | 3
| <<number, `short`>> | short | SMALLINT | 5
| <<number, `integer`>> | integer | INTEGER | 10
| <<number, `long`>> | long | BIGINT | 19
| <<number, `double`>> | double | DOUBLE | 15
| <<number, `float`>> | float | REAL | 7
| <<number, `half_float`>> | half_float | FLOAT | 3
| <<number, `scaled_float`>> | scaled_float | DOUBLE | 15
| <<keyword, `keyword`>> | keyword | VARCHAR | 32,766
| <<text, `text`>> | text | VARCHAR | 2,147,483,647
| <<binary, `binary`>> | binary | VARBINARY | 2,147,483,647
| <<date, `date`>> | datetime | TIMESTAMP | 29
| <<ip, `ip`>> | ip | VARCHAR | 39
| <<null-value, `null`>> | null | NULL | 0
| <<boolean, `boolean`>> | boolean | BOOLEAN | 1
| <<number, `byte`>> | byte | TINYINT | 3
| <<number, `short`>> | short | SMALLINT | 5
| <<number, `integer`>> | integer | INTEGER | 10
| <<number, `long`>> | long | BIGINT | 19
| <<number, `double`>> | double | DOUBLE | 15
| <<number, `float`>> | float | REAL | 7
| <<number, `half_float`>> | half_float | FLOAT | 3
| <<number, `scaled_float`>> | scaled_float | DOUBLE | 15
| <<keyword, `keyword`>> | keyword | VARCHAR | 32,766
| <<constant-keyword, `constant_keyword`>> | constant_keyword| VARCHAR | 32,766
| <<text, `text`>> | text | VARCHAR | 2,147,483,647
| <<binary, `binary`>> | binary | VARBINARY | 2,147,483,647
| <<date, `date`>> | datetime | TIMESTAMP | 29
| <<ip, `ip`>> | ip | VARCHAR | 39
4+h| Complex types

View File

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.SCALED_FLOAT;
@ -213,6 +214,7 @@ public abstract class AbstractFieldHitExtractor implements HitExtractor {
protected boolean isFromDocValuesOnly(DataType dataType) {
return dataType == KEYWORD // because of ignore_above.
|| dataType == DATETIME
|| dataType == CONSTANT_KEYWORD // because a non-existent value is considered the constant value itself
|| dataType == SCALED_FLOAT; // because of scaling_factor
}

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import org.elasticsearch.xpack.ql.type.ConstantKeywordEsField;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.DataTypeRegistry;
import org.elasticsearch.xpack.ql.type.DateEsField;
@ -60,6 +61,7 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static org.elasticsearch.action.ActionListener.wrap;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.OBJECT;
@ -298,8 +300,13 @@ public class IndexResolver {
StringBuilder errorMessage = new StringBuilder();
boolean hasUnmapped = types.containsKey(UNMAPPED);
// a keyword field and a constant_keyword field with the same name in two different indices are considered "compatible"
// since a common use case of constant_keyword field involves two indices with a field having the same name: one being
// a keyword, the other being a constant_keyword
boolean hasCompatibleKeywords = types.containsKey(KEYWORD.esType()) && types.containsKey(CONSTANT_KEYWORD.esType());
int allowedTypesCount = (hasUnmapped ? 2 : 1) + (hasCompatibleKeywords ? 1 : 0);
if (types.size() > (hasUnmapped ? 2 : 1)) {
if (types.size() > allowedTypesCount) {
// build the error message
// and create a MultiTypeField
@ -344,6 +351,11 @@ public class IndexResolver {
}
}
// if there are both a keyword and a constant_keyword type for this field, only keep the keyword as a common compatible type
if (hasCompatibleKeywords) {
types.remove(CONSTANT_KEYWORD.esType());
}
// everything checks
return null;
});
@ -435,6 +447,9 @@ public class IndexResolver {
if (esType == DATETIME) {
return new DateEsField(fieldName, props, isAggregateable);
}
if (esType == CONSTANT_KEYWORD) {
return new ConstantKeywordEsField(fieldName);
}
if (esType == UNSUPPORTED) {
return new UnsupportedEsField(fieldName, typeName, null, props);
}
@ -501,14 +516,14 @@ public class IndexResolver {
for (Entry<String, Map<String, FieldCapabilities>> entry : sortedFields) {
String fieldName = entry.getKey();
Map<String, FieldCapabilities> types = entry.getValue();
// ignore size added by the mapper plugin
if (FIELD_NAMES_BLACKLIST.contains(fieldName)) {
continue;
}
// apply verification
Map<String, FieldCapabilities> types = new LinkedHashMap<>(entry.getValue());
// apply verification and possibly remove the "duplicate" CONSTANT_KEYWORD field type
final InvalidMappedField invalidField = validityVerifier.apply(fieldName, types);
// filter meta fields and unmapped

View File

@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.ql.type;
import java.util.Collections;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
/**
* SQL-related information about an index field with a constant_keyword type
*/
public class ConstantKeywordEsField extends KeywordEsField {
public ConstantKeywordEsField(String name) {
super(name, CONSTANT_KEYWORD, Collections.emptyMap(), true, Short.MAX_VALUE, false, false);
}
}

View File

@ -21,6 +21,7 @@ import java.util.function.LongFunction;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.BYTE;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.DOUBLE;
import static org.elasticsearch.xpack.ql.type.DataTypes.FLOAT;
@ -59,9 +60,12 @@ public final class DataTypeConverter {
return left;
}
if (isString(left) && isString(right)) {
if (left == TEXT) {
if (left == TEXT || right == TEXT) {
return TEXT;
}
if (left == KEYWORD) {
return KEYWORD;
}
return right;
}
if (left.isNumeric() && right.isNumeric()) {
@ -120,7 +124,7 @@ public final class DataTypeConverter {
return DefaultConverter.TO_NULL;
}
// proper converters
if (to == KEYWORD || to == TEXT) {
if (to == KEYWORD || to == TEXT || to == CONSTANT_KEYWORD) {
return conversionToString(from);
}
if (to == LONG) {

View File

@ -20,33 +20,34 @@ import static java.util.stream.Collectors.toMap;
public final class DataTypes {
// @formatter:off
public static final DataType UNSUPPORTED = new DataType("UNSUPPORTED", null, 0, false, false, false);
public static final DataType UNSUPPORTED = new DataType("UNSUPPORTED", null, 0, false, false, false);
public static final DataType NULL = new DataType("null", 0, false, false, false);
public static final DataType NULL = new DataType("null", 0, false, false, false);
public static final DataType BOOLEAN = new DataType("boolean", 1, false, false, false);
public static final DataType BOOLEAN = new DataType("boolean", 1, false, false, false);
// integer numeric
public static final DataType BYTE = new DataType("byte", Byte.BYTES, true, false, true);
public static final DataType SHORT = new DataType("short", Short.BYTES, true, false, true);
public static final DataType INTEGER = new DataType("integer", Integer.BYTES, true, false, true);
public static final DataType LONG = new DataType("long", Long.BYTES, true, false, true);
public static final DataType BYTE = new DataType("byte", Byte.BYTES, true, false, true);
public static final DataType SHORT = new DataType("short", Short.BYTES, true, false, true);
public static final DataType INTEGER = new DataType("integer", Integer.BYTES, true, false, true);
public static final DataType LONG = new DataType("long", Long.BYTES, true, false, true);
// decimal numeric
public static final DataType DOUBLE = new DataType("double", Double.BYTES, false, true, true);
public static final DataType FLOAT = new DataType("float", Float.BYTES, false, true, true);
public static final DataType HALF_FLOAT = new DataType("half_float", Float.BYTES, false, true, true);
public static final DataType SCALED_FLOAT = new DataType("scaled_float", Long.BYTES, false, true, true);
public static final DataType DOUBLE = new DataType("double", Double.BYTES, false, true, true);
public static final DataType FLOAT = new DataType("float", Float.BYTES, false, true, true);
public static final DataType HALF_FLOAT = new DataType("half_float", Float.BYTES, false, true, true);
public static final DataType SCALED_FLOAT = new DataType("scaled_float", Long.BYTES, false, true, true);
// string
public static final DataType KEYWORD = new DataType("keyword", Integer.MAX_VALUE, false, false, true);
public static final DataType TEXT = new DataType("text", Integer.MAX_VALUE, false, false, false);
public static final DataType KEYWORD = new DataType("keyword", Integer.MAX_VALUE, false, false, true);
public static final DataType TEXT = new DataType("text", Integer.MAX_VALUE, false, false, false);
public static final DataType CONSTANT_KEYWORD = new DataType("constant_keyword", Integer.MAX_VALUE, false, false, true);
// date
public static final DataType DATETIME = new DataType("DATETIME", "date", Long.BYTES, false, false, true);
public static final DataType DATETIME = new DataType("DATETIME", "date", Long.BYTES, false, false, true);
// ip
public static final DataType IP = new DataType("ip", 45, false, false, true);
// binary
public static final DataType BINARY = new DataType("binary", Integer.MAX_VALUE, false, false, true);
public static final DataType BINARY = new DataType("binary", Integer.MAX_VALUE, false, false, true);
// complex types
public static final DataType OBJECT = new DataType("object", 0, false, false, false);
public static final DataType NESTED = new DataType("nested", 0, false, false, false);
public static final DataType OBJECT = new DataType("object", 0, false, false, false);
public static final DataType NESTED = new DataType("nested", 0, false, false, false);
//@formatter:on
private static final Collection<DataType> TYPES = unmodifiableList(Arrays.asList(
@ -63,6 +64,7 @@ public final class DataTypes {
SCALED_FLOAT,
KEYWORD,
TEXT,
CONSTANT_KEYWORD,
DATETIME,
IP,
BINARY,
@ -134,7 +136,7 @@ public final class DataTypes {
}
public static boolean isString(DataType t) {
return t == KEYWORD || t == TEXT;
return t == KEYWORD || t == TEXT || t == CONSTANT_KEYWORD;
}
public static boolean isPrimitive(DataType t) {

View File

@ -29,7 +29,12 @@ public class KeywordEsField extends EsField {
public KeywordEsField(String name, Map<String, EsField> properties, boolean hasDocValues, int precision,
boolean normalized, boolean isAlias) {
super(name, KEYWORD, properties, hasDocValues, isAlias);
this(name, KEYWORD, properties, hasDocValues, precision, normalized, isAlias);
}
protected KeywordEsField(String name, DataType esDataType, Map<String, EsField> properties, boolean hasDocValues, int precision,
boolean normalized, boolean isAlias) {
super(name, esDataType, properties, hasDocValues, isAlias);
this.precision = precision;
this.normalized = normalized;
}

View File

@ -11,6 +11,7 @@ import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.TEXT;
@ -44,7 +45,7 @@ public class TextEsField extends EsField {
private Tuple<EsField, String> findExact() {
EsField field = null;
for (EsField property : getProperties().values()) {
if (property.getDataType() == KEYWORD && property.getExactInfo().hasExact()) {
if ((property.getDataType() == KEYWORD || property.getDataType() == CONSTANT_KEYWORD) && property.getExactInfo().hasExact()) {
if (field != null) {
return new Tuple<>(null, "Multiple exact keyword candidates available for [" + getName() +
"]; specify which one to use");

View File

@ -14,6 +14,7 @@ import java.util.Map;
import java.util.Map.Entry;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.NESTED;
@ -89,6 +90,8 @@ public abstract class Types {
int length = intSetting(content.get("ignore_above"), Short.MAX_VALUE);
boolean normalized = Strings.hasText(textSetting(content.get("normalizer"), null));
field = new KeywordEsField(name, properties, docValues, length, normalized);
} else if (esDataType == CONSTANT_KEYWORD) {
field = new ConstantKeywordEsField(name);
} else if (esDataType == DATETIME) {
field = new DateEsField(name, properties, docValues);
} else if (esDataType == UNSUPPORTED) {

View File

@ -17,6 +17,7 @@ import static org.elasticsearch.xpack.ql.type.DataTypeConverter.commonType;
import static org.elasticsearch.xpack.ql.type.DataTypeConverter.converterFor;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.BYTE;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.DOUBLE;
import static org.elasticsearch.xpack.ql.type.DataTypes.FLOAT;
@ -360,6 +361,7 @@ public class DataTypeConversionTests extends ESTestCase {
assertEquals(BOOLEAN, commonType(BOOLEAN, BOOLEAN));
assertEquals(NULL, commonType(NULL, NULL));
assertEquals(INTEGER, commonType(INTEGER, KEYWORD));
assertEquals(DOUBLE, commonType(DOUBLE, CONSTANT_KEYWORD));
assertEquals(LONG, commonType(TEXT, LONG));
assertEquals(SHORT, commonType(SHORT, BYTE));
assertEquals(FLOAT, commonType(BYTE, FLOAT));
@ -369,6 +371,11 @@ public class DataTypeConversionTests extends ESTestCase {
// strings
assertEquals(TEXT, commonType(TEXT, KEYWORD));
assertEquals(TEXT, commonType(KEYWORD, TEXT));
assertEquals(TEXT, commonType(TEXT, CONSTANT_KEYWORD));
assertEquals(TEXT, commonType(CONSTANT_KEYWORD, TEXT));
assertEquals(KEYWORD, commonType(KEYWORD, CONSTANT_KEYWORD));
assertEquals(KEYWORD, commonType(CONSTANT_KEYWORD, KEYWORD));
assertEquals(CONSTANT_KEYWORD, commonType(CONSTANT_KEYWORD, CONSTANT_KEYWORD));
}
public void testEsDataTypes() {

View File

@ -14,6 +14,7 @@ import java.io.InputStream;
import java.util.Map;
import static java.util.Collections.emptyMap;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.INTEGER;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
@ -135,9 +136,10 @@ public class TypesTests extends ESTestCase {
assertThat(DataTypes.isPrimitive(field.getDataType()), is(true));
assertThat(field.getDataType(), is(TEXT));
Map<String, EsField> fields = field.getProperties();
assertThat(fields.size(), is(2));
assertThat(fields.size(), is(3));
assertThat(fields.get("raw").getDataType(), is(KEYWORD));
assertThat(fields.get("english").getDataType(), is(TEXT));
assertThat(fields.get("constant").getDataType(), is(CONSTANT_KEYWORD));
}
public void testMultiFieldTooManyOptions() {
@ -148,9 +150,10 @@ public class TypesTests extends ESTestCase {
assertThat(DataTypes.isPrimitive(field.getDataType()), is(true));
assertThat(field, instanceOf(TextEsField.class));
Map<String, EsField> fields = field.getProperties();
assertThat(fields.size(), is(2));
assertThat(fields.size(), is(3));
assertThat(fields.get("raw").getDataType(), is(KEYWORD));
assertThat(fields.get("english").getDataType(), is(TEXT));
assertThat(fields.get("constant").getDataType(), is(CONSTANT_KEYWORD));
}
public void testNestedDoc() {
@ -173,6 +176,13 @@ public class TypesTests extends ESTestCase {
assertThat(dt.getDataType().typeName(), is("ip"));
}
public void testConstantKeywordField() {
Map<String, EsField> mapping = loadMapping("mapping-constant-keyword.json");
assertThat(mapping.size(), is(1));
EsField dt = mapping.get("full_name");
assertThat(dt.getDataType().typeName(), is("constant_keyword"));
}
public void testUnsupportedTypes() {
Map<String, EsField> mapping = loadMapping("mapping-unsupported.json");
EsField dt = mapping.get("range");

View File

@ -0,0 +1,8 @@
{
"properties" : {
"full_name" : {
"type" : "constant_keyword",
"value" : "foo"
}
}
}

View File

@ -9,6 +9,10 @@
"english" : {
"type" : "text",
"analyzer" : "english"
},
"constant" : {
"type" : "constant_keyword",
"value" : "some constant value"
}
}
}

View File

@ -25,6 +25,7 @@ public enum EsType implements SQLType {
SCALED_FLOAT( Types.FLOAT),
KEYWORD( Types.VARCHAR),
TEXT( Types.VARCHAR),
CONSTANT_KEYWORD( Types.VARCHAR),
OBJECT( Types.STRUCT),
NESTED( Types.STRUCT),
BINARY( Types.VARBINARY),

View File

@ -210,6 +210,7 @@ final class TypeConverter {
case BOOLEAN:
case TEXT:
case KEYWORD:
case CONSTANT_KEYWORD:
return v; // These types are already represented correctly in JSON
case BYTE:
return ((Number) v).byteValue(); // Parser might return it as integer or long - need to update to the correct type
@ -323,6 +324,7 @@ final class TypeConverter {
return Boolean.valueOf(Integer.signum(((Number) val).intValue()) != 0);
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
return Boolean.valueOf((String) val);
default:
return failConversion(val, columnType, typeString, Boolean.class);
@ -345,6 +347,7 @@ final class TypeConverter {
return safeToByte(safeToLong(((Number) val).doubleValue()));
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Byte.valueOf((String) val);
} catch (NumberFormatException e) {
@ -372,6 +375,7 @@ final class TypeConverter {
return safeToShort(safeToLong(((Number) val).doubleValue()));
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Short.valueOf((String) val);
} catch (NumberFormatException e) {
@ -398,6 +402,7 @@ final class TypeConverter {
return safeToInt(safeToLong(((Number) val).doubleValue()));
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Integer.valueOf((String) val);
} catch (NumberFormatException e) {
@ -429,6 +434,7 @@ final class TypeConverter {
// return ((Number) val).longValue();
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Long.valueOf((String) val);
} catch (NumberFormatException e) {
@ -456,6 +462,7 @@ final class TypeConverter {
return Float.valueOf(((Number) val).floatValue());
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Float.valueOf((String) val);
} catch (NumberFormatException e) {
@ -482,6 +489,7 @@ final class TypeConverter {
return Double.valueOf(((Number) val).doubleValue());
case KEYWORD:
case TEXT:
case CONSTANT_KEYWORD:
try {
return Double.valueOf((String) val);
} catch (NumberFormatException e) {

View File

@ -76,6 +76,7 @@ final class TypeUtils {
types.put(EsType.SCALED_FLOAT, Double.class);
types.put(EsType.KEYWORD, String.class);
types.put(EsType.TEXT, String.class);
types.put(EsType.CONSTANT_KEYWORD, String.class);
types.put(EsType.BINARY, byte[].class);
types.put(EsType.DATETIME, Timestamp.class);
types.put(EsType.IP, String.class);
@ -157,7 +158,7 @@ final class TypeUtils {
}
static boolean isString(EsType dataType) {
return dataType == EsType.KEYWORD || dataType == EsType.TEXT;
return dataType == EsType.KEYWORD || dataType == EsType.TEXT || dataType == EsType.CONSTANT_KEYWORD;
}
static EsType of(Class<? extends Object> clazz) throws SQLException {

View File

@ -103,6 +103,40 @@ public abstract class FieldExtractorTestCase extends BaseRestSqlTestCase {
assertResponse(expected, runSql("SELECT keyword_field FROM test"));
}
/*
* "constant_keyword_field": {
* "type": "constant_keyword",
* "value": "foo"
* }
*/
public void testConstantKeywordField() throws IOException {
String value = randomAlphaOfLength(20);
// _source for `constant_keyword` fields doesn't matter, as they should be taken from docvalue_fields
boolean explicitSourceSetting = randomBoolean(); // default (no _source setting) or explicit setting
boolean enableSource = randomBoolean(); // enable _source at index level
Map<String, Object> indexProps = new HashMap<>(1);
indexProps.put("_source", enableSource);
Map<String, Map<String, Object>> fieldProps = null;
if (randomBoolean()) {
fieldProps = new HashMap<>(1);
Map<String, Object> fieldProp = new HashMap<>(1);
fieldProp.put("value", value);
fieldProps.put("constant_keyword_field", fieldProp);
}
createIndexWithFieldTypeAndProperties("constant_keyword", fieldProps, explicitSourceSetting ? indexProps : null);
index("{\"constant_keyword_field\":\"" + value + "\"}");
Map<String, Object> expected = new HashMap<>();
expected.put("columns", Arrays.asList(
columnInfo("plain", "constant_keyword_field", "constant_keyword", JDBCType.VARCHAR, Integer.MAX_VALUE)
));
expected.put("rows", singletonList(singletonList(value)));
assertResponse(expected, runSql("SELECT constant_keyword_field FROM test"));
}
/*
* "long/integer/short/byte_field": {
* "type": "long/integer/short/byte"

View File

@ -123,13 +123,11 @@ public class DataLoader {
createString("first_name", createIndex);
createString("last_name", createIndex);
createIndex.startObject("gender").field("type", "keyword");
if (extraFields) {
createIndex.field("copy_to", "extra_gender");
}
createIndex.endObject();
if (extraFields) {
createIndex.startObject("extra_gender").field("type", "keyword").endObject();
createIndex.startObject("extra_gender").field("type", "constant_keyword").endObject();
createIndex.startObject("null_constant").field("type", "constant_keyword").endObject();
createIndex.startObject("extra.info.gender")
.field("type", "alias")
.field("path", "gender")
@ -198,6 +196,9 @@ public class DataLoader {
}
hadLastItem = true;
bulk.append('"').append(titles.get(f)).append("\":\"").append(fields.get(f)).append('"');
if (titles.get(f).equals("gender") && extraFields) {
bulk.append(",\"extra_gender\":\"Female\"");
}
}
}
// append department

View File

@ -41,7 +41,7 @@ emp_no |INTEGER |integer
extra |STRUCT |object
extra.info |STRUCT |object
extra.info.gender |VARCHAR |keyword
extra_gender |VARCHAR |keyword
extra_gender |VARCHAR |constant_keyword
extra_no |INTEGER |integer
first_name |VARCHAR |text
first_name.keyword |VARCHAR |keyword
@ -50,6 +50,7 @@ hire_date |TIMESTAMP |datetime
languages |TINYINT |byte
last_name |VARCHAR |text
last_name.keyword |VARCHAR |keyword
null_constant |VARCHAR |constant_keyword
salary |INTEGER |integer
;
@ -69,7 +70,7 @@ emp_no |INTEGER |integer
extra |STRUCT |object
extra.info |STRUCT |object
extra.info.gender |VARCHAR |keyword
extra_gender |VARCHAR |keyword
extra_gender |VARCHAR |constant_keyword
extra_no |INTEGER |integer
first_name |VARCHAR |text
first_name.keyword |VARCHAR |keyword
@ -78,6 +79,7 @@ hire_date |TIMESTAMP |datetime
languages |TINYINT |byte
last_name |VARCHAR |text
last_name.keyword |VARCHAR |keyword
null_constant |VARCHAR |constant_keyword
salary |INTEGER |integer
;

View File

@ -276,7 +276,7 @@ emp_no |INTEGER |integer
extra |STRUCT |object
extra.info |STRUCT |object
extra.info.gender |VARCHAR |keyword
extra_gender |VARCHAR |keyword
extra_gender |VARCHAR |constant_keyword
extra_no |INTEGER |integer
first_name |VARCHAR |text
first_name.keyword |VARCHAR |keyword
@ -285,6 +285,7 @@ hire_date |TIMESTAMP |datetime
languages |TINYINT |byte
last_name |VARCHAR |text
last_name.keyword |VARCHAR |keyword
null_constant |VARCHAR |constant_keyword
salary |INTEGER |integer
;
@ -304,7 +305,7 @@ emp_no |INTEGER |integer
extra |STRUCT |object
extra.info |STRUCT |object
extra.info.gender |VARCHAR |keyword
extra_gender |VARCHAR |keyword
extra_gender |VARCHAR |constant_keyword
extra_no |INTEGER |integer
first_name |VARCHAR |text
first_name.keyword |VARCHAR |keyword
@ -313,6 +314,7 @@ hire_date |TIMESTAMP |datetime
languages |TINYINT |byte
last_name |VARCHAR |text
last_name.keyword |VARCHAR |keyword
null_constant |VARCHAR |constant_keyword
salary |INTEGER |integer
;

View File

@ -0,0 +1,163 @@
// To mute tests follow example in file: example.csv-spec
//
// Tests testing constant_keyword (introduced in ES 7.7)
//
// filtering
filterEquals
SELECT extra_gender g FROM "test_emp_copy" WHERE g = 'Female' LIMIT 5;
g
---------------
Female
Female
Female
Female
Female
;
filterNotEquals
SELECT COUNT(*) AS c FROM "test_emp_copy" WHERE extra_gender <> 'Female';
c:l
---------------
0
;
aggWithNullFilter
SELECT COUNT(*) count FROM test_emp_copy WHERE extra_gender IS NOT NULL;
count:l
---------------
100
;
// Awaits for https://github.com/elastic/elasticsearch/issues/53545
aggWithNullFilter-Ignore
SELECT COUNT(*) count FROM test_emp_copy WHERE null_constant IS NULL;
count:l
---------------
100
;
functionOverAlias
SELECT BIT_LENGTH(extra_gender) bit FROM test_emp_copy ORDER BY extra_gender LIMIT 1;
bit
---------------
48
;
singlePercentileWithoutComma
SELECT extra_gender AS gender, PERCENTILE(emp_no, 97) p1 FROM test_emp_copy GROUP BY extra_gender;
gender:s | p1:d
Female |10097.5
;
percentileRank
SELECT extra_gender AS gender, PERCENTILE_RANK(emp_no, 10025) rank FROM test_emp_copy GROUP BY extra_gender;
gender:s | rank:d
---------------+---------------
Female |24.5
;
aggSumWithAliasWithColumnRepeatedWithOrderDesc
SELECT extra_gender AS g, extra_gender, SUM(salary) AS s3, SUM(salary), SUM(salary) AS s5 FROM test_emp_copy GROUP BY extra_gender;
g:s | extra_gender:s | s3:i | SUM(salary):i | s5:i
---------------+----------------+---------------+---------------+---------------
Female |Female |4824855 |4824855 |4824855
;
topHitsAsMinAndMaxAndGroupBy
schema::extra_gender:s|min:s|max:s|first:s|last:s
SELECT extra_gender, MIN(first_name) as min, MAX(first_name) as max, FIRST(first_name) as first, LAST(first_name) as last FROM test_emp_copy GROUP BY extra_gender ORDER BY extra_gender;
extra_gender | min | max | first | last
---------------+---------------+---------------+---------------+---------------
Female |Alejandro |Zvonko |Alejandro |Zvonko
;
medianAbsoluteDeviationOnTwoFields
schema::extra_gender:s|avg:l|mad_s:l|mad_l:d
SELECT extra_gender, FLOOR(AVG(salary)) AS avg, FLOOR(MAD(salary)) AS mad_s, MAD(languages) AS mad_l FROM test_emp_copy GROUP BY extra_gender ORDER BY extra_gender;
extra_gender | avg | mad_s | mad_l
---------------+-------------+-------------+---------------
Female |48248 |10096 |1
;
caseGroupByAndHaving
schema::count:l|extra_gender:s|languages:byte
SELECT count(*) AS count, extra_gender, languages FROM test_emp_copy
GROUP BY 2, 3 HAVING CASE WHEN count(*) > 10 THEN 'many' ELSE 'a few' END = 'many'
ORDER BY 1, 3;
count | extra_gender | languages
---------------+---------------+---------------
15 |Female |1
17 |Female |3
18 |Female |4
19 |Female |2
21 |Female |5
;
whereFieldWithRLikeAndGroupByOrderBy
SELECT last_name l, extra_gender g, COUNT(*) c, MAX(salary) AS sal FROM test_emp_copy WHERE emp_no < 10050 AND (last_name RLIKE 'B.*' OR extra_gender = 'F') GROUP BY g, l ORDER BY sal;
l:s | g:s | c:l | sal:i
---------------+---------------+---------------+---------------
Berztiss |Female |1 |28336
Brender |Female |1 |36051
Bridgland |Female |1 |48942
Bouloucos |Female |1 |58715
Bamford |Female |1 |61805
;
multipleGroupingsAndOrderingByGroupsWithFunctions_2
SELECT first_name f, last_name l, LCASE(extra_gender) g, CONCAT(UCASE(first_name), LCASE(last_name)) c FROM test_emp_copy GROUP BY f, LCASE(extra_gender), l, c ORDER BY c DESC, first_name, l ASC, g LIMIT 3;
f:s | l:s | g:s | c:s
---------------+---------------+---------------+---------------
null |Swan |female |swan
null |Reistad |female |reistad
null |Portugali |female |portugali
;
isNotNullWithCount
SELECT extra_gender IS NOT NULL AS bool, COUNT(*) FROM test_emp_copy GROUP BY extra_gender;
bool:b | COUNT(*):l
------------------------+---------------
true |100
;
likeWithCount1
SELECT COUNT(*) FROM test_emp_copy WHERE extra_gender LIKE 'F%';
COUNT(*):l
---------------
100
;
likeWithCount2
SELECT COUNT(*) FROM test_emp_copy WHERE extra_gender LIKE '%m%';
COUNT(*):l
---------------
100
;
likeWithCount3
SELECT COUNT(*) FROM test_emp_copy WHERE extra_gender NOT LIKE '%m%';
COUNT(*):l
---------------
0
;

View File

@ -29,19 +29,20 @@ SYS COLUMNS TABLE LIKE 'test_emp';
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
---------------+---------------+---------------+--------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+----------------+-----------------+----------------+---------------+---------------+---------------+---------------+----------------+----------------+------------------
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra_gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |16 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
;
sysColumnsWithCatalogAndLike
@ -49,19 +50,20 @@ SYS COLUMNS CATALOG 'integTest' TABLE LIKE 'test\_emp\_copy' ESCAPE '\';
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
---------------+---------------+---------------+-------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+----------------+-----------------+----------------+---------------+---------------+---------------+---------------+----------------+----------------+------------------
integTest |null |test_emp_copy|birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra_gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |16 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy|salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
;
sysColumnsOnAliasWithTableLike
@ -69,55 +71,57 @@ SYS COLUMNS TABLE LIKE 'test\_alias' ESCAPE '\';
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
---------------+---------------+---------------+--------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+----------------+-----------------+----------------+---------------+---------------+---------------+---------------+----------------+----------------+------------------
integTest |null |test_alias |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra_gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |16 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
integTest |null |test_alias |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
;
sysColumnsAllTables
SYS COLUMNS TABLE LIKE '%';
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
---------------+---------------+---------------+------------------+---------------+---------------+---------------+----------------+----------------+-----------------+-----------+---------------+---------------+---------------+------------------+-------------------+------------------+-------------+---------------+---------------+---------------+----------------+------------------+------------------
integTest |null |logs |@timestamp |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |logs |bytes_in |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |2 |YES |null |null |null |null |NO |NO
integTest |null |logs |bytes_out |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |logs |client_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |4 |YES |null |null |null |null |NO |NO
integTest |null |logs |client_port |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |5 |YES |null |null |null |null |NO |NO
integTest |null |logs |dest_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |6 |YES |null |null |null |null |NO |NO
integTest |null |logs |id |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |7 |YES |null |null |null |null |NO |NO
integTest |null |logs |status |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |4 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |5 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra_gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |16 |YES |null |null |null |null |NO |NO
TABLE_CAT:s | TABLE_SCHEM:s| TABLE_NAME:s | COLUMN_NAME:s | DATA_TYPE:i | TYPE_NAME:s | COLUMN_SIZE:i| BUFFER_LENGTH:i|DECIMAL_DIGITS:i|NUM_PREC_RADIX:i | NULLABLE:i| REMARKS:s | COLUMN_DEF:s |SQL_DATA_TYPE:i|SQL_DATETIME_SUB:i|CHAR_OCTET_LENGTH:i|ORDINAL_POSITION:i|IS_NULLABLE:s|SCOPE_CATALOG:s|SCOPE_SCHEMA:s|SCOPE_TABLE:s|SOURCE_DATA_TYPE:sh|IS_AUTOINCREMENT:s|IS_GENERATEDCOLUMN:s
---------------+---------------+---------------+------------------+---------------+----------------+---------------+----------------+----------------+-----------------+-----------+---------------+---------------+---------------+------------------+-------------------+------------------+-------------+---------------+---------------+---------------+----------------+------------------+------------------
integTest |null |logs |@timestamp |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |logs |bytes_in |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |2 |YES |null |null |null |null |NO |NO
integTest |null |logs |bytes_out |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |logs |client_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |4 |YES |null |null |null |null |NO |NO
integTest |null |logs |client_port |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |5 |YES |null |null |null |null |NO |NO
integTest |null |logs |dest_ip |12 |IP |45 |45 |null |null |1 |null |null |12 |0 |null |6 |YES |null |null |null |null |NO |NO
integTest |null |logs |id |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |7 |YES |null |null |null |null |NO |NO
integTest |null |logs |status |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |4 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |5 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |birth_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |1 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |emp_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |3 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra.info.gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |6 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra_gender |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |7 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |extra_no |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |8 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |first_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |9 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |first_name.keyword|12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |10 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |gender |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |11 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |hire_date |93 |DATETIME |29 |8 |null |null |1 |null |null |9 |3 |null |12 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |languages |-6 |BYTE |5 |1 |null |10 |1 |null |null |-6 |0 |null |13 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |last_name |12 |TEXT |2147483647 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |14 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |last_name.keyword |12 |KEYWORD |32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |15 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |null_constant |12 |CONSTANT_KEYWORD|32766 |2147483647 |null |null |1 |null |null |12 |0 |2147483647 |16 |YES |null |null |null |null |NO |NO
integTest |null |test_emp_copy |salary |4 |INTEGER |11 |4 |null |10 |1 |null |null |4 |0 |null |17 |YES |null |null |null |null |NO |NO
;

View File

@ -36,6 +36,7 @@ import static org.elasticsearch.xpack.ql.type.DataTypeConverter.DefaultConverter
import static org.elasticsearch.xpack.ql.type.DataTypeConverter.DefaultConverter.TO_NULL;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.BYTE;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.DOUBLE;
import static org.elasticsearch.xpack.ql.type.DataTypes.FLOAT;
@ -159,7 +160,7 @@ public final class SqlDataTypeConverter {
}
// extend the default converter with DATE and TIME
if (from == DATE || from == TIME) {
if (to == KEYWORD || to == TEXT) {
if (to == KEYWORD || to == TEXT || to == CONSTANT_KEYWORD) {
return conversionToString(from);
}
if (to == LONG) {

View File

@ -30,6 +30,7 @@ import static java.util.stream.Collectors.toMap;
import static org.elasticsearch.xpack.ql.type.DataTypes.BINARY;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.BYTE;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.DOUBLE;
import static org.elasticsearch.xpack.ql.type.DataTypes.FLOAT;
@ -269,6 +270,7 @@ public class SqlDataTypes {
|| dataType == DATE // because of date formats
|| dataType == DATETIME
|| dataType == SCALED_FLOAT // because of scaling_factor
|| dataType == CONSTANT_KEYWORD
|| dataType == GEO_POINT
|| dataType == GEO_SHAPE
|| dataType == SHAPE;
@ -334,6 +336,9 @@ public class SqlDataTypes {
if (dataType == TEXT) {
return JDBCType.VARCHAR;
}
if (dataType == CONSTANT_KEYWORD) {
return JDBCType.VARCHAR;
}
if (dataType == DATETIME) {
return JDBCType.TIMESTAMP;
}
@ -457,6 +462,9 @@ public class SqlDataTypes {
if (dataType == TEXT) {
return 32766;
}
if (dataType == CONSTANT_KEYWORD) {
return 15;
}
if (dataType == DATETIME) {
return 3;
}
@ -577,6 +585,9 @@ public class SqlDataTypes {
if (dataType == TEXT) {
return dataType.size();
}
if (dataType == CONSTANT_KEYWORD) {
return 32766;
}
if (dataType == DATETIME) {
return 29;
}

View File

@ -10,10 +10,12 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.ql.index.EsIndex;
import org.elasticsearch.xpack.ql.index.IndexResolution;
import org.elasticsearch.xpack.ql.index.IndexResolver;
import org.elasticsearch.xpack.ql.type.ConstantKeywordEsField;
import org.elasticsearch.xpack.ql.type.DataType;
import org.elasticsearch.xpack.ql.type.EsField;
import org.elasticsearch.xpack.ql.type.InvalidMappedField;
import org.elasticsearch.xpack.ql.type.KeywordEsField;
import org.elasticsearch.xpack.ql.type.TextEsField;
import org.elasticsearch.xpack.sql.type.SqlDataTypeRegistry;
import java.util.ArrayList;
@ -26,6 +28,7 @@ import java.util.stream.Stream;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.INTEGER;
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
@ -268,6 +271,52 @@ public class IndexResolverTests extends ESTestCase {
((InvalidMappedField) esField).errorMessage());
}
public void testConstantKeywordTwoIndicesScenario() throws Exception {
Map<String, Map<String, FieldCapabilities>> fieldCaps = new HashMap<>();
addFieldCaps(fieldCaps, "name", "text", true, false);
addFieldCaps(fieldCaps, "wheels_count", "constant_keyword", true, true);
addFieldCaps(fieldCaps, "motor", "keyword", true, true);
Map<String, FieldCapabilities> multi = new HashMap<>();
multi.put("keyword", new FieldCapabilities("cycle_type", "keyword", true, true, new String[] { "other_cycles" }, null, null,
Collections.emptyMap()));
multi.put("constant_keyword", new FieldCapabilities("cycle_type", "constant_keyword", true, false, new String[] { "bicycles" },
null, null, Collections.emptyMap()));
fieldCaps.put("cycle_type", multi);
String wildcard = "*";
IndexResolution resolution = mergedMappings(wildcard, new String[] { "other_cycles", "bicycles" }, fieldCaps);
assertTrue(resolution.isValid());
EsIndex esIndex = resolution.get();
assertEquals(wildcard, esIndex.name());
EsField esField = null;
Map<String, EsField> props = esIndex.mapping();
assertEquals(4, props.size());
assertTrue(props.containsKey("cycle_type"));
assertTrue(props.containsKey("name"));
assertTrue(props.containsKey("wheels_count"));
assertTrue(props.containsKey("motor"));
esField = props.get("cycle_type");
assertTrue(esField instanceof KeywordEsField);
assertEquals(KEYWORD, ((KeywordEsField) esField).getDataType());
esField = props.get("name");
assertTrue(esField instanceof TextEsField);
assertEquals(TEXT, ((TextEsField) esField).getDataType());
esField = props.get("wheels_count");
assertTrue(esField instanceof ConstantKeywordEsField);
assertEquals(CONSTANT_KEYWORD, ((ConstantKeywordEsField) esField).getDataType());
esField = props.get("motor");
assertTrue(esField instanceof KeywordEsField);
assertEquals(KEYWORD, ((KeywordEsField) esField).getDataType());
}
public void testSeparateSameMappingDifferentIndices() throws Exception {
Map<String, EsField> oneMapping = loadMapping("mapping-basic.json", true);
Map<String, EsField> sameMapping = loadMapping("mapping-basic.json", true);
@ -383,7 +432,7 @@ public class IndexResolverTests extends ESTestCase {
}
private static boolean isAggregatable(DataType type) {
return type.isNumeric() || type == KEYWORD || type == DATETIME;
return type.isNumeric() || type == KEYWORD || type == DATETIME || type == CONSTANT_KEYWORD;
}
private static class UpdateableFieldCapabilities extends FieldCapabilities {

View File

@ -46,7 +46,7 @@ public class SysTypesTests extends ESTestCase {
Command cmd = sql("SYS TYPES").v1();
List<String> names = asList("BYTE", "LONG", "BINARY", "NULL", "INTEGER", "SHORT", "HALF_FLOAT", "FLOAT", "DOUBLE", "SCALED_FLOAT",
"IP", "KEYWORD", "TEXT", "BOOLEAN", "DATE", "TIME", "DATETIME",
"CONSTANT_KEYWORD", "IP", "KEYWORD", "TEXT", "BOOLEAN", "DATE", "TIME", "DATETIME",
"INTERVAL_YEAR", "INTERVAL_MONTH", "INTERVAL_DAY", "INTERVAL_HOUR", "INTERVAL_MINUTE", "INTERVAL_SECOND",
"INTERVAL_YEAR_TO_MONTH", "INTERVAL_DAY_TO_HOUR", "INTERVAL_DAY_TO_MINUTE", "INTERVAL_DAY_TO_SECOND",
"INTERVAL_HOUR_TO_MINUTE", "INTERVAL_HOUR_TO_SECOND", "INTERVAL_MINUTE_TO_SECOND",
@ -107,7 +107,9 @@ public class SysTypesTests extends ESTestCase {
cmd.execute(session(), wrap(p -> {
SchemaRowSet r = (SchemaRowSet) p.rowSet();
assertEquals(3, r.size());
assertEquals(4, r.size());
assertEquals("CONSTANT_KEYWORD", r.column(0));
assertTrue(r.advanceRow());
assertEquals("IP", r.column(0));
assertTrue(r.advanceRow());
assertEquals("KEYWORD", r.column(0));

View File

@ -22,6 +22,7 @@ import java.time.ZonedDateTime;
import static java.util.stream.Collectors.toList;
import static org.elasticsearch.xpack.ql.type.DataTypes.BOOLEAN;
import static org.elasticsearch.xpack.ql.type.DataTypes.BYTE;
import static org.elasticsearch.xpack.ql.type.DataTypes.CONSTANT_KEYWORD;
import static org.elasticsearch.xpack.ql.type.DataTypes.DATETIME;
import static org.elasticsearch.xpack.ql.type.DataTypes.DOUBLE;
import static org.elasticsearch.xpack.ql.type.DataTypes.FLOAT;
@ -631,6 +632,7 @@ public class SqlDataTypeConverterTests extends ESTestCase {
assertEquals(BOOLEAN, commonType(BOOLEAN, BOOLEAN));
assertEquals(NULL, commonType(NULL, NULL));
assertEquals(INTEGER, commonType(INTEGER, KEYWORD));
assertEquals(DOUBLE, commonType(DOUBLE, CONSTANT_KEYWORD));
assertEquals(LONG, commonType(TEXT, LONG));
assertEquals(SHORT, commonType(SHORT, BYTE));
assertEquals(FLOAT, commonType(BYTE, FLOAT));
@ -640,6 +642,11 @@ public class SqlDataTypeConverterTests extends ESTestCase {
// strings
assertEquals(TEXT, commonType(TEXT, KEYWORD));
assertEquals(TEXT, commonType(KEYWORD, TEXT));
assertEquals(TEXT, commonType(TEXT, CONSTANT_KEYWORD));
assertEquals(TEXT, commonType(CONSTANT_KEYWORD, TEXT));
assertEquals(KEYWORD, commonType(KEYWORD, CONSTANT_KEYWORD));
assertEquals(KEYWORD, commonType(CONSTANT_KEYWORD, KEYWORD));
assertEquals(CONSTANT_KEYWORD, commonType(CONSTANT_KEYWORD, CONSTANT_KEYWORD));
// numeric and intervals
assertEquals(INTERVAL_YEAR_TO_MONTH, commonType(INTERVAL_YEAR_TO_MONTH, LONG));