Merge branch 'master' into salsubaiee/master_fix_asterix_issue_460
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
index d6e0f42..282d26b 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
@@ -188,8 +188,12 @@
         // if already rewritten, the required type is not null
         if (TypeComputerUtilities.getRequiredType(funcExpr) != null)
             return false;
-        TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
-        return staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
+        boolean casted = staticRecordTypeCast(funcExpr, requiredRecordType, inputRecordType, env);
+        if (casted) {
+            //enforce the required type if it is statically casted
+            TypeComputerUtilities.setRequiredAndInputTypes(funcExpr, requiredRecordType, inputRecordType);
+        }
+        return casted;
     }
 
     /**
diff --git a/asterix-app/data/tinysocial/twm.adm b/asterix-app/data/tinysocial/twm.adm
new file mode 100644
index 0000000..d18c70f
--- /dev/null
+++ b/asterix-app/data/tinysocial/twm.adm
@@ -0,0 +1,12 @@
+{"tweetid":"1","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("47.44,80.65"),"send-time":datetime("2008-04-26T10:10:00"),"referred-topics":{{"t-mobile","customization"}},"message-text":" love t-mobile its customization is good:)"}
+{"tweetid":"2","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("32.84,67.14"),"send-time":datetime("2010-05-13T10:10:00"),"referred-topics":{{"verizon","shortcut-menu"}},"message-text":" like verizon its shortcut-menu is awesome:)"}
+{"tweetid":"3","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("29.72,75.8"),"send-time":datetime("2006-11-04T10:10:00"),"referred-topics":{{"motorola","speed"}},"message-text":" like motorola the speed is good:)"}
+{"tweetid":"4","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("39.28,70.48"),"send-time":datetime("2011-12-26T10:10:00"),"referred-topics":{{"sprint","voice-command"}},"message-text":" like sprint the voice-command is mind-blowing:)"}
+{"tweetid":"5","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("40.09,92.69"),"send-time":datetime("2006-08-04T10:10:00"),"referred-topics":{{"motorola","speed"}},"message-text":" can't stand motorola its speed is terrible:("}
+{"tweetid":"6","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("47.51,83.99"),"send-time":datetime("2010-05-07T10:10:00"),"referred-topics":{{"iphone","voice-clarity"}},"message-text":" like iphone the voice-clarity is good:)"}
+{"tweetid":"7","user":{"screen-name":"ChangEwing_573","lang":"en","friends_count":182,"statuses_count":394,"name":"Chang Ewing","followers_count":32136},"sender-location":point("36.21,72.6"),"send-time":datetime("2011-08-25T10:10:00"),"referred-topics":{{"samsung","platform"}},"message-text":" like samsung the platform is good"}
+{"tweetid":"8","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("46.05,93.34"),"send-time":datetime("2005-10-14T10:10:00"),"referred-topics":{{"t-mobile","shortcut-menu"}},"message-text":" like t-mobile the shortcut-menu is awesome:)"}
+{"tweetid":"9","user":{"screen-name":"NathanGiesen@211","lang":"en","friends_count":39339,"statuses_count":473,"name":"Nathan Giesen","followers_count":49416},"sender-location":point("36.86,74.62"),"send-time":datetime("2012-07-21T10:10:00"),"referred-topics":{{"verizon","voicemail-service"}},"message-text":" love verizon its voicemail-service is awesome"}
+{"tweetid":"10","user":{"screen-name":"ColineGeyer@63","lang":"en","friends_count":121,"statuses_count":362,"name":"Coline Geyer","followers_count":17159},"sender-location":point("29.15,76.53"),"send-time":datetime("2008-01-26T10:10:00"),"referred-topics":{{"verizon","voice-clarity"}},"message-text":" hate verizon its voice-clarity is OMG:("}
+{"tweetid":"11","user":{"screen-name":"NilaMilliron_tw","lang":"en","friends_count":445,"statuses_count":164,"name":"Nila Milliron","followers_count":22649},"sender-location":point("37.59,68.42"),"send-time":datetime("2008-03-09T10:10:00"),"referred-topics":{{"iphone","platform"}},"message-text":" can't stand iphone its platform is terrible"}
+{"tweetid":"12","user":{"screen-name":"OliJackson_512","lang":"en","friends_count":445,"statuses_count":164,"name":"Oli Jackson","followers_count":22649},"sender-location":point("24.82,94.63"),"send-time":datetime("2010-02-13T10:10:00"),"referred-topics":{{"samsung","voice-command"}},"message-text":" like samsung the voice-command is amazing:)"}
\ No newline at end of file
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
index 32f17b2..02cf6a4 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/result/ResultUtils.java
@@ -91,11 +91,10 @@
     public static String extractErrorMessage(Throwable e) {
         StringBuilder errorMessageBuilder = new StringBuilder();
         Throwable cause = e;
+        errorMessageBuilder.append(cause.getLocalizedMessage());
         while (cause != null) {
-            StackTraceElement[] stackTraceElements = e.getStackTrace();
-            errorMessageBuilder.append(cause.toString());
-            errorMessageBuilder.append(stackTraceElements.length > 0 ? "\n at " + stackTraceElements[0] : "");
-            errorMessageBuilder.append("\n");
+            StackTraceElement[] stackTraceElements = cause.getStackTrace();
+            errorMessageBuilder.append(stackTraceElements.length > 0 ? "\n caused by: " + stackTraceElements[0] : "");
             cause = cause.getCause();
         }
         return errorMessageBuilder.toString();
diff --git a/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.1.ddl.aql
new file mode 100644
index 0000000..17da24b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.1.ddl.aql
@@ -0,0 +1,13 @@
+drop dataverse TinySocial if exists;
+create dataverse TinySocial;
+use dataverse TinySocial;
+
+create type TweetMessageType as open {
+        tweetid: string
+}
+
+create dataset TweetMessages(TweetMessageType)
+primary key tweetid
+hints(cardinality=100); 
+
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.2.update.aql
new file mode 100644
index 0000000..627623a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.2.update.aql
@@ -0,0 +1,5 @@
+use dataverse TinySocial;
+
+load dataset TweetMessages
+using "edu.uci.ics.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="nc1://data/tinysocial/twm.adm"),("format"="adm"));
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.3.query.aql
new file mode 100644
index 0000000..f40e884
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/fuzzyjoin/opentype/opentype.3.query.aql
@@ -0,0 +1,15 @@
+use dataverse TinySocial;
+
+set simfunction "jaccard";
+set simthreshold "0.3";
+
+for $t in dataset TweetMessages
+order by $t.tweetid
+return {                     
+    "tweet": $t,               
+    "similar-tweets": for $t2 in dataset TweetMessages
+    					order by $t2.tweetid
+                        where  $t2.referred-topics ~= $t.referred-topics
+                        and $t2.tweetid != $t.tweetid
+                        return $t2.referred-topics
+};
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.1.ddl.aql
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.1.ddl.aql
@@ -0,0 +1,2 @@
+
+
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.2.update.aql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.2.update.aql
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.3.query.aql
new file mode 100644
index 0000000..825b269
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/numeric/caret0/caret0.3.query.aql
@@ -0,0 +1,5 @@
+let $n1 := 2.0
+let $n2 := 4096.0
+let $n3 := 3
+let $n4 := 2
+return { "c1": $n1^$n2, "c2": $n2^$n1, "c3": $n3^$n4 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.1.ddl.aql
new file mode 100644
index 0000000..4d74b83
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.1.ddl.aql
@@ -0,0 +1,18 @@
+/*
+ * Description  : This test case is to verify the fix for issue487
+ 				: https://code.google.com/p/asterixdb/issues/detail?id=487
+ * Expected Res : FAIL
+ * Date         : 30th May 2013
+ */
+ 
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type EmpType as open {
+id : int32,
+name : string
+}
+
+create dataset Employee(EmpType) primary key id;
+ 
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.2.update.aql
new file mode 100644
index 0000000..6913b4f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.2.update.aql
@@ -0,0 +1,10 @@
+/*
+ * Description  : This test case is to verify the fix for issue487
+ 				: https://code.google.com/p/asterixdb/issues/detail?id=487
+ * Expected Res : FAIL
+ * Date         : 30th May 2013
+ */
+
+use dataverse test;
+ 
+insert into dataset Employee ({ "id":123});
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.3.query.aql
new file mode 100644
index 0000000..d53aba9
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/open-closed/query-issue487/query-issue487.3.query.aql
@@ -0,0 +1,12 @@
+/*
+ * Description  : This test case is to verify the fix for issue487
+ 				: https://code.google.com/p/asterixdb/issues/detail?id=487
+ * Expected Res : FAIL
+ * Date         : 30th May 2013
+ */
+
+use dataverse test;
+
+for $l in dataset Employee
+return $l;
+ 
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/fuzzyjoin/opentype/opentype.1.adm b/asterix-app/src/test/resources/runtimets/results/fuzzyjoin/opentype/opentype.1.adm
new file mode 100644
index 0000000..ae0c4cb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/fuzzyjoin/opentype/opentype.1.adm
@@ -0,0 +1,12 @@
+{ "tweet": { "tweetid": "1", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("47.44,80.65"), "send-time": datetime("2008-04-26T10:10:00.000Z"), "referred-topics": {{ "t-mobile", "customization" }}, "message-text": " love t-mobile its customization is good:)" }, "similar-tweets": [ {{ "t-mobile", "shortcut-menu" }} ] }
+{ "tweet": { "tweetid": "10", "user": { "screen-name": "ColineGeyer@63", "lang": "en", "friends_count": 121, "statuses_count": 362, "name": "Coline Geyer", "followers_count": 17159 }, "sender-location": point("29.15,76.53"), "send-time": datetime("2008-01-26T10:10:00.000Z"), "referred-topics": {{ "verizon", "voice-clarity" }}, "message-text": " hate verizon its voice-clarity is OMG:(" }, "similar-tweets": [ {{ "verizon", "shortcut-menu" }}, {{ "iphone", "voice-clarity" }}, {{ "verizon", "voicemail-service" }} ] }
+{ "tweet": { "tweetid": "11", "user": { "screen-name": "NilaMilliron_tw", "lang": "en", "friends_count": 445, "statuses_count": 164, "name": "Nila Milliron", "followers_count": 22649 }, "sender-location": point("37.59,68.42"), "send-time": datetime("2008-03-09T10:10:00.000Z"), "referred-topics": {{ "iphone", "platform" }}, "message-text": " can't stand iphone its platform is terrible" }, "similar-tweets": [ {{ "iphone", "voice-clarity" }}, {{ "samsung", "platform" }} ] }
+{ "tweet": { "tweetid": "12", "user": { "screen-name": "OliJackson_512", "lang": "en", "friends_count": 445, "statuses_count": 164, "name": "Oli Jackson", "followers_count": 22649 }, "sender-location": point("24.82,94.63"), "send-time": datetime("2010-02-13T10:10:00.000Z"), "referred-topics": {{ "samsung", "voice-command" }}, "message-text": " like samsung the voice-command is amazing:)" }, "similar-tweets": [ {{ "sprint", "voice-command" }}, {{ "samsung", "platform" }} ] }
+{ "tweet": { "tweetid": "2", "user": { "screen-name": "ColineGeyer@63", "lang": "en", "friends_count": 121, "statuses_count": 362, "name": "Coline Geyer", "followers_count": 17159 }, "sender-location": point("32.84,67.14"), "send-time": datetime("2010-05-13T10:10:00.000Z"), "referred-topics": {{ "verizon", "shortcut-menu" }}, "message-text": " like verizon its shortcut-menu is awesome:)" }, "similar-tweets": [ {{ "verizon", "voice-clarity" }}, {{ "t-mobile", "shortcut-menu" }}, {{ "verizon", "voicemail-service" }} ] }
+{ "tweet": { "tweetid": "3", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("29.72,75.8"), "send-time": datetime("2006-11-04T10:10:00.000Z"), "referred-topics": {{ "motorola", "speed" }}, "message-text": " like motorola the speed is good:)" }, "similar-tweets": [ {{ "motorola", "speed" }} ] }
+{ "tweet": { "tweetid": "4", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("39.28,70.48"), "send-time": datetime("2011-12-26T10:10:00.000Z"), "referred-topics": {{ "sprint", "voice-command" }}, "message-text": " like sprint the voice-command is mind-blowing:)" }, "similar-tweets": [ {{ "samsung", "voice-command" }} ] }
+{ "tweet": { "tweetid": "5", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("40.09,92.69"), "send-time": datetime("2006-08-04T10:10:00.000Z"), "referred-topics": {{ "motorola", "speed" }}, "message-text": " can't stand motorola its speed is terrible:(" }, "similar-tweets": [ {{ "motorola", "speed" }} ] }
+{ "tweet": { "tweetid": "6", "user": { "screen-name": "ColineGeyer@63", "lang": "en", "friends_count": 121, "statuses_count": 362, "name": "Coline Geyer", "followers_count": 17159 }, "sender-location": point("47.51,83.99"), "send-time": datetime("2010-05-07T10:10:00.000Z"), "referred-topics": {{ "iphone", "voice-clarity" }}, "message-text": " like iphone the voice-clarity is good:)" }, "similar-tweets": [ {{ "verizon", "voice-clarity" }}, {{ "iphone", "platform" }} ] }
+{ "tweet": { "tweetid": "7", "user": { "screen-name": "ChangEwing_573", "lang": "en", "friends_count": 182, "statuses_count": 394, "name": "Chang Ewing", "followers_count": 32136 }, "sender-location": point("36.21,72.6"), "send-time": datetime("2011-08-25T10:10:00.000Z"), "referred-topics": {{ "samsung", "platform" }}, "message-text": " like samsung the platform is good" }, "similar-tweets": [ {{ "iphone", "platform" }}, {{ "samsung", "voice-command" }} ] }
+{ "tweet": { "tweetid": "8", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("46.05,93.34"), "send-time": datetime("2005-10-14T10:10:00.000Z"), "referred-topics": {{ "t-mobile", "shortcut-menu" }}, "message-text": " like t-mobile the shortcut-menu is awesome:)" }, "similar-tweets": [ {{ "t-mobile", "customization" }}, {{ "verizon", "shortcut-menu" }} ] }
+{ "tweet": { "tweetid": "9", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("36.86,74.62"), "send-time": datetime("2012-07-21T10:10:00.000Z"), "referred-topics": {{ "verizon", "voicemail-service" }}, "message-text": " love verizon its voicemail-service is awesome" }, "similar-tweets": [ {{ "verizon", "voice-clarity" }}, {{ "verizon", "shortcut-menu" }} ] }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/caret0/caret0.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/caret0/caret0.1.adm
new file mode 100644
index 0000000..1edec8a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/numeric/caret0/caret0.1.adm
@@ -0,0 +1 @@
+{ "c1": Infinityd, "c2": 1.6777216E7d, "c3": 9 }
diff --git a/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue487/query-issue487.1.adm b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue487/query-issue487.1.adm
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/open-closed/query-issue487/query-issue487.1.adm
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 1fb101d..0c43526 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -1750,6 +1750,11 @@
       </compilation-unit>
     </test-case>
     -->
