Add functions: atan2, power, trunc, and uuid.

Change-Id: I3aa3be97809be7d03bbab919252af7bbfe6f00e0
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1138
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
index 27454e3..09cb856 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
@@ -165,6 +165,7 @@
 import org.apache.asterix.runtime.evaluators.functions.NotDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericACosDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericASinDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.NumericATan2Descriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericATanDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericAbsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericAddDescriptor;
@@ -186,6 +187,7 @@
 import org.apache.asterix.runtime.evaluators.functions.NumericSqrtDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericSubDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericTanDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.NumericTruncDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.NumericUnaryMinusDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.OrDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.OrderedListConstructorDescriptor;
@@ -234,6 +236,7 @@
 import org.apache.asterix.runtime.evaluators.functions.SubstringBeforeDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SubstringDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.SwitchCaseDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.UUIDDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.UnorderedListConstructorDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.WordTokensDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.binary.BinaryConcatDescriptor;
@@ -416,6 +419,7 @@
 
         // uuid generators (zero independent functions)
         temp.add(CreateUUIDDescriptor.FACTORY);
+        temp.add(UUIDDescriptor.FACTORY);
         temp.add(CreateQueryUIDDescriptor.FACTORY);
         temp.add(CurrentDateDescriptor.FACTORY);
         temp.add(CurrentTimeDescriptor.FACTORY);
