You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by al...@apache.org on 2019/06/06 21:26:32 UTC

[asterixdb] branch master updated: [ASTERIXDB-2574][COMP] Fix min/max functions

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 77450e6  [ASTERIXDB-2574][COMP] Fix min/max functions
77450e6 is described below

commit 77450e6a1ad081d2dc2d00b2847f45d8b9a407e5
Author: Ali Alsuliman <al...@gmail.com>
AuthorDate: Wed Jun 5 18:44:09 2019 -0700

    [ASTERIXDB-2574][COMP] Fix min/max functions
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    This change is mainly for 2 things. The first thing is to not throw
    an exception when the type of the aggregated field is invalid for min/max
    (e.g. record or rectange) or min/max get incompatible data like string
    and int. The result in this case would be NULL. The second thing is to
    enable comparing ARRAYs correctly by using logical comparison. When
    a partition runs into type invalidity, it will output NULL. The global
    aggregator interprets NULL received from a partition as type invalidity
    and outputs NULL as the final result. Both SQL and SQL++ will do that.
    Special treatment is needed for scalar and distinct version of SQL since
    SQL min/max ignores NULL values and continue aggregation and the scalar
    and distinct version of SQL are normally setup as a global aggregator
    since they behave like the global aggregator in a two-step aggregation.
    Currently, there is only a local min and max functions. The other
    min/max functions are used for everything, the global function of
    two-step aggregation, and for scalar and distinct min/max. In order to
    differentiate, a global min/max functions are added that will be used
    for the two-step aggregation.
    
    Details:
    - fixed listify to open up elements when adding them to the collection
    and the collection item type is of type ANY and changed the type inferer
    of listify to enable that.
    - fixed AbstractCollectionType to make sure itemType is never null.
    - changed MinMaxAggTypeComputer to not throw an exception but return
    NULL for invalid types.
    - changed min/max descriptors to implement inferer to propagate the
    type of the field and pass that when getting a comparator.
    - switched min/max comparison to the logical comparison.
    - refactored method inequalityUndefined to be shared by logical comparison
    and min/max functions.
    - added global max/min functions to enable differentiating between
    scalar min/max, distinct min/max and two-step min/max (global & local).
    - code clean-up for LogicalScalarBinaryComparator; created two INSTANCES
    and re-used.
    
    Change-Id: I1231cfe558099d167bae0b2fa7fc4879b756baf0
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/3427
    Contrib: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
---
 .../min_max_arrays/min_max_arrays.01.ddl.sqlpp}    |  19 ++--
 .../min_max_arrays/min_max_arrays.02.update.sqlpp  |  71 ++++++++++++++
 .../min_max_arrays/min_max_arrays.03.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.04.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.05.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.06.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.07.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.08.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.09.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.10.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.11.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.12.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.13.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.14.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.15.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.16.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.17.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.18.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.19.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.20.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.21.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.22.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.23.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.24.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.25.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.26.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.27.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.28.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.29.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.30.query.sqlpp}  |  10 +-
 .../min_max_arrays/min_max_arrays.31.ddl.sqlpp}    |   6 +-
 .../min_max_arrays/min_max_arrays.01.ddl.sqlpp}    |  19 ++--
 .../min_max_arrays/min_max_arrays.02.update.sqlpp  |  71 ++++++++++++++
 .../min_max_arrays.03.query.sqlpp}                 |  10 +-
 .../min_max_arrays.04.query.sqlpp}                 |  10 +-
 .../min_max_arrays.05.query.sqlpp}                 |  10 +-
 .../min_max_arrays.06.query.sqlpp}                 |  10 +-
 .../min_max_arrays.07.query.sqlpp}                 |  10 +-
 .../min_max_arrays.08.query.sqlpp}                 |  10 +-
 .../min_max_arrays.09.query.sqlpp}                 |  10 +-
 .../min_max_arrays.10.query.sqlpp}                 |  10 +-
 .../min_max_arrays.11.query.sqlpp}                 |  10 +-
 .../min_max_arrays.12.query.sqlpp}                 |  10 +-
 .../min_max_arrays.13.query.sqlpp}                 |  10 +-
 .../min_max_arrays.14.query.sqlpp}                 |  10 +-
 .../min_max_arrays.15.query.sqlpp}                 |  10 +-
 .../min_max_arrays.16.query.sqlpp}                 |  10 +-
 .../min_max_arrays.17.query.sqlpp}                 |  10 +-
 .../min_max_arrays.18.query.sqlpp}                 |  10 +-
 .../min_max_arrays.19.query.sqlpp}                 |  10 +-
 .../min_max_arrays.20.query.sqlpp}                 |  10 +-
 .../min_max_arrays.21.query.sqlpp}                 |  10 +-
 .../min_max_arrays.22.query.sqlpp}                 |  10 +-
 .../min_max_arrays.23.ddl.sqlpp}                   |   6 +-
 .../aggregate/min_mixed/min_mixed.1.ddl.sqlpp      |   2 +-
 .../aggregate/min_mixed/min_mixed.3.query.sqlpp    |   2 +-
 .../min_max_arrays/min_max_arrays.03.adm           |   1 +
 .../min_max_arrays/min_max_arrays.04.adm           |   1 +
 .../min_max_arrays/min_max_arrays.05.adm           |   1 +
 .../min_max_arrays/min_max_arrays.06.adm           |   3 +
 .../min_max_arrays/min_max_arrays.07.adm           |   3 +
 .../min_max_arrays/min_max_arrays.08.adm           |   3 +
 .../min_max_arrays/min_max_arrays.09.adm           |   1 +
 .../min_max_arrays/min_max_arrays.10.adm           |   1 +
 .../min_max_arrays/min_max_arrays.11.adm           |   1 +
 .../min_max_arrays/min_max_arrays.12.adm           |   3 +
 .../min_max_arrays/min_max_arrays.13.adm           |   3 +
 .../min_max_arrays/min_max_arrays.14.adm           |   3 +
 .../min_max_arrays/min_max_arrays.15.adm           |   7 ++
 .../min_max_arrays/min_max_arrays.16.adm           |   7 ++
 .../min_max_arrays/min_max_arrays.17.adm           |   1 +
 .../min_max_arrays/min_max_arrays.18.adm           |   1 +
 .../min_max_arrays/min_max_arrays.19.adm           |   1 +
 .../min_max_arrays/min_max_arrays.20.adm           |   3 +
 .../min_max_arrays/min_max_arrays.21.adm           |   3 +
 .../min_max_arrays/min_max_arrays.22.adm           |   3 +
 .../min_max_arrays/min_max_arrays.23.adm           |   1 +
 .../min_max_arrays/min_max_arrays.24.adm           |   1 +
 .../min_max_arrays/min_max_arrays.25.adm           |   1 +
 .../min_max_arrays/min_max_arrays.26.adm           |   3 +
 .../min_max_arrays/min_max_arrays.27.adm           |   3 +
 .../min_max_arrays/min_max_arrays.28.adm           |   3 +
 .../min_max_arrays/min_max_arrays.29.adm           |   7 ++
 .../min_max_arrays/min_max_arrays.30.adm           |   7 ++
 .../aggregate-sql/min_mixed/min_mixed.1.adm        |   2 +-
 .../aggregate/min_max_arrays/min_max_arrays.03.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.04.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.05.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.06.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.07.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.08.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.09.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.10.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.11.adm |   7 ++
 .../aggregate/min_max_arrays/min_max_arrays.12.adm |   7 ++
 .../aggregate/min_max_arrays/min_max_arrays.13.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.14.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.15.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.16.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.17.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.18.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.19.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.20.adm |   1 +
 .../aggregate/min_max_arrays/min_max_arrays.21.adm |   7 ++
 .../aggregate/min_max_arrays/min_max_arrays.22.adm |   7 ++
 .../results/aggregate/min_mixed/min_mixed.1.adm    |   2 +-
 .../test/resources/runtimets/testsuite_sqlpp.xml   |  12 ++-
 .../data/common/ILogicalBinaryComparator.java      |  21 ++++
 .../data/nontagged/comparators/ComparatorUtil.java |   3 +-
 .../LogicalComplexBinaryComparator.java            |   4 +-
 .../LogicalGenericBinaryComparator.java            |   4 +-
 .../comparators/LogicalScalarBinaryComparator.java |  24 ++---
 .../asterix/om/functions/BuiltinFunctions.java     |  54 ++++++----
 .../typecomputer/impl/MinMaxAggTypeComputer.java   |  35 ++-----
 .../impl/ScalarVersionOfAggregateResultType.java   |   1 +
 .../apache/asterix/om/types/AOrderedListType.java  |   8 +-
 .../asterix/om/types/AUnorderedListType.java       |   8 +-
 .../asterix/om/types/AbstractCollectionType.java   |  15 +--
 .../org/apache/asterix/om/types/TypeHelper.java    |  34 ++++++-
 ...AbstractAggregateFunctionDynamicDescriptor.java |  10 ++
 .../collections/ListifyAggregateDescriptor.java    |   7 +-
 .../ListifyAggregateFunctionEvalFactory.java       |  25 ++++-
 .../scalar/AbstractScalarAggregateDescriptor.java  |   9 ++
 .../AbstractScalarDistinctAggregateDescriptor.java |   9 --
 .../scalar/ScalarArrayAggAggregateDescriptor.java  |   2 +-
 .../ScalarArrayAggDistinctAggregateDescriptor.java |   2 +-
 .../scalar/ScalarMaxAggregateDescriptor.java       |  13 ++-
 .../ScalarMaxDistinctAggregateDescriptor.java      |  10 +-
 .../scalar/ScalarMinAggregateDescriptor.java       |  13 ++-
 .../ScalarMinDistinctAggregateDescriptor.java      |  10 +-
 .../scalar/ScalarSqlMaxAggregateDescriptor.java    |  16 ++-
 .../ScalarSqlMaxDistinctAggregateDescriptor.java   |  12 ++-
 .../scalar/ScalarSqlMinAggregateDescriptor.java    |  14 ++-
 .../ScalarSqlMinDistinctAggregateDescriptor.java   |  10 +-
 .../AbstractMinMaxAggregateDescriptor.java}        |  16 +--
 .../std/AbstractMinMaxAggregateFunction.java       | 109 +++++++++++++--------
 ...ptor.java => GlobalMaxAggregateDescriptor.java} |  17 ++--
 ...ptor.java => GlobalMinAggregateDescriptor.java} |  17 ++--
 ...r.java => GlobalSqlMaxAggregateDescriptor.java} |  17 ++--
 ...r.java => GlobalSqlMinAggregateDescriptor.java} |  17 ++--
 .../std/LocalMaxAggregateDescriptor.java           |  19 ++--
 .../std/LocalMinAggregateDescriptor.java           |  18 ++--
 .../std/LocalSqlMaxAggregateDescriptor.java        |  19 ++--
 .../std/LocalSqlMinAggregateDescriptor.java        |  18 ++--
 .../aggregates/std/MaxAggregateDescriptor.java     |  15 ++-
 .../aggregates/std/MinAggregateDescriptor.java     |  15 ++-
 .../aggregates/std/MinMaxAggregateFunction.java    |  42 +++-----
 .../aggregates/std/SqlMaxAggregateDescriptor.java  |  15 ++-
 .../aggregates/std/SqlMinAggregateDescriptor.java  |  15 ++-
 .../aggregates/std/SqlMinMaxAggregateFunction.java |  45 ++++-----
 .../runtime/functions/FunctionCollection.java      |   8 ++
 .../runtime/functions/FunctionTypeInferers.java    |  35 ++++---
 152 files changed, 1042 insertions(+), 600 deletions(-)

diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp
similarity index 61%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp
index e583e5f..33b1a10 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp
@@ -16,16 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.runtime.aggregates.base;
 
-import org.apache.asterix.common.functions.FunctionDescriptorTag;
-import org.apache.asterix.om.functions.AbstractFunctionDescriptor;
+drop dataverse test if exists;
+create dataverse test;
 