+    <test-case FilePath="fuzzyjoin">
+      <compilation-unit name="opentype">
+        <output-dir compare="Text">opentype</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="index-join">
     <test-case FilePath="index-join">
@@ -2155,6 +2160,11 @@
   </test-group>
   <test-group name="numeric">
     <test-case FilePath="numeric">
+      <compilation-unit name="caret0">
+        <output-dir compare="Text">caret0</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="numeric">
       <compilation-unit name="abs0">
         <output-dir compare="Text">abs0</output-dir>
       </compilation-unit>
@@ -2727,6 +2737,12 @@
         <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="open-closed">
+      <compilation-unit name="query-issue487">
+        <output-dir compare="Text">query-issue487</output-dir>
+        <expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="quantifiers">
     <test-case FilePath="quantifiers">
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
new file mode 100644
index 0000000..6e80fe6
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.dataflow.data.nontagged.comparators;
+
+import edu.uci.ics.asterix.formats.nontagged.UTF8StringLowercasePointable;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparator;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryComparatorFactory;
+import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryComparatorFactory;
+import edu.uci.ics.hyracks.data.std.primitive.DoublePointable;
+import edu.uci.ics.hyracks.data.std.primitive.FloatPointable;
+import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
+import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
+
+public class ListItemBinaryComparatorFactory implements IBinaryComparatorFactory {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final ListItemBinaryComparatorFactory INSTANCE = new ListItemBinaryComparatorFactory();
+
+    private ListItemBinaryComparatorFactory() {
+    }
+
+    @Override
+    public IBinaryComparator createBinaryComparator() {
+        return createBinaryComparator(ATypeTag.NULL, ATypeTag.NULL, false);
+    }
+
+    public IBinaryComparator createBinaryComparator(final ATypeTag firstItemTypeTag, final ATypeTag secondItemTypeTag,
+            final boolean ignoreCase) {
+        return new IBinaryComparator() {
+            final IBinaryComparator ascBoolComp = BooleanBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+            final IBinaryComparator ascIntComp = new PointableBinaryComparatorFactory(IntegerPointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascLongComp = LongBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+            final IBinaryComparator ascStrComp = new PointableBinaryComparatorFactory(UTF8StringPointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascLowerCaseStrComp = new PointableBinaryComparatorFactory(
+                    UTF8StringLowercasePointable.FACTORY).createBinaryComparator();
+            final IBinaryComparator ascFloatComp = new PointableBinaryComparatorFactory(FloatPointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascDoubleComp = new PointableBinaryComparatorFactory(DoublePointable.FACTORY)
+                    .createBinaryComparator();
+            final IBinaryComparator ascRectangleComp = ARectanglePartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascCircleComp = ACirclePartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascDurationComp = ADurationPartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascIntervalComp = AIntervalPartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascLineComp = ALinePartialBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+            final IBinaryComparator ascPointComp = APointPartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascPoint3DComp = APoint3DPartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator ascPolygonComp = APolygonPartialBinaryComparatorFactory.INSTANCE
+                    .createBinaryComparator();
+            final IBinaryComparator rawComp = RawBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+
+            @Override
+            public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
+
+                if (b1[s1] == ATypeTag.NULL.serialize()) {
+                    if (b2[s2] == ATypeTag.NULL.serialize())
+                        return 0;
+                    else
+                        return -1;
+                } else {
+                    if (b2[s2] == ATypeTag.NULL.serialize())
+                        return 1;
+                }
+
+                ATypeTag tag1 = firstItemTypeTag;
+                int skip1 = 0;
+                if (firstItemTypeTag == ATypeTag.ANY) {
+                    tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b1[s1]);
+                    skip1 = 1;
+                }
+
+                ATypeTag tag2 = secondItemTypeTag;
+                int skip2 = 0;
+                if (secondItemTypeTag == ATypeTag.ANY) {
+                    tag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b2[s2]);
+                    skip2 = 1;
+                }
+
+                if (tag1 != tag2) {
+                    return rawComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                }
+
+                switch (tag1) {
+                    case BOOLEAN: {
+                        return ascBoolComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case TIME:
+                    case DATE:
+                    case YEARMONTHDURATION:
+                    case INT32: {
+                        return ascIntComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case DATETIME:
+                    case DAYTIMEDURATION:
+                    case INT64: {
+                        return ascLongComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case FLOAT: {
+                        return ascFloatComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case DOUBLE: {
+                        return ascDoubleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case STRING: {
+                        if (ignoreCase) {
+                            return ascLowerCaseStrComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                        } else {
+                            return ascStrComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                        }
+                    }
+                    case RECTANGLE: {
+                        return ascRectangleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case CIRCLE: {
+                        return ascCircleComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case POINT: {
+                        return ascPointComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case POINT3D: {
+                        return ascPoint3DComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case LINE: {
+                        return ascLineComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case POLYGON: {
+                        return ascPolygonComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case DURATION: {
+                        return ascDurationComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    case INTERVAL: {
+                        return ascIntervalComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                    default: {
+                        return rawComp.compare(b1, s1 + skip1, l1 - skip1, b2, s2 + skip2, l2 - skip2);
+                    }
+                }
+            }
+        };
+    }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/ListItemBinaryHashFunctionFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/ListItemBinaryHashFunctionFactory.java
new file mode 100644
index 0000000..0fab7de
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/hash/ListItemBinaryHashFunctionFactory.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.dataflow.data.nontagged.hash;
+
+import java.io.IOException;
+
+import edu.uci.ics.asterix.formats.nontagged.UTF8StringLowercasePointable;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunction;
+import edu.uci.ics.hyracks.api.dataflow.value.IBinaryHashFunctionFactory;
+import edu.uci.ics.hyracks.data.std.accessors.MurmurHash3BinaryHashFunctionFamily;
+import edu.uci.ics.hyracks.data.std.accessors.PointableBinaryHashFunctionFactory;
+import edu.uci.ics.hyracks.data.std.util.GrowableArray;
+
+/**
+ * This hash function factory is introduced to be able to hash heterogeneous list items.
+ * The item type tag is also included in the hash computation to distinguish the different
+ * types with the same raw bytes.
+ */
+public class ListItemBinaryHashFunctionFactory implements IBinaryHashFunctionFactory {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final ListItemBinaryHashFunctionFactory INSTANCE = new ListItemBinaryHashFunctionFactory();
+
+    private ListItemBinaryHashFunctionFactory() {
+    }
+
+    @Override
+    public IBinaryHashFunction createBinaryHashFunction() {
+        return createBinaryHashFunction(ATypeTag.ANY, false);
+    }
+
+    public IBinaryHashFunction createBinaryHashFunction(final ATypeTag itemTypeTag, final boolean ignoreCase) {
+        return new IBinaryHashFunction() {
+
+            private IBinaryHashFunction lowerCaseStringHash = new PointableBinaryHashFunctionFactory(
+                    UTF8StringLowercasePointable.FACTORY).createBinaryHashFunction();
+            private IBinaryHashFunction genericBinaryHash = MurmurHash3BinaryHashFunctionFamily.INSTANCE
+                    .createBinaryHashFunction(0);
+            private GrowableArray taggedBytes = new GrowableArray();
+
+            @Override
+            public int hash(byte[] bytes, int offset, int length) {
+                ATypeTag tag = itemTypeTag;
+                int skip = 0;
+                if (itemTypeTag == ATypeTag.ANY) {
+                    tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset]);
+                    skip = 1;
+                }
+                switch (tag) {
+                    case STRING: {
+                        if (ignoreCase) {
+                            return lowerCaseStringHash.hash(bytes, offset + skip, length - skip);
+                        }
+                    }
+                    default: {
+                        if (itemTypeTag != ATypeTag.ANY) {
+                            // add the itemTypeTag in front of the data
+                            try {
+                                resetTaggedBytes(bytes, offset, length);
+                                return genericBinaryHash.hash(taggedBytes.getByteArray(), 0, length + 1);
+                            } catch (IOException e) {
+                                throw new RuntimeException(e);
+                            }
+                        } else {
+                            return genericBinaryHash.hash(bytes, offset, length);
+                        }
+                    }
+                }
+            }
+
+            private void resetTaggedBytes(byte[] data, int offset, int length) throws IOException {
+                taggedBytes.reset();
+                taggedBytes.getDataOutput().writeByte(itemTypeTag.serialize());
+                taggedBytes.getDataOutput().write(data, offset, length);
+            }
+        };
+    }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java
index efae5f9..269d363 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AbstractAsterixListIterator.java
@@ -13,7 +13,10 @@
     protected byte[] data;
     protected int count = 0;
     protected int pos = -1;
-    protected int size = -1;
+    protected int nextPos = -1;
+    protected int itemLen = -1;
+    protected int numberOfItems = -1;
+    protected int listLength = -1;
     protected int startOff = -1;
     protected IBinaryComparator cmp;
 
@@ -27,12 +30,12 @@
 
     @Override
     public boolean hasNext() {
-        return count < size;
+        return count < numberOfItems;
     }
 
     @Override
     public int size() {
-        return size;
+        return numberOfItems;
     }
 
     @Override
@@ -45,10 +48,20 @@
         return pos;
     }
 
+    public int getItemLen() {
+        return itemLen;
+    }
+
     @Override
     public void next() {
         try {
-            pos = getItemOffset(data, startOff, ++count);
+            pos = nextPos;
+            ++count;
+            nextPos = startOff + listLength;
+            if (count + 1 < numberOfItems) {
+                nextPos = getItemOffset(data, startOff, count + 1);
+            }
+            itemLen = nextPos - pos;
         } catch (AsterixException e) {
             throw new AsterixRuntimeException(e);
         }
@@ -59,6 +72,11 @@
         count = 0;
         try {
             pos = getItemOffset(data, startOff, count);
+            nextPos = startOff + listLength;
+            if (count + 1 < numberOfItems) {
+                nextPos = getItemOffset(data, startOff, count + 1);
+            }
+            itemLen = nextPos - pos;
         } catch (AsterixException e) {
             throw new AsterixRuntimeException(e);
         }
@@ -67,7 +85,8 @@
     public void reset(byte[] data, int startOff) {
         this.data = data;
         this.startOff = startOff;
-        size = getNumberOfItems(data, startOff);
+        this.numberOfItems = getNumberOfItems(data, startOff);
+        this.listLength = getListLength(data, startOff);
         ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(data[startOff + 1]);
         switch (tag) {
             case INT32: {
@@ -102,4 +121,6 @@
     protected abstract int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws AsterixException;
 
     protected abstract int getNumberOfItems(byte[] serOrderedList, int offset);
+
+    protected abstract int getListLength(byte[] serOrderedList, int offset);
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java
index d3714c1..fc92875 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixOrderedListIterator.java
@@ -14,4 +14,9 @@
     protected int getNumberOfItems(byte[] serOrderedList, int offset) {
         return AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList, offset);
     }
+
+    @Override
+    protected int getListLength(byte[] serOrderedList, int offset) {
+        return AOrderedListSerializerDeserializer.getOrderedListLength(serOrderedList, offset + 1);
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java
index de7742b..5f01581 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/AsterixUnorderedListIterator.java
@@ -14,4 +14,9 @@
     protected int getNumberOfItems(byte[] serOrderedList, int offset) {
         return AUnorderedListSerializerDeserializer.getNumberOfItems(serOrderedList, offset);
     }
+
+    @Override
+    protected int getListLength(byte[] serOrderedList, int offset) {
+        return AUnorderedListSerializerDeserializer.getUnorderedListLength(serOrderedList, offset + 1);
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardCheckEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardCheckEvaluator.java
index ab73df2..b732f40 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardCheckEvaluator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardCheckEvaluator.java
@@ -62,8 +62,8 @@
             probeListCount++;
             byte[] buf = probeIter.getData();
             int off = probeIter.getPos();
-            int len = getItemLen(buf, off);
-            keyEntry.set(buf, off, len);            
+            int len = probeIter.getItemLen();
+            keyEntry.set(buf, off, len);
             BinaryEntry entry = hashMap.get(keyEntry);
             if (entry != null) {
                 // Increment second value.
@@ -94,7 +94,7 @@
         }
         return intersectionSize;
     }
-    
+
     @Override
     protected void writeResult(float jacc) throws IOException {
         listBuilder.reset(listType);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java
index 9f5c9c8..391fb30 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/common/SimilarityJaccardEvaluator.java
@@ -4,8 +4,6 @@
 import java.io.IOException;
 import java.util.Arrays;
 
-import edu.uci.ics.asterix.formats.nontagged.AqlBinaryComparatorFactoryProvider;
-import edu.uci.ics.asterix.formats.nontagged.AqlBinaryHashFunctionFactoryProvider;
 import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
 import edu.uci.ics.asterix.om.base.AFloat;
 import edu.uci.ics.asterix.om.base.AMutableFloat;
@@ -22,9 +20,10 @@
 import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
 import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
 import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
-import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable;
 import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
 import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+import edu.uci.ics.asterix.dataflow.data.nontagged.comparators.ListItemBinaryComparatorFactory;
+import edu.uci.ics.asterix.dataflow.data.nontagged.hash.ListItemBinaryHashFunctionFactory;
 
 public class SimilarityJaccardEvaluator implements ICopyEvaluator {
 
@@ -58,7 +57,8 @@
     protected int firstStart = -1;
     protected int secondStart = -1;
     protected float jaccSim = 0.0f;
-    protected ATypeTag itemTypeTag;
+    protected ATypeTag firstItemTypeTag;
+    protected ATypeTag secondItemTypeTag;
 
     protected BinaryHashMap hashMap;
     protected BinaryEntry keyEntry = new BinaryEntry();
@@ -105,6 +105,9 @@
 
         firstTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[firstStart]);
         secondTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[secondStart]);
+
+        firstItemTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[firstStart + 1]);
+        secondItemTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[secondStart + 1]);
     }
 
     protected boolean prepareLists(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
@@ -116,17 +119,12 @@
         if (firstListIter.size() == 0 || secondListIter.size() == 0) {
             return false;
         }
-        if (firstTypeTag == ATypeTag.ANY || secondTypeTag == ATypeTag.ANY) {
-            throw new AlgebricksException("\n Jaccard can only be called on homogenous lists");
-        }
         // TODO: Check item types are compatible.
-        itemTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[firstStart + 1]);
         return true;
     }
 
     protected float computeResult(byte[] bytes, int firstStart, int secondStart, ATypeTag argType)
             throws AlgebricksException {
-        setHashMap(bytes, firstStart, secondStart);
         // We will subtract the intersection size later to get the real union size.
         int firstListSize = firstListIter.size();
         int secondListSize = secondListIter.size();
@@ -136,7 +134,10 @@
         AbstractAsterixListIterator probeList = (buildList == firstListIter) ? secondListIter : firstListIter;
         int buildListSize = (buildList == firstListIter) ? firstListSize : secondListSize;
         int probeListSize = (probeList == firstListIter) ? firstListSize : secondListSize;
+        ATypeTag buildItemTypeTag = (buildList == firstListIter) ? firstItemTypeTag : secondItemTypeTag;
+        ATypeTag probeItemTypeTag = (probeList == firstListIter) ? firstItemTypeTag : secondItemTypeTag;
 
+        setHashMap(bytes, buildItemTypeTag, probeItemTypeTag);
         buildHashMap(buildList);
         int intersectionSize = probeHashMap(probeList, buildListSize, probeListSize);
         // Special indicator for the "check" version of jaccard.
@@ -154,7 +155,7 @@
         while (buildIter.hasNext()) {
             byte[] buf = buildIter.getData();
             int off = buildIter.getPos();
-            int len = getItemLen(buf, off);
+            int len = buildIter.getItemLen();
             keyEntry.set(buf, off, len);
             BinaryEntry entry = hashMap.put(keyEntry, valEntry);
             if (entry != null) {
@@ -172,7 +173,7 @@
         while (probeIter.hasNext()) {
             byte[] buf = probeIter.getData();
             int off = probeIter.getPos();
-            int len = getItemLen(buf, off);
+            int len = probeIter.getItemLen();
             keyEntry.set(buf, off, len);
             BinaryEntry entry = hashMap.get(keyEntry);
             if (entry != null) {
@@ -195,69 +196,19 @@
         return intersectionSize;
     }
 
-    protected void setHashMap(byte[] bytes, int firstStart, int secondStart) {
+    protected void setHashMap(byte[] bytes, ATypeTag buildItemTypeTag, ATypeTag probeItemTypeTag) {
         if (hashMap != null) {
             hashMap.clear();
             return;
         }
-        IBinaryHashFunction hashFunc = null;
-        IBinaryComparator cmp = null;
-        switch (itemTypeTag) {
-            case INT32: {
-                hashFunc = AqlBinaryHashFunctionFactoryProvider.INTEGER_POINTABLE_INSTANCE.createBinaryHashFunction();
-                cmp = AqlBinaryComparatorFactoryProvider.INTEGER_POINTABLE_INSTANCE.createBinaryComparator();
-                break;
-            }
-            case FLOAT: {
-                hashFunc = AqlBinaryHashFunctionFactoryProvider.FLOAT_POINTABLE_INSTANCE.createBinaryHashFunction();
-                cmp = AqlBinaryComparatorFactoryProvider.FLOAT_POINTABLE_INSTANCE.createBinaryComparator();
-                break;
-            }
-            case DOUBLE: {
-                hashFunc = AqlBinaryHashFunctionFactoryProvider.DOUBLE_POINTABLE_INSTANCE.createBinaryHashFunction();
-                cmp = AqlBinaryComparatorFactoryProvider.DOUBLE_POINTABLE_INSTANCE.createBinaryComparator();
-                break;
-            }
-            case STRING: {
-                if (ignoreCase) {
-                    // Ignore case in comparisons and hashing.
-                    hashFunc = AqlBinaryHashFunctionFactoryProvider.UTF8STRING_LOWERCASE_POINTABLE_INSTANCE
-                            .createBinaryHashFunction();
-                    cmp = AqlBinaryComparatorFactoryProvider.UTF8STRING_LOWERCASE_POINTABLE_INSTANCE
-                            .createBinaryComparator();
-                } else {
-                    hashFunc = AqlBinaryHashFunctionFactoryProvider.UTF8STRING_POINTABLE_INSTANCE
-                            .createBinaryHashFunction();
-                    cmp = AqlBinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
-                }
-                break;
-            }
-            default: {
-                break;
-            }
-        }
-        hashMap = new BinaryHashMap(TABLE_SIZE, TABLE_FRAME_SIZE, hashFunc, cmp);
-    }
 
-    protected int getItemLen(byte[] bytes, int itemOff) {
-        switch (itemTypeTag) {
-            case INT32: {
-                return 4;
-            }
-            case FLOAT: {
-                return 4;
-            }
-            case DOUBLE: {
-                return 8;
-            }
-            case STRING: {
-                // 2 bytes for the UTF8 len, plus the string data.
-                return 2 + UTF8StringPointable.getUTFLength(bytes, itemOff);
-            }
-            default: {
-                return -1;
-            }
-        }
+        IBinaryHashFunction putHashFunc = ListItemBinaryHashFunctionFactory.INSTANCE.createBinaryHashFunction(
+                buildItemTypeTag, ignoreCase);
+        IBinaryHashFunction getHashFunc = ListItemBinaryHashFunctionFactory.INSTANCE.createBinaryHashFunction(
+                probeItemTypeTag, ignoreCase);
+        IBinaryComparator cmp = ListItemBinaryComparatorFactory.INSTANCE.createBinaryComparator(buildItemTypeTag,
+                probeItemTypeTag, ignoreCase);
+        hashMap = new BinaryHashMap(TABLE_SIZE, TABLE_FRAME_SIZE, putHashFunc, getHashFunc, cmp);
     }
 
     protected boolean checkArgTypes(ATypeTag typeTag1, ATypeTag typeTag2) throws AlgebricksException {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/BinaryHashMap.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/BinaryHashMap.java
index 240f8c7..6367996 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/BinaryHashMap.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/BinaryHashMap.java
@@ -20,150 +20,154 @@
  * Intended to work with binary data and be able to map arbitrary key types to
  * arbitrary value types, given that they have implementations of
  * IBinaryHashFunction and IBinaryComparator.
- * 
  * Uses 2 bytes each to indicate the length of the key and the value.
  * Uses 8 byte pointers for the linked list (4 bytes frame index, 4 bytes frame offset).
- * 
  * This class is NOT thread safe.
- * 
  */
 public class BinaryHashMap {
-	// Special value to indicate an empty "bucket" in the header array.
-	private static final long NULL_PTR = -1;
-	private static final int PTR_SIZE = 8;
-	private static final int SLOT_SIZE = 2;
-	private static final int ENTRY_HEADER_SIZE = PTR_SIZE + 2 * SLOT_SIZE;
-	private final IBinaryHashFunction hashFunc;
-	private final IBinaryComparator cmp;
-	private final BinaryEntry returnValue = new BinaryEntry();
-	
-	private final long[] listHeads;
-	private final int frameSize;
-	private final List<ByteBuffer> frames = new ArrayList<ByteBuffer>();
-	private int currFrameIndex;
-	private int nextOff;
-	private int size;
-	
-	// Can be used for key or value.
-	public static class BinaryEntry {
-		public byte[] buf;
-		public int off;
-		public int len;
-		
-		public void set(byte[] buf, int off, int len) {
-			this.buf = buf;
-			this.off = off;
-			this.len = len;
-		}
-		
-		// Inefficient. Just for debugging.
-		@SuppressWarnings("rawtypes")
-		public String print(ISerializerDeserializer serde) throws HyracksDataException {
-			ByteArrayInputStream inStream = new ByteArrayInputStream(buf, off, len);
+    // Special value to indicate an empty "bucket" in the header array.
+    private static final long NULL_PTR = -1;
+    private static final int PTR_SIZE = 8;
+    private static final int SLOT_SIZE = 2;
+    private static final int ENTRY_HEADER_SIZE = PTR_SIZE + 2 * SLOT_SIZE;
+    private final IBinaryHashFunction putHashFunc;
+    private final IBinaryHashFunction getHashFunc;
+    private final IBinaryComparator cmp;
+    private final BinaryEntry returnValue = new BinaryEntry();
+
+    private final long[] listHeads;
+    private final int frameSize;
+    private final List<ByteBuffer> frames = new ArrayList<ByteBuffer>();
+    private int currFrameIndex;
+    private int nextOff;
+    private int size;
+
+    // Can be used for key or value.
+    public static class BinaryEntry {
+        public byte[] buf;
+        public int off;
+        public int len;
+
+        public void set(byte[] buf, int off, int len) {
+            this.buf = buf;
+            this.off = off;
+            this.len = len;
+        }
+
+        // Inefficient. Just for debugging.
+        @SuppressWarnings("rawtypes")
+        public String print(ISerializerDeserializer serde) throws HyracksDataException {
+            ByteArrayInputStream inStream = new ByteArrayInputStream(buf, off, len);
             DataInput dataIn = new DataInputStream(inStream);
             return serde.deserialize(dataIn).toString();
-		}
-	}
-	
-	public BinaryHashMap(int tableSize, int frameSize, IBinaryHashFunction hashFunc, IBinaryComparator cmp) {
-		listHeads = new long[tableSize];
-		this.frameSize = frameSize;		
-		this.hashFunc = hashFunc;
-		this.cmp = cmp;
-		frames.add(ByteBuffer.allocate(frameSize));
-		clear();
-	}
-	
-	/**
-	 * Inserts key, value into the hash map. If key already exists, returns
-	 * existing entry. Otherwise, returns null.
-	 * 
-	 * @param key
-	 * @param value
-	 * @return
-	 */
-	public BinaryEntry put(BinaryEntry key, BinaryEntry value) {
-		return getPutInternal(key, value, true);
-	}
-	
-	/**
-	 * Retrieves value for given key. Returns null if key doesn't exist.
-	 * 
-	 * @param key
-	 * @param value
-	 * @return
-	 */
-	public BinaryEntry get(BinaryEntry key) {
-		return getPutInternal(key, null, false);
-	}
-	
-	private BinaryEntry getPutInternal(BinaryEntry key, BinaryEntry value, boolean put) {
-		int bucket = Math.abs(hashFunc.hash(key.buf, key.off, key.len) % listHeads.length);
-		long headPtr = listHeads[bucket];
-		if (headPtr == NULL_PTR) {
-			// Key definitely doesn't exist yet.
-			if (put) {
-				listHeads[bucket] = appendEntry(key, value);
-			}
-			return null;
-		}
-		// Follow the chain until we found an entry matching the given key.
-		int frameOff;
-		ByteBuffer frame;
-		do {				
-			int frameIndex = getFrameIndex(headPtr);
-			frameOff = getFrameOffset(headPtr);
-			frame = frames.get(frameIndex);
-			int entryKeyOff = frameOff + ENTRY_HEADER_SIZE;
-			int entryKeyLen = frame.getShort(frameOff);
-			if (cmp.compare(frame.array(), entryKeyOff, entryKeyLen, key.buf,
-					key.off, key.len) == 0) {
-				// Key found, set values and return.
-				int entryValOff = frameOff + ENTRY_HEADER_SIZE + entryKeyLen;
-				int entryValLen = frame.getShort(frameOff + SLOT_SIZE);
-				returnValue.set(frame.array(), entryValOff, entryValLen);
-				return returnValue;
-			}
-			headPtr = frame.getLong(frameOff + 2 * SLOT_SIZE);
-		} while (headPtr != NULL_PTR);
-		// We've followed the chain to its end, and didn't find the key.
-		if (put) {
-			// Append the new entry, and set a pointer to it in the last entry we've checked.
-			long newPtr = appendEntry(key, value);
-			frame.putLong(frameOff + 2 * SLOT_SIZE, newPtr);
-		}
-		return null;
-	}
-	
-	public long appendEntry(BinaryEntry key, BinaryEntry value) {
-		ByteBuffer frame = frames.get(currFrameIndex);
-		int requiredSpace = key.len + value.len + ENTRY_HEADER_SIZE;
-		if (nextOff + requiredSpace >= frameSize) {
-			// Entry doesn't fit on frame, allocate a new one.
-			if (requiredSpace > frameSize) {
-				throw new IllegalStateException("Key and value greater than framesize.");
-			}
-			frames.add(ByteBuffer.allocate(frameSize));
-			currFrameIndex++;
-			nextOff = 0;
-			frame = frames.get(currFrameIndex);
-		}
-		writeEntryHeader(frame, nextOff, key.len, value.len, NULL_PTR);
-		System.arraycopy(key.buf, key.off, frame.array(), nextOff + ENTRY_HEADER_SIZE, key.len);
-		System.arraycopy(value.buf, value.off, frame.array(), nextOff + ENTRY_HEADER_SIZE + key.len, value.len);
-		long entryPtr = getEntryPtr(currFrameIndex, nextOff);
-		nextOff += requiredSpace;
-		size++;
-		return entryPtr;
-	}
-	
-	private void writeEntryHeader(ByteBuffer frame, int targetOff, int keyLen, int valLen, long ptr) {
-		frame.putShort(targetOff, (short) keyLen);
-		frame.putShort(targetOff + SLOT_SIZE, (short) valLen);
-		frame.putLong(targetOff + 2 * SLOT_SIZE, ptr);
-	}
+        }
+    }
 
-	private long getEntryPtr(int frameIndex, int frameOff) {
+    public BinaryHashMap(int tableSize, int frameSize, IBinaryHashFunction putHashFunc,
+            IBinaryHashFunction getHashFunc, IBinaryComparator cmp) {
+        listHeads = new long[tableSize];
+        this.frameSize = frameSize;
+        this.putHashFunc = putHashFunc;
+        this.getHashFunc = getHashFunc;
+        this.cmp = cmp;
+        frames.add(ByteBuffer.allocate(frameSize));
+        clear();
+    }
+
+    /**
+     * Inserts key, value into the hash map. If key already exists, returns
+     * existing entry. Otherwise, returns null.
+     * 
+     * @param key
+     * @param value
+     * @return
+     */
+    public BinaryEntry put(BinaryEntry key, BinaryEntry value) {
+        return getPutInternal(key, value, true);
+    }
+
+    /**
+     * Retrieves value for given key. Returns null if key doesn't exist.
+     * 
+     * @param key
+     * @param value
+     * @return
+     */
+    public BinaryEntry get(BinaryEntry key) {
+        return getPutInternal(key, null, false);
+    }
+
+    private BinaryEntry getPutInternal(BinaryEntry key, BinaryEntry value, boolean put) {
+        int bucket;
+        if (put) {
+            bucket = Math.abs(putHashFunc.hash(key.buf, key.off, key.len) % listHeads.length);
+        } else {
+            bucket = Math.abs(getHashFunc.hash(key.buf, key.off, key.len) % listHeads.length);
+        }
+        long headPtr = listHeads[bucket];
+        if (headPtr == NULL_PTR) {
+            // Key definitely doesn't exist yet.
+            if (put) {
+                listHeads[bucket] = appendEntry(key, value);
+            }
+            return null;
+        }
+        // Follow the chain until we found an entry matching the given key.
+        int frameOff;
+        ByteBuffer frame;
+        do {
+            int frameIndex = getFrameIndex(headPtr);
+            frameOff = getFrameOffset(headPtr);
+            frame = frames.get(frameIndex);
+            int entryKeyOff = frameOff + ENTRY_HEADER_SIZE;
+            int entryKeyLen = frame.getShort(frameOff);
+            if (cmp.compare(frame.array(), entryKeyOff, entryKeyLen, key.buf, key.off, key.len) == 0) {
+                // Key found, set values and return.
+                int entryValOff = frameOff + ENTRY_HEADER_SIZE + entryKeyLen;
+                int entryValLen = frame.getShort(frameOff + SLOT_SIZE);
+                returnValue.set(frame.array(), entryValOff, entryValLen);
+                return returnValue;
+            }
+            headPtr = frame.getLong(frameOff + 2 * SLOT_SIZE);
+        } while (headPtr != NULL_PTR);
+        // We've followed the chain to its end, and didn't find the key.
+        if (put) {
+            // Append the new entry, and set a pointer to it in the last entry we've checked.
+            long newPtr = appendEntry(key, value);
+            frame.putLong(frameOff + 2 * SLOT_SIZE, newPtr);
+        }
+        return null;
+    }
+
+    public long appendEntry(BinaryEntry key, BinaryEntry value) {
+        ByteBuffer frame = frames.get(currFrameIndex);
+        int requiredSpace = key.len + value.len + ENTRY_HEADER_SIZE;
+        if (nextOff + requiredSpace >= frameSize) {
+            // Entry doesn't fit on frame, allocate a new one.
+            if (requiredSpace > frameSize) {
+                throw new IllegalStateException("Key and value greater than framesize.");
+            }
+            frames.add(ByteBuffer.allocate(frameSize));
+            currFrameIndex++;
+            nextOff = 0;
+            frame = frames.get(currFrameIndex);
+        }
+        writeEntryHeader(frame, nextOff, key.len, value.len, NULL_PTR);
+        System.arraycopy(key.buf, key.off, frame.array(), nextOff + ENTRY_HEADER_SIZE, key.len);
+        System.arraycopy(value.buf, value.off, frame.array(), nextOff + ENTRY_HEADER_SIZE + key.len, value.len);
+        long entryPtr = getEntryPtr(currFrameIndex, nextOff);
+        nextOff += requiredSpace;
+        size++;
+        return entryPtr;
+    }
+
+    private void writeEntryHeader(ByteBuffer frame, int targetOff, int keyLen, int valLen, long ptr) {
+        frame.putShort(targetOff, (short) keyLen);
+        frame.putShort(targetOff + SLOT_SIZE, (short) valLen);
+        frame.putLong(targetOff + 2 * SLOT_SIZE, ptr);
+    }
+
+    private long getEntryPtr(int frameIndex, int frameOff) {
         return (((long) frameIndex) << 32) + frameOff;
     }
 
@@ -175,93 +179,94 @@
         return (int) (ptr & 0xffffffff);
     }
 
-	public int size() {
-		return size;
-	}
+    public int size() {
+        return size;
+    }
 
-	public boolean isEmpty() {
-		return size > 0;
-	}
+    public boolean isEmpty() {
+        return size > 0;
+    }
 
-	public void clear() {
-		// Initialize all entries to point to nothing.
-		Arrays.fill(listHeads, NULL_PTR);
-		currFrameIndex = 0;
-		nextOff = 0;
-		size = 0;
-	}
-	
-	public Iterator<Pair<BinaryEntry, BinaryEntry>> iterator() {
-		return new BinaryHashMapIterator();
-	}
-	
-	public class BinaryHashMapIterator implements Iterator<Pair<BinaryEntry, BinaryEntry> > {
-		private final Pair<BinaryEntry, BinaryEntry> val = new Pair<BinaryEntry, BinaryEntry>(new BinaryEntry(), new BinaryEntry());
-		private int listHeadIndex;
-		private ByteBuffer frame;
-		private int frameIndex;
-		private int frameOff;
-		
-		public BinaryHashMapIterator() {
-			listHeadIndex = 0;
-			frame = null;
-			frameIndex = -1;
-			frameOff = -1;
-		}
-		
-		@Override
-		public boolean hasNext() {
-			if (frame != null) {
-				long nextPtr = frame.getLong(frameOff + 2 * SLOT_SIZE);
-				if (nextPtr == NULL_PTR) {
-					// End of current list.
-					listHeadIndex++;
-					return nextListHead();
-				} else {
-					// Follow pointer.
-					setValue(nextPtr);
-					return true;
-				}
-			}
-			return nextListHead();
-		}
+    public void clear() {
+        // Initialize all entries to point to nothing.
+        Arrays.fill(listHeads, NULL_PTR);
+        currFrameIndex = 0;
+        nextOff = 0;
+        size = 0;
+    }
 
-		private boolean nextListHead() {
-			// Position to first non-null list-head pointer.
-			while(listHeadIndex < listHeads.length && listHeads[listHeadIndex] == NULL_PTR) {
-				listHeadIndex++;
-			}
-			if (listHeadIndex < listHeads.length) {
-				// Positioned to first non-null list head.
-				setValue(listHeads[listHeadIndex]);
-				return true;
-			} else {
-				// No more lists.
-				frame = null;
-				return false;
-			}
-		}
-		
-		private void setValue(long ptr) {
-			frameIndex = getFrameIndex(ptr);
-			frameOff = getFrameOffset(ptr);
-			frame = frames.get(frameIndex);
-			int entryKeyOff = frameOff + ENTRY_HEADER_SIZE;
-			int entryKeyLen = frame.getShort(frameOff);
-			int entryValOff = frameOff + ENTRY_HEADER_SIZE + entryKeyLen;
-			int entryValLen = frame.getShort(frameOff + SLOT_SIZE);
-			val.first.set(frame.array(), entryKeyOff, entryKeyLen);
-			val.second.set(frame.array(), entryValOff, entryValLen);
-		}
-		
-		@Override
-		public Pair<BinaryEntry, BinaryEntry> next() {
-			return val;
-		}
+    public Iterator<Pair<BinaryEntry, BinaryEntry>> iterator() {
+        return new BinaryHashMapIterator();
+    }
 
-		@Override
-		public void remove() {
-			throw new UnsupportedOperationException("Remove not implemented");
-		}
-	}
+    public class BinaryHashMapIterator implements Iterator<Pair<BinaryEntry, BinaryEntry>> {
+        private final Pair<BinaryEntry, BinaryEntry> val = new Pair<BinaryEntry, BinaryEntry>(new BinaryEntry(),
+                new BinaryEntry());
+        private int listHeadIndex;
+        private ByteBuffer frame;
+        private int frameIndex;
+        private int frameOff;
+
+        public BinaryHashMapIterator() {
+            listHeadIndex = 0;
+            frame = null;
+            frameIndex = -1;
+            frameOff = -1;
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (frame != null) {
+                long nextPtr = frame.getLong(frameOff + 2 * SLOT_SIZE);
+                if (nextPtr == NULL_PTR) {
+                    // End of current list.
+                    listHeadIndex++;
+                    return nextListHead();
+                } else {
+                    // Follow pointer.
+                    setValue(nextPtr);
+                    return true;
+                }
+            }
+            return nextListHead();
+        }
+
+        private boolean nextListHead() {
+            // Position to first non-null list-head pointer.
+            while (listHeadIndex < listHeads.length && listHeads[listHeadIndex] == NULL_PTR) {
+                listHeadIndex++;
+            }
+            if (listHeadIndex < listHeads.length) {
+                // Positioned to first non-null list head.
+                setValue(listHeads[listHeadIndex]);
+                return true;
+            } else {
+                // No more lists.
+                frame = null;
+                return false;
+            }
+        }
+
+        private void setValue(long ptr) {
+            frameIndex = getFrameIndex(ptr);
+            frameOff = getFrameOffset(ptr);
+            frame = frames.get(frameIndex);
+            int entryKeyOff = frameOff + ENTRY_HEADER_SIZE;
+            int entryKeyLen = frame.getShort(frameOff);
+            int entryValOff = frameOff + ENTRY_HEADER_SIZE + entryKeyLen;
+            int entryValLen = frame.getShort(frameOff + SLOT_SIZE);
+            val.first.set(frame.array(), entryKeyOff, entryKeyLen);
+            val.second.set(frame.array(), entryValOff, entryValLen);
+        }
+
+        @Override
+        public Pair<BinaryEntry, BinaryEntry> next() {
+            return val;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException("Remove not implemented");
+        }
+    }
 }
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java
new file mode 100644
index 0000000..208c454
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ * 
+ *     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 edu.uci.ics.asterix.runtime.evaluators.functions;
+
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public class NumericCaretDescriptor extends AbstractNumericArithmeticEval {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new NumericCaretDescriptor();
+        }
+    };
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateInteger(long, long)
+     */
+    @Override
+    protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
+        double result = Math.pow(lhs, rhs);
+        if (result > Long.MAX_VALUE) {
+            throw new ArithmeticException("Overflow of caret operation: " + lhs + " ^ " + rhs);
+        }
+        if (result < Long.MIN_VALUE) {
+            throw new ArithmeticException("Underflow of caret operation: " + lhs + " ^ " + rhs);
+        }
+        return (long) result;
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateDouble(double, double)
+     */
+    @Override
+    protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException {
+        return Math.pow(lhs, rhs);
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+     */
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.CARET;
+    }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 2c81b7c..af647e9 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -149,6 +149,7 @@
 import edu.uci.ics.asterix.runtime.evaluators.functions.NotNullDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.NumericAbsDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.NumericAddDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericCaretDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.NumericCeilingDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.NumericDivideDescriptor;
 import edu.uci.ics.asterix.runtime.evaluators.functions.NumericFloorDescriptor;
@@ -347,6 +348,7 @@
         temp.add(NumericMultiplyDescriptor.FACTORY);
         temp.add(NumericSubtractDescriptor.FACTORY);
         temp.add(NumericModuloDescriptor.FACTORY);
+        temp.add(NumericCaretDescriptor.FACTORY);
         temp.add(IsNullDescriptor.FACTORY);
         temp.add(NotDescriptor.FACTORY);
         temp.add(LenDescriptor.FACTORY);