@@ -463,6 +467,8 @@
         functionsToInjectUnkownHandling.add(NumericLogDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(NumericSqrtDescriptor.FACTORY);
         functionsToInjectUnkownHandling.add(NumericSignDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(NumericTruncDescriptor.FACTORY);
+        functionsToInjectUnkownHandling.add(NumericATan2Descriptor.FACTORY);
 
         // Comparisons.
         functionsToInjectUnkownHandling.add(EqualsDescriptor.FACTORY);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/uuid/uuid.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/uuid/uuid.1.query.sqlpp
new file mode 100644
index 0000000..06e6291
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/uuid/uuid.1.query.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.
+ */
+
+uuid() != uuid();
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/atan2/atan2.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/atan2/atan2.1.query.sqlpp
new file mode 100644
index 0000000..46d8480
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/atan2/atan2.1.query.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.
+ */
+
+{
+  "a": atan2(10.0, 1.0f),
+  "b": atan2(0.5f, 10.0),
+  "c": atan2(100, int8("1")),
+  "d": atan2(int32("0"), 0.5f),
+  "e": atan2(int8("-1"), 3.5),
+  "f": atan2(int16("1"), int16("20")),
+  "g": atan2(int16("1"), null),
+  "h": atan2(missing, 1.5),
+  "i": atan2(null, missing),
+  "j": atan2(null, null),
+  "k": atan2(missing, missing)
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/power/power.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/power/power.1.query.sqlpp
new file mode 100644
index 0000000..7c00589
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/power/power.1.query.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.
+ */
+
+{
+  "a": power(10.0, 1.0f),
+  "b": power(0.5f, 10.0),
+  "c": power(100, int8("1")),
+  "d": power(int32("0"), 0.5f),
+  "e": power(int8("-1"), 3.5),
+  "f": power(int16("2"), int16("10")),
+  "g": power(int16("1"), null),
+  "h": power(missing, 1.5),
+  "i": power(null, missing),
+  "j": power(null, null),
+  "k": power(missing, missing)
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/trunc/trunc.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/trunc/trunc.1.query.sqlpp
new file mode 100644
index 0000000..e3050d0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/trunc/trunc.1.query.sqlpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+{
+  'f0':trunc(int8('-20'),2),
+  'f1':trunc(int16('-23'),2),
+  'f2':trunc(int32('-29'),2),
+  'f3':trunc(int64('-21'),2),
+  'f4':trunc(int8('20'),2),
+  'f5':trunc(int16('22'),2),
+  'f6':trunc(int32('23'),2),
+  'f7':trunc(int64('27'),2),
+  'f8':trunc(1.555f,2),
+  'f9':trunc(1.7777999, 3),
+  'f10':trunc(21.7777999, -1),
+  'f11':trunc(21.7777999, null),
+  'f12':trunc(21.7777999, missing),
+  'f13':trunc(null, 2),
+  'f14':trunc(missing, 2),
+  'f15':trunc(null, null),
+  'f16':trunc(null, missing),
+  'f17':trunc(missing, missing)
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/uuid/uuid.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/uuid/uuid.1.adm
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/uuid/uuid.1.adm
@@ -0,0 +1 @@
+true
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/atan2/atan2.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/atan2/atan2.1.adm
new file mode 100644
index 0000000..94aab82
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/atan2/atan2.1.adm
@@ -0,0 +1 @@
+{ "a": 1.4711276743037347, "b": 0.049958395721942765, "c": 1.5607966601082315, "d": 0.0, "e": -0.27829965900511133, "f": 0.049958395721942765, "g": null, "j": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/power/power.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/power/power.1.adm
new file mode 100644
index 0000000..ee9989d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/power/power.1.adm
@@ -0,0 +1 @@
+{ "a": 10.0, "b": 9.765625E-4, "c": 100, "d": 0.0, "e": NaN, "f": 1024, "g": null, "j": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/trunc/trunc.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/trunc/trunc.1.adm
new file mode 100644
index 0000000..74d05a9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/trunc/trunc.1.adm
@@ -0,0 +1 @@
+{ "f0": -20, "f1": -23, "f2": -29, "f3": -21, "f4": 20, "f5": 22, "f6": 23, "f7": 27, "f8": 1.55, "f9": 1.777, "f10": 20.0, "f11": null, "f13": null, "f15": null }
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 fb9a8e8..d5fe65b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -3119,6 +3119,11 @@
         <expected-error>The first argument of a field access should be a RECORD, but it is</expected-error>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="uuid">
+        <output-dir compare="Text">uuid</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="open-index-enforced">
     <test-group name="open-index-enforced/error-checking">
@@ -4152,6 +4157,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="numeric">
+      <compilation-unit name="power">
+        <output-dir compare="Text">power</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="numeric">
       <compilation-unit name="round-half-to-even0">
         <output-dir compare="Text">round-half-to-even0</output-dir>
       </compilation-unit>
@@ -4262,6 +4272,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="numeric">
+      <compilation-unit name="trunc">
+        <output-dir compare="Text">trunc</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="numeric">
       <compilation-unit name="unary-minus_double_02">
         <output-dir compare="Text">unary-minus_double_02</output-dir>
       </compilation-unit>
@@ -4303,6 +4318,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="numeric">
+      <compilation-unit name="atan2">
+        <output-dir compare="Text">atan2</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="numeric">
       <compilation-unit name="cos">
         <output-dir compare="Text">cos</output-dir>
       </compilation-unit>
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
index 369b8dd..449cb63 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/FunctionMapUtil.java
@@ -52,6 +52,7 @@
         FUNCTION_NAME_MAP.put("regexp_like", "regexp-like"); //SQL: regexp_like, AQL: regexp-like
         FUNCTION_NAME_MAP.put("regexp_position", "regexp-position"); //SQL: regexp_position, AQL: regexp-position
         FUNCTION_NAME_MAP.put("regexp_replace", "replace"); //SQL: regexp_replace, AQL: replace
+        FUNCTION_NAME_MAP.put("power", "caret"); //SQL: pow, AQL: caret
     }
 
     // Maps from a variable-arg SQL function names to an internal list-arg function name.
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index da6ee02..184dd84 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -72,7 +72,9 @@
 import org.apache.asterix.om.typecomputer.impl.NullableDoubleTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericAddSubMulDivTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericAggTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.NumericRoundHalfToEven2TypeComputer;
+import org.apache.asterix.om.typecomputer.impl.NumericDoubleOutputFunctionTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.NumericInt8OutputFunctionTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.NumericRound2TypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericUnaryFunctionTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.OpenARecordTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.OpenRecordConstructorResultType;
@@ -207,6 +209,8 @@
             1);
     public static final FunctionIdentifier NUMERIC_ATAN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "atan",
             1);
+    public static final FunctionIdentifier NUMERIC_ATAN2 = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "atan2",
+            2);
     public static final FunctionIdentifier NUMERIC_COS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "cos", 1);
     public static final FunctionIdentifier NUMERIC_SIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "sin", 1);
     public static final FunctionIdentifier NUMERIC_TAN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "tan", 1);