-public abstract class AbstractAggregateFunctionDynamicDescriptor extends AbstractFunctionDescriptor {
-    private static final long serialVersionUID = 1L;
+use test;
 
-    public FunctionDescriptorTag getFunctionDescriptorTag() {
-        return FunctionDescriptorTag.AGGREGATE;
-    }
+create type openType as { id : integer, group_id : string };
+create type closedType1 as closed { id : integer, group_id : string, array_f : [int] };
+create type closedType2 as closed { id : integer, group_id : string, array_f : [int]?};
 
-}
+create dataset openDs(openType) primary key id;
+create dataset openDs2(openType) primary key id;
+create dataset closedDs1(closedType1) primary key id;
+create dataset closedDs2(closedType2) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.02.update.sqlpp
new file mode 100644
index 0000000..a1d60cb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.02.update.sqlpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+use test;
+
+insert into openDs([
+{"id": 1, "group_id": "g1", "array_f": [4, "str"]},
+{"id": 2, "group_id": "g1", "array_f": [1, "str2"]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, "str3"]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, "str"]},
+{"id": 7, "group_id": "g3", "array_f": [12, "str"]},
+{"id": 8, "group_id": "g3", "array_f": [9, null]}
+]);
+
+insert into openDs2([
+{"id": 1, "group_id": "g1", "array_f": [[4, "str"], [6, "test"], [2, "hi"]]},
+{"id": 2, "group_id": "g1", "array_f": [[1, "str2"], [10, "may"]]},
+{"id": 3, "group_id": "g1", "array_f": [[6.0, "str3"], [4, "june"], [4, "oct"]]},
+
+{"id": 4, "group_id": "g2", "array_f": [[6.0, 7], [12, 18], null]},
+{"id": 5, "group_id": "g2", "array_f": [[6.0, 10], [20, 11]]},
+
+{"id": 6, "group_id": "g3", "array_f": [[6.0, 10], [20, 11], [4, null]]},
+{"id": 7, "group_id": "g3", "array_f": [[6.0, 10], [20, 11], [4, "str"]]}
+]);
+
+insert into closedDs1([
+{"id": 1, "group_id": "g1", "array_f": [4, 3]},
+{"id": 2, "group_id": "g1", "array_f": [9, 7]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, 1]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, 14]},
+{"id": 7, "group_id": "g3", "array_f": [12, 2]},
+{"id": 8, "group_id": "g3", "array_f": [7, 4]}
+]);
+
+insert into closedDs2([
+{"id": 1, "group_id": "g1", "array_f": [4, 3]},
+{"id": 2, "group_id": "g1", "array_f": [9, 7]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, 1]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, 14]},
+{"id": 7, "group_id": "g3", "array_f": [12, 2]},
+{"id": 8, "group_id": "g3", "array_f": null}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.03.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.03.query.sqlpp
index 45af77f..2927c05 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.03.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min()
+ * Expected Res : NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select value min(array_f) from openDs;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.04.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.04.query.sqlpp
index 45af77f..9f7798f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.04.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value min(array_f) from closedDs1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.05.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.05.query.sqlpp
index 45af77f..3876650 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.05.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min()
+ * Expected Res : SUCCESS; Ignores NULL
+ */
+
+use test;
 
+select value min(array_f) from closedDs2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.06.query.sqlpp
similarity index 77%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.06.query.sqlpp
index 45af77f..c9bd556 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.06.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min() with group by
+ * Expected Res : group "g3" produces NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select group_id,min(array_f) from openDs group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.07.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.07.query.sqlpp
index 45af77f..95bc61c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.07.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min() with group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,min(array_f) from closedDs1 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.08.query.sqlpp
similarity index 77%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.08.query.sqlpp
index 45af77f..3a235da 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.08.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-min() & agg-local-sql-min() with group by
+ * Expected Res : SUCCESS; testing group "g3" ignores NULL value
+ */
+
+use test;
 
+select group_id,min(array_f) from closedDs2 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.09.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.09.query.sqlpp
index 45af77f..97faea8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.09.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct
+ * Expected Res : produces NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select value min(distinct array_f) from openDs;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.10.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.10.query.sqlpp
index 45af77f..c287262 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.10.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value min(distinct array_f) from closedDs1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.11.query.sqlpp
similarity index 82%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.11.query.sqlpp
index 45af77f..f63558f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.11.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct
+ * Expected Res : SUCCESS; testing ignoring NULL tuple
+ */
+
+use test;
 
+select value min(distinct array_f) from closedDs2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.12.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.12.query.sqlpp
index 45af77f..fe0ed35 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.12.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct and group by
+ * Expected Res : SUCCESS; "g3" = NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select group_id,min(distinct array_f) from openDs group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.13.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.13.query.sqlpp
index 45af77f..35790e6 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.13.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct and group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,min(distinct array_f) from closedDs1 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.14.query.sqlpp
similarity index 78%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.14.query.sqlpp
index 45af77f..21549f6 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.14.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-min() with distinct and group by
+ * Expected Res : SUCCESS; "g3" ignores NULL tuple
+ */
+
+use test;
 
