You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ay...@apache.org on 2022/11/24 12:32:36 UTC

[hive] branch master updated: HIVE-26744: Add array_max and array_min UDFs (#3774). (Taraka Rama Rao Lethavadla, reviewed by Ayush Saxena, Sourabh Badhya)

This is an automated email from the ASF dual-hosted git repository.

ayushsaxena pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new c50679c1083 HIVE-26744: Add array_max and array_min UDFs (#3774). (Taraka Rama Rao Lethavadla, reviewed by Ayush Saxena, Sourabh Badhya)
c50679c1083 is described below

commit c50679c1083f9450678bd481ca017c09b06286ca
Author: tarak271 <ta...@gmail.com>
AuthorDate: Thu Nov 24 18:02:24 2022 +0530

    HIVE-26744: Add array_max and array_min UDFs (#3774). (Taraka Rama Rao Lethavadla, reviewed by Ayush Saxena, Sourabh Badhya)
---
 .../hadoop/hive/ql/exec/FunctionRegistry.java      |   2 +
 .../udf/generic/AbstractGenericUDFArrayBase.java   | 109 ++++++++++++++++++
 .../hive/ql/udf/generic/GenericUDFArrayMax.java    |  61 ++++++++++
 .../hive/ql/udf/generic/GenericUDFArrayMin.java    |  61 ++++++++++
 .../generic/TestAbstractGenericUDFArrayBase.java   | 123 +++++++++++++++++++++
 .../ql/udf/generic/TestGenericUDFArrayMax.java     |  25 +++++
 .../ql/udf/generic/TestGenericUDFArrayMin.java     |  25 +++++
 ql/src/test/queries/clientpositive/udf_array_max.q |  18 +++
 ql/src/test/queries/clientpositive/udf_array_min.q |  18 +++
 .../clientpositive/llap/show_functions.q.out       |   4 +
 .../clientpositive/llap/udf_array_max.q.out        |  69 ++++++++++++
 .../clientpositive/llap/udf_array_min.q.out        |  69 ++++++++++++
 12 files changed, 584 insertions(+)

diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
index e7f0f8e9711..46c5eb3efa7 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java
@@ -600,6 +600,8 @@ public final class FunctionRegistry {
     system.registerGenericUDF("sort_array", GenericUDFSortArray.class);
     system.registerGenericUDF("sort_array_by", GenericUDFSortArrayByField.class);
     system.registerGenericUDF("array_contains", GenericUDFArrayContains.class);
+    system.registerGenericUDF("array_min", GenericUDFArrayMin.class);
+    system.registerGenericUDF("array_max", GenericUDFArrayMax.class);
     system.registerGenericUDF("deserialize", GenericUDFDeserialize.class);
     system.registerGenericUDF("sentences", GenericUDFSentences.class);
     system.registerGenericUDF("map_keys", GenericUDFMapKeys.class);
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/AbstractGenericUDFArrayBase.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/AbstractGenericUDFArrayBase.java
new file mode 100644
index 00000000000..d954cbb1e3b
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/AbstractGenericUDFArrayBase.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.udf.generic;
+
+import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
+import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
+import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
+
+/**
+ * Abstract GenericUDF for array functions
+ */
+
+public abstract class AbstractGenericUDFArrayBase extends GenericUDF {
+
+    static final int ARRAY_IDX = 0;
+
+    private final int minArgCount;
+    private final int maxArgCount;
+    private final ObjectInspector.Category outputCategory;
+
+    private final String functionName;
+
+    transient ListObjectInspector arrayOI;
+    transient ObjectInspector[] argumentOIs;
+
+    transient Converter converter;
+
+    protected AbstractGenericUDFArrayBase(String functionName, int minArgCount, int maxArgCount, ObjectInspector.Category outputCategory) {
+        this.functionName = functionName;
+        this.minArgCount = minArgCount;
+        this.maxArgCount = maxArgCount;
+        this.outputCategory = outputCategory;
+    }
+
+    @Override
+    public ObjectInspector initialize(ObjectInspector[] arguments)
+            throws UDFArgumentException {
+
+        // Check if wrong number of arguments were passed
+        checkArgsSize(arguments, minArgCount, maxArgCount);
+
+        // Check if the argument is of category LIST or not
+        checkArgCategory(arguments, ARRAY_IDX, ObjectInspector.Category.LIST, functionName,
+                org.apache.hadoop.hive.serde.serdeConstants.LIST_TYPE_NAME);
+
+        //return ObjectInspectors based on expected output type
+        arrayOI = (ListObjectInspector) arguments[ARRAY_IDX];
+        argumentOIs = arguments;
+        if (outputCategory == ObjectInspector.Category.LIST) {
+            return initListOI(arguments);
+        } else {
+            return initOI(arguments);
+        }
+    }
+
+    @Override
+    public String getDisplayString(String[] children) {
+        return getStandardDisplayString(functionName.toLowerCase(), children);
+    }
+
+    void checkArgCategory(ObjectInspector[] arguments, int idx, ObjectInspector.Category category,
+                          String functionName, String typeName) throws UDFArgumentTypeException {
+
+        if (!arguments[idx].getCategory().equals(category)) {
+            throw new UDFArgumentTypeException(idx,
+                    "\"" + typeName + "\" "
+                            + "expected at function " + functionName + ", but "
+                            + "\"" + arguments[idx].getTypeName() + "\" "
+                            + "is found");
+        }
+    }
+
+    ObjectInspector initOI(ObjectInspector[] arguments) {
+
+        GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver =
+                new GenericUDFUtils.ReturnObjectInspectorResolver(true);
+
+        ObjectInspector elementObjectInspector =
+                ((ListObjectInspector) (arguments[0])).getListElementObjectInspector();
+
+        ObjectInspector returnOI = returnOIResolver.get(elementObjectInspector);
+        converter = ObjectInspectorConverters.getConverter(elementObjectInspector, returnOI);
+        return returnOI;
+    }
+
+    ObjectInspector initListOI(ObjectInspector[] arguments) {
+        return ObjectInspectorFactory.getStandardListObjectInspector(initOI(arguments));
+    }
+
+}
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMax.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMax.java
new file mode 100644
index 00000000000..db14d0283d1
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMax.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.udf.generic;
+
+import org.apache.hadoop.hive.ql.exec.Description;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Generic UDF to find out max from array elements
+ * <code>ARRAY_MAX(array(obj1, obj2, obj3...))</code>.
+ *
+ * @see GenericUDF
+ */
+@Description(name = "array_max",
+        value = "_FUNC_(array(obj1, obj2,...)) - "
+                + "The function returns the maximum value in array with elements for which order is supported",
+        extended = "Example:\n"
+                + "  > SELECT _FUNC_(array(1, 3, 0, NULL)) FROM src LIMIT 1;\n"
+                + "  3")
+public class GenericUDFArrayMax extends AbstractGenericUDFArrayBase {
+
+    //Initialise parent member variables
+    public GenericUDFArrayMax() {
+        super("ARRAY_MAX", 1, 1, ObjectInspector.Category.PRIMITIVE);
+    }
+
+    @Override
+    public Object evaluate(DeferredObject[] arguments) throws HiveException {
+        Object array = arguments[ARRAY_IDX].get();
+
+        if (arrayOI.getListLength(array) <= 0) {
+            return null;
+        }
+
+        List retArray = ((ListObjectInspector) argumentOIs[ARRAY_IDX]).getList(array);
+        Optional value = retArray.stream().filter(Objects::nonNull).max(Comparator.naturalOrder());
+        return value.isPresent() ? value.get() : null;
+    }
+}
\ No newline at end of file
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMin.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMin.java
new file mode 100644
index 00000000000..efb9c084982
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFArrayMin.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hive.ql.udf.generic;
+
+import org.apache.hadoop.hive.ql.exec.Description;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Generic UDF to find out min from array elements
+ * <code>ARRAY_MIN(array(obj1, obj2, obj3...))</code>.
+ *
+ * @see GenericUDF
+ */
+@Description(name = "array_min",
+        value = "_FUNC_(array(obj1, obj2,...)) - "
+                + "The function returns the minimum value in array with elements for which order is supported",
+        extended = "Example:\n"
+                + "  > SELECT _FUNC_(array(1, 3, 0, NULL)) FROM src LIMIT 1;\n"
+                + "  0")
+public class GenericUDFArrayMin extends AbstractGenericUDFArrayBase {
+
+    //Initialise parent member variables
+    public GenericUDFArrayMin() {
+        super("ARRAY_MIN", 1, 1, ObjectInspector.Category.PRIMITIVE);
+    }
+
+    @Override
+    public Object evaluate(DeferredObject[] arguments) throws HiveException {
+        Object array = arguments[ARRAY_IDX].get();
+
+        if (arrayOI.getListLength(array) <= 0) {
+            return null;
+        }
+
+        List retArray = ((ListObjectInspector) argumentOIs[ARRAY_IDX]).getList(array);
+        Optional value = retArray.stream().filter(Objects::nonNull).min(Comparator.naturalOrder());
+        return value.isPresent() ? value.get() : null;
+    }
+}
\ No newline at end of file
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestAbstractGenericUDFArrayBase.java b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestAbstractGenericUDFArrayBase.java
new file mode 100644
index 00000000000..cddbe06c4a8
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestAbstractGenericUDFArrayBase.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.udf.generic;
+
+import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.serde2.io.DoubleWritable;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.AbstractPrimitiveWritableObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
+import org.apache.hadoop.io.FloatWritable;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.io.LongWritable;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+import static java.util.Arrays.asList;
+
+public class TestAbstractGenericUDFArrayBase {
+    GenericUDF udf = null;
+
+    @Test
+    public void testIntArray() throws HiveException {
+
+        initUdf(PrimitiveObjectInspectorFactory.writableIntObjectInspector);
+        Object i1 = new IntWritable(3);
+        Object i2 = new IntWritable(1);
+        Object i3 = new IntWritable(2);
+        Object i4 = new IntWritable(4);
+        Object i5 = new IntWritable(-4);
+        //Object i5 = new IntWritable(null);
+        if (udf instanceof GenericUDFArrayMax) {
+            runAndVerify(asList(i1, i2, i3, i4, i5), i4);
+        }
+        if (udf instanceof GenericUDFArrayMin) {
+            runAndVerify(asList(i1, i2, i3, i4, i5), i5);
+        }
+    }
+
+    @Test
+    public void testFloatArray() throws HiveException {
+        initUdf(PrimitiveObjectInspectorFactory.writableFloatObjectInspector);
+        Object i1 = new FloatWritable(5.3f);
+        Object i2 = new FloatWritable(1.1f);
+        Object i3 = new FloatWritable(3.3f);
+        Object i4 = new FloatWritable(2.20f);
+        if (udf instanceof GenericUDFArrayMax) {
+            runAndVerify(asList(i1, i2, i3, i4), i1);
+        }
+        if (udf instanceof GenericUDFArrayMin) {
+            runAndVerify(asList(i1, i2, i3, i4), i2);
+        }
+    }
+
+    @Test
+    public void testDoubleArray() throws HiveException {
+        initUdf(PrimitiveObjectInspectorFactory.writableDoubleObjectInspector);
+        Object i1 = new DoubleWritable(3.31234567890);
+        Object i2 = new DoubleWritable(1.11234567890);
+        Object i3 = new DoubleWritable(4.31234567890);
+        Object i4 = new DoubleWritable(2.21234567890);
+
+        if (udf instanceof GenericUDFArrayMax) {
+            runAndVerify(asList(i1, i2, i3, i4), i3);
+        }
+        if (udf instanceof GenericUDFArrayMin) {
+            runAndVerify(asList(i1, i2, i3, i4), i2);
+        }
+    }
+
+    @Test
+    public void testLongArray() throws HiveException {
+        initUdf(PrimitiveObjectInspectorFactory.writableLongObjectInspector);
+        Object i1 = new LongWritable(331234567890L);
+        Object i2 = new LongWritable(911234567890L);
+        Object i3 = new LongWritable(131234567890L);
+        Object i4 = new LongWritable(221234567890L);
+
+        if (udf instanceof GenericUDFArrayMax) {
+            runAndVerify(asList(i1, i2, i3, i4), i2);
+        }
+        if (udf instanceof GenericUDFArrayMin) {
+            runAndVerify(asList(i1, i2, i3, i4), i3);
+        }
+    }
+
+    private void initUdf(AbstractPrimitiveWritableObjectInspector writableIntObjectInspector) throws UDFArgumentException {
+        ObjectInspector[] inputOIs = {
+                ObjectInspectorFactory.getStandardListObjectInspector(writableIntObjectInspector)
+        };
+        if (udf != null ) {
+            udf.initialize(inputOIs);
+        }
+    }
+
+    private void runAndVerify(List<Object> actual, Object expected)
+            throws HiveException {
+        GenericUDF.DeferredJavaObject[] args = {new GenericUDF.DeferredJavaObject(actual)};
+        Object result = udf.evaluate(args);
+
+        Assert.assertEquals("Max/Min value", expected, result);
+    }
+
+}
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMax.java b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMax.java
new file mode 100644
index 00000000000..b680e015de5
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMax.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.udf.generic;
+
+public class TestGenericUDFArrayMax extends TestAbstractGenericUDFArrayBase {
+  public TestGenericUDFArrayMax(){
+    super.udf=new GenericUDFArrayMax();
+  }
+}
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMin.java b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMin.java
new file mode 100644
index 00000000000..be2a695f1a1
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFArrayMin.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.ql.udf.generic;
+
+public class TestGenericUDFArrayMin extends TestAbstractGenericUDFArrayBase {
+  public TestGenericUDFArrayMin() {
+    super.udf = new GenericUDFArrayMin();
+  }
+}
\ No newline at end of file
diff --git a/ql/src/test/queries/clientpositive/udf_array_max.q b/ql/src/test/queries/clientpositive/udf_array_max.q
new file mode 100644
index 00000000000..f3086a62e1f
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/udf_array_max.q
@@ -0,0 +1,18 @@
+--! qt:dataset:src
+set hive.fetch.task.conversion=more;
+
+DESCRIBE FUNCTION array_max;
+DESCRIBE FUNCTION EXTENDED array_max;
+
+-- evalutes function for array of primitives
+SELECT array_max(array(1, 2, 3, null)) FROM src tablesample (1 rows);
+
+SELECT array_max(array()) FROM src tablesample (1 rows);
+
+SELECT array_max(array(null)) FROM src tablesample (1 rows);
+
+SELECT array_max(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows);
+
+SELECT array_max(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows);
+
+SELECT array_max(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows);
\ No newline at end of file
diff --git a/ql/src/test/queries/clientpositive/udf_array_min.q b/ql/src/test/queries/clientpositive/udf_array_min.q
new file mode 100644
index 00000000000..bd9557f110c
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/udf_array_min.q
@@ -0,0 +1,18 @@
+--! qt:dataset:src
+set hive.fetch.task.conversion=more;
+
+DESCRIBE FUNCTION array_min;
+DESCRIBE FUNCTION EXTENDED array_min;
+
+-- evalutes function for array of primitives
+SELECT array_min(array(1, 2, 3, null)) FROM src tablesample (1 rows);
+
+SELECT array_min(array()) FROM src tablesample (1 rows);
+
+SELECT array_min(array(null)) FROM src tablesample (1 rows);
+
+SELECT array_min(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows);
+
+SELECT array_min(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows);
+
+SELECT array_min(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows);
\ No newline at end of file
diff --git a/ql/src/test/results/clientpositive/llap/show_functions.q.out b/ql/src/test/results/clientpositive/llap/show_functions.q.out
index 9006d187eea..de0ced3fa6f 100644
--- a/ql/src/test/results/clientpositive/llap/show_functions.q.out
+++ b/ql/src/test/results/clientpositive/llap/show_functions.q.out
@@ -47,6 +47,8 @@ and
 approx_distinct
 array
 array_contains
+array_max
+array_min
 ascii
 asin
 assert_true
@@ -662,6 +664,8 @@ and
 approx_distinct
 array
 array_contains
+array_max
+array_min
 ascii
 asin
 assert_true
diff --git a/ql/src/test/results/clientpositive/llap/udf_array_max.q.out b/ql/src/test/results/clientpositive/llap/udf_array_max.q.out
new file mode 100644
index 00000000000..9c285ebb953
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/udf_array_max.q.out
@@ -0,0 +1,69 @@
+PREHOOK: query: DESCRIBE FUNCTION array_max
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: DESCRIBE FUNCTION array_max
+POSTHOOK: type: DESCFUNCTION
+array_max(array(obj1, obj2,...)) - The function returns the maximum value in array with elements for which order is supported
+PREHOOK: query: DESCRIBE FUNCTION EXTENDED array_max
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: DESCRIBE FUNCTION EXTENDED array_max
+POSTHOOK: type: DESCFUNCTION
+array_max(array(obj1, obj2,...)) - The function returns the maximum value in array with elements for which order is supported
+Example:
+  > SELECT array_max(array(1, 3, 0, NULL)) FROM src LIMIT 1;
+  3
+Function class:org.apache.hadoop.hive.ql.udf.generic.GenericUDFArrayMax
+Function type:BUILTIN
+PREHOOK: query: SELECT array_max(array(1, 2, 3, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array(1, 2, 3, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+3
+PREHOOK: query: SELECT array_max(array()) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array()) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+NULL
+PREHOOK: query: SELECT array_max(array(null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array(null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+NULL
+PREHOOK: query: SELECT array_max(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+3.34
+PREHOOK: query: SELECT array_max(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+3.345678900
+PREHOOK: query: SELECT array_max(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_max(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+11234567890
diff --git a/ql/src/test/results/clientpositive/llap/udf_array_min.q.out b/ql/src/test/results/clientpositive/llap/udf_array_min.q.out
new file mode 100644
index 00000000000..4452e423bcb
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/udf_array_min.q.out
@@ -0,0 +1,69 @@
+PREHOOK: query: DESCRIBE FUNCTION array_min
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: DESCRIBE FUNCTION array_min
+POSTHOOK: type: DESCFUNCTION
+array_min(array(obj1, obj2,...)) - The function returns the minimum value in array with elements for which order is supported
+PREHOOK: query: DESCRIBE FUNCTION EXTENDED array_min
+PREHOOK: type: DESCFUNCTION
+POSTHOOK: query: DESCRIBE FUNCTION EXTENDED array_min
+POSTHOOK: type: DESCFUNCTION
+array_min(array(obj1, obj2,...)) - The function returns the minimum value in array with elements for which order is supported
+Example:
+  > SELECT array_min(array(1, 3, 0, NULL)) FROM src LIMIT 1;
+  0
+Function class:org.apache.hadoop.hive.ql.udf.generic.GenericUDFArrayMin
+Function type:BUILTIN
+PREHOOK: query: SELECT array_min(array(1, 2, 3, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array(1, 2, 3, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+1
+PREHOOK: query: SELECT array_min(array()) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array()) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+NULL
+PREHOOK: query: SELECT array_min(array(null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array(null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+NULL
+PREHOOK: query: SELECT array_min(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array(1.12, 2.23, 3.34, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+1.12
+PREHOOK: query: SELECT array_min(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array(1.1234567890, 2.234567890, 3.34567890, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+1.123456789
+PREHOOK: query: SELECT array_min(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT array_min(array(11234567890, 2234567890, 334567890, null)) FROM src tablesample (1 rows)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+334567890