@@ -228,6 +232,8 @@
             FunctionConstants.ASTERIX_NS, "round-half-to-even", 1);
     public static final FunctionIdentifier NUMERIC_ROUND_HALF_TO_EVEN2 = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "round-half-to-even", 2);
+    public static final FunctionIdentifier NUMERIC_TRUNC = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "trunc",
+            2);
 
     // binary functions
     public static final FunctionIdentifier BINARY_LENGTH = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -642,6 +648,7 @@
 
     public static final FunctionIdentifier CREATE_UUID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "create-uuid", 0);
+    public static final FunctionIdentifier UUID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "uuid", 0);
     public static final FunctionIdentifier CREATE_QUERY_UID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "create-query-uid", 0);
 
@@ -806,7 +813,7 @@
         addPrivateFunction(CHECK_UNKNOWN, NotMissingTypeComputer.INSTANCE, true);
         addPrivateFunction(ANY_COLLECTION_MEMBER, CollectionMemberResultType.INSTANCE, true);
         addFunction(BOOLEAN_CONSTRUCTOR, StringBooleanTypeComputer.INSTANCE, true);
-        addPrivateFunction(CARET, NumericAddSubMulDivTypeComputer.INSTANCE, true);
+        addFunction(CARET, NumericAddSubMulDivTypeComputer.INSTANCE, true);
         addFunction(CIRCLE_CONSTRUCTOR, ACircleTypeComputer.INSTANCE, true);
         addPrivateFunction(CONCAT_NON_NULL, ConcatNonNullTypeComputer.INSTANCE, true);
 
@@ -819,6 +826,7 @@
         addFunction(CREATE_POLYGON, APolygonTypeComputer.INSTANCE, true);
         addFunction(CREATE_RECTANGLE, ARectangleTypeComputer.INSTANCE, true);
         addFunction(CREATE_UUID, AUUIDTypeComputer.INSTANCE, false);
+        addFunction(UUID, AUUIDTypeComputer.INSTANCE, false);
         addFunction(CREATE_QUERY_UID, ABinaryTypeComputer.INSTANCE, false);
         addFunction(UUID_CONSTRUCTOR, AUUIDTypeComputer.INSTANCE, true);
 