+select group_id,min(distinct array_f) from closedDs2 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.15.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.15.query.sqlpp
index 45af77f..74f9685 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.15.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar array min -> sql-min()
+ * Expected Res : SUCCESS; id "4" ignores NULL, "6" & "7" = NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select id,array_min(array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.16.query.sqlpp
similarity index 82%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.16.query.sqlpp
index 45af77f..7e7a8e5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.16.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar array min distinct -> sql-min-distinct()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select id,array_min(distinct array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.17.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.17.query.sqlpp
index 45af77f..02d088d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.17.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(array_f) from openDs;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.18.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.18.query.sqlpp
index 45af77f..01546b7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.18.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(array_f) from closedDs1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.19.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.19.query.sqlpp
index 45af77f..e289a1b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.19.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(array_f) from closedDs2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.20.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.20.query.sqlpp
index 45af77f..bbd580b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.20.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max() with group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(array_f) from openDs group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.21.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.21.query.sqlpp
index 45af77f..31e5c6a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.21.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max() with group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(array_f) from closedDs1 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.22.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.22.query.sqlpp
index 45af77f..cf0c45f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.22.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-global-sql-max() & agg-local-sql-max() with group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(array_f) from closedDs2 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.23.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.23.query.sqlpp
index 45af77f..e2c7b74 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.23.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(distinct array_f) from openDs;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.24.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.24.query.sqlpp
index 45af77f..fe846f9 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.24.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(distinct array_f) from closedDs1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.25.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.25.query.sqlpp
index 45af77f..92e7dfd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.25.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select value max(distinct array_f) from closedDs2;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.26.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.26.query.sqlpp
index 45af77f..789b847 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.26.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct and group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(distinct array_f) from openDs group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.27.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.27.query.sqlpp
index 45af77f..c625fbe 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.27.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct and group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(distinct array_f) from closedDs1 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.28.query.sqlpp
similarity index 80%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.28.query.sqlpp
index 45af77f..e0840a7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.28.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : SQL92 agg-sql-max() with distinct and group by
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select group_id,max(distinct array_f) from closedDs2 group by group_id order by group_id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.29.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.29.query.sqlpp
index 45af77f..f968d01 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.29.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar array max -> sql-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select id,array_max(array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.30.query.sqlpp
similarity index 82%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.30.query.sqlpp
index 45af77f..cf2c844 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.30.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar array max distinct -> sql-max-distinct()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select id,array_max(distinct array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp
similarity index 86%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp
index 45af77f..548e632 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp
@@ -16,9 +16,5 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
 
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.01.ddl.sqlpp
similarity index 61%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.01.ddl.sqlpp
index e583e5f..33b1a10 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.01.ddl.sqlpp
@@ -16,16 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.runtime.aggregates.base;
 
-import org.apache.asterix.common.functions.FunctionDescriptorTag;
-import org.apache.asterix.om.functions.AbstractFunctionDescriptor;
+drop dataverse test if exists;
+create dataverse test;
 
-public abstract class AbstractAggregateFunctionDynamicDescriptor extends AbstractFunctionDescriptor {
-    private static final long serialVersionUID = 1L;
+use test;
 
-    public FunctionDescriptorTag getFunctionDescriptorTag() {
-        return FunctionDescriptorTag.AGGREGATE;
-    }
+create type openType as { id : integer, group_id : string };
+create type closedType1 as closed { id : integer, group_id : string, array_f : [int] };
+create type closedType2 as closed { id : integer, group_id : string, array_f : [int]?};
 
-}
+create dataset openDs(openType) primary key id;
+create dataset openDs2(openType) primary key id;
+create dataset closedDs1(closedType1) primary key id;
+create dataset closedDs2(closedType2) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.02.update.sqlpp
new file mode 100644
index 0000000..a1d60cb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.02.update.sqlpp
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+use test;
+
+insert into openDs([
+{"id": 1, "group_id": "g1", "array_f": [4, "str"]},
+{"id": 2, "group_id": "g1", "array_f": [1, "str2"]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, "str3"]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, "str"]},
+{"id": 7, "group_id": "g3", "array_f": [12, "str"]},
+{"id": 8, "group_id": "g3", "array_f": [9, null]}
+]);
+
+insert into openDs2([
+{"id": 1, "group_id": "g1", "array_f": [[4, "str"], [6, "test"], [2, "hi"]]},
+{"id": 2, "group_id": "g1", "array_f": [[1, "str2"], [10, "may"]]},
+{"id": 3, "group_id": "g1", "array_f": [[6.0, "str3"], [4, "june"], [4, "oct"]]},
+
+{"id": 4, "group_id": "g2", "array_f": [[6.0, 7], [12, 18], null]},
+{"id": 5, "group_id": "g2", "array_f": [[6.0, 10], [20, 11]]},
+
+{"id": 6, "group_id": "g3", "array_f": [[6.0, 10], [20, 11], [4, null]]},
+{"id": 7, "group_id": "g3", "array_f": [[6.0, 10], [20, 11], [4, "str"]]}
+]);
+
+insert into closedDs1([
+{"id": 1, "group_id": "g1", "array_f": [4, 3]},
+{"id": 2, "group_id": "g1", "array_f": [9, 7]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, 1]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, 14]},
+{"id": 7, "group_id": "g3", "array_f": [12, 2]},
+{"id": 8, "group_id": "g3", "array_f": [7, 4]}
+]);
+
+insert into closedDs2([
+{"id": 1, "group_id": "g1", "array_f": [4, 3]},
+{"id": 2, "group_id": "g1", "array_f": [9, 7]},
+{"id": 3, "group_id": "g1", "array_f": [6.0, 1]},
+
+{"id": 4, "group_id": "g2", "array_f": [6.0, 7]},
+{"id": 5, "group_id": "g2", "array_f": [6.0, 10]},
+
+{"id": 6, "group_id": "g3", "array_f": [9, 14]},
+{"id": 7, "group_id": "g3", "array_f": [12, 2]},
+{"id": 8, "group_id": "g3", "array_f": null}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.03.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.03.query.sqlpp
index 45af77f..830d96f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.03.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-min() & agg-local-min()
+ * Expected Res : NULL due to INCOMPARABLE
+ */
+
+use test;
 
+strict_min((select value array_f from openDs));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.04.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.04.query.sqlpp
index 45af77f..0daa8d2 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.04.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-min() & agg-local-min()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_min((select value array_f from openDs where group_id = "g1"));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.05.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.05.query.sqlpp
index 45af77f..b1b61c8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.05.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-min() & agg-local-min()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_min((select value array_f from closedDs1));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.06.query.sqlpp
similarity index 81%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.06.query.sqlpp
index 45af77f..ea124af 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.06.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-min() & agg-local-min()
+ * Expected Res : produces NULL due to encountering NULL tuple
+ */
+
+use test;
 
+strict_min((select value array_f from closedDs2));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.07.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.07.query.sqlpp
index 45af77f..7ac8e1e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.07.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-min() with distinct
+ * Expected Res : NULL due to INCOMPARABLE
+ */
+
+use test;
 
+strict_min(distinct (select value array_f from openDs));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.08.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.08.query.sqlpp
index 45af77f..02d882c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.08.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-min() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_min(distinct (select value array_f from openDs where group_id = "g1"));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.09.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.09.query.sqlpp
index 45af77f..a69ccc3 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.09.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-min() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_min(distinct (select value array_f from closedDs1));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.10.query.sqlpp
similarity index 82%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.10.query.sqlpp
index 45af77f..a62deb7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.10.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-min() with distinct
+ * Expected Res : NULL due to encountering NULL tuple
+ */
+
+use test;
 
+strict_min(distinct (select value array_f from closedDs2));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.11.query.sqlpp
similarity index 79%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.11.query.sqlpp
index 45af77f..3893443 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.11.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar strict min -> min()
+ * Expected Res : SUCCESS; id "4" = NULL due to NULL tuple, "6" & "7" = NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select id,strict_min(array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.12.query.sqlpp
similarity index 77%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.12.query.sqlpp
index 45af77f..a421996 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.12.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar strict distinct min -> min-distinct()
+ * Expected Res : SUCCESS; id "4" = NULL due to NULL tuple, "6" & "7" = NULL due to INCOMPARABLE
+ */
+
+use test;
 
+select id,strict_min(distinct array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.13.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.13.query.sqlpp
index 45af77f..a5fa8fa 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.13.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-max() & agg-local-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max((select value array_f from openDs));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.14.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.14.query.sqlpp
index 45af77f..5cb5e8f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.14.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-max() & agg-local-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max((select value array_f from openDs where group_id = "g1"));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.15.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.15.query.sqlpp
index 45af77f..2ddc453 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.15.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-max() & agg-local-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max((select value array_f from closedDs1));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.16.query.sqlpp
similarity index 84%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.16.query.sqlpp
index 45af77f..87cedb5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.16.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-global-max() & agg-local-max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max((select value array_f from closedDs2));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.17.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.17.query.sqlpp
index 45af77f..c6534da 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.17.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max(distinct (select value array_f from openDs));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.18.query.sqlpp
similarity index 83%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.18.query.sqlpp
index 45af77f..5526d69 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.18.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max(distinct (select value array_f from openDs where group_id = "g1"));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.19.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.19.query.sqlpp
index 45af77f..cfb414d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.19.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max(distinct (select value array_f from closedDs1));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.20.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.20.query.sqlpp
index 45af77f..643d51a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.20.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : agg-max() with distinct
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+strict_max(distinct (select value array_f from closedDs2));
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.21.query.sqlpp
similarity index 85%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.21.query.sqlpp
index 45af77f..e382111 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.21.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar strict max -> max()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select id,strict_max(array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.22.query.sqlpp
similarity index 82%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.22.query.sqlpp
index 45af77f..7ea5696 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.22.query.sqlpp
@@ -17,8 +17,10 @@
  * under the License.
  */
 /*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
+ * Description  : scalar strict distinct max -> max-distinct()
+ * Expected Res : SUCCESS
+ */
+
+use test;
 
+select id,strict_max(distinct array_f) from openDs2 order by id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.23.ddl.sqlpp
similarity index 86%
copy from asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.23.ddl.sqlpp
index 45af77f..548e632 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.23.ddl.sqlpp
@@ -16,9 +16,5 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/*
-* Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
-* Date         : Jun 2nd 2013
-*/
 
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
index 45af77f..b25505f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.1.ddl.sqlpp
@@ -18,7 +18,7 @@
  */
 /*
 * Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
+* Expected Res : NULL
 * Date         : Jun 2nd 2013
 */
 
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.3.query.sqlpp
index c55fb2f..a81e400 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_mixed/min_mixed.3.query.sqlpp
@@ -18,7 +18,7 @@
  */
 /*
 * Description  : Run min over an ordered list with mixed types
-* Expected Res : Failure
+* Expected Res : NULL
 * Date         : Jun 2nd 2013
 */
 
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.03.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.03.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.04.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.04.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.05.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.05.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.06.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.06.adm
new file mode 100644
index 0000000..67d8cdb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.06.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 1, "str2" ] }
+{ "group_id": "g2", "$1": [ 6.0, 7 ] }
+{ "group_id": "g3", "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.07.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.07.adm
new file mode 100644
index 0000000..944f143
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.07.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 4, 3 ] }
+{ "group_id": "g2", "$1": [ 6, 7 ] }
+{ "group_id": "g3", "$1": [ 7, 4 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.08.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.08.adm
new file mode 100644
index 0000000..bdb59e3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.08.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 4, 3 ] }
+{ "group_id": "g2", "$1": [ 6, 7 ] }
+{ "group_id": "g3", "$1": [ 9, 14 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.09.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.09.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.09.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.10.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.10.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.10.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.11.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.11.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.12.adm
new file mode 100644
index 0000000..67d8cdb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.12.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 1, "str2" ] }
+{ "group_id": "g2", "$1": [ 6.0, 7 ] }
+{ "group_id": "g3", "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.13.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.13.adm
new file mode 100644
index 0000000..944f143
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.13.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 4, 3 ] }
+{ "group_id": "g2", "$1": [ 6, 7 ] }
+{ "group_id": "g3", "$1": [ 7, 4 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.14.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.14.adm
new file mode 100644
index 0000000..bdb59e3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.14.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 4, 3 ] }
+{ "group_id": "g2", "$1": [ 6, 7 ] }
+{ "group_id": "g3", "$1": [ 9, 14 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.15.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.15.adm
new file mode 100644
index 0000000..821589e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.15.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 2, "hi" ] }
+{ "id": 2, "$1": [ 1, "str2" ] }
+{ "id": 3, "$1": [ 4, "june" ] }
+{ "id": 4, "$1": [ 6.0, 7 ] }
+{ "id": 5, "$1": [ 6.0, 10 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.16.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.16.adm
new file mode 100644
index 0000000..821589e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.16.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 2, "hi" ] }
+{ "id": 2, "$1": [ 1, "str2" ] }
+{ "id": 3, "$1": [ 4, "june" ] }
+{ "id": 4, "$1": [ 6.0, 7 ] }
+{ "id": 5, "$1": [ 6.0, 10 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.17.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.17.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.17.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.18.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.18.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.18.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.19.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.19.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.19.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.20.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.20.adm
new file mode 100644
index 0000000..3750c61
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.20.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 6.0, "str3" ] }
+{ "group_id": "g2", "$1": [ 6.0, 10 ] }
+{ "group_id": "g3", "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.21.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.21.adm
new file mode 100644
index 0000000..498208f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.21.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 9, 7 ] }
+{ "group_id": "g2", "$1": [ 6, 10 ] }
+{ "group_id": "g3", "$1": [ 12, 2 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.22.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.22.adm
new file mode 100644
index 0000000..498208f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.22.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 9, 7 ] }
+{ "group_id": "g2", "$1": [ 6, 10 ] }
+{ "group_id": "g3", "$1": [ 12, 2 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.23.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.23.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.23.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.24.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.24.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.24.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.25.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.25.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.25.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.26.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.26.adm
new file mode 100644
index 0000000..3750c61
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.26.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 6.0, "str3" ] }
+{ "group_id": "g2", "$1": [ 6.0, 10 ] }
+{ "group_id": "g3", "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.27.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.27.adm
new file mode 100644
index 0000000..498208f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.27.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 9, 7 ] }
+{ "group_id": "g2", "$1": [ 6, 10 ] }
+{ "group_id": "g3", "$1": [ 12, 2 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.28.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.28.adm
new file mode 100644
index 0000000..498208f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.28.adm
@@ -0,0 +1,3 @@
+{ "group_id": "g1", "$1": [ 9, 7 ] }
+{ "group_id": "g2", "$1": [ 6, 10 ] }
+{ "group_id": "g3", "$1": [ 12, 2 ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.29.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.29.adm
new file mode 100644
index 0000000..1c1b4e9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.29.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 6, "test" ] }
+{ "id": 2, "$1": [ 10, "may" ] }
+{ "id": 3, "$1": [ 6.0, "str3" ] }
+{ "id": 4, "$1": [ 12, 18 ] }
+{ "id": 5, "$1": [ 20, 11 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.30.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.30.adm
new file mode 100644
index 0000000..1c1b4e9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_max_arrays/min_max_arrays.30.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 6, "test" ] }
+{ "id": 2, "$1": [ 10, "may" ] }
+{ "id": 3, "$1": [ 6.0, "str3" ] }
+{ "id": 4, "$1": [ 12, 18 ] }
+{ "id": 5, "$1": [ 20, 11 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_mixed/min_mixed.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_mixed/min_mixed.1.adm
index e3b97f5..ec747fa 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_mixed/min_mixed.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate-sql/min_mixed/min_mixed.1.adm
@@ -1 +1 @@
-[  ]
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.03.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.03.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.04.adm
new file mode 100644
index 0000000..9362341
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.04.adm
@@ -0,0 +1 @@
+[ 1, "str2" ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.05.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.05.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.06.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.06.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.06.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.07.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.07.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.07.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.08.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.08.adm
new file mode 100644
index 0000000..9362341
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.08.adm
@@ -0,0 +1 @@
+[ 1, "str2" ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.09.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.09.adm
new file mode 100644
index 0000000..2ad7e4f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.09.adm
@@ -0,0 +1 @@
+[ 4, 3 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.10.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.10.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.10.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.11.adm
new file mode 100644
index 0000000..55abf4e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.11.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 2, "hi" ] }
+{ "id": 2, "$1": [ 1, "str2" ] }
+{ "id": 3, "$1": [ 4, "june" ] }
+{ "id": 4, "$1": null }
+{ "id": 5, "$1": [ 6.0, 10 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.12.adm
new file mode 100644
index 0000000..55abf4e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.12.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 2, "hi" ] }
+{ "id": 2, "$1": [ 1, "str2" ] }
+{ "id": 3, "$1": [ 4, "june" ] }
+{ "id": 4, "$1": null }
+{ "id": 5, "$1": [ 6.0, 10 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.13.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.13.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.13.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.14.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.14.adm
new file mode 100644
index 0000000..b304f8d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.14.adm
@@ -0,0 +1 @@
+[ 6.0, "str3" ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.15.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.15.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.15.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.16.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.16.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.16.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.17.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.17.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.17.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.18.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.18.adm
new file mode 100644
index 0000000..b304f8d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.18.adm
@@ -0,0 +1 @@
+[ 6.0, "str3" ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.19.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.19.adm
new file mode 100644
index 0000000..3b4fabf
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.19.adm
@@ -0,0 +1 @@
+[ 12, 2 ]
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.20.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.20.adm
new file mode 100644
index 0000000..ec747fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.20.adm
@@ -0,0 +1 @@
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.21.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.21.adm
new file mode 100644
index 0000000..5d4051d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.21.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 6, "test" ] }
+{ "id": 2, "$1": [ 10, "may" ] }
+{ "id": 3, "$1": [ 6.0, "str3" ] }
+{ "id": 4, "$1": null }
+{ "id": 5, "$1": [ 20, 11 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.22.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.22.adm
new file mode 100644
index 0000000..5d4051d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_max_arrays/min_max_arrays.22.adm
@@ -0,0 +1,7 @@
+{ "id": 1, "$1": [ 6, "test" ] }
+{ "id": 2, "$1": [ 10, "may" ] }
+{ "id": 3, "$1": [ 6.0, "str3" ] }
+{ "id": 4, "$1": null }
+{ "id": 5, "$1": [ 20, 11 ] }
+{ "id": 6, "$1": null }
+{ "id": 7, "$1": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm
index e3b97f5..ec747fa 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/aggregate/min_mixed/min_mixed.1.adm
@@ -1 +1 @@
-[  ]
+null
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 112277c..2a1dbd3 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -223,7 +223,6 @@
     <test-case FilePath="aggregate">
       <compilation-unit name="min_mixed">
         <output-dir compare="Text">min_mixed</output-dir>
-        <expected-error>Type incompatibility: function min/max gets incompatible input values: string and float</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="aggregate">
@@ -1453,9 +1452,19 @@
         <output-dir compare="Text">var_pop_misc</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="aggregate">
+      <compilation-unit name="min_max_arrays">
+        <output-dir compare="Text">min_max_arrays</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="aggregate-sql">
     <test-case FilePath="aggregate-sql">
+      <compilation-unit name="min_max_arrays">
+        <output-dir compare="Text">min_max_arrays</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="aggregate-sql">
       <compilation-unit name="issue531_string_min_max">
         <output-dir compare="Text">issue531_string_min_max</output-dir>
       </compilation-unit>
@@ -1489,7 +1498,6 @@
     <test-case FilePath="aggregate-sql">
       <compilation-unit name="min_mixed">
         <output-dir compare="Text">min_mixed</output-dir>
-        <expected-error>Type incompatibility: function min/max gets incompatible input values: string and float</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="aggregate-sql">
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/ILogicalBinaryComparator.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/ILogicalBinaryComparator.java
index eb99918..982a5a0 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/ILogicalBinaryComparator.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/ILogicalBinaryComparator.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.dataflow.data.common;
 
 import org.apache.asterix.om.base.IAObject;
+import org.apache.asterix.om.types.ATypeTag;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
@@ -37,6 +38,26 @@ public interface ILogicalBinaryComparator {
         return result < 0 ? Result.LT : (result == 0 ? Result.EQ : Result.GT);
     }
 
+    static boolean inequalityUndefined(ATypeTag tag) {
+        switch (tag) {
+            case OBJECT:
+            case MULTISET:
+            case DURATION:
+            case INTERVAL:
+            case LINE:
+            case POINT:
+            case POINT3D:
+            case POLYGON:
+            case CIRCLE:
+            case RECTANGLE:
+                return true;
+            case UNION:
+                throw new IllegalArgumentException();
+            default:
+                return false;
+        }
+    }
+
     Result compare(IPointable left, IPointable right) throws HyracksDataException;
 
     Result compare(IPointable left, IAObject rightConstant);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ComparatorUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ComparatorUtil.java
index 9cd2723..6f08b37 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ComparatorUtil.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ComparatorUtil.java
@@ -59,13 +59,12 @@ public class ComparatorUtil {
         IAType leftType = TypeComputeUtils.getActualType(left);
         IAType rightType = TypeComputeUtils.getActualType(right);
 
-        // TODO(ali): after making comparators in scalar comparator stateless, create an INSTANCE only and use it here
         if (leftType.getTypeTag().isDerivedType() && rightType.getTypeTag().isDerivedType()) {
             return new LogicalComplexBinaryComparator(leftType, rightType, isEquality);
         } else if (leftType.getTypeTag() == ATypeTag.ANY || rightType.getTypeTag() == ATypeTag.ANY) {
             return new LogicalGenericBinaryComparator(leftType, rightType, isEquality);
         } else {
-            return new LogicalScalarBinaryComparator(isEquality);
+            return LogicalScalarBinaryComparator.of(isEquality);
         }
     }
 
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalComplexBinaryComparator.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalComplexBinaryComparator.java
index e1becc4..a4fce6d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalComplexBinaryComparator.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalComplexBinaryComparator.java
@@ -51,7 +51,7 @@ import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.util.string.UTF8StringUtil;
 
-public class LogicalComplexBinaryComparator implements ILogicalBinaryComparator {
+public final class LogicalComplexBinaryComparator implements ILogicalBinaryComparator {
 
     private final IAType leftType;
     private final IAType rightType;
@@ -66,7 +66,7 @@ public class LogicalComplexBinaryComparator implements ILogicalBinaryComparator
         this.leftType = leftType;
         this.rightType = rightType;
         this.isEquality = isEquality;
-        this.scalarComparator = new LogicalScalarBinaryComparator(isEquality);
+        this.scalarComparator = LogicalScalarBinaryComparator.of(isEquality);
         storageAllocator = new ListObjectPool<>(STORAGE_FACTORY);
         voidPointableAllocator = new ListObjectPool<>(VOID_FACTORY);
         bitSetAllocator = new ListObjectPool<>(BIT_SET_FACTORY);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalGenericBinaryComparator.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalGenericBinaryComparator.java
index 51a782d..57dbb33 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalGenericBinaryComparator.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalGenericBinaryComparator.java
@@ -27,14 +27,14 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-public class LogicalGenericBinaryComparator implements ILogicalBinaryComparator {
+public final class LogicalGenericBinaryComparator implements ILogicalBinaryComparator {
 
     private final LogicalComplexBinaryComparator complexComparator;
     private final LogicalScalarBinaryComparator scalarComparator;
 
     LogicalGenericBinaryComparator(IAType leftType, IAType rightType, boolean isEquality) {
         complexComparator = new LogicalComplexBinaryComparator(leftType, rightType, isEquality);
-        scalarComparator = new LogicalScalarBinaryComparator(isEquality);
+        scalarComparator = LogicalScalarBinaryComparator.of(isEquality);
     }
 
     @Override
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalScalarBinaryComparator.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalScalarBinaryComparator.java
index f0e31c4..f2f637a 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalScalarBinaryComparator.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/LogicalScalarBinaryComparator.java
@@ -18,18 +18,9 @@
  */
 package org.apache.asterix.dataflow.data.nontagged.comparators;
 
-import static org.apache.asterix.om.types.ATypeTag.CIRCLE;
-import static org.apache.asterix.om.types.ATypeTag.DURATION;
-import static org.apache.asterix.om.types.ATypeTag.INTERVAL;
-import static org.apache.asterix.om.types.ATypeTag.LINE;
-import static org.apache.asterix.om.types.ATypeTag.POINT;
-import static org.apache.asterix.om.types.ATypeTag.POINT3D;
-import static org.apache.asterix.om.types.ATypeTag.POLYGON;
-import static org.apache.asterix.om.types.ATypeTag.RECTANGLE;
+import static org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator.inequalityUndefined;
 import static org.apache.asterix.om.types.ATypeTag.VALUE_TYPE_MAPPING;
 
-import java.util.EnumSet;
-
 import org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator;
 import org.apache.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
 import org.apache.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
@@ -47,14 +38,18 @@ import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
 
 public final class LogicalScalarBinaryComparator implements ILogicalBinaryComparator {
 
-    private static final EnumSet<ATypeTag> INEQUALITY_UNDEFINED_TYPES =
-            EnumSet.of(DURATION, INTERVAL, LINE, POINT, POINT3D, POLYGON, CIRCLE, RECTANGLE);
     private final boolean isEquality;
+    private static final LogicalScalarBinaryComparator INSTANCE_EQ = new LogicalScalarBinaryComparator(true);
+    private static final LogicalScalarBinaryComparator INSTANCE_INEQ = new LogicalScalarBinaryComparator(false);
 
-    LogicalScalarBinaryComparator(boolean isEquality) {
+    private LogicalScalarBinaryComparator(boolean isEquality) {
         this.isEquality = isEquality;
     }
 
+    static LogicalScalarBinaryComparator of(boolean isEquality) {
+        return isEquality ? INSTANCE_EQ : INSTANCE_INEQ;
+    }
+
     @Override
     public Result compare(IPointable left, IPointable right) throws HyracksDataException {
         ATypeTag leftTag = VALUE_TYPE_MAPPING[left.getByteArray()[left.getStartOffset()]];
@@ -206,7 +201,6 @@ public final class LogicalScalarBinaryComparator implements ILogicalBinaryCompar
     }
 
     private static boolean comparisonUndefined(ATypeTag leftTag, ATypeTag rightTag, boolean isEquality) {
-        return !isEquality
-                && (INEQUALITY_UNDEFINED_TYPES.contains(leftTag) || INEQUALITY_UNDEFINED_TYPES.contains(rightTag));
+        return !isEquality && (inequalityUndefined(leftTag) || inequalityUndefined(rightTag));
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 06dcb89..e53d0bd 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -517,9 +517,13 @@ public class BuiltinFunctions {
     public static final FunctionIdentifier MAX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-max", 1);
     public static final FunctionIdentifier LOCAL_MAX =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-max", 1);
+    public static final FunctionIdentifier GLOBAL_MAX =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-max", 1);
     public static final FunctionIdentifier MIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-min", 1);
     public static final FunctionIdentifier LOCAL_MIN =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-min", 1);
+    public static final FunctionIdentifier GLOBAL_MIN =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-min", 1);
     public static final FunctionIdentifier GLOBAL_AVG =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-avg", 1);
     public static final FunctionIdentifier INTERMEDIATE_AVG =
@@ -779,10 +783,14 @@ public class BuiltinFunctions {
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-sql-max", 1);
     public static final FunctionIdentifier LOCAL_SQL_MAX =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-sql-max", 1);
+    public static final FunctionIdentifier GLOBAL_SQL_MAX =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-sql-max", 1);
     public static final FunctionIdentifier SQL_MIN =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-sql-min", 1);
     public static final FunctionIdentifier LOCAL_SQL_MIN =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-local-sql-min", 1);
+    public static final FunctionIdentifier GLOBAL_SQL_MIN =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-sql-min", 1);
     public static final FunctionIdentifier GLOBAL_SQL_AVG =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "agg-global-sql-avg", 1);
     public static final FunctionIdentifier LOCAL_SQL_AVG =
@@ -1805,8 +1813,10 @@ public class BuiltinFunctions {
         addFunction(SCALAR_ARRAYAGG, ScalarArrayAggTypeComputer.INSTANCE, true);
         addFunction(MAX, MinMaxAggTypeComputer.INSTANCE, true);
         addPrivateFunction(LOCAL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
+        addPrivateFunction(GLOBAL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
         addFunction(MIN, MinMaxAggTypeComputer.INSTANCE, true);
         addPrivateFunction(LOCAL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
+        addPrivateFunction(GLOBAL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
         addPrivateFunction(NON_EMPTY_STREAM, ABooleanTypeComputer.INSTANCE, true);
         addFunction(COUNT, AInt64TypeComputer.INSTANCE, true);
         addPrivateFunction(LOCAL_AVG, LocalAvgTypeComputer.INSTANCE, true);
@@ -1930,8 +1940,10 @@ public class BuiltinFunctions {
         addFunction(SQL_COUNT, AInt64TypeComputer.INSTANCE, true);
         addFunction(SQL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
         addPrivateFunction(LOCAL_SQL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
+        addPrivateFunction(GLOBAL_SQL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
         addFunction(SQL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
         addPrivateFunction(LOCAL_SQL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
+        addPrivateFunction(GLOBAL_SQL_MIN, MinMaxAggTypeComputer.INSTANCE, true);
         addFunction(SCALAR_SQL_AVG, NullableDoubleTypeComputer.INSTANCE, true);
         addFunction(SCALAR_SQL_COUNT, AInt64TypeComputer.INSTANCE, true);
         addPrivateFunction(SCALAR_GLOBAL_SQL_AVG, NullableDoubleTypeComputer.INSTANCE, true);
@@ -2413,18 +2425,18 @@ public class BuiltinFunctions {
         addScalarAgg(COUNT_DISTINCT, SCALAR_COUNT_DISTINCT);
 
         // MAX
-
         addAgg(MAX);
         addAgg(LOCAL_MAX);
+        addAgg(GLOBAL_MAX);
         addLocalAgg(MAX, LOCAL_MAX);
-        addIntermediateAgg(LOCAL_MAX, MAX);
-        addIntermediateAgg(MAX, MAX);
-        addGlobalAgg(MAX, MAX);
+        addIntermediateAgg(LOCAL_MAX, GLOBAL_MAX);
+        addIntermediateAgg(GLOBAL_MAX, GLOBAL_MAX);
+        addIntermediateAgg(MAX, GLOBAL_MAX);
+        addGlobalAgg(MAX, GLOBAL_MAX);
 
         addScalarAgg(MAX, SCALAR_MAX);
 
         // MAX DISTINCT
-
         addDistinctAgg(MAX_DISTINCT, MAX);
         addScalarAgg(MAX_DISTINCT, SCALAR_MAX_DISTINCT);
 
@@ -2651,17 +2663,18 @@ public class BuiltinFunctions {
         addGlobalAgg(NULL_WRITER, NULL_WRITER);
 
         // MIN
-
         addAgg(MIN);
+        addAgg(LOCAL_MIN);
+        addAgg(GLOBAL_MIN);
         addLocalAgg(MIN, LOCAL_MIN);
-        addIntermediateAgg(LOCAL_MIN, MIN);
-        addIntermediateAgg(MIN, MIN);
-        addGlobalAgg(MIN, MIN);
+        addIntermediateAgg(LOCAL_MIN, GLOBAL_MIN);
+        addIntermediateAgg(GLOBAL_MIN, GLOBAL_MIN);
+        addIntermediateAgg(MIN, GLOBAL_MIN);
+        addGlobalAgg(MIN, GLOBAL_MIN);
 
         addScalarAgg(MIN, SCALAR_MIN);
 
         // MIN DISTINCT
-
         addDistinctAgg(MIN_DISTINCT, MIN);
         addScalarAgg(MIN_DISTINCT, SCALAR_MIN_DISTINCT);
 
@@ -2949,33 +2962,34 @@ public class BuiltinFunctions {
         addScalarAgg(SQL_COUNT_DISTINCT, SCALAR_SQL_COUNT_DISTINCT);
 
         // SQL MAX
-
         addAgg(SQL_MAX);
         addAgg(LOCAL_SQL_MAX);
+        addAgg(GLOBAL_SQL_MAX);
         addLocalAgg(SQL_MAX, LOCAL_SQL_MAX);
-        addIntermediateAgg(LOCAL_SQL_MAX, SQL_MAX);
-        addIntermediateAgg(SQL_MAX, SQL_MAX);
-        addGlobalAgg(SQL_MAX, SQL_MAX);
+        addIntermediateAgg(LOCAL_SQL_MAX, GLOBAL_SQL_MAX);
+        addIntermediateAgg(GLOBAL_SQL_MAX, GLOBAL_SQL_MAX);
+        addIntermediateAgg(SQL_MAX, GLOBAL_SQL_MAX);
+        addGlobalAgg(SQL_MAX, GLOBAL_SQL_MAX);
 
         addScalarAgg(SQL_MAX, SCALAR_SQL_MAX);
 
         // SQL MAX DISTINCT
-
         addDistinctAgg(SQL_MAX_DISTINCT, SQL_MAX);
         addScalarAgg(SQL_MAX_DISTINCT, SCALAR_SQL_MAX_DISTINCT);
 
         // SQL MIN
-
         addAgg(SQL_MIN);
+        addAgg(LOCAL_SQL_MIN);
+        addAgg(GLOBAL_SQL_MIN);
         addLocalAgg(SQL_MIN, LOCAL_SQL_MIN);
-        addIntermediateAgg(LOCAL_SQL_MIN, SQL_MIN);
-        addIntermediateAgg(SQL_MIN, SQL_MIN);
-        addGlobalAgg(SQL_MIN, SQL_MIN);
+        addIntermediateAgg(LOCAL_SQL_MIN, GLOBAL_SQL_MIN);
+        addIntermediateAgg(GLOBAL_SQL_MIN, GLOBAL_SQL_MIN);
+        addIntermediateAgg(SQL_MIN, GLOBAL_SQL_MIN);
+        addGlobalAgg(SQL_MIN, GLOBAL_SQL_MIN);
 
         addScalarAgg(SQL_MIN, SCALAR_SQL_MIN);
 
         // SQL MIN DISTINCT
-
         addDistinctAgg(SQL_MIN_DISTINCT, SQL_MIN);
         addScalarAgg(SQL_MIN_DISTINCT, SCALAR_SQL_MIN_DISTINCT);
 
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
index 596ef67..c34b5ed 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/MinMaxAggTypeComputer.java
@@ -18,15 +18,14 @@
  */
 package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.exceptions.UnsupportedTypeException;
+import org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator;
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.api.exceptions.SourceLocation;
 
 public class MinMaxAggTypeComputer extends AbstractResultTypeComputer {
 
@@ -36,31 +35,11 @@ public class MinMaxAggTypeComputer extends AbstractResultTypeComputer {
     }
 
     @Override
-    protected void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
-            throws AlgebricksException {
-        ATypeTag tag = type.getTypeTag();
-        switch (tag) {
-            case DOUBLE:
-            case FLOAT:
-            case BIGINT:
-            case INTEGER:
-            case SMALLINT:
-            case TINYINT:
-            case STRING:
-            case DATE:
-            case TIME:
-            case DATETIME:
-            case YEARMONTHDURATION:
-            case DAYTIMEDURATION:
-            case ANY:
-                return;
-            default:
-                throw new UnsupportedTypeException(sourceLoc, funcId, tag);
-        }
-    }
-
-    @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        return AUnionType.createUnknownableType(strippedInputTypes[0]);
+        ATypeTag typeTag = strippedInputTypes[0].getTypeTag();
+        if (ILogicalBinaryComparator.inequalityUndefined(typeTag)) {
+            return BuiltinType.ANULL;
+        }
+        return typeTag == ATypeTag.ANY ? BuiltinType.ANY : AUnionType.createUnknownableType(strippedInputTypes[0]);
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
index fd1e136..5b90974 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ScalarVersionOfAggregateResultType.java
@@ -53,6 +53,7 @@ public class ScalarVersionOfAggregateResultType extends AbstractResultTypeComput
             return BuiltinType.ANY;
         }
         if (tag != ATypeTag.ARRAY && tag != ATypeTag.MULTISET) {
+            // this condition being true would've thrown an exception above, no?
             return strippedInputTypes[0];
         }
         AbstractCollectionType act = (AbstractCollectionType) strippedInputTypes[0];
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java
index 097b4a7..426d361 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AOrderedListType.java
@@ -53,21 +53,21 @@ public class AOrderedListType extends AbstractCollectionType {
 
     @Override
     public String toString() {
-        return "[ " + itemType + " ]";
+        return "[ " + getItemType() + " ]";
     }
 
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof AOrderedListType) {
             AOrderedListType type = (AOrderedListType) obj;
-            return this.itemType.equals(type.itemType);
+            return this.getItemType().equals(type.getItemType());
         }
         return false;
     }
 
     @Override
     public int hashCode() {
-        return this.itemType.hashCode() * 10;
+        return this.getItemType().hashCode() * 10;
     }
 
     @Override
@@ -85,7 +85,7 @@ public class AOrderedListType extends AbstractCollectionType {
         ObjectMapper om = new ObjectMapper();
         ObjectNode type = om.createObjectNode();
         type.put("type", AOrderedListType.class.getName());
-        type.set("item-type", itemType.toJSON());
+        type.set("item-type", getItemType().toJSON());
         return type;
     }
 
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnorderedListType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnorderedListType.java
index 711b2f3..6d72119 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnorderedListType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AUnorderedListType.java
@@ -53,21 +53,21 @@ public class AUnorderedListType extends AbstractCollectionType {
 
     @Override
     public String toString() {
-        return "{{ " + itemType + " }}";
+        return "{{ " + getItemType() + " }}";
     }
 
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof AUnorderedListType) {
             AUnorderedListType type = (AUnorderedListType) obj;
-            return this.itemType.equals(type.itemType);
+            return this.getItemType().equals(type.getItemType());
         }
         return false;
     }
 
     @Override
     public int hashCode() {
-        return this.itemType.hashCode() * 10;
+        return this.getItemType().hashCode() * 10;
     }
 
     @Override
@@ -85,7 +85,7 @@ public class AUnorderedListType extends AbstractCollectionType {
         ObjectMapper om = new ObjectMapper();
         ObjectNode type = om.createObjectNode();
         type.put("type", AUnorderedListType.class.getName());
-        type.set("item-type", itemType.toJSON());
+        type.set("item-type", getItemType().toJSON());
         return type;
     }
 
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
index 4b748a9..ef15224 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/AbstractCollectionType.java
@@ -31,7 +31,7 @@ public abstract class AbstractCollectionType extends AbstractComplexType {
 
     private static final long serialVersionUID = 1L;
     private static final String ITEM_TYPE_FIELD = "itemType";
-    protected IAType itemType;
+    private IAType itemType;
 
     AbstractCollectionType(IAType itemType, String typeName) {
         super(typeName);
@@ -39,6 +39,7 @@ public abstract class AbstractCollectionType extends AbstractComplexType {
     }
 
     public boolean isTyped() {
+        // TODO(ali): this should be removed. itemType is already enforced to be NonNull
         return itemType != null;
     }
 
@@ -47,7 +48,7 @@ public abstract class AbstractCollectionType extends AbstractComplexType {
     }
 
     public void setItemType(IAType itemType) {
-        this.itemType = itemType;
+        this.itemType = Objects.requireNonNull(itemType);
     }
 
     @Override
@@ -58,7 +59,7 @@ public abstract class AbstractCollectionType extends AbstractComplexType {
     @Override
     public void generateNestedDerivedTypeNames() {
         if (itemType.getTypeTag().isDerivedType() && itemType.getTypeName() == null) {
-            AbstractComplexType nestedType = ((AbstractComplexType) itemType);
+            AbstractComplexType nestedType = (AbstractComplexType) itemType;
             nestedType.setTypeName(getTypeName() + "_Item");
             nestedType.generateNestedDerivedTypeNames();
         }
@@ -69,16 +70,16 @@ public abstract class AbstractCollectionType extends AbstractComplexType {
         return isTyped() && itemType.getTypeName().equals(type.getTypeName());
     }
 
-    protected JsonNode convertToJson(IPersistedResourceRegistry registry, Class<? extends IJsonSerializable> clazz,
-            long version) throws HyracksDataException {
+    JsonNode convertToJson(IPersistedResourceRegistry registry, Class<? extends IJsonSerializable> clazz, long version)
+            throws HyracksDataException {
         final ObjectNode jsonObject = registry.getClassIdentifier(clazz, version);
         addToJson(jsonObject);
         jsonObject.set(ITEM_TYPE_FIELD, itemType.toJson(registry));
         return jsonObject;
     }
 
-    protected static IJsonSerializable convertToObject(IPersistedResourceRegistry registry, JsonNode json,
-            boolean ordered) throws HyracksDataException {
+    static IJsonSerializable convertToObject(IPersistedResourceRegistry registry, JsonNode json, boolean ordered)
+            throws HyracksDataException {
         String typeName = json.get(TYPE_NAME_FIELD).asText();
         JsonNode itemTypeJson = json.get(ITEM_TYPE_FIELD);
         IAType itemType = (IAType) registry.deserialize(itemTypeJson);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/TypeHelper.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/TypeHelper.java
index 2e403ce..b444053 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/TypeHelper.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/types/TypeHelper.java
@@ -18,17 +18,22 @@
  */
 package org.apache.asterix.om.types;
 
+import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
+import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
+
 public class TypeHelper {
 
+    private TypeHelper() {
+    }
+
     public static boolean canBeMissing(IAType t) {
         switch (t.getTypeTag()) {
             case MISSING:
                 return true;
             case UNION:
                 return ((AUnionType) t).isMissableType();
-            default: {
+            default:
                 return false;
-            }
         }
     }
 
@@ -57,4 +62,29 @@ public class TypeHelper {
         }
     }
 
+    /**
+     * Decides whether the {@param type} represents a type for data in the "opened up" form.
+     * @param type type
+     * @return true if the type will represent data in the "opened up" form. False, otherwise.
+     */
+    public static boolean isFullyOpen(IAType type) {
+        IAType actualType = TypeComputeUtils.getActualType(type);
+        switch (actualType.getTypeTag()) {
+            case OBJECT:
+                ARecordType recordType = (ARecordType) actualType;
+                return recordType.getFieldNames().length == 0 && recordType.isOpen();
+            case ARRAY:
+            case MULTISET:
+                AbstractCollectionType collectionType = (AbstractCollectionType) actualType;
+                return TypeComputeUtils.getActualType(collectionType.getItemType()).getTypeTag() == ATypeTag.ANY;
+            case ANY:
+                return true;
+            default:
+                if (actualType.getTypeTag().isDerivedType()) {
+                    throw new NotImplementedException();
+                }
+                // all other scalar types & ANY are open by nature and they don't need to be "opened up"
+                return true;
+        }
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
index e583e5f..dcf9f5f 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
@@ -18,12 +18,22 @@
  */
 package org.apache.asterix.runtime.aggregates.base;
 
+import java.util.function.Supplier;
+
 import org.apache.asterix.common.functions.FunctionDescriptorTag;
 import org.apache.asterix.om.functions.AbstractFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.asterix.runtime.utils.DescriptorFactoryUtil;
 
 public abstract class AbstractAggregateFunctionDynamicDescriptor extends AbstractFunctionDescriptor {
     private static final long serialVersionUID = 1L;
 
+    public static IFunctionDescriptorFactory createFactory(Supplier<IFunctionDescriptor> descriptorSupplier) {
+        return DescriptorFactoryUtil.createFactory(descriptorSupplier, FunctionTypeInferers.SET_ARGUMENT_TYPE);
+    }
+
     public FunctionDescriptorTag getFunctionDescriptorTag() {
         return FunctionDescriptorTag.AGGREGATE;
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java
index 6cc119e..b3b69dc 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateDescriptor.java
@@ -23,6 +23,7 @@ import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.om.functions.IFunctionTypeInferer;
 import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.asterix.runtime.functions.FunctionTypeInferers;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -39,16 +40,18 @@ public class ListifyAggregateDescriptor extends AbstractAggregateFunctionDynamic
 
         @Override
         public IFunctionTypeInferer createFunctionTypeInferer() {
-            return FunctionTypeInferers.SET_EXPRESSION_TYPE;
+            return FunctionTypeInferers.LISTIFY_INFERER;
         }
     };
 
     private static final long serialVersionUID = 1L;
     private AOrderedListType oltype;
+    private IAType itemType;
 
     @Override
     public void setImmutableStates(Object... states) {
         this.oltype = (AOrderedListType) states[0];
+        this.itemType = (IAType) states[1];
     }
 
     @Override
@@ -58,6 +61,6 @@ public class ListifyAggregateDescriptor extends AbstractAggregateFunctionDynamic
 
     @Override
     public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
-        return new ListifyAggregateFunctionEvalFactory(args, oltype, sourceLoc);
+        return new ListifyAggregateFunctionEvalFactory(args, oltype, itemType, sourceLoc);
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java
index e2e2859..21429f1 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/collections/ListifyAggregateFunctionEvalFactory.java
@@ -22,7 +22,12 @@ import java.io.IOException;
 
 import org.apache.asterix.builders.OrderedListBuilder;
 import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.TypeHelper;
 import org.apache.asterix.runtime.aggregates.std.AbstractAggregateFunction;
+import org.apache.asterix.runtime.evaluators.functions.CastTypeEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -39,13 +44,15 @@ public class ListifyAggregateFunctionEvalFactory implements IAggregateEvaluatorF
 
     private static final long serialVersionUID = 1L;
     private IScalarEvaluatorFactory[] args;
-    private final AOrderedListType orderedlistType;
+    private final AOrderedListType orderedListType;
+    private final IAType itemType;
     private final SourceLocation sourceLoc;
 
-    public ListifyAggregateFunctionEvalFactory(IScalarEvaluatorFactory[] args, AOrderedListType type,
+    ListifyAggregateFunctionEvalFactory(IScalarEvaluatorFactory[] args, AOrderedListType type, IAType itemType,
             SourceLocation sourceLoc) {
         this.args = args;
-        this.orderedlistType = type;
+        this.orderedListType = type;
+        this.itemType = itemType;
         this.sourceLoc = sourceLoc;
     }
 
@@ -57,16 +64,24 @@ public class ListifyAggregateFunctionEvalFactory implements IAggregateEvaluatorF
             private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
             private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
             private OrderedListBuilder builder = new OrderedListBuilder();
+            // create caster to open up input item if the list item type is ANY but the received item is not fully open
+            private final CastTypeEvaluator caster =
+                    orderedListType.getItemType().getTypeTag() == ATypeTag.ANY && !TypeHelper.isFullyOpen(itemType)
+                            ? new CastTypeEvaluator(BuiltinType.ANY, itemType, eval) : null;
 
             @Override
             public void init() throws HyracksDataException {
-                builder.reset(orderedlistType);
+                builder.reset(orderedListType);
             }
 
             @Override
             public void step(IFrameTupleReference tuple) throws HyracksDataException {
                 try {
-                    eval.evaluate(tuple, inputVal);
+                    if (caster != null) {
+                        caster.evaluate(tuple, inputVal);
+                    } else {
+                        eval.evaluate(tuple, inputVal);
+                    }
                     builder.addItem(inputVal);
                 } catch (IOException e) {
                     throw HyracksDataException.create(e);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
index a220e67..db31b1c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarAggregateDescriptor.java
@@ -18,13 +18,18 @@
  */
 package org.apache.asterix.runtime.aggregates.scalar;
 
+import java.util.function.Supplier;
+
+import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
 import org.apache.asterix.runtime.unnestingfunctions.std.ScanCollectionDescriptor.ScanCollectionUnnestingFunctionFactory;
+import org.apache.asterix.runtime.utils.DescriptorFactoryUtil;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
@@ -85,4 +90,8 @@ public abstract class AbstractScalarAggregateDescriptor extends AbstractScalarFu
         IAType itemType = TypeComputeUtils.extractListItemType(listType);
         return itemType != null ? itemType : BuiltinType.ANY;
     }
+
+    public static IFunctionDescriptorFactory createDescriptorFactory(Supplier<IFunctionDescriptor> descriptorSupplier) {
+        return DescriptorFactoryUtil.createFactory(descriptorSupplier, FunctionTypeInferers.SET_ARGUMENT_TYPE);
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarDistinctAggregateDescriptor.java
index 2059a2b..3ea4ccc 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/AbstractScalarDistinctAggregateDescriptor.java
@@ -19,14 +19,9 @@
 
 package org.apache.asterix.runtime.aggregates.scalar;
 
-import java.util.function.Supplier;
-
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.runtime.functions.FunctionTypeInferers;
 import org.apache.asterix.runtime.unnestingfunctions.std.ScanCollectionDescriptor;
-import org.apache.asterix.runtime.utils.DescriptorFactoryUtil;
 import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
@@ -52,8 +47,4 @@ public abstract class AbstractScalarDistinctAggregateDescriptor extends Abstract
             IHyracksTaskContext ctx) throws HyracksDataException {
         return new GenericScalarDistinctAggregateFunction(aggEval, scanCollectionFactory, ctx, sourceLoc, itemType);
     }
-
-    public static IFunctionDescriptorFactory createDescriptorFactory(Supplier<IFunctionDescriptor> descriptorSupplier) {
-        return DescriptorFactoryUtil.createFactory(descriptorSupplier, FunctionTypeInferers.SET_ARGUMENT_TYPE);
-    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggAggregateDescriptor.java
index 8d99d4d..c764cf2 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggAggregateDescriptor.java
@@ -44,7 +44,7 @@ public final class ScalarArrayAggAggregateDescriptor extends AbstractScalarAggre
         super.setImmutableStates(states);
         // listify() needs an ordered list type for its output
         IAType itemType = getItemType((IAType) states[0]);
-        aggFuncDesc.setImmutableStates(new AOrderedListType(itemType, null));
+        aggFuncDesc.setImmutableStates(new AOrderedListType(itemType, null), itemType);
     }
 
     @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggDistinctAggregateDescriptor.java
index ec7c547..9f04979 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarArrayAggDistinctAggregateDescriptor.java
@@ -40,7 +40,7 @@ public final class ScalarArrayAggDistinctAggregateDescriptor extends AbstractSca
     public void setImmutableStates(Object... states) {
         super.setImmutableStates(states);
         // listify() needs an ordered list type for its output
-        aggFuncDesc.setImmutableStates(new AOrderedListType(itemType, null));
+        aggFuncDesc.setImmutableStates(new AOrderedListType(itemType, null), itemType);
     }
 
     @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java
index 961890a..2f6602e 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxAggregateDescriptor.java
@@ -20,6 +20,7 @@ package org.apache.asterix.runtime.aggregates.scalar;
 
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.std.MaxAggregateDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -27,9 +28,7 @@ public class ScalarMaxAggregateDescriptor extends AbstractScalarAggregateDescrip
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_MAX;
-
-    public static final IFunctionDescriptorFactory FACTORY = ScalarMaxAggregateDescriptor::new;
+    public static final IFunctionDescriptorFactory FACTORY = createDescriptorFactory(ScalarMaxAggregateDescriptor::new);
 
     private ScalarMaxAggregateDescriptor() {
         super(MaxAggregateDescriptor.FACTORY);
@@ -37,6 +36,12 @@ public class ScalarMaxAggregateDescriptor extends AbstractScalarAggregateDescrip
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_MAX;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(getItemType((IAType) states[0]));
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxDistinctAggregateDescriptor.java
index 77b462b..4a33b5c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMaxDistinctAggregateDescriptor.java
@@ -28,8 +28,6 @@ public class ScalarMaxDistinctAggregateDescriptor extends AbstractScalarDistinct
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_MAX_DISTINCT;
-
     public static final IFunctionDescriptorFactory FACTORY =
             createDescriptorFactory(ScalarMaxDistinctAggregateDescriptor::new);
 
@@ -39,6 +37,12 @@ public class ScalarMaxDistinctAggregateDescriptor extends AbstractScalarDistinct
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_MAX_DISTINCT;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(itemType);
     }
 }
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java
index 706dfcd..1b454a3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinAggregateDescriptor.java
@@ -20,6 +20,7 @@ package org.apache.asterix.runtime.aggregates.scalar;
 
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.std.MinAggregateDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -27,9 +28,7 @@ public class ScalarMinAggregateDescriptor extends AbstractScalarAggregateDescrip
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_MIN;
-
-    public static final IFunctionDescriptorFactory FACTORY = ScalarMinAggregateDescriptor::new;
+    public static final IFunctionDescriptorFactory FACTORY = createDescriptorFactory(ScalarMinAggregateDescriptor::new);
 
     private ScalarMinAggregateDescriptor() {
         super(MinAggregateDescriptor.FACTORY);
@@ -37,6 +36,12 @@ public class ScalarMinAggregateDescriptor extends AbstractScalarAggregateDescrip
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_MIN;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(getItemType((IAType) states[0]));
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinDistinctAggregateDescriptor.java
index 2affa37..4149b7d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarMinDistinctAggregateDescriptor.java
@@ -28,8 +28,6 @@ public class ScalarMinDistinctAggregateDescriptor extends AbstractScalarDistinct
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_MIN_DISTINCT;
-
     public static final IFunctionDescriptorFactory FACTORY =
             createDescriptorFactory(ScalarMinDistinctAggregateDescriptor::new);
 
@@ -39,6 +37,12 @@ public class ScalarMinDistinctAggregateDescriptor extends AbstractScalarDistinct
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_MIN_DISTINCT;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(itemType);
     }
 }
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxAggregateDescriptor.java
index 9e47104..e971665 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxAggregateDescriptor.java
@@ -20,6 +20,7 @@ package org.apache.asterix.runtime.aggregates.scalar;
 
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.std.SqlMaxAggregateDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -27,16 +28,21 @@ public class ScalarSqlMaxAggregateDescriptor extends AbstractScalarAggregateDesc
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_SQL_MAX;
+    public static final IFunctionDescriptorFactory FACTORY =
+            createDescriptorFactory(ScalarSqlMaxAggregateDescriptor::new);
 
-    public static final IFunctionDescriptorFactory FACTORY = ScalarSqlMaxAggregateDescriptor::new;
-
-    public ScalarSqlMaxAggregateDescriptor() {
+    private ScalarSqlMaxAggregateDescriptor() {
         super(SqlMaxAggregateDescriptor.FACTORY);
     }
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_SQL_MAX;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(getItemType((IAType) states[0]));
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxDistinctAggregateDescriptor.java
index 3f73592..e258879 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMaxDistinctAggregateDescriptor.java
@@ -28,17 +28,21 @@ public class ScalarSqlMaxDistinctAggregateDescriptor extends AbstractScalarDisti
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_SQL_MAX_DISTINCT;
-
     public static final IFunctionDescriptorFactory FACTORY =
             createDescriptorFactory(ScalarSqlMaxDistinctAggregateDescriptor::new);
 
-    public ScalarSqlMaxDistinctAggregateDescriptor() {
+    private ScalarSqlMaxDistinctAggregateDescriptor() {
         super(SqlMaxAggregateDescriptor.FACTORY);
     }
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_SQL_MAX_DISTINCT;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(itemType);
     }
 }
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinAggregateDescriptor.java
index 2d4267d..9e228c1 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinAggregateDescriptor.java
@@ -20,6 +20,7 @@ package org.apache.asterix.runtime.aggregates.scalar;
 
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.std.SqlMinAggregateDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -27,9 +28,8 @@ public class ScalarSqlMinAggregateDescriptor extends AbstractScalarAggregateDesc
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_SQL_MIN;
-
-    public static final IFunctionDescriptorFactory FACTORY = ScalarSqlMinAggregateDescriptor::new;
+    public static final IFunctionDescriptorFactory FACTORY =
+            createDescriptorFactory(ScalarSqlMinAggregateDescriptor::new);
 
     private ScalarSqlMinAggregateDescriptor() {
         super(SqlMinAggregateDescriptor.FACTORY);
@@ -37,6 +37,12 @@ public class ScalarSqlMinAggregateDescriptor extends AbstractScalarAggregateDesc
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_SQL_MIN;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(getItemType((IAType) states[0]));
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinDistinctAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinDistinctAggregateDescriptor.java
index 25d69c3..224c595 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinDistinctAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/scalar/ScalarSqlMinDistinctAggregateDescriptor.java
@@ -28,8 +28,6 @@ public class ScalarSqlMinDistinctAggregateDescriptor extends AbstractScalarDisti
 
     private static final long serialVersionUID = 1L;
 
-    public static final FunctionIdentifier FID = BuiltinFunctions.SCALAR_SQL_MIN_DISTINCT;
-
     public static final IFunctionDescriptorFactory FACTORY =
             createDescriptorFactory(ScalarSqlMinDistinctAggregateDescriptor::new);
 
@@ -39,6 +37,12 @@ public class ScalarSqlMinDistinctAggregateDescriptor extends AbstractScalarDisti
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.SCALAR_SQL_MIN_DISTINCT;
+    }
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        super.setImmutableStates(states);
+        aggFuncDesc.setImmutableStates(itemType);
     }
 }
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateDescriptor.java
similarity index 66%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateDescriptor.java
index e583e5f..1733f35 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/base/AbstractAggregateFunctionDynamicDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateDescriptor.java
@@ -16,16 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.runtime.aggregates.base;
+package org.apache.asterix.runtime.aggregates.std;
 
-import org.apache.asterix.common.functions.FunctionDescriptorTag;
-import org.apache.asterix.om.functions.AbstractFunctionDescriptor;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+
+public abstract class AbstractMinMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
 
-public abstract class AbstractAggregateFunctionDynamicDescriptor extends AbstractFunctionDescriptor {
     private static final long serialVersionUID = 1L;
+    IAType aggFieldType;
 
-    public FunctionDescriptorTag getFunctionDescriptorTag() {
-        return FunctionDescriptorTag.AGGREGATE;
+    @Override
+    public void setImmutableStates(Object... types) {
+        aggFieldType = (IAType) types[0];
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
index 90f006d..b32aae5 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
@@ -20,16 +20,17 @@ package org.apache.asterix.runtime.aggregates.std;
 
 import java.io.IOException;
 
-import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
+import org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator;
+import org.apache.asterix.dataflow.data.nontagged.comparators.ComparatorUtil;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.om.types.hierachy.ITypeConvertComputer;
-import org.apache.asterix.runtime.exceptions.IncompatibleTypeException;
+import org.apache.asterix.runtime.exceptions.UnsupportedItemTypeException;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
-import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
@@ -38,20 +39,24 @@ import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateFunction {
-    protected final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
     private final IPointable inputVal = new VoidPointable();
     private final ArrayBackedValueStorage outputVal = new ArrayBackedValueStorage();
     private final ArrayBackedValueStorage tempValForCasting = new ArrayBackedValueStorage();
     private final IScalarEvaluator eval;
     private final boolean isMin;
+    private final IAType aggFieldType;
+    private final boolean isLocal;
     protected ATypeTag aggType;
-    private IBinaryComparator cmp;
+    private ILogicalBinaryComparator cmp;
 
     AbstractMinMaxAggregateFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext context, boolean isMin,
-            SourceLocation sourceLoc) throws HyracksDataException {
+            SourceLocation sourceLoc, boolean isLocal, IAType aggFieldType) throws HyracksDataException {
         super(sourceLoc);
-        eval = args[0].createScalarEvaluator(context);
+        this.eval = args[0].createScalarEvaluator(context);
         this.isMin = isMin;
+        this.aggFieldType = aggFieldType;
+        this.isLocal = isLocal;
     }
 
     @Override
@@ -70,40 +75,30 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
                 EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(inputVal.getByteArray()[inputVal.getStartOffset()]);
         if (typeTag == ATypeTag.MISSING || typeTag == ATypeTag.NULL) {
             processNull();
-            return;
+        } else if (typeTag == ATypeTag.SYSTEM_NULL) {
+            // if a system_null is encountered locally, it would be an error; otherwise it is ignored
+            if (isLocal) {
+                throw new UnsupportedItemTypeException(sourceLoc, "min/max", ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
+            }
         } else if (aggType == ATypeTag.SYSTEM_NULL) {
-            if (typeTag == ATypeTag.SYSTEM_NULL) {
-                // Ignore.
+            // First value encountered. Set type, comparator, and initial value.
+            if (ILogicalBinaryComparator.inequalityUndefined(typeTag)) {
+                handleInvalidInput();
                 return;
             }
-            // First value encountered. Set type, comparator, and initial value.
             aggType = typeTag;
-            // Set comparator.
-            cmp = BinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(aggType, isMin)
-                    .createBinaryComparator();
-            // Initialize min value.
+            cmp = ComparatorUtil.createLogicalComparator(aggFieldType, aggFieldType, false);
             outputVal.assign(inputVal);
-        } else if (typeTag != ATypeTag.SYSTEM_NULL && !ATypeHierarchy.isCompatible(typeTag, aggType)) {
-            if (typeTag.ordinal() > aggType.ordinal()) {
-                throw new IncompatibleTypeException(sourceLoc, "min/max", typeTag.serialize(), aggType.serialize());
-            } else {
-                throw new IncompatibleTypeException(sourceLoc, "min/max", aggType.serialize(), typeTag.serialize());
-            }
+        } else if (!ATypeHierarchy.isCompatible(typeTag, aggType)) {
+            handleInvalidInput();
         } else {
-            // If a system_null is encountered locally, it would be an error; otherwise if it is seen
-            // by a global aggregator, it is simple ignored.
-            if (typeTag == ATypeTag.SYSTEM_NULL) {
-                processSystemNull();
-                return;
-            }
+            // the two values are compatible non-null/non-missing values
             if (aggType == typeTag) {
                 compareAndUpdate(cmp, inputVal, outputVal);
                 return;
             }
             if (ATypeHierarchy.canPromote(aggType, typeTag)) {
                 // switch to new comp & aggregation type (i.e. current min/max is int and new input is double)
-                cmp = BinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(typeTag, isMin)
-                        .createBinaryComparator();
                 castValue(ATypeHierarchy.getTypePromoteComputer(aggType, typeTag), outputVal, tempValForCasting);
                 outputVal.assign(tempValForCasting);
                 compareAndUpdate(cmp, inputVal, outputVal);
@@ -125,7 +120,11 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
                     result.set(resultStorage);
                     break;
                 case SYSTEM_NULL:
-                    finishSystemNull();
+                    if (isLocal) {
+                        resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
+                    } else {
+                        resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_NULL_TYPE_TAG);
+                    }
                     result.set(resultStorage);
                     break;
                 default:
@@ -142,21 +141,45 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
         finish(result);
     }
 
-    protected boolean skipStep() {
-        return false;
-    }
-
     protected abstract void processNull();
 
-    protected abstract void processSystemNull() throws HyracksDataException;
+    private boolean skipStep() {
+        return aggType == ATypeTag.NULL;
+    }
 
-    protected abstract void finishSystemNull() throws IOException;
+    private void handleInvalidInput() {
+        aggType = ATypeTag.NULL;
+    }
 
-    private static void compareAndUpdate(IBinaryComparator comp, IPointable newVal, ArrayBackedValueStorage oldVal)
+    private void compareAndUpdate(ILogicalBinaryComparator c, IPointable newVal, ArrayBackedValueStorage currentVal)
             throws HyracksDataException {
-        if (comp.compare(newVal.getByteArray(), newVal.getStartOffset(), newVal.getLength(), oldVal.getByteArray(),
-                oldVal.getStartOffset(), oldVal.getLength()) < 0) {
-            oldVal.assign(newVal);
+        // newVal is never NULL/MISSING here. it's already checked up. current value is the first encountered non-null.
+        ILogicalBinaryComparator.Result result = c.compare(newVal, currentVal);
+        switch (result) {
+            case LT:
+                if (isMin) {
+                    currentVal.assign(newVal);
+                }
+                break;
+            case GT:
+                if (!isMin) {
+                    // update the current value with the new maximum
+                    currentVal.assign(newVal);
+                }
+                break;
+            case MISSING:
+            case NULL:
+                // this should never happen given that the two values were not NULL/MISSING. aggregation is made NULL.
+                // it shouldn't happen for scalar values. For ARRAY values this should not happen as well.
+                // if some elements are NULL/MISSING, the ARRAY comparison returns INCOMPARABLE.
+                aggType = ATypeTag.NULL;
+                return;
+            case INCOMPARABLE:
+                handleInvalidInput();
+                return;
+            default:
+                // EQ, do nothing
+                break;
         }
     }
 
@@ -170,4 +193,10 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
             throw HyracksDataException.create(e);
         }
     }
+
+    enum Type {
+        LOCAL,
+        GLOBAL,
+        ONE_STEP
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMaxAggregateDescriptor.java
similarity index 82%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMaxAggregateDescriptor.java
index 2575440..5f1937d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,19 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class MaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class GlobalMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new MaxAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalMaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return BuiltinFunctions.MAX;
+        return BuiltinFunctions.GLOBAL_MAX;
     }
 
     @Override
@@ -52,7 +49,7 @@ public class MaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDesc
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, false, false, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, false, Type.GLOBAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMinAggregateDescriptor.java
similarity index 82%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMinAggregateDescriptor.java
index dfff5f7..32fcdad 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,19 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class MinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class GlobalMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new MinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalMinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return BuiltinFunctions.MIN;
+        return BuiltinFunctions.GLOBAL_MIN;
     }
 
     @Override
@@ -52,7 +49,7 @@ public class MinAggregateDescriptor extends AbstractAggregateFunctionDynamicDesc
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, true, false, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, true, Type.GLOBAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMaxAggregateDescriptor.java
similarity index 82%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMaxAggregateDescriptor.java
index 3abaa2c..2c10156 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,19 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class GlobalSqlMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new SqlMinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalSqlMaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return BuiltinFunctions.SQL_MIN;
+        return BuiltinFunctions.GLOBAL_SQL_MAX;
     }
 
     @Override
@@ -52,7 +49,7 @@ public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicD
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, true, false, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, false, Type.GLOBAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMinAggregateDescriptor.java
similarity index 82%
copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMinAggregateDescriptor.java
index 3abaa2c..20e6223 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,19 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class GlobalSqlMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new SqlMinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalSqlMinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return BuiltinFunctions.SQL_MIN;
+        return BuiltinFunctions.GLOBAL_SQL_MIN;
     }
 
     @Override
@@ -52,7 +49,7 @@ public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicD
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, true, false, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, true, Type.GLOBAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMaxAggregateDescriptor.java
index ea9b2ae..8b85316 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,21 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class LocalMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class LocalMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    private final static FunctionIdentifier FID = BuiltinFunctions.LOCAL_MAX;
-
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new LocalMaxAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(LocalMaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.LOCAL_MAX;
     }
 
     @Override
@@ -54,7 +49,7 @@ public class LocalMaxAggregateDescriptor extends AbstractAggregateFunctionDynami
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, false, true, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, false, Type.LOCAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMinAggregateDescriptor.java
index d4355df..0256244 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalMinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,20 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class LocalMinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class LocalMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    private final static FunctionIdentifier FID = BuiltinFunctions.LOCAL_MIN;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new LocalMinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(LocalMinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.LOCAL_MIN;
     }
 
     @Override
@@ -53,7 +49,7 @@ public class LocalMinAggregateDescriptor extends AbstractAggregateFunctionDynami
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, true, true, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, true, Type.LOCAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMaxAggregateDescriptor.java
index 57da62b..daa2517 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,21 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class LocalSqlMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class LocalSqlMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    private final static FunctionIdentifier FID = BuiltinFunctions.LOCAL_SQL_MAX;
-
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new LocalSqlMaxAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(LocalSqlMaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.LOCAL_SQL_MAX;
     }
 
     @Override
@@ -54,7 +49,7 @@ public class LocalSqlMaxAggregateDescriptor extends AbstractAggregateFunctionDyn
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, false, true, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, false, Type.LOCAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMinAggregateDescriptor.java
index ca2f65d..f464737 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/LocalSqlMinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,20 +30,15 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class LocalSqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class LocalSqlMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    private final static FunctionIdentifier FID = BuiltinFunctions.LOCAL_SQL_MIN;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new LocalSqlMinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(LocalSqlMinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
-        return FID;
+        return BuiltinFunctions.LOCAL_SQL_MIN;
     }
 
     @Override
@@ -53,7 +49,7 @@ public class LocalSqlMinAggregateDescriptor extends AbstractAggregateFunctionDyn
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, true, true, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, true, Type.LOCAL, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
index 2575440..214fa7c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,15 +30,11 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class MaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class MaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new MaxAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(MaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
@@ -52,7 +49,7 @@ public class MaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDesc
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, false, false, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, false, Type.ONE_STEP, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
index dfff5f7..434f729 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,15 +30,11 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class MinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class MinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new MinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(MinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
@@ -52,7 +49,7 @@ public class MinAggregateDescriptor extends AbstractAggregateFunctionDynamicDesc
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new MinMaxAggregateFunction(args, ctx, true, false, sourceLoc);
+                return new MinMaxAggregateFunction(args, ctx, true, Type.ONE_STEP, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
index 3aeb58a..7d69ff3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/MinMaxAggregateFunction.java
@@ -18,49 +18,29 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
-import java.io.IOException;
-
 import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.runtime.exceptions.UnsupportedItemTypeException;
+import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 
+/**
+ * SQL++ min/max functions will mark aggregation as NULL and start to skip aggregating tuples when:
+ * <ul>
+ *     <li>NULL/MISSING value was encountered locally or globally</li>
+ *     <li>Input data type is invalid (i.e. min/max on records) or incompatible (i.e. min/max on string & int)</li>
+ * </ul>
+ */
 public class MinMaxAggregateFunction extends AbstractMinMaxAggregateFunction {
-    private final boolean isLocalAgg;
 
-    public MinMaxAggregateFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext context, boolean isMin,
-            boolean isLocalAgg, SourceLocation sourceLoc) throws HyracksDataException {
-        super(args, context, isMin, sourceLoc);
-        this.isLocalAgg = isLocalAgg;
+    MinMaxAggregateFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext context, boolean isMin, Type type,
+            SourceLocation sourceLoc, IAType aggFieldType) throws HyracksDataException {
+        super(args, context, isMin, sourceLoc, type == Type.LOCAL, aggFieldType);
     }
 
     @Override
     protected void processNull() {
         aggType = ATypeTag.NULL;
     }
-
-    @Override
-    protected boolean skipStep() {
-        return aggType == ATypeTag.NULL;
-    }
-
-    @Override
-    protected void processSystemNull() throws HyracksDataException {
-        if (isLocalAgg) {
-            throw new UnsupportedItemTypeException(sourceLoc, "min/max", ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
-        }
-    }
-
-    @Override
-    protected void finishSystemNull() throws IOException {
-        // Empty stream. For local agg return system null. For global agg return null.
-        if (isLocalAgg) {
-            resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
-        } else {
-            resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_NULL_TYPE_TAG);
-        }
-    }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMaxAggregateDescriptor.java
index d5b86f9..55fa0f5 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMaxAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMaxAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,15 +30,11 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class SqlMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class SqlMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new SqlMaxAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(SqlMaxAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
@@ -52,7 +49,7 @@ public class SqlMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicD
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, false, false, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, false, Type.ONE_STEP, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
index 3abaa2c..d153b83 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinAggregateDescriptor.java
@@ -18,8 +18,9 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
+import static org.apache.asterix.runtime.aggregates.std.AbstractMinMaxAggregateFunction.Type;
+
 import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -29,15 +30,11 @@ import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+public class SqlMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
 
     private static final long serialVersionUID = 1L;
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new SqlMinAggregateDescriptor();
-        }
-    };
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(SqlMinAggregateDescriptor::new);
 
     @Override
     public FunctionIdentifier getIdentifier() {
@@ -52,7 +49,7 @@ public class SqlMinAggregateDescriptor extends AbstractAggregateFunctionDynamicD
             @Override
             public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
                     throws HyracksDataException {
-                return new SqlMinMaxAggregateFunction(args, ctx, true, false, sourceLoc);
+                return new SqlMinMaxAggregateFunction(args, ctx, true, Type.ONE_STEP, sourceLoc, aggFieldType);
             }
         };
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinMaxAggregateFunction.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinMaxAggregateFunction.java
index c31acda..dec97ff 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinMaxAggregateFunction.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/SqlMinMaxAggregateFunction.java
@@ -18,42 +18,39 @@
  */
 package org.apache.asterix.runtime.aggregates.std;
 
-import java.io.IOException;
-
 import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.runtime.exceptions.UnsupportedItemTypeException;
+import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 
+/**
+ * SQL min/max functions will mark aggregation as NULL and start to skip aggregating tuples when:
+ * <ul>
+ *     <li>NULL/MISSING value was encountered globally</li>
+ *     <li>Input data type is invalid (i.e. min/max on records) or incompatible (i.e. min/max on string & int)</li>
+ * </ul>
+ * When NULL/MISSING value is encountered, local aggregator will ignore and continue aggregation. Global aggregator
+ * will mark aggregation as NULL since getting NULL/MISSING at the global level indicates type invalidity (Some
+ * aggregators are global in nature yet they ignore NULLs similar to a local aggregator, e.g. scalar min/max, normal
+ * global aggregators with no local aggregators like distinct min/max (one-step aggregators)).
+ */
 public class SqlMinMaxAggregateFunction extends AbstractMinMaxAggregateFunction {
-    private final boolean isLocalAgg;
 
-    public SqlMinMaxAggregateFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext context, boolean isMin,
-            boolean isLocalAgg, SourceLocation sourceLoc) throws HyracksDataException {
-        super(args, context, isMin, sourceLoc);
-        this.isLocalAgg = isLocalAgg;
-    }
-
-    @Override
-    protected void processNull() {
-    }
+    private final Type type;
 
-    @Override
-    protected void processSystemNull() throws HyracksDataException {
-        if (isLocalAgg) {
-            throw new UnsupportedItemTypeException(sourceLoc, "min/max", ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
-        }
+    SqlMinMaxAggregateFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext context, boolean isMin, Type type,
+            SourceLocation sourceLoc, IAType aggFieldType) throws HyracksDataException {
+        super(args, context, isMin, sourceLoc, type == Type.LOCAL, aggFieldType);
+        this.type = type;
     }
 
     @Override
-    protected void finishSystemNull() throws IOException {
-        // Empty stream. For local agg return system null. For global agg return null.
-        if (isLocalAgg) {
-            resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
-        } else {
-            resultStorage.getDataOutput().writeByte(ATypeTag.SERIALIZED_NULL_TYPE_TAG);
+    protected void processNull() {
+        if (type == Type.GLOBAL) {
+            // getting NULL at the global step should only mean the local step ran into type invalidity
+            aggType = ATypeTag.NULL;
         }
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
index 088b25c..2e9c688 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
@@ -147,9 +147,13 @@ import org.apache.asterix.runtime.aggregates.std.AvgAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.CountAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalAvgAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalKurtosisAggregateDescriptor;
+import org.apache.asterix.runtime.aggregates.std.GlobalMaxAggregateDescriptor;
+import org.apache.asterix.runtime.aggregates.std.GlobalMinAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSkewnessAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSqlAvgAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSqlKurtosisAggregateDescriptor;
+import org.apache.asterix.runtime.aggregates.std.GlobalSqlMaxAggregateDescriptor;
+import org.apache.asterix.runtime.aggregates.std.GlobalSqlMinAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSqlSkewnessAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSqlStddevAggregateDescriptor;
 import org.apache.asterix.runtime.aggregates.std.GlobalSqlStddevPopAggregateDescriptor;
@@ -599,8 +603,10 @@ public final class FunctionCollection implements IFunctionCollection {
         fc.add(GlobalSumAggregateDescriptor.FACTORY);
         fc.add(MaxAggregateDescriptor.FACTORY);
         fc.add(LocalMaxAggregateDescriptor.FACTORY);
+        fc.add(GlobalMaxAggregateDescriptor.FACTORY);
         fc.add(MinAggregateDescriptor.FACTORY);
         fc.add(LocalMinAggregateDescriptor.FACTORY);
+        fc.add(GlobalMinAggregateDescriptor.FACTORY);
         fc.add(FirstElementAggregateDescriptor.FACTORY);
         fc.add(LocalFirstElementAggregateDescriptor.FACTORY);
         fc.add(LastElementAggregateDescriptor.FACTORY);
@@ -707,8 +713,10 @@ public final class FunctionCollection implements IFunctionCollection {
         fc.add(GlobalSqlSumAggregateDescriptor.FACTORY);
         fc.add(SqlMaxAggregateDescriptor.FACTORY);
         fc.add(LocalSqlMaxAggregateDescriptor.FACTORY);
+        fc.add(GlobalSqlMaxAggregateDescriptor.FACTORY);
         fc.add(SqlMinAggregateDescriptor.FACTORY);
         fc.add(LocalSqlMinAggregateDescriptor.FACTORY);
+        fc.add(GlobalSqlMinAggregateDescriptor.FACTORY);
         fc.add(SqlStddevAggregateDescriptor.FACTORY);
         fc.add(LocalSqlStddevAggregateDescriptor.FACTORY);
         fc.add(IntermediateSqlStddevAggregateDescriptor.FACTORY);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
index 4be71e3..be4a1f0 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
@@ -110,6 +110,17 @@ public final class FunctionTypeInferers {
         }
     };
 
+    public static final IFunctionTypeInferer LISTIFY_INFERER = new IFunctionTypeInferer() {
+        @Override
+        public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
+                CompilerProperties compilerProps) throws AlgebricksException {
+            AbstractFunctionCallExpression listifyExpression = (AbstractFunctionCallExpression) expr;
+            IAType outputListType = (IAType) context.getType(listifyExpression);
+            IAType itemType = (IAType) context.getType(listifyExpression.getArguments().get(0).getValue());
+            fd.setImmutableStates(outputListType, TypeComputeUtils.getActualType(itemType));
+        }
+    };
+
     public static final class CastTypeInferer implements IFunctionTypeInferer {
         @Override
         public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
@@ -139,11 +150,10 @@ public final class FunctionTypeInferers {
             AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
             IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
             switch (t.getTypeTag()) {
-                case OBJECT: {
+                case OBJECT:
                     fd.setImmutableStates(t);
                     break;
-                }
-                case UNION: {
+                case UNION:
                     AUnionType unionT = (AUnionType) t;
                     if (unionT.isUnknownableType()) {
                         IAType t2 = unionT.getActualType();
@@ -153,10 +163,8 @@ public final class FunctionTypeInferers {
                         }
                     }
                     throw new NotImplementedException("field-access-by-index for data of type " + t);
-                }
-                default: {
+                default:
                     throw new NotImplementedException("field-access-by-index for data of type " + t);
-                }
             }
         }
     }
@@ -176,16 +184,14 @@ public final class FunctionTypeInferers {
             }
 
             switch (t.getTypeTag()) {
-                case OBJECT: {
+                case OBJECT:
                     fd.setImmutableStates(t, listFieldPath);
                     break;
-                }
                 case ANY:
                     fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE, listFieldPath);
                     break;
-                default: {
+                default:
                     throw new NotImplementedException("field-access-nested for data of type " + t);
-                }
             }
         }
     }
@@ -209,22 +215,19 @@ public final class FunctionTypeInferers {
             IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
             ATypeTag typeTag = t.getTypeTag();
             switch (typeTag) {
-                case OBJECT: {
+                case OBJECT:
                     fd.setImmutableStates(t);
                     break;
-                }
-                case ANY: {
+                case ANY:
                     fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE);
                     break;
-                }
-                default: {
+                default:
                     if (strict) {
                         throw new NotImplementedException(fd.getIdentifier().getName() + " for data of type " + t);
                     } else {
                         fd.setImmutableStates(new Object[] { null });
                     }
                     break;
-                }
             }
         }
     }