[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 <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp
new file mode 100644
index 0000000..33b1a10
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.01.ddl.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+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-sql/min_max_arrays/min_max_arrays.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.03.query.sqlpp
new file mode 100644
index 0000000..2927c05
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.03.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.04.query.sqlpp
new file mode 100644
index 0000000..9f7798f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.04.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.05.query.sqlpp
new file mode 100644
index 0000000..3876650
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.05.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.06.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.06.query.sqlpp
new file mode 100644
index 0000000..c9bd556
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.06.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.07.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.07.query.sqlpp
new file mode 100644
index 0000000..95bc61c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.07.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.08.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.08.query.sqlpp
new file mode 100644
index 0000000..3a235da
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.08.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.09.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.09.query.sqlpp
new file mode 100644
index 0000000..97faea8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.09.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.10.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.10.query.sqlpp
new file mode 100644
index 0000000..c287262
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.10.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.11.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.11.query.sqlpp
new file mode 100644
index 0000000..f63558f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.11.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.12.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.12.query.sqlpp
new file mode 100644
index 0000000..fe0ed35
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.12.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.13.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.13.query.sqlpp
new file mode 100644
index 0000000..35790e6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.13.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.14.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.14.query.sqlpp
new file mode 100644
index 0000000..21549f6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.14.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.15.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.15.query.sqlpp
new file mode 100644
index 0000000..74f9685
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.15.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.16.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.16.query.sqlpp
new file mode 100644
index 0000000..7e7a8e5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.16.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.17.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.17.query.sqlpp
new file mode 100644
index 0000000..02d088d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.17.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.18.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.18.query.sqlpp
new file mode 100644
index 0000000..01546b7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.18.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.19.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.19.query.sqlpp
new file mode 100644
index 0000000..e289a1b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.19.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.20.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.20.query.sqlpp
new file mode 100644
index 0000000..bbd580b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.20.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.21.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.21.query.sqlpp
new file mode 100644
index 0000000..31e5c6a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.21.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.22.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.22.query.sqlpp
new file mode 100644
index 0000000..cf0c45f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.22.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.23.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.23.query.sqlpp
new file mode 100644
index 0000000..e2c7b74
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.23.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.24.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.24.query.sqlpp
new file mode 100644
index 0000000..fe846f9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.24.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.25.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.25.query.sqlpp
new file mode 100644
index 0000000..92e7dfd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.25.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.26.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.26.query.sqlpp
new file mode 100644
index 0000000..789b847
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.26.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.27.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.27.query.sqlpp
new file mode 100644
index 0000000..c625fbe
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.27.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.28.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.28.query.sqlpp
new file mode 100644
index 0000000..e0840a7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.28.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.29.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.29.query.sqlpp
new file mode 100644
index 0000000..f968d01
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.29.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.30.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.30.query.sqlpp
new file mode 100644
index 0000000..cf2c844
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.30.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp
new file mode 100644
index 0000000..548e632
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate-sql/min_max_arrays/min_max_arrays.31.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+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_max_arrays/min_max_arrays.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.01.ddl.sqlpp
new file mode 100644
index 0000000..33b1a10
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.01.ddl.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+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_max_arrays/min_max_arrays.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.03.query.sqlpp
new file mode 100644
index 0000000..830d96f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.03.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.04.query.sqlpp
new file mode 100644
index 0000000..0daa8d2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.04.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.05.query.sqlpp
new file mode 100644
index 0000000..b1b61c8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.05.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.06.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.06.query.sqlpp
new file mode 100644
index 0000000..ea124af
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.06.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.07.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.07.query.sqlpp
new file mode 100644
index 0000000..7ac8e1e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.07.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.08.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.08.query.sqlpp
new file mode 100644
index 0000000..02d882c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.08.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.09.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.09.query.sqlpp
new file mode 100644
index 0000000..a69ccc3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.09.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.10.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.10.query.sqlpp
new file mode 100644
index 0000000..a62deb7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.10.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.11.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.11.query.sqlpp
new file mode 100644
index 0000000..3893443
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.11.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.12.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.12.query.sqlpp
new file mode 100644
index 0000000..a421996
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.12.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.13.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.13.query.sqlpp
new file mode 100644
index 0000000..a5fa8fa
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.13.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.14.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.14.query.sqlpp
new file mode 100644
index 0000000..5cb5e8f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.14.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.15.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.15.query.sqlpp
new file mode 100644
index 0000000..2ddc453
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.15.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.16.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.16.query.sqlpp
new file mode 100644
index 0000000..87cedb5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.16.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.17.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.17.query.sqlpp
new file mode 100644
index 0000000..c6534da
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.17.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.18.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.18.query.sqlpp
new file mode 100644
index 0000000..5526d69
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.18.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.19.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.19.query.sqlpp
new file mode 100644
index 0000000..cfb414d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.19.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.20.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.20.query.sqlpp
new file mode 100644
index 0000000..643d51a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.20.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.21.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.21.query.sqlpp
new file mode 100644
index 0000000..e382111
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.21.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.22.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.22.query.sqlpp
new file mode 100644
index 0000000..7ea5696
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.22.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+/*
+ * 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_max_arrays/min_max_arrays.23.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.23.ddl.sqlpp
new file mode 100644
index 0000000..548e632
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/aggregate/min_max_arrays/min_max_arrays.23.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+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 @@
         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 @@
         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.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 @@
         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.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 @@
 
 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 @@
     }
 
     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 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 @@
             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 @@
         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 @@
         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 @@
         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 @@
         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 @@
         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 @@
     }
 
     @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 @@
             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 @@
 
     @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 @@
         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 @@
 
     @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 @@
         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 @@
 
     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 boolean isTyped() {
+        // TODO(ali): this should be removed. itemType is already enforced to be NonNull
         return itemType != null;
     }
 
@@ -47,7 +48,7 @@
     }
 
     public void setItemType(IAType itemType) {
-        this.itemType = itemType;
+        this.itemType = Objects.requireNonNull(itemType);
     }
 
     @Override
@@ -58,7 +59,7 @@
     @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 @@
         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 @@
         }
     }
 
+    /**
+     * 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.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 @@
 
         @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 @@
 
     @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 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 @@
 
     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 @@
             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 @@
         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 @@
             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 @@
         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 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 @@
 
 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 @@
 
     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 @@
 
     @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 @@
 
     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 @@
 
     @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 @@
 
 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 @@
 
     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 @@
 
     @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 @@
 
     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 @@
 
     @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 @@
 
 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 @@
 
     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 @@
 
     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 @@
 
 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 @@
 
     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 @@
 
     @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 @@
 
     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 @@
 
     @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/std/AbstractMinMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateDescriptor.java
new file mode 100644
index 0000000..1733f35
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateDescriptor.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.runtime.aggregates.std;
+
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+
+public abstract class AbstractMinMaxAggregateDescriptor extends AbstractAggregateFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    IAType aggFieldType;
+
+    @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 @@
 
 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.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 @@
                 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.
-                return;
-            }
             // First value encountered. Set type, comparator, and initial value.
-            aggType = typeTag;
-            // Set comparator.
-            cmp = BinaryComparatorFactoryProvider.INSTANCE.getBinaryComparatorFactory(aggType, isMin)
-                    .createBinaryComparator();
-            // Initialize min value.
-            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 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();
+            if (ILogicalBinaryComparator.inequalityUndefined(typeTag)) {
+                handleInvalidInput();
                 return;
             }
+            aggType = typeTag;
+            cmp = ComparatorUtil.createLogicalComparator(aggFieldType, aggFieldType, false);
+            outputVal.assign(inputVal);
+        } else if (!ATypeHierarchy.isCompatible(typeTag, aggType)) {
+            handleInvalidInput();
+        } else {
+            // 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 @@
                     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 @@
         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 @@
             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/GlobalMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMaxAggregateDescriptor.java
new file mode 100644
index 0000000..5f1937d
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMaxAggregateDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class GlobalMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalMaxAggregateDescriptor::new);
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.GLOBAL_MAX;
+    }
+
+    @Override
+    public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IAggregateEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
+                    throws HyracksDataException {
+                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/GlobalMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMinAggregateDescriptor.java
new file mode 100644
index 0000000..32fcdad
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalMinAggregateDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class GlobalMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalMinAggregateDescriptor::new);
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.GLOBAL_MIN;
+    }
+
+    @Override
+    public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IAggregateEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
+                    throws HyracksDataException {
+                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/GlobalSqlMaxAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMaxAggregateDescriptor.java
new file mode 100644
index 0000000..2c10156
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMaxAggregateDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class GlobalSqlMaxAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalSqlMaxAggregateDescriptor::new);
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.GLOBAL_SQL_MAX;
+    }
+
+    @Override
+    public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IAggregateEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
+                    throws HyracksDataException {
+                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/GlobalSqlMinAggregateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMinAggregateDescriptor.java
new file mode 100644
index 0000000..20e6223
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/GlobalSqlMinAggregateDescriptor.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.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.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.aggregates.base.AbstractAggregateFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IAggregateEvaluatorFactory;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class GlobalSqlMinAggregateDescriptor extends AbstractMinMaxAggregateDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY =
+            AbstractAggregateFunctionDynamicDescriptor.createFactory(GlobalSqlMinAggregateDescriptor::new);
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.GLOBAL_SQL_MIN;
+    }
+
+    @Override
+    public IAggregateEvaluatorFactory createAggregateEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IAggregateEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IAggregateEvaluator createAggregateEvaluator(final IHyracksTaskContext ctx)
+                    throws HyracksDataException {
+                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.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 @@
             @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.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 @@
             @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.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 @@
             @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.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 @@
             @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.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 @@
             @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.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 @@
             @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.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 @@
             @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.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 @@
             @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;
+    private final Type type;
+
+    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 processNull() {
-    }
-
-    @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);
+        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.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 @@
         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 @@
         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 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 @@
             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 @@
                         }
                     }
                     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 @@
             }
 
             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 @@
             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;
-                }
             }
         }
     }