@@ -861,22 +869,24 @@
         addPrivateFunction(NUMERIC_MOD, NumericAddSubMulDivTypeComputer.INSTANCE, true);
         addPrivateFunction(NUMERIC_IDIV, AInt64TypeComputer.INSTANCE, true);
         addFunction(NUMERIC_ABS, NumericUnaryFunctionTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_ACOS, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_ASIN, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_ATAN, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_COS, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_SIN, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_TAN, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_EXP, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_LN, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_LOG, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_SQRT, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_SIGN, AInt8TypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_ACOS, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_ASIN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_ATAN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_ATAN2, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_COS, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_SIN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_TAN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_EXP, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_LN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_LOG, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_SQRT, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_SIGN, NumericInt8OutputFunctionTypeComputer.INSTANCE, true);
         addFunction(NUMERIC_CEILING, NumericUnaryFunctionTypeComputer.INSTANCE, true);
         addFunction(NUMERIC_FLOOR, NumericUnaryFunctionTypeComputer.INSTANCE, true);
         addFunction(NUMERIC_ROUND, NumericUnaryFunctionTypeComputer.INSTANCE, true);
         addFunction(NUMERIC_ROUND_HALF_TO_EVEN, NumericUnaryFunctionTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_ROUND_HALF_TO_EVEN2, NumericRoundHalfToEven2TypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_ROUND_HALF_TO_EVEN2, NumericRound2TypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_TRUNC, NumericRound2TypeComputer.INSTANCE, true);
 
         addFunction(BINARY_LENGTH, UnaryBinaryInt64TypeComputer.INSTANCE, true);
         addFunction(PARSE_BINARY, ABinaryTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java
new file mode 100644
index 0000000..910db02
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDoubleOutputFunctionTypeComputer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+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;
+
+public class NumericDoubleOutputFunctionTypeComputer extends AbstractResultTypeComputer {
+
+    private static final String ERR_MSG = "Arithmetic operations are not implemented for ";
+    public static final NumericDoubleOutputFunctionTypeComputer INSTANCE =
+            new NumericDoubleOutputFunctionTypeComputer();
+
+    private NumericDoubleOutputFunctionTypeComputer() {
+    }
+
+    @Override
+    protected void checkArgType(int argIndex, IAType type) throws AlgebricksException {
+        ATypeTag tag = type.getTypeTag();
+        switch (tag) {
+            case INT8:
+            case INT16:
+            case INT32:
+            case INT64:
+            case FLOAT:
+            case DOUBLE:
+                break;
+            default:
+                throw new AlgebricksException(ERR_MSG + type.getDisplayName());
+        }
+    }
+
+    @Override
+    protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+        return BuiltinType.ADOUBLE;
+    }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java
new file mode 100644
index 0000000..6e32fe0
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericInt8OutputFunctionTypeComputer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+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;
+
+public class NumericInt8OutputFunctionTypeComputer extends AbstractResultTypeComputer {
+
+    private static final String ERR_MSG = "Arithmetic operations are not implemented for ";
+    public static final NumericInt8OutputFunctionTypeComputer INSTANCE = new NumericInt8OutputFunctionTypeComputer();
+
+    private NumericInt8OutputFunctionTypeComputer() {
+    }
+
+    @Override
+    protected void checkArgType(int argIndex, IAType type) throws AlgebricksException {
+        ATypeTag tag = type.getTypeTag();
+        switch (tag) {
+            case INT8:
+            case INT16:
+            case INT32:
+            case INT64:
+            case FLOAT:
+            case DOUBLE:
+                break;
+            default:
+                throw new AlgebricksException(ERR_MSG + type.getDisplayName());
+        }
+    }
+
+    @Override
+    protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+        return BuiltinType.AINT8;
+    }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundHalfToEven2TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java
similarity index 91%
rename from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundHalfToEven2TypeComputer.java
rename to asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java
index 9ba0c8d..2335e46 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundHalfToEven2TypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRound2TypeComputer.java
@@ -30,11 +30,11 @@
 import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
-public class NumericRoundHalfToEven2TypeComputer extends AbstractResultTypeComputer {
+public class NumericRound2TypeComputer extends AbstractResultTypeComputer {
 
-    public static final NumericRoundHalfToEven2TypeComputer INSTANCE = new NumericRoundHalfToEven2TypeComputer();
+    public static final NumericRound2TypeComputer INSTANCE = new NumericRound2TypeComputer();
 
-    private NumericRoundHalfToEven2TypeComputer() {
+    private NumericRound2TypeComputer() {
 
     }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericATan2Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericATan2Descriptor.java
new file mode 100644
index 0000000..e7b51c0
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericATan2Descriptor.java
@@ -0,0 +1,107 @@
+/*
+ * 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.evaluators.functions;
+
+import java.io.DataOutput;
+
+import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableDouble;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+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.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericATan2Descriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericATan2Descriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.NUMERIC_ATAN2;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
+            throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException {
+                return new IScalarEvaluator() {
+                    // For inputs.
+                    private final IPointable leftPtr = new VoidPointable();
+                    private final IPointable rightPtr = new VoidPointable();
+                    private final IScalarEvaluator evalLeft = args[0].createScalarEvaluator(ctx);
+                    private final IScalarEvaluator evalRight = args[1].createScalarEvaluator(ctx);
+                    private final double[] operands = new double[args.length];
+
+                    // For the output.
+                    private final AMutableDouble aDouble = new AMutableDouble(0.0);
+                    @SuppressWarnings("rawtypes")
+                    private final ISerializerDeserializer outputSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ADOUBLE);
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+                        try {
+                            resultStorage.reset();
+                            evalLeft.evaluate(tuple, leftPtr);
+                            evalRight.evaluate(tuple, rightPtr);
+                            for (int i = 0; i < args.length; i++) {
+                                IPointable argPtr = i == 0 ? leftPtr : rightPtr;
+                                byte[] data = argPtr.getByteArray();
+                                int offset = argPtr.getStartOffset();
+                                operands[i] = ATypeHierarchy.getDoubleValue(data, offset);
+                            }
+                            aDouble.setValue(Math.atan2(operands[0], operands[1]));
+                            outputSerde.serialize(aDouble, out);
+                            result.set(resultStorage);
+                        } catch (HyracksDataException hde) {
+                            throw new AlgebricksException(hde);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
index d40cb70..335dc41 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
@@ -18,48 +18,18 @@
  */
 package org.apache.asterix.runtime.evaluators.functions;
 
-import java.io.DataOutput;
-
-import org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
-import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import org.apache.asterix.om.base.AMutableDouble;
-import org.apache.asterix.om.base.AMutableFloat;
-import org.apache.asterix.om.base.AMutableInt16;
-import org.apache.asterix.om.base.AMutableInt32;
-import org.apache.asterix.om.base.AMutableInt64;
-import org.apache.asterix.om.base.AMutableInt8;
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-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.ISerializerDeserializer;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
-/**
- * @author kisskys
- */
-public class NumericModuloDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class NumericModuloDescriptor extends AbstractNumericArithmeticEval {
 
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
         @Override
         public IFunctionDescriptor createFunctionDescriptor() {
             return new NumericModuloDescriptor();
@@ -72,125 +42,23 @@
     }
 
     @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args)
-            throws AlgebricksException {
-        return new IScalarEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws AlgebricksException {
-
-                return new IScalarEvaluator() {
-                    private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-                    private DataOutput out = resultStorage.getDataOutput();
-                    private IPointable leftPtr = new VoidPointable();
-                    private IPointable rightPtr = new VoidPointable();
-                    private IScalarEvaluator evalLeft = args[0].createScalarEvaluator(ctx);
-                    private IScalarEvaluator evalRight = args[1].createScalarEvaluator(ctx);
-                    private double[] operands = new double[args.length];
-                    private boolean metInt8 = false, metInt16 = false, metInt32 = false, metInt64 = false,
-                            metFloat = false, metDouble = false;
-                    private ATypeTag typeTag;
-                    private AMutableDouble aDouble = new AMutableDouble(0);
-                    private AMutableFloat aFloat = new AMutableFloat(0);
-                    private AMutableInt64 aInt64 = new AMutableInt64(0);
-                    private AMutableInt32 aInt32 = new AMutableInt32(0);
-                    private AMutableInt16 aInt16 = new AMutableInt16((short) 0);
-                    private AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
-                    @SuppressWarnings("rawtypes")
-                    private ISerializerDeserializer serde;
-
-                    @SuppressWarnings("unchecked")
-                    @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-
-                        try {
-                            resultStorage.reset();
-                            evalLeft.evaluate(tuple, leftPtr);
-                            evalRight.evaluate(tuple, rightPtr);
-                            for (int i = 0; i < args.length; i++) {
-                                IPointable argPtr = i == 0 ? leftPtr : rightPtr;
-                                byte[] data = argPtr.getByteArray();
-                                int offset = argPtr.getStartOffset();
-                                typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[offset]);
-                                switch (typeTag) {
-                                    case INT8: {
-                                        metInt8 = true;
-                                        operands[i] = AInt8SerializerDeserializer.getByte(data, offset + 1);
-                                        break;
-                                    }
-                                    case INT16: {
-                                        metInt16 = true;
-                                        operands[i] = AInt16SerializerDeserializer.getShort(data, offset + 1);
-                                        break;
-                                    }
-                                    case INT32: {
-                                        metInt32 = true;
-                                        operands[i] = AInt32SerializerDeserializer.getInt(data, offset + 1);
-                                        break;
-                                    }
-                                    case INT64: {
-                                        metInt64 = true;
-                                        operands[i] = AInt64SerializerDeserializer.getLong(data, offset + 1);
-                                        break;
-                                    }
-                                    case FLOAT: {
-                                        metFloat = true;
-                                        operands[i] = AFloatSerializerDeserializer.getFloat(data, offset + 1);
-                                        break;
-                                    }
-                                    case DOUBLE: {
-                                        metDouble = true;
-                                        operands[i] = ADoubleSerializerDeserializer.getDouble(data, offset + 1);
-                                        break;
-                                    }
-                                    default: {
-                                        throw new NotImplementedException(AsterixBuiltinFunctions.NUMERIC_MOD.getName()
-                                                + (i == 0 ? ": left" : ": right") + " operand can not be "
-                                                + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[offset]));
-                                    }
-                                }
-                            }
-
-                            if (metDouble) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.ADOUBLE);
-                                aDouble.setValue(operands[0] % operands[1]);
-                                serde.serialize(aDouble, out);
-                            } else if (metFloat) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.AFLOAT);
-                                aFloat.setValue((float) (operands[0] % operands[1]));
-                                serde.serialize(aFloat, out);
-                            } else if (metInt64) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.AINT64);
-                                aInt64.setValue((long) (operands[0] % operands[1]));
-                                serde.serialize(aInt64, out);
-                            } else if (metInt32) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.AINT32);
-                                aInt32.setValue((int) (operands[0] % operands[1]));
-                                serde.serialize(aInt32, out);
-                            } else if (metInt16) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.AINT16);
-                                aInt16.setValue((short) (operands[0] % operands[1]));
-                                serde.serialize(aInt16, out);
-                            } else if (metInt8) {
-                                serde = AqlSerializerDeserializerProvider.INSTANCE
-                                        .getSerializerDeserializer(BuiltinType.AINT8);
-                                aInt8.setValue((byte) (operands[0] % operands[1]));
-                                serde.serialize(aInt8, out);
-                            }
-                            result.set(resultStorage);
-                        } catch (HyracksDataException hde) {
-                            throw new AlgebricksException(hde);
-                        }
-                    }
-                };
-            }
-        };
+    protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
+        return lhs % rhs;
     }
 
