From bc1884915da8e67419f074dd8b6b151a93855365 Mon Sep 17 00:00:00 2001 From: Marios Trivyzas Date: Mon, 4 Mar 2019 15:29:10 +0100 Subject: [PATCH] SQL: Don't allow inexact fields for MIN/MAX (#39563) MIN/MAX on strings are supported and are implemented with TopAggs FIRST/LAST respectively, but they cannot operate on `text` fields without underlying `keyword` fields => inexact. Follows: #39427 --- .../xpack/sql/expression/function/aggregate/Max.java | 3 ++- .../xpack/sql/expression/function/aggregate/Min.java | 3 ++- .../analyzer/VerifierErrorMessagesTests.java | 12 ++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Max.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Max.java index cd03ea85e4558..5827083343a0f 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Max.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Max.java @@ -13,6 +13,7 @@ import java.util.List; +import static org.elasticsearch.xpack.sql.expression.TypeResolutions.isExact; import static org.elasticsearch.xpack.sql.expression.TypeResolutions.isNumericOrDate; /** @@ -47,7 +48,7 @@ public String innerName() { @Override protected TypeResolution resolveType() { if (field().dataType().isString()) { - return TypeResolution.TYPE_RESOLVED; + return isExact(field(), sourceText(), ParamOrdinal.DEFAULT); } else { return isNumericOrDate(field(), sourceText(), ParamOrdinal.DEFAULT); } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Min.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Min.java index 07fa44769b2db..e64774fe8e720 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Min.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/aggregate/Min.java @@ -13,6 +13,7 @@ import java.util.List; +import static org.elasticsearch.xpack.sql.expression.TypeResolutions.isExact; import static org.elasticsearch.xpack.sql.expression.TypeResolutions.isNumericOrDate; /** @@ -50,7 +51,7 @@ public String innerName() { @Override protected TypeResolution resolveType() { if (field().dataType().isString()) { - return TypeResolution.TYPE_RESOLVED; + return isExact(field(), sourceText(), ParamOrdinal.DEFAULT); } else { return isNumericOrDate(field(), sourceText(), ParamOrdinal.DEFAULT); } diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java index dfeb44dfe2165..3c19b84ac4e3a 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java @@ -717,6 +717,18 @@ public void testTopHitsGroupByHavingUnsupported() { error("SELECT FIRST(int) FROM test GROUP BY text HAVING FIRST(int) > 10")); } + public void testMinOnInexactUnsupported() { + assertEquals("1:8: [MIN(text)] cannot operate on field of data type [text]: " + + "No keyword/multi-field defined exact matches for [text]; define one or use MATCH/QUERY instead", + error("SELECT MIN(text) FROM test")); + } + + public void testMaxOnInexactUnsupported() { + assertEquals("1:8: [MAX(text)] cannot operate on field of data type [text]: " + + "No keyword/multi-field defined exact matches for [text]; define one or use MATCH/QUERY instead", + error("SELECT MAX(text) FROM test")); + } + public void testMinOnKeywordGroupByHavingUnsupported() { assertEquals("1:52: HAVING filter is unsupported for function [MIN(keyword)]", error("SELECT MIN(keyword) FROM test GROUP BY text HAVING MIN(keyword) > 10"));