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);