diff --git a/presto-docs/src/main/sphinx/functions/array.rst b/presto-docs/src/main/sphinx/functions/array.rst index 03777f2d10321..2268e2beeb937 100644 --- a/presto-docs/src/main/sphinx/functions/array.rst +++ b/presto-docs/src/main/sphinx/functions/array.rst @@ -223,11 +223,13 @@ Array Functions .. function:: find_first(array(E), function(T,boolean)) -> E - Returns the first element of ``array`` which returns true for ``function(T,boolean)``. Returns ``NULL`` if no such element exists. + Returns the first element of ``array`` which returns true for ``function(T,boolean)``, throws exception if the returned element is NULL. + Returns ``NULL`` if no such element exists. .. function:: find_first(array(E), index, function(T,boolean)) -> E - Returns the first element of ``array`` which returns true for ``function(T,boolean)``. Returns ``NULL`` if no such element exists. + Returns the first element of ``array`` which returns true for ``function(T,boolean)``, throws exception if the returned element is NULL. + Returns ``NULL`` if no such element exists. If ``index`` > 0, the search for element starts at position ``index`` until the end of array. If ``index`` < 0, the search for element starts at position ``abs(index)`` counting from last, until the start of array. :: diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInTypeAndFunctionNamespaceManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInTypeAndFunctionNamespaceManager.java index 4b032713b78c9..98741672bce63 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInTypeAndFunctionNamespaceManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/BuiltInTypeAndFunctionNamespaceManager.java @@ -102,7 +102,7 @@ import com.facebook.presto.operator.scalar.ArrayEqualOperator; import com.facebook.presto.operator.scalar.ArrayExceptFunction; import com.facebook.presto.operator.scalar.ArrayFilterFunction; -import com.facebook.presto.operator.scalar.ArrayFindFirstFirstFunction; +import com.facebook.presto.operator.scalar.ArrayFindFirstFunction; import com.facebook.presto.operator.scalar.ArrayFindFirstIndexFunction; import com.facebook.presto.operator.scalar.ArrayFindFirstIndexWithOffsetFunction; import com.facebook.presto.operator.scalar.ArrayFindFirstWithOffsetFunction; @@ -810,7 +810,7 @@ private List getBuildInFunctions(FeaturesConfig featuresC .scalar(ArrayNgramsFunction.class) .scalar(ArrayAllMatchFunction.class) .scalar(ArrayAnyMatchFunction.class) - .scalar(ArrayFindFirstFirstFunction.class) + .scalar(ArrayFindFirstFunction.class) .scalar(ArrayFindFirstWithOffsetFunction.class) .scalar(ArrayFindFirstIndexFunction.class) .scalar(ArrayFindFirstIndexWithOffsetFunction.class) diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFirstFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFunction.java similarity index 97% rename from presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFirstFunction.java rename to presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFunction.java index 5d83c09c5a898..f69169e67aa71 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFirstFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstFunction.java @@ -24,10 +24,10 @@ @Description("Return the first element which matches the given predicate, null if no match") @ScalarFunction(value = "find_first", deterministic = true) -public final class ArrayFindFirstFirstFunction +public final class ArrayFindFirstFunction extends ArrayFindFirstWithOffsetFunction { - private ArrayFindFirstFirstFunction() {} + private ArrayFindFirstFunction() {} @TypeParameter("T") @SqlType("T") diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstWithOffsetFunction.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstWithOffsetFunction.java index fa4a1864ce497..716f80421d6f2 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstWithOffsetFunction.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayFindFirstWithOffsetFunction.java @@ -25,6 +25,7 @@ import io.airlift.slice.Slice; import static com.facebook.presto.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; +import static com.facebook.presto.util.Failures.checkCondition; import static java.lang.Boolean.TRUE; import static java.lang.Math.toIntExact; @@ -112,6 +113,9 @@ public static Block findBlockUtil( } Boolean match = function.apply(element); if (TRUE.equals(match)) { + if (element == null) { + checkCondition(false, INVALID_FUNCTION_ARGUMENT, "FIND_FIRST finds NULL as match, which is not supported."); + } return element; } } @@ -136,6 +140,9 @@ public static Slice findSliceUtil( } Boolean match = function.apply(element); if (TRUE.equals(match)) { + if (element == null) { + checkCondition(false, INVALID_FUNCTION_ARGUMENT, "FIND_FIRST finds NULL as match, which is not supported."); + } return element; } } @@ -160,6 +167,9 @@ public static Long findLongUtil( } Boolean match = function.apply(element); if (TRUE.equals(match)) { + if (element == null) { + checkCondition(false, INVALID_FUNCTION_ARGUMENT, "FIND_FIRST finds NULL as match, which is not supported."); + } return element; } } @@ -184,6 +194,9 @@ public static Double findDoubleUtil( } Boolean match = function.apply(element); if (TRUE.equals(match)) { + if (element == null) { + checkCondition(false, INVALID_FUNCTION_ARGUMENT, "FIND_FIRST finds NULL as match, which is not supported."); + } return element; } } @@ -208,6 +221,9 @@ public static Boolean findBooleanUtil( } Boolean match = function.apply(element); if (TRUE.equals(match)) { + if (element == null) { + checkCondition(false, INVALID_FUNCTION_ARGUMENT, "FIND_FIRST finds NULL as match, which is not supported."); + } return element; } } diff --git a/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestArrayFindFirstFunction.java b/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestArrayFindFirstFunction.java index 30fce9a9a764d..bcc8bdaedf706 100644 --- a/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestArrayFindFirstFunction.java +++ b/presto-main/src/test/java/com/facebook/presto/operator/scalar/TestArrayFindFirstFunction.java @@ -89,9 +89,9 @@ public void testEmpty() @Test public void testNullArray() { - assertFunction("find_first(ARRAY [NULL], x -> x IS NULL)", UNKNOWN, null); + assertInvalidFunction("find_first(ARRAY [NULL], x -> x IS NULL)", "FIND_FIRST finds NULL as match, which is not supported."); assertFunction("find_first(ARRAY [NULL], x -> x IS NOT NULL)", UNKNOWN, null); - assertFunction("find_first(ARRAY [CAST (NULL AS INTEGER)], x -> x IS NULL)", INTEGER, null); + assertInvalidFunction("find_first(ARRAY [CAST (NULL AS INTEGER)], x -> x IS NULL)", "FIND_FIRST finds NULL as match, which is not supported."); } @Test