+    @Override
+    protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException {
+        return lhs % rhs;
+    }
+
+    @Override
+    protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+            throws HyracksDataException {
+        throw new NotImplementedException("Multiply operation is not defined for temporal types");
+    }
+
+    @Override
+    protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+        throw new NotImplementedException("Multiply operation is not defined for temporal types");
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java
index d39478d..e8d97a7 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundHalfToEven2Descriptor.java
@@ -155,7 +155,8 @@
                                 serde = AqlSerializerDeserializerProvider.INSTANCE
                                         .getSerializerDeserializer(BuiltinType.AFLOAT);
                                 float val = AFloatSerializerDeserializer.getFloat(data, offset + 1);
-                                if (Float.isNaN(val) || Float.isInfinite(val) || val == -0.0F || val == 0.0F) {
+                                if (Float.isNaN(val) || Float.isInfinite(val) || Float.compare(val, -0.0F) == 0
+                                        || Float.compare(val, 0.0F) == 0) {
                                     aFloat.setValue(val);
                                     serde.serialize(aFloat, out);
                                 } else {
@@ -168,7 +169,8 @@
                                 serde = AqlSerializerDeserializerProvider.INSTANCE
                                         .getSerializerDeserializer(BuiltinType.ADOUBLE);
                                 double val = ADoubleSerializerDeserializer.getDouble(data, offset + 1);
-                                if (Double.isNaN(val) || Double.isInfinite(val) || val == -0.0D || val == 0.0D) {
+                                if (Double.isNaN(val) || Double.isInfinite(val) || Double.compare(val, -0.0D) == 0
+                                        || Double.compare(val, 0.0D) == 0) {
                                     aDouble.setValue(val);
                                     serde.serialize(aDouble, out);
                                 } else {
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericTruncDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericTruncDescriptor.java
new file mode 100644
index 0000000..6900027
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericTruncDescriptor.java
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+/*
+ * Numeric function Round half to even
+ * Author : Xiaoyu Ma@UC Irvine
+ * 01/30/2012
+ */
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.DataOutput;
+import java.math.BigDecimal;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableDouble;
+import org.apache.asterix.om.base.AMutableFloat;
+import org.apache.asterix.om.base.AMutableInt16;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.base.AMutableInt8;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+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.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class NumericTruncDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericTruncDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.NUMERIC_TRUNC;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new NumericTruncEvaluator(args, ctx);
+            }
+        };
+    }
+
+    class NumericTruncEvaluator implements IScalarEvaluator {
+        private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+        private final DataOutput out = resultStorage.getDataOutput();
+        private final IPointable argValue = new VoidPointable();
+        private final IPointable argPrecision = new VoidPointable();
+        private final IScalarEvaluator eval;
+        private final IScalarEvaluator precision;
+        private final AMutableDouble aDouble = new AMutableDouble(0);
+        private final AMutableFloat aFloat = new AMutableFloat(0);
+        private final AMutableInt64 aInt64 = new AMutableInt64(0);
+        private final AMutableInt32 aInt32 = new AMutableInt32(0);
+        private final AMutableInt16 aInt16 = new AMutableInt16((short) 0);
+        private final AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+        @SuppressWarnings("rawtypes")
+        private ISerializerDeserializer serde;
+
+        NumericTruncEvaluator(IScalarEvaluatorFactory[] args, IHyracksTaskContext ctx) throws AlgebricksException {
+            eval = args[0].createScalarEvaluator(ctx);
+            precision = args[1].createScalarEvaluator(ctx);
+        }
+
+        private int getPrecision() throws AlgebricksException {
+            byte[] bytes = argPrecision.getByteArray();
+            int offset = argPrecision.getStartOffset();
+
+            if (bytes[offset] == ATypeTag.SERIALIZED_INT8_TYPE_TAG) {
+                return AInt8SerializerDeserializer.getByte(bytes, offset + 1);
+            } else if (bytes[offset] == ATypeTag.SERIALIZED_INT16_TYPE_TAG) {
+                return AInt16SerializerDeserializer.getShort(bytes, offset + 1);
+            } else if (bytes[offset] == ATypeTag.SERIALIZED_INT32_TYPE_TAG) {
+                return AInt32SerializerDeserializer.getInt(bytes, offset + 1);
+            } else if (bytes[offset] == ATypeTag.SERIALIZED_INT64_TYPE_TAG) {
+                return (int) AInt64SerializerDeserializer.getLong(bytes, offset + 1);
+            } else {
+                throw new AlgebricksException(NumericTruncDescriptor.this.getIdentifier().getName()
+                        + ": the precision argument should be an INT8/INT16/INT32/INT64.");
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+            resultStorage.reset();
+            eval.evaluate(tuple, argValue);
+            precision.evaluate(tuple, argPrecision);
+            byte[] data = argValue.getByteArray();
+            int offset = argValue.getStartOffset();
+
+            try {
+                if (data[offset] == ATypeTag.SERIALIZED_INT8_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT8);
+                    byte val = AInt8SerializerDeserializer.getByte(data, offset + 1);
+                    aInt8.setValue(val);
+                    serde.serialize(aInt8, out);
+                } else if (data[offset] == ATypeTag.SERIALIZED_INT16_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT16);
+                    short val = AInt16SerializerDeserializer.getShort(data, offset + 1);
+                    aInt16.setValue(val);
+                    serde.serialize(aInt16, out);
+                } else if (data[offset] == ATypeTag.SERIALIZED_INT32_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT32);
+                    int val = AInt32SerializerDeserializer.getInt(data, offset + 1);
+                    aInt32.setValue(val);
+                    serde.serialize(aInt32, out);
+                } else if (data[offset] == ATypeTag.SERIALIZED_INT64_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+                    long val = AInt64SerializerDeserializer.getLong(data, offset + 1);
+                    aInt64.setValue(val);
+                    serde.serialize(aInt64, out);
+                } else if (data[offset] == ATypeTag.SERIALIZED_FLOAT_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AFLOAT);
+                    float val = AFloatSerializerDeserializer.getFloat(data, offset + 1);
+                    if (Float.isNaN(val) || Float.isInfinite(val) || Float.compare(val, -0.0F) == 0
+                            || Float.compare(val, 0.0F) == 0) {
+                        aFloat.setValue(val);
+                        serde.serialize(aFloat, out);
+                    } else {
+                        BigDecimal r = new BigDecimal(Float.toString(val));
+                        aFloat.setValue(r.setScale(getPrecision(), BigDecimal.ROUND_DOWN).floatValue());
+                        serde.serialize(aFloat, out);
+                    }
+                } else if (data[offset] == ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG) {
+                    serde = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE);
+                    double val = ADoubleSerializerDeserializer.getDouble(data, offset + 1);
+                    if (Double.isNaN(val) || Double.isInfinite(val) || Double.compare(val, -0.0D) == 0
+                            || Double.compare(val, 0.0D) == 0) {
+                        aDouble.setValue(val);
+                        serde.serialize(aDouble, out);
+                    } else {
+                        BigDecimal r = new BigDecimal(Double.toString(val));
+                        aDouble.setValue(r.setScale(getPrecision(), BigDecimal.ROUND_DOWN).doubleValue());
+                        serde.serialize(aDouble, out);
+                    }
+                } else {
+                    throw new NotImplementedException(
+                            NumericTruncDescriptor.this.getIdentifier().getName() + ": not implemented for "
+                                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[offset]));
+                }
+            } catch (HyracksDataException e) {
+                throw new AlgebricksException(e);
+            }
+            result.set(resultStorage);
+        }
+    }
+
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/UUIDDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/UUIDDescriptor.java
new file mode 100644
index 0000000..e306cc4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/UUIDDescriptor.java
@@ -0,0 +1,92 @@
+/*
+ * 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.evaluators.functions;
+
+import java.io.DataOutput;
+
+import org.apache.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import org.apache.asterix.om.base.AGeneratedUUID;
+import org.apache.asterix.om.base.AUUID;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+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.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class UUIDDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new UUIDDescriptor();
+        }
+    };
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(IScalarEvaluatorFactory[] args) throws AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+
+            private static final long serialVersionUID = 1L;
+
+            @SuppressWarnings("unchecked")
+            private final ISerializerDeserializer<AUUID> uuidSerDe = AqlSerializerDeserializerProvider.INSTANCE
+                    .getSerializerDeserializer(BuiltinType.AUUID);
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new IScalarEvaluator() {
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput output = resultStorage.getDataOutput();
+                    private final AGeneratedUUID uuid = new AGeneratedUUID();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+                        uuid.nextUUID();
+                        try {
+                            resultStorage.reset();
+                            uuidSerDe.serialize(uuid, output);
+                            result.set(resultStorage);
+                        } catch (HyracksDataException e) {
+                            throw new AlgebricksException(e);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.UUID;
+    }
+
+}