Merge branch 'master' into dev/asterix_msr
Conflicts:
asterix-aql/src/main/javacc/AQL.jj
asterix-external-data/src/main/java/edu/uci/ics/asterix/external/dataset/adapter/FileSystemBasedAdapter.java
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
index b272b95..1123076 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
@@ -64,6 +64,7 @@
import edu.uci.ics.hyracks.algebricks.rewriter.rules.ComplexUnnestToProductRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateAssignsRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.ConsolidateSelectsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateGroupByEmptyKeyRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.EliminateSubplanRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.EnforceOrderByAfterSubplan;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.EnforceStructuralPropertiesRule;
@@ -83,6 +84,7 @@
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceGroupByForSubplanRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IntroduceProjectsRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.IsolateHyracksOperatorsRule;
+import edu.uci.ics.hyracks.algebricks.rewriter.rules.LeftOuterJoinToInnerJoinRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PullSelectOutOfEqJoin;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushAssignBelowUnionAllRule;
import edu.uci.ics.hyracks.algebricks.rewriter.rules.PushAssignDownThroughProductRule;
@@ -163,6 +165,8 @@
condPushDownAndJoinInference.add(new PushProperJoinThroughProduct());
condPushDownAndJoinInference.add(new PushGroupByThroughProduct());
condPushDownAndJoinInference.add(new NestGroupByRule());
+ condPushDownAndJoinInference.add(new EliminateGroupByEmptyKeyRule());
+ condPushDownAndJoinInference.add(new LeftOuterJoinToInnerJoinRule());
return condPushDownAndJoinInference;
}
diff --git a/asterix-app/data/csv/sample_01.csv b/asterix-app/data/csv/sample_01.csv
new file mode 100644
index 0000000..4dd437a
--- /dev/null
+++ b/asterix-app/data/csv/sample_01.csv
@@ -0,0 +1,8 @@
+1,0.899682764,5.6256,2013-08-07,07:22:35,1979-02-25T23:48:27.034
+2,0.669052398,,-1923-03-29,19:33:34,-1979-02-25T23:48:27.002
+3,0.572733058,192674,-1923-03-28,19:33:34,-1979-02-25T23:48:27.001
+4,,192674,-1923-03-27,19:33:34,-1979-02-25T23:48:27.001
+5,0.572733058,192674,,19:33:34,-1979-02-25T23:48:27.001
+6,0.572733058,192674,-1923-03-25,,-1979-02-25T23:48:27.001
+7,0.572733058,192674,-1923-03-24,19:33:34,
+8,,,,,
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/optimizerts/queries/q08_group_by.aql b/asterix-app/src/test/resources/optimizerts/queries/q08_group_by.aql
new file mode 100644
index 0000000..96b20a4
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/q08_group_by.aql
@@ -0,0 +1,149 @@
+drop dataverse q08_group_by if exists;
+
+create dataverse q08_group_by;
+
+use dataverse q08_group_by;
+
+create type LineItemType as closed {
+ l_orderkey: int32,
+ l_partkey: int32,
+ l_suppkey: int32,
+ l_linenumber: int32,
+ l_quantity: double,
+ l_extendedprice: double,
+ l_discount: double,
+ l_tax: double,
+ l_returnflag: string,
+ l_linestatus: string,
+ l_shipdate: string,
+ l_commitdate: string,
+ l_receiptdate: string,
+ l_shipinstruct: string,
+ l_shipmode: string,
+ l_comment: string
+}
+
+create type OrderType as closed {
+ o_orderkey: int32,
+ o_custkey: int32,
+ o_orderstatus: string,
+ o_totalprice: double,
+ o_orderdate: string,
+ o_orderpriority: string,
+ o_clerk: string,
+ o_shippriority: int32,
+ o_comment: string
+}
+
+create type CustomerType as closed {
+ c_custkey: int32,
+ c_name: string,
+ c_address: string,
+ c_nationkey: int32,
+ c_phone: string,
+ c_acctbal: double,
+ c_mktsegment: string,
+ c_comment: string
+}
+
+create type SupplierType as closed {
+ s_suppkey: int32,
+ s_name: string,
+ s_address: string,
+ s_nationkey: int32,
+ s_phone: string,
+ s_acctbal: double,
+ s_comment: string
+}
+
+create type NationType as closed {
+ n_nationkey: int32,
+ n_name: string,
+ n_regionkey: int32,
+ n_comment: string
+}
+
+create type RegionType as closed {
+ r_regionkey: int32,
+ r_name: string,
+ r_comment: string
+}
+
+create type PartType as closed {
+ p_partkey: int32,
+ p_name: string,
+ p_mfgr: string,
+ p_brand: string,
+ p_type: string,
+ p_size: int32,
+ p_container: string,
+ p_retailprice: double,
+ p_comment: string
+}
+
+create dataset LineItem(LineItemType)
+ primary key l_orderkey, l_linenumber;
+create dataset Orders(OrderType)
+ primary key o_orderkey;
+create dataset Customer(CustomerType)
+ primary key c_custkey;
+create dataset Supplier(SupplierType)
+ primary key s_suppkey;
+create dataset Nation(NationType)
+ primary key n_nationkey;
+create dataset Region(RegionType)
+ primary key r_regionkey;
+create dataset Part(PartType)
+ primary key p_partkey;
+
+for $s in dataset("Supplier")
+ for $lnrcop in (
+ for $lnrco in (
+ for $l in dataset('LineItem')
+ for $nrco in (
+ for $o in dataset('Orders')
+ for $nrc in (
+ for $c in dataset('Customer')
+ for $nr in (
+ for $n1 in dataset('Nation')
+ for $r1 in dataset('Region')
+ where $n1.n_regionkey = $r1.r_regionkey and $r1.r_name = 'AMERICA'
+ return { "n_nationkey": $n1.n_nationkey }
+ )
+ where $c.c_nationkey = $nr.n_nationkey
+ return { "c_custkey": $c.c_custkey }
+ )
+ where $nrc.c_custkey = $o.o_custkey
+ return {
+ "o_orderdate" : $o.o_orderdate,
+ "o_orderkey": $o.o_orderkey
+ }
+ )
+ where $l.l_orderkey = $nrco.o_orderkey
+ and $nrco.o_orderdate >= '1995-01-01'
+ and $nrco.o_orderdate <= '1996-12-31'
+ return {
+ "o_orderdate": $nrco.o_orderdate,
+ "l_partkey": $l.l_partkey,
+ "l_discount": $l.l_discount,
+ "l_extendedprice": $l.l_extendedprice,
+ "l_suppkey": $l.l_suppkey
+ }
+ )
+ for $p in dataset("Part")
+ where $p.p_partkey = $lnrco.l_partkey and $p.p_type = 'ECONOMY ANODIZED STEEL'
+ return {
+ "o_orderdate": $lnrco.o_orderdate,
+ "l_discount": $lnrco.l_discount,
+ "l_extendedprice": $lnrco.l_extendedprice,
+ "l_suppkey": $lnrco.l_suppkey
+ }
+ )
+ where $s.s_suppkey = $lnrcop.l_suppkey
+ return {
+ "o_orderdate": $lnrcop.o_orderdate,
+ "l_discount": $lnrcop.l_discount,
+ "l_extendedprice": $lnrcop.l_extendedprice,
+ "l_suppkey": $lnrcop.l_suppkey,
+ "s_nationkey": $s.s_nationkey
+ }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/optimizerts/queries/q09_group_by.aql b/asterix-app/src/test/resources/optimizerts/queries/q09_group_by.aql
new file mode 100644
index 0000000..3c9dc47
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/q09_group_by.aql
@@ -0,0 +1,153 @@
+drop dataverse q09_group_by if exists;
+
+create dataverse q09_group_by;
+
+use dataverse q09_group_by;
+
+create type LineItemType as closed {
+ l_orderkey: int32,
+ l_partkey: int32,
+ l_suppkey: int32,
+ l_linenumber: int32,
+ l_quantity: int32,
+ l_extendedprice: double,
+ l_discount: double,
+ l_tax: double,
+ l_returnflag: string,
+ l_linestatus: string,
+ l_shipdate: string,
+ l_commitdate: string,
+ l_receiptdate: string,
+ l_shipinstruct: string,
+ l_shipmode: string,
+ l_comment: string
+}
+
+create type OrderType as closed {
+ o_orderkey: int32,
+ o_custkey: int32,
+ o_orderstatus: string,
+ o_totalprice: double,
+ o_orderdate: string,
+ o_orderpriority: string,
+ o_clerk: string,
+ o_shippriority: int32,
+ o_comment: string
+}
+
+create type CustomerType as closed {
+ c_custkey: int32,
+ c_name: string,
+ c_address: string,
+ c_nationkey: int32,
+ c_phone: string,
+ c_acctbal: double,
+ c_mktsegment: string,
+ c_comment: string
+}
+
+create type SupplierType as closed {
+ s_suppkey: int32,
+ s_name: string,
+ s_address: string,
+ s_nationkey: int32,
+ s_phone: string,
+ s_acctbal: double,
+ s_comment: string
+}
+
+create type NationType as closed {
+ n_nationkey: int32,
+ n_name: string,
+ n_regionkey: int32,
+ n_comment: string
+}
+
+create type RegionType as closed {
+ r_regionkey: int32,
+ r_name: string,
+ r_comment: string
+}
+
+create type PartType as closed {
+ p_partkey: int32,
+ p_name: string,
+ p_mfgr: string,
+ p_brand: string,
+ p_type: string,
+ p_size: int32,
+ p_container: string,
+ p_retailprice: double,
+ p_comment: string
+}
+
+create type PartSuppType as closed {
+ ps_partkey: int32,
+ ps_suppkey: int32,
+ ps_availqty: int32,
+ ps_supplycost: double,
+ ps_comment: string
+}
+
+create dataset LineItem(LineItemType)
+ primary key l_orderkey, l_linenumber;
+create dataset Orders(OrderType)
+ primary key o_orderkey;
+create dataset Supplier(SupplierType)
+ primary key s_suppkey;
+create dataset Region(RegionType)
+ primary key r_regionkey;
+create dataset Nation(NationType)
+ primary key n_nationkey;
+create dataset Part(PartType)
+ primary key p_partkey;
+create dataset Partsupp(PartSuppType)
+ primary key ps_partkey, ps_suppkey;
+create dataset Customer(CustomerType)
+ primary key c_custkey;
+
+for $p in dataset('Part')
+ for $l2 in (
+ for $ps in dataset('Partsupp')
+ for $l1 in (
+ for $s1 in (
+ for $s in dataset('Supplier')
+ for $n in dataset('Nation')
+ where $n.n_nationkey = $s.s_nationkey
+ return {
+ "s_suppkey": $s.s_suppkey,
+ "n_name": $n.n_name
+ }
+ )
+ for $l in dataset('LineItem')
+ where $s1.s_suppkey = $l.l_suppkey
+ return {
+ "l_suppkey": $l.l_suppkey,
+ "l_extendedprice": $l.l_extendedprice,
+ "l_discount": $l.l_discount,
+ "l_quantity": $l.l_quantity,
+ "l_partkey": $l.l_partkey,
+ "l_orderkey": $l.l_orderkey,
+ "n_name": $s1.n_name
+ }
+ )
+ where $ps.ps_suppkey = $l1.l_suppkey and $ps.ps_partkey = $l1.l_partkey
+ return {
+ "l_extendedprice": $l1.l_extendedprice,
+ "l_discount": $l1.l_discount,
+ "l_quantity": $l1.l_quantity,
+ "l_partkey": $l1.l_partkey,
+ "l_orderkey": $l1.l_orderkey,
+ "n_name": $l1.n_name,
+ "ps_supplycost": $ps.ps_supplycost
+ }
+ )
+ where contains($p.p_name, 'green') and $p.p_partkey = $l2.l_partkey
+ return {
+ "l_extendedprice": $l2.l_extendedprice,
+ "l_discount": $l2.l_discount,
+ "l_quantity": $l2.l_quantity,
+ "l_orderkey": $l2.l_orderkey,
+ "n_name": $l2.n_name,
+ "ps_supplycost": $l2.ps_supplycost
+ }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan b/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
new file mode 100644
index 0000000..fefdfcb
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
@@ -0,0 +1,78 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$78][$$104] |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$104] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$101][$$85] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$101] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$79][$$81] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$79] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$81] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$96][$$82] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$96] |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$82] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$92][$$83] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$92] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$83] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$89][$$84] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$89] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan b/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan
new file mode 100644
index 0000000..8a08e39
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan
@@ -0,0 +1,55 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$62][$$80] |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$80] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$64, $$63][$$69, $$80] |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$80, $$69] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$65][$$69] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$65] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$73][$$66] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$73] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$69] |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.1.ddl.aql
new file mode 100644
index 0000000..04c1e6f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.1.ddl.aql
@@ -0,0 +1,18 @@
+/**
+ * issue531_string_min_max
+ *
+ * Purpose: test the support of string values for min and max aggregation function
+ * Result: success
+ *
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type TestType as open{
+id:int32,
+name:string
+}
+
+create dataset t1(TestType) primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.2.update.aql
new file mode 100644
index 0000000..2e0bb6c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.2.update.aql
@@ -0,0 +1,18 @@
+/**
+ * issue531_string_min_max
+ *
+ * Purpose: test the support of string values for min and max aggregation function
+ * Result: success
+ *
+ */
+
+use dataverse test;
+
+insert into dataset t1({"id":5,"name":"Smith"});
+insert into dataset t1({"id":12,"name":"Roger"});
+insert into dataset t1({"id":67,"name":"Kevin"});
+insert into dataset t1({"id":32,"name":"Bob"});
+insert into dataset t1({"id":89,"name":"John"});
+insert into dataset t1({"id":10,"name":"Alex"});
+insert into dataset t1({"id":37,"name":"Calvin"});
+insert into dataset t1({"id":98,"name":"Susan"});
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.3.query.aql
new file mode 100644
index 0000000..1fa706c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/aggregate/issue531_string_min_max/issue531_string_min_max.3.query.aql
@@ -0,0 +1,13 @@
+/**
+ * issue531_string_min_max
+ *
+ * Purpose: test the support of string values for min and max aggregation function
+ * Result: success
+ *
+ */
+
+use dataverse test;
+
+{"min": min(for $l in dataset t1
+return $l.name), "max": max(for $l in dataset t1
+return $l.name)}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/boolean/and_null/and_null.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/boolean/and_null/and_null.3.query.aql
index 830ffe9..f49dbd7 100644
--- a/asterix-app/src/test/resources/runtimets/queries/boolean/and_null/and_null.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/boolean/and_null/and_null.3.query.aql
@@ -1,5 +1,5 @@
use dataverse test;
-let $x := boolean("true")
+let $x := true
let $y := null
return $x and $y
diff --git a/asterix-app/src/test/resources/runtimets/queries/boolean/and_null_false/and_null_false.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/boolean/and_null_false/and_null_false.3.query.aql
index 5e646a8..371246d 100644
--- a/asterix-app/src/test/resources/runtimets/queries/boolean/and_null_false/and_null_false.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/boolean/and_null_false/and_null_false.3.query.aql
@@ -1,5 +1,5 @@
use dataverse test;
-let $x := boolean("false")
+let $x := false
let $y := null
return $x and $y
diff --git a/asterix-app/src/test/resources/runtimets/queries/distinct/query-issue443-2/query-issue443-2.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/distinct/query-issue443-2/query-issue443-2.3.query.aql
index 6b09eec..38f292b 100644
--- a/asterix-app/src/test/resources/runtimets/queries/distinct/query-issue443-2/query-issue443-2.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/distinct/query-issue443-2/query-issue443-2.3.query.aql
@@ -1,11 +1,10 @@
/*
* Description : This test case is to verify the fix for issue443
- : https://code.google.com/p/asterixdb/issues/detail?id=443
- * Expected Res : Fail
+ * https://code.google.com/p/asterixdb/issues/detail?id=443
+ * Expected Res : Success
* Date : 22th May 2013
*/
-
for $a in [ {"f" : 19, "g": 1} , {"f" : 12, "g": 2} , {"f" : 10, "g": 1} , {"f" : 17, "g": 1}, {"f" : 12, "g": 4} ]
distinct by $a.f
-return $a
\ No newline at end of file
+return $a
diff --git a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-insert2/opentype-insert2.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-insert2/opentype-insert2.2.update.aql
index ec357bf..be95b39 100644
--- a/asterix-app/src/test/resources/runtimets/queries/dml/opentype-insert2/opentype-insert2.2.update.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/dml/opentype-insert2/opentype-insert2.2.update.aql
@@ -7,5 +7,5 @@
use dataverse test;
-insert into dataset testds( for $i in range(1,10) return { "id":$i,"name":"John Doe" });
+insert into dataset testds( for $i in range(1, 10) return { "id":$i,"name":"John Doe" });
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.1.ddl.aql
new file mode 100644
index 0000000..e890942
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.1.ddl.aql
@@ -0,0 +1,22 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+drop dataverse temp if exists;
+create dataverse temp
+use dataverse temp;
+
+create type test as closed {
+ id: int32,
+ float: float?,
+ double: double?,
+ date: string?,
+ time: string?,
+ datetime: string?
+};
+
+create dataset testds (test)
+primary key id;
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.2.update.aql
new file mode 100644
index 0000000..c3161d5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.2.update.aql
@@ -0,0 +1,12 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+use dataverse temp;
+
+load dataset testds
+using "edu.uci.ics.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="nc1://data/csv/sample_01.csv"),("format"="delimited-text"),("delimiter"=","));
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.3.query.aql
new file mode 100644
index 0000000..efa6dbc
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_01/csv_01.3.query.aql
@@ -0,0 +1,18 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+use dataverse temp;
+
+for $i in dataset testds
+order by $i.id
+return { "id": $i.id,
+ "float": $i.float,
+ "double": $i.double,
+ "date-before": $i.date, "date-after": date($i.date),
+ "time-before": $i.time, "time-after": time($i.time),
+ "datetime-before": $i.datetime, "datetime-after": datetime($i.datetime)
+ }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.1.ddl.aql
new file mode 100644
index 0000000..b6884a8
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.1.ddl.aql
@@ -0,0 +1,22 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+drop dataverse temp if exists;
+create dataverse temp
+use dataverse temp;
+
+create type test as closed {
+ id: int32,
+ float: float?,
+ double: double?,
+ date: string,
+ time: string,
+ datetime: string
+};
+
+create dataset testds (test)
+primary key id;
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.2.update.aql
new file mode 100644
index 0000000..c3161d5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.2.update.aql
@@ -0,0 +1,12 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+use dataverse temp;
+
+load dataset testds
+using "edu.uci.ics.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="nc1://data/csv/sample_01.csv"),("format"="delimited-text"),("delimiter"=","));
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.3.query.aql
new file mode 100644
index 0000000..1299235
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/load/csv_02/csv_02.3.query.aql
@@ -0,0 +1,18 @@
+/**
+ *
+ * CSV file loading test
+ * Expected result: success
+ *
+ */
+
+use dataverse temp;
+
+for $i in dataset testds
+order by $i.id
+return { "id": $i.id,
+ "float": $i.float,
+ "double": $i.double,
+ "date-string": $i.date,
+ "time-string": $i.time,
+ "datetime-string": $i.datetime
+ }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord/nestrecord.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord/nestrecord.2.update.aql
index bca3929..ac1a9f1 100644
--- a/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord/nestrecord.2.update.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/nestrecords/nestrecord/nestrecord.2.update.aql
@@ -7,7 +7,7 @@
use dataverse testdv2;
insert into dataset testds (
-{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697} }
+{ "id": "001", "name": "Person One", "address": {"street": "3019 DBH", "city": "Irvine", "zip": 92697}}
);
insert into dataset testds (
@@ -15,10 +15,10 @@
);
insert into dataset testds (
-{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH", "city": "Irvine"} }
+{ "id": "003", "name": "Person Three", "address": {"street": "2019 DBH", "city": "Irvine"}}
);
insert into dataset testds (
-{ "id": "004", "name": "Person Four", "home": {"street": "2019 DBH", "city": {"name": "Irvine", "zip": 92697} } }
+{ "id": "004", "name": "Person Four", "home": {"street": "2019 DBH", "city": {"name": "Irvine", "zip": 92697}}}
);
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql
deleted file mode 100644
index 169ca39..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_double_01/unary-minus_double_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := double("-20.56e-30")
-let $c2 := double("NaN")
-let $c3 := double("INF")
-let $c4 := double("-INF")
-return {"double1": numeric-unary-minus($c1),"double2": numeric-unary-minus($c2),"double3": numeric-unary-minus($c3),"double4": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql
deleted file mode 100644
index e5e0071..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_float_01/unary-minus_float_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := float("-80.20f")
-let $c2 := float("NaN")
-let $c3 := float("INF")
-let $c4 := float("-INF")
-return {"float1": numeric-unary-minus($c1),"float2": numeric-unary-minus($c2),"float3": numeric-unary-minus($c3),"float4": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql
deleted file mode 100644
index 754ea81..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.1.ddl.aql
+++ /dev/null
@@ -1,3 +0,0 @@
-drop dataverse test if exists;
-create dataverse test;
-
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql
deleted file mode 100644
index e69de29..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.2.update.aql
+++ /dev/null
diff --git a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql
deleted file mode 100644
index 660e55f..0000000
--- a/asterix-app/src/test/resources/runtimets/queries/numeric/unary-minus_int_01/unary-minus_int_01.3.query.aql
+++ /dev/null
@@ -1,7 +0,0 @@
-use dataverse test;
-
-let $c1 := int8("+80")
-let $c2 := int16("160")
-let $c3 := int32("+320")
-let $c4 := int64("-640")
-return {"int8": numeric-unary-minus($c1),"int16": numeric-unary-minus($c2),"int32": numeric-unary-minus($c3),"int64": numeric-unary-minus($c4)}
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/calendar_duration/calendar_duration.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/calendar_duration/calendar_duration.3.query.aql
index 016f3b3..b1c3a20 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/calendar_duration/calendar_duration.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/calendar_duration/calendar_duration.3.query.aql
@@ -8,36 +8,36 @@
let $dr3 := duration("P1Y90M")
let $dr4 := duration("-P3Y89M4089DT47382.983S")
let $cdr1 := calendar-duration-from-datetime($t1, $dr1)
-let $dt1 := add-datetime-duration($t1, $dr1)
-let $dtt1 := add-datetime-duration($t1, $cdr1)
+let $dt1 := $t1 + $dr1
+let $dtt1 := $t1 + $cdr1
let $c1 := $dt1 = $dtt1
let $cdr2 := calendar-duration-from-datetime($t1, $dr2)
-let $dt2 := add-datetime-duration($t1, $dr2)
-let $dtt2 := add-datetime-duration($t1, $cdr2)
+let $dt2 := $t1 + $dr2
+let $dtt2 := $t1 + $cdr2
let $c2 := $dt2 = $dtt2
let $cdr3 := calendar-duration-from-datetime($t1, $dr3)
-let $dt3 := add-datetime-duration($t1, $dr3)
-let $dtt3 := add-datetime-duration($t1, $cdr3)
+let $dt3 := $t1 + $dr3
+let $dtt3 := $t1 + $cdr3
let $c3 := $dt3 = $dtt3
let $cdr4 := calendar-duration-from-datetime($t1, $dr4)
-let $dt4 := add-datetime-duration($t1, $dr4)
-let $dtt4 := add-datetime-duration($t1, $cdr4)
+let $dt4 := $t1 + $dr4
+let $dtt4 := $t1 + $cdr4
let $c4 := $dt4 = $dtt4
let $cdr5 := calendar-duration-from-date($t2, $dr1)
-let $dt5 := add-date-duration($t2, $dr1)
-let $dtt5 := add-date-duration($t2, $cdr5)
+let $dt5 := $t2 + $dr1
+let $dtt5 := $t2 + $cdr5
let $c5 := $dt5 = $dtt5
let $cdr6 := calendar-duration-from-date($t2, $dr2)
-let $dt6 := add-date-duration($t2, $dr2)
-let $dtt6 := add-date-duration($t2, $cdr6)
+let $dt6 := $t2 + $dr2
+let $dtt6 := $t2 + $cdr6
let $c6 := $dt6 = $dtt6
let $cdr7 := calendar-duration-from-date($t2, $dr3)
-let $dt7 := add-date-duration($t2, $dr3)
-let $dtt7 := add-date-duration($t2, $cdr7)
+let $dt7 := $t2 + $dr3
+let $dtt7 := $t2 + $cdr7
let $c7 := $dt7 = $dtt7
let $cdr8 := calendar-duration-from-date($t2, $dr4)
-let $dt8 := add-date-duration($t2, $dr4)
-let $dtt8 := add-date-duration($t2, $cdr8)
+let $dt8 := $t2 + $dr4
+let $dtt8 := $t2 + $cdr8
let $c8 := $dt8 = $dtt8
return { "cduration1":$cdr1, "c1":$c1, "cduration2":$cdr2, "c2":$c2, "cduration3":$cdr3, "c3":$c3, "cduration4":$cdr4, "c4":$c4, "cduration5":$cdr5, "c5":$c5, "cduration6":$cdr6, "c6":$c6, "cduration7":$cdr7, "c7":$c7, "cduration8":$cdr8, "c8":$c8, "cduration-null-1": calendar-duration-from-datetime(null, $dr1), "cduration-null-2": calendar-duration-from-datetime($t1, null), "cduration-null-3": calendar-duration-from-date(null, $dr1), "cduration-null-4": calendar-duration-from-date($t2, null) }
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/date_functions/date_functions.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/date_functions/date_functions.3.query.aql
index 3927f72..e540817 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/date_functions/date_functions.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/date_functions/date_functions.3.query.aql
@@ -9,16 +9,16 @@
let $dt2 := datetime("2012-10-11T02:30:23+03:00")
let $d3 := get-date-from-datetime($dt2)
let $dr1 := duration("-P2Y1M90DT30H")
-let $d4 := add-date-duration($d1, $dr1)
-let $null3 := add-date-duration(null, $dr1)
-let $null4 := add-date-duration($d1, null)
-let $c1 := $d1 = add-date-duration($d4, subtract-date($d1, $d4))
+let $d4 := $d1 + $dr1
+let $null3 := null + $dr1
+let $null4 := $d1 + null
+let $c1 := ($d1 = ($d4 + ($d1 - $d4)))
let $dr2 := duration("P300Y900MT360000M")
-let $d5 := add-date-duration($d2, $dr2)
-let $c2 := $d2 = add-date-duration($d5, subtract-date($d2, $d5))
-let $dr3 := subtract-date($d5, $d2)
-let $dr4 := subtract-date($d4, $d1)
-let $null5 := subtract-date(null, $d2)
-let $null6 := subtract-date($d5, null)
+let $d5 := $d2 + $dr2
+let $c2 := ($d2 = ($d5 + ($d2 - $d5)))
+let $dr3 := $d5 - $d2
+let $dr4 := $d4 - $d1
+let $null5 := null - $d2
+let $null6 := $d5 - null
return { "date1": $d1, "date2": $d2, "date3": $d3, "date4": $d4, "date5": $d5, "duration1": $dr3, "duration2": $dr4, "c1": $c1, "c2": $c2, "null1": $null1, "null2": $null2, "null3": $null3, "null4": $null4, "null5": $null5, "null6": $null6 }
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
index 3d24549..fe0c099 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
@@ -8,12 +8,12 @@
let $dt2 := datetime-from-date-time($d1, $t1)
let $null2 := datetime-from-date-time(null, $t1)
let $null3 := datetime-from-date-time($d1, null)
-let $dr1 := subtract-datetime($dt2, $dt1)
-let $null4 := subtract-datetime(null, $dt1)
-let $null5 := subtract-datetime($dt2, null)
-let $dt3 := add-datetime-duration($dt1, $dr1)
-let $null6 := add-datetime-duration(null, $dr1)
-let $null7 := add-datetime-duration($dt1, null)
-let $c1 := $dt1 = add-datetime-duration($dt3, subtract-datetime($dt1, $dt3))
+let $dr1 := $dt2 - $dt1
+let $null4 := null - $dt1
+let $null5 := $dt2 - null
+let $dt3 := $dt1 + $dr1
+let $null6 := null + $dr1
+let $null7 := $dt1 + null
+let $c1 := $dt1 = ($dt1 - $dt3) + $dt3
return { "datetime1" : $dt1, "datetime2" : $dt2, "datetime3" : $dt3, "duration1" : $dr1, "c1" : $c1, "null1" : $null1, "null2" : $null2, "null3" : $null3, "null4" : $null4, "null5" : $null5, "null6" : $null6, "null7" : $null7 }
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql
new file mode 100644
index 0000000..f92bdd4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql
new file mode 100644
index 0000000..cf8a1ae
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql
new file mode 100644
index 0000000..fc1e705
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql
@@ -0,0 +1,12 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+let $d1 := date("2013-08-06")
+let $d2 := date("-2013-08-06")
+let $dt1 := datetime("1913-08-06T15:53:28Z")
+let $dt2 := datetime("-1913-08-10T15:53:28Z")
+return { "1970-01-01": day-of-week(date("1970-01-01")), "2013-08-06": day-of-week($d1), "-2013-08-06": day-of-week($d2), "1913-08-06T15:53:28Z": day-of-week($dt1), "-1913-08-10T15:53:28Z": day-of-week($dt2), "null": day-of-week(null) }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql
new file mode 100644
index 0000000..57b3b28
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql
new file mode 100644
index 0000000..e2e3afb
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql
new file mode 100644
index 0000000..adbb2a2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin/interval_bin.3.query.aql
@@ -0,0 +1,19 @@
+/**
+ * Interval_bin test case: test the interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+let $c1 := date("2010-10-30")
+let $c2 := datetime("-1987-11-19T23:49:23.938")
+let $c3 := time("12:23:34.930+07:00")
+
+return { "bin1": interval-bin($c1, date("1990-01-01"), year-month-duration("P1Y")),
+ "bin2": interval-bin($c1, date("-1990-01-01"), year-month-duration("P1Y")),
+ "bin3": interval-bin($c2, datetime("1990-01-01T00:00:00.000Z"), year-month-duration("P6M")),
+ "bin4": interval-bin($c2, datetime("-1990-01-01T00:00:00.000Z"), day-time-duration("PT12H")),
+ "bin5": interval-bin($c3, time("12:00:00"), day-time-duration("PT2H")),
+ "bin6": interval-bin(null, date("-0023-01-01"), year-month-duration("P6M")),
+ "bin7": interval-bin($c1, null, year-month-duration("P6M")),
+ "bin8": interval-bin($c1, date("-0023-01-01"), null) }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql
new file mode 100644
index 0000000..841d8da
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.1.ddl.aql
@@ -0,0 +1,16 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type Schema as closed{
+id: int32,
+timestamp: datetime
+}
+
+create dataset tsdata(Schema)
+primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql
new file mode 100644
index 0000000..b1119e5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.2.update.aql
@@ -0,0 +1,18 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+use dataverse test;
+
+insert into dataset tsdata({"id": 1, "timestamp": datetime("-1987-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 2, "timestamp": datetime("-1987-11-20T00:27:13.432")})
+insert into dataset tsdata({"id": 3, "timestamp": datetime("-1987-11-18T18:00:00")})
+insert into dataset tsdata({"id": 4, "timestamp": datetime("19871119T234923938")})
+insert into dataset tsdata({"id": 5, "timestamp": datetime("1987-11-19T23:58:17.038")})
+insert into dataset tsdata({"id": 6, "timestamp": datetime("1987-11-19T23:30:00")})
+insert into dataset tsdata({"id": 7, "timestamp": datetime("1987-11-19T23:22:38")})
+insert into dataset tsdata({"id": 8, "timestamp": datetime("1988-01-21T17:28:13.900")})
+insert into dataset tsdata({"id": 9, "timestamp": datetime("-1987-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 10, "timestamp": datetime("-0987-07-01T09:35:28.039")})
+insert into dataset tsdata({"id": 11, "timestamp": datetime("2012-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 12, "timestamp": datetime("2013-11-19T23:49:23.938")})
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql
new file mode 100644
index 0000000..776493f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_0/interval_bin_gby_0.3.query.aql
@@ -0,0 +1,11 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+for $i in dataset tsdata
+group by $d := interval-bin($i.timestamp, datetime("1990-01-01T00:00:00.000Z"), year-month-duration("P20Y")) with $i
+order by get-interval-start($d)
+return { "tbin": $d, "count": count($i)}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql
new file mode 100644
index 0000000..841d8da
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.1.ddl.aql
@@ -0,0 +1,16 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
+use dataverse test;
+
+create type Schema as closed{
+id: int32,
+timestamp: datetime
+}
+
+create dataset tsdata(Schema)
+primary key id;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql
new file mode 100644
index 0000000..b1119e5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.2.update.aql
@@ -0,0 +1,18 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+use dataverse test;
+
+insert into dataset tsdata({"id": 1, "timestamp": datetime("-1987-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 2, "timestamp": datetime("-1987-11-20T00:27:13.432")})
+insert into dataset tsdata({"id": 3, "timestamp": datetime("-1987-11-18T18:00:00")})
+insert into dataset tsdata({"id": 4, "timestamp": datetime("19871119T234923938")})
+insert into dataset tsdata({"id": 5, "timestamp": datetime("1987-11-19T23:58:17.038")})
+insert into dataset tsdata({"id": 6, "timestamp": datetime("1987-11-19T23:30:00")})
+insert into dataset tsdata({"id": 7, "timestamp": datetime("1987-11-19T23:22:38")})
+insert into dataset tsdata({"id": 8, "timestamp": datetime("1988-01-21T17:28:13.900")})
+insert into dataset tsdata({"id": 9, "timestamp": datetime("-1987-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 10, "timestamp": datetime("-0987-07-01T09:35:28.039")})
+insert into dataset tsdata({"id": 11, "timestamp": datetime("2012-11-19T23:49:23.938")})
+insert into dataset tsdata({"id": 12, "timestamp": datetime("2013-11-19T23:49:23.938")})
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql
new file mode 100644
index 0000000..61a4c5b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/interval_bin_gby_1/interval_bin_gby_1.3.query.aql
@@ -0,0 +1,11 @@
+/**
+ * Interval_bin_gby test case: test the group-by using interval-bin function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+for $i in dataset tsdata
+group by $d := interval-bin(get-time-from-datetime($i.timestamp), time("00:00:00.000Z"), day-time-duration("PT10M")) with $i
+order by get-interval-start($d)
+return { "tbin": $d, "count": count($i)}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.1.ddl.aql
new file mode 100644
index 0000000..b899dc2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.2.update.aql
new file mode 100644
index 0000000..ec16dd3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql
new file mode 100644
index 0000000..53e1285
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql
@@ -0,0 +1,22 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
+
+use dataverse test;
+
+{ "date1": parse-date("2013-8-23", "YY-M-D"),
+ "date2": parse-date("Aug 12 -12", "MMM D Y"),
+ "date3": parse-date("-1234-01-01", "YYYY-MM-DD"),
+ "date4": parse-date("09/11/-1980", "D/M/Y"),
+ "date5": parse-date("09/11/-1990", "YY-M-D|MMM D Y|D/M/Y"),
+ "time1": parse-time("8:23:49", "h:m:s"),
+ "time2": parse-time("8.19.23:32", "h.m.s:nn"),
+ "time3": parse-time("08.19.23:32 pm", "h.m.s:nn a"),
+ "time4": parse-time("6:30:40.948 pm PST", "h:mm:ss.nnn a z"),
+ "time5": parse-time("6:30:40.948 pm PST", "h:m:s|h.m.s:nn|h.m.s:nn a|h:mm:ss.nnn a z"),
+ "datetime1": parse-datetime("Dec 30 -1203 3:48:27 PM", "MMM DD YYYY h:m:s a"),
+ "datetime2": parse-datetime("12/30/-1203 03:48:27.392 PM Asia/Shanghai", "MM/DD/YYY hh:mm:ss.nnn a z"),
+ "datetime3": parse-datetime("1723-12-03T23:59:23.392Z", "YYYY-MM-DDThh:mm:ss.nnnz"),
+ "datetime4": parse-datetime("1723-12-03T23:59:23.392-04:00", "YYYY-MM-DDThh:mm:ss.nnnz"),
+ "datetime5": parse-datetime("1723-12-03T23:59:23.392-04:00", "MMM DD YYYY h:m:s a|MM/DD/YYY hh:mm:ss.nnn a z|YYYY-MM-DDThh:mm:ss.nnnz") }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.1.ddl.aql
new file mode 100644
index 0000000..b899dc2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.2.update.aql
new file mode 100644
index 0000000..ec16dd3
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.3.query.aql
new file mode 100644
index 0000000..7617d5f
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_02/parse_02.3.query.aql
@@ -0,0 +1,20 @@
+/**
+ * Test case for parsing temporal strings with format strings
+ * Expected Result: Success
+ **/
+
+use dataverse test;
+
+let $date := date("-0123-01-30")
+let $time := time("08:07:29.030Z")
+let $datetime := datetime("0137-12-31T23:59:59.999+08:00")
+return {
+ "date-string-1": print-date($date, "YY/M/D"),
+ "date-string-2": print-date($date, "MMM DD, YYYY"),
+ "date-string-3": print-date($date, "YYYY/MM/DD"),
+ "time-string-1": print-time($time, "h.m.s.nn a z"),
+ "time-string-2": print-time($time, "hh.mm.ss.nnn a z"),
+ "datetime-string-1": print-datetime($datetime, "MMM DD h:m:s.nnn a YY z"),
+ "datetime-string-2": print-datetime($datetime, "YYYY/MMM/DD h:m:s.nnnz a"),
+ "datetime-string-3": print-datetime($datetime, "YYYY-MM-DDThh:mm:ss.nnnz")
+ }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/time_functions/time_functions.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/time_functions/time_functions.3.query.aql
index d2befcc..09e1aa9 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/time_functions/time_functions.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/time_functions/time_functions.3.query.aql
@@ -8,18 +8,18 @@
let $null2 := get-time-from-datetime(null)
let $dt2 := datetime("2012-10-11T02:30:23+03:00")
let $t3 := get-time-from-datetime($dt2)
-let $dr1 := duration("-PT30H")
-let $t4 := add-time-duration($t1, $dr1)
-let $null3 := add-time-duration(null, $dr1)
-let $null4 := add-time-duration($t1, null)
-let $c1 := $t1 = add-time-duration($t4, subtract-time($t1, $t4))
-let $dr2 := duration("PT36M")
-let $t5 := add-time-duration($t2, $dr2)
-let $c2 := $t2 = add-time-duration($t5, subtract-time($t2, $t5))
-let $dr3 := subtract-time($t5, $t2)
-let $dr4 := subtract-time($t4, $t1)
-let $null5 := subtract-time(null, $t1)
-let $null6 := subtract-time($t4, null)
+let $dr1 := day-time-duration("-PT30H")
+let $t4 := $t1 + $dr1
+let $null3 := null + $dr1
+let $null4 := $t1 + null
+let $c1 := $t1 = ($t1 - $t4) + $t4
+let $dr2 := day-time-duration("PT36M")
+let $t5 := $t2 + $dr2
+let $c2 := $t2 = $t5 + ($t2 - $t5)
+let $dr3 := $t5 - $t2
+let $dr4 := $t4 - $t1
+let $null5 := null - $t1
+let $null6 := $t4 - null
let $ct := current-time()
let $cd := current-date()
let $cdt := current-datetime()
diff --git a/asterix-app/src/test/resources/runtimets/results/aggregate/issue531_string_min_max/issue531_string_min_max.1.adm b/asterix-app/src/test/resources/runtimets/results/aggregate/issue531_string_min_max/issue531_string_min_max.1.adm
new file mode 100644
index 0000000..9f575f1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/aggregate/issue531_string_min_max/issue531_string_min_max.1.adm
@@ -0,0 +1 @@
+{ "min": "Alex", "max": "Susan" }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/load/csv_01/csv_01.1.adm b/asterix-app/src/test/resources/runtimets/results/load/csv_01/csv_01.1.adm
new file mode 100644
index 0000000..b8d4151
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/load/csv_01/csv_01.1.adm
@@ -0,0 +1,8 @@
+{ "id": 1, "float": 0.89968276f, "double": 5.6256d, "date-before": "2013-08-07", "date-after": date("2013-08-07"), "time-before": "07:22:35", "time-after": time("07:22:35.000Z"), "datetime-before": "1979-02-25T23:48:27.034", "datetime-after": datetime("1979-02-25T23:48:27.034Z") }
+{ "id": 2, "float": 0.6690524f, "double": null, "date-before": "-1923-03-29", "date-after": date("-1923-03-29"), "time-before": "19:33:34", "time-after": time("19:33:34.000Z"), "datetime-before": "-1979-02-25T23:48:27.002", "datetime-after": datetime("-1979-02-25T23:48:27.002Z") }
+{ "id": 3, "float": 0.57273304f, "double": 192674.0d, "date-before": "-1923-03-28", "date-after": date("-1923-03-28"), "time-before": "19:33:34", "time-after": time("19:33:34.000Z"), "datetime-before": "-1979-02-25T23:48:27.001", "datetime-after": datetime("-1979-02-25T23:48:27.001Z") }
+{ "id": 4, "float": null, "double": 192674.0d, "date-before": "-1923-03-27", "date-after": date("-1923-03-27"), "time-before": "19:33:34", "time-after": time("19:33:34.000Z"), "datetime-before": "-1979-02-25T23:48:27.001", "datetime-after": datetime("-1979-02-25T23:48:27.001Z") }
+{ "id": 5, "float": 0.57273304f, "double": 192674.0d, "date-before": null, "date-after": null, "time-before": "19:33:34", "time-after": time("19:33:34.000Z"), "datetime-before": "-1979-02-25T23:48:27.001", "datetime-after": datetime("-1979-02-25T23:48:27.001Z") }
+{ "id": 6, "float": 0.57273304f, "double": 192674.0d, "date-before": "-1923-03-25", "date-after": date("-1923-03-25"), "time-before": null, "time-after": null, "datetime-before": "-1979-02-25T23:48:27.001", "datetime-after": datetime("-1979-02-25T23:48:27.001Z") }
+{ "id": 7, "float": 0.57273304f, "double": 192674.0d, "date-before": "-1923-03-24", "date-after": date("-1923-03-24"), "time-before": "19:33:34", "time-after": time("19:33:34.000Z"), "datetime-before": null, "datetime-after": null }
+{ "id": 8, "float": null, "double": null, "date-before": null, "date-after": null, "time-before": null, "time-after": null, "datetime-before": null, "datetime-after": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/load/csv_02/csv_02.1.adm b/asterix-app/src/test/resources/runtimets/results/load/csv_02/csv_02.1.adm
new file mode 100644
index 0000000..44240dd
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/load/csv_02/csv_02.1.adm
@@ -0,0 +1,8 @@
+{ "id": 1, "float": 0.89968276f, "double": 5.6256d, "date-string": "2013-08-07", "time-string": "07:22:35", "datetime-string": "1979-02-25T23:48:27.034" }
+{ "id": 2, "float": 0.6690524f, "double": null, "date-string": "-1923-03-29", "time-string": "19:33:34", "datetime-string": "-1979-02-25T23:48:27.002" }
+{ "id": 3, "float": 0.57273304f, "double": 192674.0d, "date-string": "-1923-03-28", "time-string": "19:33:34", "datetime-string": "-1979-02-25T23:48:27.001" }
+{ "id": 4, "float": null, "double": 192674.0d, "date-string": "-1923-03-27", "time-string": "19:33:34", "datetime-string": "-1979-02-25T23:48:27.001" }
+{ "id": 5, "float": 0.57273304f, "double": 192674.0d, "date-string": "", "time-string": "19:33:34", "datetime-string": "-1979-02-25T23:48:27.001" }
+{ "id": 6, "float": 0.57273304f, "double": 192674.0d, "date-string": "-1923-03-25", "time-string": "", "datetime-string": "-1979-02-25T23:48:27.001" }
+{ "id": 7, "float": 0.57273304f, "double": 192674.0d, "date-string": "-1923-03-24", "time-string": "19:33:34", "datetime-string": "" }
+{ "id": 8, "float": null, "double": null, "date-string": "", "time-string": "", "datetime-string": "" }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm
deleted file mode 100644
index 3a72bb8..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_double_01/unary-minus_double_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "double1": 2.056E-29d, "double2": NaNd, "double3": -Infinityd, "double4": Infinityd }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm
deleted file mode 100644
index e6541ae..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_float_01/unary-minus_float_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "float1": 80.2f, "float2": NaNf, "float3": -Infinityf, "float4": Infinityf }
diff --git a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm b/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm
deleted file mode 100644
index 4ecc59b..0000000
--- a/asterix-app/src/test/resources/runtimets/results/numeric/unary-minus_int_01/unary-minus_int_01.1.adm
+++ /dev/null
@@ -1 +0,0 @@
-{ "int8": -80i8, "int16": -160i16, "int32": -320, "int64": 640i64 }
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm
new file mode 100644
index 0000000..dff4aa2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm
@@ -0,0 +1 @@
+{ "1970-01-01": 4, "2013-08-06": 2, "-2013-08-06": 4, "1913-08-06T15:53:28Z": 3, "-1913-08-10T15:53:28Z": 7, "null": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm
new file mode 100644
index 0000000..3ba93a5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin/interval_bin.1.adm
@@ -0,0 +1 @@
+{ "bin1": interval-date("2010-01-01, 2011-01-01"), "bin2": interval-date("2010-01-01, 2011-01-01"), "bin3": interval-datetime("-1987-07-01T00:00:00.000Z, -1986-01-01T00:00:00.000Z"), "bin4": interval-datetime("-1987-11-19T12:00:00.000Z, -1987-11-20T00:00:00.000Z"), "bin5": interval-time("04:00:00.000Z, 06:00:00.000Z"), "bin6": null, "bin7": null, "bin8": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm
new file mode 100644
index 0000000..c21626b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_0/interval_bin_gby_0.1.adm
@@ -0,0 +1,4 @@
+{ "tbin": interval-datetime("-1990-01-01T00:00:00.000Z, -1970-01-01T00:00:00.000Z"), "count": 4i64 }
+{ "tbin": interval-datetime("-0990-01-01T00:00:00.000Z, -0970-01-01T00:00:00.000Z"), "count": 1i64 }
+{ "tbin": interval-datetime("1970-01-01T00:00:00.000Z, 1990-01-01T00:00:00.000Z"), "count": 5i64 }
+{ "tbin": interval-datetime("2010-01-01T00:00:00.000Z, 2030-01-01T00:00:00.000Z"), "count": 2i64 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm
new file mode 100644
index 0000000..b67989d
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/interval_bin_gby_1/interval_bin_gby_1.1.adm
@@ -0,0 +1,8 @@
+{ "tbin": interval-time("00:20:00.000Z, 00:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("09:30:00.000Z, 09:40:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("17:20:00.000Z, 17:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("18:00:00.000Z, 18:10:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:20:00.000Z, 23:30:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:30:00.000Z, 23:40:00.000Z"), "count": 1i64 }
+{ "tbin": interval-time("23:40:00.000Z, 23:50:00.000Z"), "count": 5i64 }
+{ "tbin": interval-time("23:50:00.000Z, 00:00:00.000Z"), "count": 1i64 }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm
new file mode 100644
index 0000000..f86335c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm
@@ -0,0 +1 @@
+{ "date1": date("2013-08-23"), "date2": date("-0012-08-12"), "date3": date("-1234-01-01"), "date4": date("-1980-11-09"), "date5": date("-1990-11-09"), "time1": time("08:23:49.000Z"), "time2": time("08:19:23.320Z"), "time3": time("20:19:23.320Z"), "time4": time("10:30:40.948Z"), "time5": time("10:30:40.948Z"), "datetime1": datetime("-1203-12-30T15:48:27.000Z"), "datetime2": datetime("-1203-12-30T23:48:27.392Z"), "datetime3": datetime("1723-12-03T23:59:23.392Z"), "datetime4": datetime("1723-12-04T03:59:23.392Z"), "datetime5": datetime("1723-12-04T03:59:23.392Z") }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/parse_02/parse_02.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/parse_02/parse_02.1.adm
new file mode 100644
index 0000000..963e8d0
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/parse_02/parse_02.1.adm
@@ -0,0 +1 @@
+{ "date-string-1": "-123/1/30", "date-string-2": "JAN 30, -0123", "date-string-3": "-0123/01/30", "time-string-1": "8.7.29.03 AM Z", "time-string-2": "08.07.29.030 AM Z", "datetime-string-1": "DEC 31 3:59:59.999 PM 137 Z", "datetime-string-2": "0137/DEC/31 3:59:59.999Z PM", "datetime-string-3": "0137-12-31T15:59:59.999Z" }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 366ca13..bf7c03a 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -15,6 +15,11 @@
<test-suite xmlns="urn:xml.testframework.asterix.ics.uci.edu" ResultOffsetPath="results" QueryOffsetPath="queries" QueryFileExtension=".aql">
<test-group name="aggregate">
<test-case FilePath="aggregate">
+ <compilation-unit name="issue531_string_min_max">
+ <output-dir compare="Text">issue531_string_min_max</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="aggregate">
<compilation-unit name="agg_null">
<output-dir compare="Text">agg_null</output-dir>
</compilation-unit>
@@ -2532,31 +2537,16 @@
</compilation-unit>
</test-case>
<test-case FilePath="numeric">
- <compilation-unit name="unary-minus_double_01">
- <output-dir compare="Text">unary-minus_double_01</output-dir>
- </compilation-unit>
- </test-case>
- <test-case FilePath="numeric">
<compilation-unit name="unary-minus_double_02">
<output-dir compare="Text">unary-minus_double_02</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="numeric">
- <compilation-unit name="unary-minus_float_01">
- <output-dir compare="Text">unary-minus_float_01</output-dir>
- </compilation-unit>
- </test-case>
- <test-case FilePath="numeric">
<compilation-unit name="unary-minus_float_02">
<output-dir compare="Text">unary-minus_float_02</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="numeric">
- <compilation-unit name="unary-minus_int_01">
- <output-dir compare="Text">unary-minus_int_01</output-dir>
- </compilation-unit>
- </test-case>
- <test-case FilePath="numeric">
<compilation-unit name="unary-minus_int_02">
<output-dir compare="Text">unary-minus_int_02</output-dir>
</compilation-unit>
@@ -4263,6 +4253,16 @@
</test-group>
<test-group name="load">
<test-case FilePath="load">
+ <compilation-unit name="csv_01">
+ <output-dir compare="Text">csv_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="load">
+ <compilation-unit name="csv_02">
+ <output-dir compare="Text">csv_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="load">
<compilation-unit name="issue14_query">
<output-dir compare="Text">none</output-dir>
<expected-error>edu.uci.ics.asterix.common.exceptions.AsterixException</expected-error>
@@ -4359,6 +4359,36 @@
</test-group>
<test-group name="temporal">
<test-case FilePath="temporal">
+ <compilation-unit name="parse_02">
+ <output-dir compare="Text">parse_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
+ <compilation-unit name="parse_01">
+ <output-dir compare="Text">parse_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
+ <compilation-unit name="day_of_week_01">
+ <output-dir compare="Text">day_of_week_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
+ <compilation-unit name="interval_bin">
+ <output-dir compare="Text">interval_bin</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
+ <compilation-unit name="interval_bin_gby_0">
+ <output-dir compare="Text">interval_bin_gby_0</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
+ <compilation-unit name="interval_bin_gby_1">
+ <output-dir compare="Text">interval_bin_gby_1</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
<compilation-unit name="accessors">
<output-dir compare="Text">accessors</output-dir>
</compilation-unit>
diff --git a/asterix-aql/pom.xml b/asterix-aql/pom.xml
index baa2c30..4b83e1c 100644
--- a/asterix-aql/pom.xml
+++ b/asterix-aql/pom.xml
@@ -145,6 +145,11 @@
<version>0.0.3</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xerces</artifactId>
+ <version>2.4.0</version>
+ </dependency>
</dependencies>
</project>
diff --git a/asterix-aql/src/main/javacc/AQL.jj b/asterix-aql/src/main/javacc/AQL.jj
index 46e4f64..3898e39 100644
--- a/asterix-aql/src/main/javacc/AQL.jj
+++ b/asterix-aql/src/main/javacc/AQL.jj
@@ -13,11 +13,12 @@
import java.io.*;
import java.util.List;
import java.util.ArrayList;
-import java.util.Stack;
-
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
+
+import org.apache.xerces.util.IntStack;
+
import edu.uci.ics.asterix.aql.literal.FloatLiteral;
import edu.uci.ics.asterix.aql.literal.DoubleLiteral;
import edu.uci.ics.asterix.aql.literal.FalseLiteral;
@@ -285,7 +286,7 @@
ncNames = new ArrayList<Identifier>();
ncNames.add(new Identifier(tmp));
}
- ( "," tmp = Identifier()
+ ( <COMMA> tmp = Identifier()
{
ncNames.add(new Identifier(tmp));
}
@@ -369,7 +370,7 @@
{
cis.addFieldExpr(fieldExpr);
}
- ) ("," fieldExpr = Identifier()
+ ) (<COMMA> fieldExpr = Identifier()
{
cis.addFieldExpr(fieldExpr);
}
@@ -448,25 +449,12 @@
{
"function" fctName = FunctionName()
ifNotExists = IfNotExists()
- <LEFTPAREN> (<VARIABLE>
- {
- var = new VarIdentifier();
- var.setValue(token.image);
- paramList.add(var);
- getCurrentScope().addNewVarSymbolToScope(var);
- }
- ("," <VARIABLE>
- {
- var = new VarIdentifier();
- var.setValue(token.image);
- paramList.add(var);
- getCurrentScope().addNewVarSymbolToScope(var);
- }
- )*)? <RIGHTPAREN> "{"
+ paramList = ParameterList()
+ <LEFTBRACE>
{
beginPos = token;
}
- functionBodyExpr = Expression() "}"
+ functionBodyExpr = Expression() <RIGHTBRACE>
{
endPos = token;
functionBody = extractFragment(beginPos.beginLine, beginPos.beginColumn, endPos.beginLine, endPos.beginColumn);
@@ -518,7 +506,7 @@
paramList.add(var);
getCurrentScope().addNewVarSymbolToScope(var);
}
- ("," <VARIABLE>
+ (<COMMA> <VARIABLE>
{
var = new VarIdentifier();
var.setValue(token.image);
@@ -597,7 +585,7 @@
{
primaryKeyFields.add(tmp);
}
- ( "," tmp = Identifier()
+ ( <COMMA> tmp = Identifier()
{
primaryKeyFields.add(tmp);
}
@@ -657,7 +645,7 @@
{
}
{
- ( "if" "exists"
+ ( <IF> "exists"
{
return true;
}
@@ -691,7 +679,7 @@
getCurrentScope().addNewVarSymbolToScope(var.getVar());
}
"from" <DATASET> nameComponents = QualifiedName()
- ("where" condition = Expression())?
+ (<WHERE> condition = Expression())?
{
return new DeleteStatement(var, nameComponents.first, nameComponents.second, condition, getVarCounter());
}
@@ -706,13 +694,13 @@
List<UpdateClause> ucs = new ArrayList<UpdateClause>();
}
{
- "update" vars = Variable() "in" target = Expression()
- "where" condition = Expression()
+ "update" vars = Variable() <IN> target = Expression()
+ <WHERE> condition = Expression()
<LEFTPAREN> (uc = UpdateClause()
{
ucs.add(uc);
}
- ("," uc = UpdateClause()
+ (<COMMA> uc = UpdateClause()
{
ucs.add(uc);
}
@@ -734,13 +722,13 @@
UpdateClause elsebranch = null;
}
{
- "set" target = Expression() ":=" value = Expression()
+ "set" target = Expression() <ASSIGN> value = Expression()
| is = InsertStatement()
| ds = DeleteStatement()
| us = UpdateStatement()
- | "if" <LEFTPAREN> condition = Expression() <RIGHTPAREN>
- "then" ifbranch = UpdateClause()
- [LOOKAHEAD(1) "else" elsebranch = UpdateClause()]
+ | <IF> <LEFTPAREN> condition = Expression() <RIGHTPAREN>
+ <THEN> ifbranch = UpdateClause()
+ [LOOKAHEAD(1) <ELSE> elsebranch = UpdateClause()]
{
return new UpdateClause(target, value, is, ds, us, condition, ifbranch, elsebranch);
}
@@ -767,7 +755,7 @@
Pair<Identifier,Identifier> nameComponents = null;
}
{
- "write" "output" "to" nodeName = Identifier() ":" fileName = StringLiteral()
+ "write" "output" "to" nodeName = Identifier() <COLON> fileName = StringLiteral()
( "using" writerClass = StringLiteral() )?
{
return new WriteStatement(new Identifier(nodeName), fileName, writerClass);
@@ -847,7 +835,7 @@
{
configuration.put(keyValuePair.first, keyValuePair.second);
}
- ( "," keyValuePair = KeyValuePair()
+ ( <COMMA> keyValuePair = KeyValuePair()
{
configuration.put(keyValuePair.first, keyValuePair.second);
}
@@ -863,7 +851,7 @@
String value;
}
{
- <LEFTPAREN> key = StringLiteral() "=" value = StringLiteral() <RIGHTPAREN>
+ <LEFTPAREN> key = StringLiteral() <EQ> value = StringLiteral() <RIGHTPAREN>
{
return new Pair<String, String>(key, value);
}
@@ -879,7 +867,7 @@
{
properties.put(property.first, property.second);
}
- ( "," property = Property()
+ ( <COMMA> property = Property()
{
properties.put(property.first, property.second);
}
@@ -895,7 +883,7 @@
String value;
}
{
- key = Identifier() "=" ( value = StringLiteral() | <INTEGER_LITERAL>
+ key = Identifier() <EQ> ( value = StringLiteral() | <INTEGER_LITERAL>
{
try {
value = "" + Long.valueOf(token.image);
@@ -933,7 +921,7 @@
{
( "closed" { recordKind = RecordTypeDefinition.RecordKind.CLOSED; }
| "open" { recordKind = RecordTypeDefinition.RecordKind.OPEN; } )?
- "{"
+ <LEFTBRACE>
{
String hint = getHint(token);
if (hint != null) {
@@ -954,9 +942,9 @@
}
(
RecordField(recType)
- ( "," RecordField(recType) )*
+ ( <COMMA> RecordField(recType) )*
)?
- "}"
+ <RIGHTBRACE>
{
if (recordKind == null) {
recordKind = RecordTypeDefinition.RecordKind.OPEN;
@@ -978,7 +966,7 @@
String hint = getHint(token);
IRecordFieldDataGen rfdg = hint != null ? parseFieldDataGen(hint) : null;
}
- ":" type = TypeExpr() ("?" { nullable = true; } )?
+ <COLON> type = TypeExpr() (<QUES> { nullable = true; } )?
{
recType.addField(fieldName, type, nullable, rfdg);
}
@@ -1000,9 +988,9 @@
TypeExpression type = null;
}
{
- "["
+ <LEFTBRACKET>
( type = TypeExpr() )
- "]"
+ <RIGHTBRACKET>
{
return new OrderedListTypeDefinition(type);
}
@@ -1014,9 +1002,9 @@
TypeExpression type = null;
}
{
- "{{"
+ <LEFTDBLBRACE>
( type = TypeExpr() )
- "}}"
+ <RIGHTDBLBRACE>
{
return new UnorderedListTypeDefinition(type);
}
@@ -1030,7 +1018,7 @@
boolean secondAfterDot = false;
}
{
- first = Identifier() ( "." second = Identifier()
+ first = Identifier() ( <DOT> second = Identifier()
{
secondAfterDot = true;
}
@@ -1106,7 +1094,7 @@
String second = null;
}
{
- first = Identifier() ("." second = Identifier())?
+ first = Identifier() (<DOT> second = Identifier())?
{
Identifier id1 = null;
Identifier id2 = null;
@@ -1128,7 +1116,7 @@
String third = null;
}
{
- first = Identifier() "." second = Identifier() ("." third = Identifier())?
+ first = Identifier() <DOT> second = Identifier() (<DOT> third = Identifier())?
{
Identifier id1 = null;
Identifier id2 = null;
@@ -1157,7 +1145,7 @@
{
"declare" "function" functionName = Identifier()
paramList = ParameterList()
- "{" funcBody = Expression() "}"
+ <LEFTBRACE> funcBody = Expression() <RIGHTBRACE>
{
signature = new FunctionSignature(defaultDataverse, functionName, paramList.size());
getCurrentScope().addFunctionDescriptor(signature, false);
@@ -1217,7 +1205,7 @@
operand = AndExpr()
(
- "or"
+ <OR>
{
if (op == null) {
op = new OperatorExpr();
@@ -1248,7 +1236,7 @@
operand = RelExpr()
(
- "and"
+ <AND>
{
if (op == null) {
op = new OperatorExpr();
@@ -1291,7 +1279,7 @@
}
(
- LOOKAHEAD(2)( "<" | ">" | "<=" | ">=" | "=" | "!=" |"~=")
+ LOOKAHEAD(2)( <LT> | <GT> | <LE> | <GE> | <EQ> | <NE> |<SIMILAR>)
{
String mhint = getHint(token);
if (mhint != null && mhint.equals(INDEXED_NESTED_LOOP_JOIN_HINT)) {
@@ -1335,7 +1323,7 @@
{
operand = MultExpr()
- ( ("+" | "-")
+ ( (<PLUS> | <MINUS>)
{
if (op == null) {
op = new OperatorExpr();
@@ -1364,7 +1352,7 @@
{
operand = UnionExpr()
- (( "*" | "/" | "%" | <CARET> | "idiv")
+ (( <MUL> | <DIV> | <MOD> | <CARET> | <IDIV>)
{
if (op == null) {
op = new OperatorExpr();
@@ -1392,7 +1380,7 @@
}
{
operand1 = UnaryExpr()
- ("union"
+ (<UNION>
(operand2 = UnaryExpr()) {
if (union == null) {
union = new UnionExpr();
@@ -1411,7 +1399,7 @@
Expression expr = null;
}
{
- (( "+"|"-")
+ ( (<PLUS> | <MINUS>)
{
uexpr = new UnaryExpr();
if("+".equals(token.image))
@@ -1464,7 +1452,7 @@
String ident = null;
}
{
- "." ident = Identifier()
+ <DOT> ident = Identifier()
{
return new Identifier(ident);
}
@@ -1476,7 +1464,7 @@
int idx = -2;
}
{
- "[" ( expr = Expression()
+ <LEFTBRACKET> ( expr = Expression()
{
if(expr.getKind() == Expression.Kind.LITERAL_EXPRESSION)
{
@@ -1492,7 +1480,7 @@
}
- | "?"
+ | <QUES>
{
idx = IndexAccessor.ANY;
// ANY
@@ -1500,7 +1488,7 @@
)
- "]"
+ <RIGHTBRACKET>
{
return idx;
}
@@ -1642,16 +1630,16 @@
}
{
- "["
+ <LEFTBRACKET>
( tmp = Expression()
{
exprList.add(tmp);
}
- ("," tmp = Expression() { exprList.add(tmp); })*
+ (<COMMA> tmp = Expression() { exprList.add(tmp); })*
)?
- "]"
+ <RIGHTBRACKET>
{
expr.setExprList(exprList);
@@ -1668,11 +1656,11 @@
}
{
- "{{" ( tmp = Expression()
+ <LEFTDBLBRACE> ( tmp = Expression()
{
exprList.add(tmp);
}
- ("," tmp = Expression() { exprList.add(tmp); })*)? "}}"
+ (<COMMA> tmp = Expression() { exprList.add(tmp); })*)? <RIGHTDBLBRACE>
{
expr.setExprList(exprList);
return expr;
@@ -1686,11 +1674,11 @@
List<FieldBinding> fbList = new ArrayList<FieldBinding>();
}
{
- "{" (tmp = FieldBinding()
+ <LEFTBRACE> (tmp = FieldBinding()
{
fbList.add(tmp);
}
- ("," tmp = FieldBinding() { fbList.add(tmp); })*)? "}"
+ (<COMMA> tmp = FieldBinding() { fbList.add(tmp); })*)? <RIGHTBRACE>
{
expr.setFbList(fbList);
return expr;
@@ -1703,7 +1691,7 @@
Expression left, right;
}
{
- left = Expression() ":" right = Expression()
+ left = Expression() <COLON> right = Expression()
{
fb.setLeftExpr(left);
fb.setRightExpr(right);
@@ -1731,7 +1719,7 @@
argList.add(tmp);
arity ++;
}
- ("," tmp = Expression()
+ (<COMMA> tmp = Expression()
{
argList.add(tmp);
arity++;
@@ -1766,7 +1754,7 @@
{
funcName = token.image;
}
- ( ( arg1 = Identifier() ( "." arg2 = Identifier() )? )
+ ( ( arg1 = Identifier() ( <DOT> arg2 = Identifier() )? )
{
String name = arg2 == null ? arg1 : arg1 + "." + arg2;
LiteralExpr ds = new LiteralExpr();
@@ -1805,7 +1793,7 @@
IfExpr ifExpr = new IfExpr();
}
{
- "if" <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> "then" thenExpr = Expression() "else" elseExpr = Expression()
+ <IF> <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> <THEN> thenExpr = Expression() <ELSE> elseExpr = Expression()
{
ifExpr.setCondExpr(condExpr);
@@ -1825,7 +1813,7 @@
}
{
(tmp = ForClause() {clauseList.add(tmp);} | tmp = LetClause() {clauseList.add(tmp);})
- (tmp = Clause() {clauseList.add(tmp);})* "return" returnExpr = Expression()
+ (tmp = Clause() {clauseList.add(tmp);})* <RETURN> returnExpr = Expression()
{
flworg.setClauseList(clauseList);
@@ -1863,7 +1851,7 @@
extendCurrentScope();
}
{
- "for" varExp = Variable() ("at" varPos = Variable())? "in" ( inExp = Expression() )
+ <FOR> varExp = Variable() (<AT> varPos = Variable())? <IN> ( inExp = Expression() )
{
fc.setVarExpr(varExp);
getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
@@ -1884,7 +1872,7 @@
extendCurrentScope();
}
{
- "let" varExp = Variable() ":=" beExp = Expression()
+ <LET> varExp = Variable() <ASSIGN> beExp = Expression()
{
getCurrentScope().addNewVarSymbolToScope(varExp.getVar());
lc.setVarExpr(varExp);
@@ -1899,7 +1887,7 @@
Expression whereExpr;
}
{
- "where" whereExpr = Expression()
+ <WHERE> whereExpr = Expression()
{
wc.setWhereExpr(whereExpr);
return wc;
@@ -1916,7 +1904,7 @@
}
{
(
- "order"
+ <ORDER>
{
String hint = getHint(token);
if (hint != null && hint.startsWith(INMEMORY_HINT)) {
@@ -1927,24 +1915,24 @@
oc.setNumTuples(numTuples);
}
}
- "by" orderbyExpr = Expression()
+ <BY> orderbyExpr = Expression()
{
orderbyList.add(orderbyExpr);
OrderbyClause.OrderModifier modif = OrderbyClause.OrderModifier.ASC;
}
- ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
- | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
+ ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
+ | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
{
modifierList.add(modif);
}
- ("," orderbyExpr = Expression()
+ (<COMMA> orderbyExpr = Expression()
{
orderbyList.add(orderbyExpr);
modif = OrderbyClause.OrderModifier.ASC;
}
- ( ("asc" { modif = OrderbyClause.OrderModifier.ASC; })
- | ("desc" { modif = OrderbyClause.OrderModifier.DESC; }))?
+ ( (<ASC> { modif = OrderbyClause.OrderModifier.ASC; })
+ | (<DESC> { modif = OrderbyClause.OrderModifier.DESC; }))?
{
modifierList.add(modif);
}
@@ -1974,39 +1962,39 @@
Scope newScope = extendCurrentScopeNoPush(true);
// extendCurrentScope(true);
}
- "group"
+ <GROUP>
{
String hint = getHint(token);
if (hint != null && hint.equals(HASH_GROUP_BY_HINT)) {
gbc.setHashGroupByHint(true);
}
}
- "by" (LOOKAHEAD(2) var = Variable()
+ <BY> (LOOKAHEAD(2) var = Variable()
{
newScope.addNewVarSymbolToScope(var.getVar());
- } ":=")?
+ } <ASSIGN>)?
expr = Expression()
{
GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);
vePairList.add(pair1);
}
- ("," ( LOOKAHEAD(2) var = Variable()
+ (<COMMA> ( LOOKAHEAD(2) var = Variable()
{
newScope.addNewVarSymbolToScope(var.getVar());
- } ":=")?
+ } <ASSIGN>)?
expr = Expression()
{
GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);
vePairList.add(pair2);
}
)*
- ("decor" decorVar = Variable() ":=" decorExpr = Expression()
+ (<DECOR> decorVar = Variable() <ASSIGN> decorExpr = Expression()
{
newScope.addNewVarSymbolToScope(decorVar.getVar());
GbyVariableExpressionPair pair3 = new GbyVariableExpressionPair(decorVar, decorExpr);
decorPairList.add(pair3);
}
- ("," "decor" decorVar = Variable() ":=" decorExpr = Expression()
+ (<COMMA> <DECOR> decorVar = Variable() <ASSIGN> decorExpr = Expression()
{
newScope.addNewVarSymbolToScope(decorVar.getVar());
GbyVariableExpressionPair pair4 = new GbyVariableExpressionPair(decorVar, decorExpr);
@@ -2014,14 +2002,14 @@
}
)*
)?
- "with" withVar = VariableRef()
+ <WITH> withVar = VariableRef()
{
if(withVar.getIsNewVar()==true)
throw new ParseException("can't find variable " + withVar.getVar());
withVarList.add(withVar);
newScope.addNewVarSymbolToScope(withVar.getVar());
}
- ("," withVar = VariableRef()
+ (<COMMA> withVar = VariableRef()
{
if(withVar.getIsNewVar()==true)
throw new ParseException("can't find variable " + withVar.getVar());
@@ -2045,8 +2033,8 @@
pushForbiddenScope(getCurrentScope());
}
{
- "limit" expr = Expression() { lc.setLimitExpr(expr); }
- ("offset" expr = Expression() { lc.setOffset(expr); })?
+ <LIMIT> expr = Expression() { lc.setLimitExpr(expr); }
+ (<OFFSET> expr = Expression() { lc.setOffset(expr); })?
{
popForbiddenScope();
@@ -2060,11 +2048,11 @@
Expression expr;
}
{
- "distinct" "by" expr = Expression()
+ <DISTINCT> <BY> expr = Expression()
{
exprs.add(expr);
}
- ("," expr = Expression()
+ (<COMMA> expr = Expression()
{
exprs.add(expr);
}
@@ -2088,23 +2076,23 @@
createNewScope();
}
- ( ("some" { qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); })
- | ("every" { qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); }))
- var = Variable() "in" inExpr = Expression()
+ ( (<SOME> { qc.setQuantifier(QuantifiedExpression.Quantifier.SOME); })
+ | (<EVERY> { qc.setQuantifier(QuantifiedExpression.Quantifier.EVERY); }))
+ var = Variable() <IN> inExpr = Expression()
{
pair = new QuantifiedPair(var, inExpr);
getCurrentScope().addNewVarSymbolToScope(var.getVar());
quantifiedList.add(pair);
}
(
- "," var = Variable() "in" inExpr = Expression()
+ <COMMA> var = Variable() <IN> inExpr = Expression()
{
pair = new QuantifiedPair(var, inExpr);
getCurrentScope().addNewVarSymbolToScope(var.getVar());
quantifiedList.add(pair);
}
)*
- "satisfies" satisfiesExpr = Expression()
+ <SATISFIES> satisfiesExpr = Expression()
{
qc.setSatisfiesExpr(satisfiesExpr);
qc.setQuantifiedList(quantifiedList);
@@ -2115,155 +2103,212 @@
TOKEN_MGR_DECLS:
{
- public int commentDepth = 0;
+ public int commentDepth = 0;
+ public IntStack lexerStateStack = new IntStack();
+
+ public void pushState() {
+ lexerStateStack.push( curLexState );
+ }
+
+ public void popState() {
+ if (lexerStateStack.size() > 0) {
+ SwitchTo( lexerStateStack.pop() );
+ } else {
+ throw new RuntimeException();
+ }
+ }
+}
+
+<DEFAULT,IN_DBL_BRACE>
+TOKEN :
+{
+ <ASC : "asc">
+ | <AT : "at">
+ | <BY : "by">
+ | <DATASET : "dataset">
+ | <DECOR : "decor">
+ | <DESC : "desc">
+ | <DISTINCT : "distinct">
+ | <ELSE : "else">
+ | <EVERY : "every">
+ | <FOR : "for">
+ | <GROUP : "group">
+ | <IF : "if">
+ | <IN : "in">
+ | <LET : "let">
+ | <LIMIT : "limit">
+ | <OFFSET : "offset">
+ | <ORDER : "order">
+ | <RETURN : "return">
+ | <SATISFIES : "satisfies">
+ | <SOME : "some">
+ | <THEN : "then">
+ | <UNION : "union">
+ | <WHERE : "where">
+ | <WITH : "with">
+}
+
+<DEFAULT,IN_DBL_BRACE>
+TOKEN :
+{
+ <CARET : "^">
+ | <DIV : "/">
+ | <IDIV : "idiv">
+ | <MINUS : "-">
+ | <MOD : "%">
+ | <MUL : "*">
+ | <PLUS : "+">
+
+ | <LEFTPAREN : "(">
+ | <RIGHTPAREN : ")">
+ | <LEFTBRACKET : "[">
+ | <RIGHTBRACKET : "]">
+
+ | <COLON : ":">
+ | <COMMA : ",">
+ | <DOT : ".">
+ | <QUES : "?">
+
+ | <LT : "<">
+ | <GT : ">">
+ | <LE : "<=">
+ | <GE : ">=">
+ | <EQ : "=">
+ | <NE : "!=">
+ | <SIMILAR : "~=">
+ | <ASSIGN : ":=">
+
+ | <AND : "and">
+ | <OR : "or">
+}
+
+<DEFAULT,IN_DBL_BRACE>
+TOKEN :
+{
+ <LEFTBRACE : "{"> { pushState(); } : DEFAULT
}
<DEFAULT>
TOKEN :
{
- <CARET : "^" >
+ <RIGHTBRACE : "}"> { popState(); }
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <DATASET : "dataset" >
+ <LEFTDBLBRACE : "{{"> { pushState(); } : IN_DBL_BRACE
}
-<DEFAULT>
+<IN_DBL_BRACE>
TOKEN :
{
- <LEFTPAREN : "(" >
+ <RIGHTDBLBRACE : "}}"> { popState(); }
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <RIGHTPAREN : ")" >
+ <INTEGER_LITERAL : (<DIGIT>)+ >
}
-
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <INTEGER_LITERAL : (<DIGIT>)+ >
+ <NULL : "null">
+ | <TRUE : "true">
+ | <FALSE : "false">
}
-
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <NULL : "null">
+ <#DIGIT : ["0" - "9"]>
}
-<DEFAULT>
-TOKEN :
-{
- <TRUE : "true">
-}
-
-<DEFAULT>
-TOKEN :
-{
- <FALSE : "false">
-}
-
-<DEFAULT>
-TOKEN :
-{
- <#DIGIT : ["0" - "9"]>
-}
-
-
+<DEFAULT,IN_DBL_BRACE>
TOKEN:
{
- < DOUBLE_LITERAL: <DIGITS>
+ < DOUBLE_LITERAL: <DIGITS>
| <DIGITS> ( "." <DIGITS> )?
| "." <DIGITS>
- >
- |
- < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
+ >
+ | < FLOAT_LITERAL: <DIGITS> ( "f" | "F" )
| <DIGITS> ( "." <DIGITS> ( "f" | "F" ) )?
| "." <DIGITS> ( "f" | "F" )
- >
- |
- <DIGITS : (<DIGIT>)+ >
+ >
+ | <DIGITS : (<DIGIT>)+ >
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <#LETTER : ["A" - "Z", "a" - "z"]>
+ <#LETTER : ["A" - "Z", "a" - "z"]>
+ | <SPECIALCHARS : ["$", "_", "-"]>
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <SPECIALCHARS : ["$", "_", "-"] >
+ <STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") | ("\'"(<EscapeApos> | ~["\'"])* "\'")>
+ | < #EscapeQuot: "\\\"" >
+ | < #EscapeApos: "\\\'" >
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <STRING_LITERAL : ("\"" (<EscapeQuot> | ~["\""])* "\"") | ("\'"(<EscapeApos> | ~["\'"])* "\'")>
- |
- < #EscapeQuot: "\\\"" >
- |
- < #EscapeApos: "\\\'" >
+ <IDENTIFIER : <LETTER> (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
}
-<DEFAULT>
+<DEFAULT,IN_DBL_BRACE>
TOKEN :
{
- <IDENTIFIER : <LETTER> (<LETTER> | <DIGIT> | <SPECIALCHARS>)*>
+ <VARIABLE : "$" <LETTER> (<LETTER> | <DIGIT> | "_")*>
}
-
-<DEFAULT>
-TOKEN :
-{
- <VARIABLE : "$" <LETTER> (<LETTER> | <DIGIT> | "_")*>
-}
-
+<DEFAULT,IN_DBL_BRACE>
SKIP:
{
" "
-| "\t"
-| "\r"
-| "\n"
+ | "\t"
+ | "\r"
+ | "\n"
}
+<DEFAULT,IN_DBL_BRACE>
SKIP:
{
- <"//" (~["\n"])* "\n">
+ <"//" (~["\n"])* "\n">
}
+<DEFAULT,IN_DBL_BRACE>
SKIP:
{
- <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
+ <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")?>
}
-
+<DEFAULT,IN_DBL_BRACE>
SKIP:
{
- <"/*"> {commentDepth=1;}: INSIDE_COMMENT
+ <"/*"> { pushState(); } : INSIDE_COMMENT
}
<INSIDE_COMMENT>
SPECIAL_TOKEN:
{
- <"+"(" ")*(~["*"])*>
+ <"+"(" ")*(~["*"])*>
}
<INSIDE_COMMENT>
SKIP:
{
- <"/*"> {commentDepth++;}
+ <"/*"> { pushState(); }
}
<INSIDE_COMMENT>
SKIP:
{
- <"*/"> {commentDepth--; if (commentDepth == 0) SwitchTo(DEFAULT);}
-| <~[]>
+ <"*/"> { popState(); }
+ | <~[]>
}
diff --git a/asterix-benchmarks/src/main/resources/tpc-h/queries/q05_local_supplier_volume.3.query.aql b/asterix-benchmarks/src/main/resources/tpc-h/queries/q05_local_supplier_volume.3.query.aql
index e0e0563..342a85a 100644
--- a/asterix-benchmarks/src/main/resources/tpc-h/queries/q05_local_supplier_volume.3.query.aql
+++ b/asterix-benchmarks/src/main/resources/tpc-h/queries/q05_local_supplier_volume.3.query.aql
@@ -11,6 +11,7 @@
for $n in dataset('Nation')
for $r in dataset('Region')
where $n.n_regionkey = $r.r_regionkey
+ and $r.r_name = 'ASIA'
return {
"n_name": $n.n_name,
"n_nationkey": $n.n_nationkey
@@ -32,7 +33,7 @@
"s_nationkey": $s1.s_nationkey
}
)
- where $l1.l_orderkey = $o.o_orderkey and $o.o_orderdate >= '1990-01-01' and $o.o_orderdate < '1995-01-01'
+ where $l1.l_orderkey = $o.o_orderkey and $o.o_orderdate >= '1994-01-01' and $o.o_orderdate < '1995-01-01'
return {
"n_name": $l1.n_name,
"l_extendedprice": $l1.l_extendedprice,
diff --git a/asterix-benchmarks/src/main/resources/tpc-h/queries/q14_promotion_effect.3.query.aql b/asterix-benchmarks/src/main/resources/tpc-h/queries/q14_promotion_effect.3.query.aql
index 786637d..e6007e7 100644
--- a/asterix-benchmarks/src/main/resources/tpc-h/queries/q14_promotion_effect.3.query.aql
+++ b/asterix-benchmarks/src/main/resources/tpc-h/queries/q14_promotion_effect.3.query.aql
@@ -5,11 +5,16 @@
where $l.l_partkey = $p.p_partkey
and $l.l_shipdate >= '1995-09-01'
and $l.l_shipdate < '1995-10-01'
-group by $t:=1 with $l, $p
+let $lp := {
+ "l_extendedprice": $l.l_extendedprice,
+ "l_discount": $l.l_discount,
+ "p_type": $p.p_type
+ }
+group by $t:=1 with $lp
return 100.00 * sum(
- for $i in $l
- return switch-case(like($i.p_type, 'PROMO%'),
+ for $i in $lp
+ return switch-case(like($i.p_type, 'PROMO%'),
true, $i.l_extendedprice*(1-$i.l_discount),
false, 0.0)
- ) / sum(for $i in $l return $i.l_extendedprice * (1 - $i.l_discount)
+ ) / sum(for $i in $lp return $i.l_extendedprice * (1 - $i.l_discount)
)
diff --git a/asterix-benchmarks/src/main/resources/tpc-h/queries/q18_large_volume_customer.3.query.aql b/asterix-benchmarks/src/main/resources/tpc-h/queries/q18_large_volume_customer.3.query.aql
index 289d900..86b95cf 100644
--- a/asterix-benchmarks/src/main/resources/tpc-h/queries/q18_large_volume_customer.3.query.aql
+++ b/asterix-benchmarks/src/main/resources/tpc-h/queries/q18_large_volume_customer.3.query.aql
@@ -11,7 +11,7 @@
"t_sum_quantity": sum(for $i in $l return $i.l_quantity)
}
)
-where $o.o_orderkey = $t.l_orderkey and $t.t_sum_quantity > 30
+where $o.o_orderkey = $t.l_orderkey and $t.t_sum_quantity > 300
for $l in dataset('LineItem')
where $l.l_orderkey = $o.o_orderkey
group by $c_name := $c.c_name, $c_custkey := $c.c_custkey, $o_orderkey := $o.o_orderkey,
diff --git a/asterix-benchmarks/src/main/resources/tpc-h/queries/q19_discounted_revenue.3.query.aql b/asterix-benchmarks/src/main/resources/tpc-h/queries/q19_discounted_revenue.3.query.aql
index 7e26d94..9ef0088 100644
--- a/asterix-benchmarks/src/main/resources/tpc-h/queries/q19_discounted_revenue.3.query.aql
+++ b/asterix-benchmarks/src/main/resources/tpc-h/queries/q19_discounted_revenue.3.query.aql
@@ -8,24 +8,24 @@
where $p.p_partkey = $l.l_partkey
and ( (
$p.p_brand = 'Brand#12'
- and reg-exp($p.p_container,'SM CASE||SM BOX||SM PACK||SM PKG')
+ and reg-exp($p.p_container,'SM CASE|SM BOX|SM PACK|SM PKG')
and $l.l_quantity >= 1 and $l.l_quantity <= 11
and $p.p_size >= 1 and $p.p_size <= 5
- and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+ and ($l.l_shipmode = 'AIR' or $l.l_shipmode = 'AIR REG')
and $l.l_shipinstruct = 'DELIVER IN PERSON'
) or (
$p.p_brand = 'Brand#23'
- and reg-exp($p.p_container, 'MED BAG||MED BOX||MED PKG||MED PACK')
+ and reg-exp($p.p_container, 'MED BAG|MED BOX|MED PKG|MED PACK')
and $l.l_quantity >= 10 and $l.l_quantity <= 20
and $p.p_size >= 1 and $p.p_size <= 10
- and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+ and ($l.l_shipmode = 'AIR' or $l.l_shipmode = 'AIR REG')
and $l.l_shipinstruct = 'DELIVER IN PERSON'
) or (
$p.p_brand = 'Brand#34'
- and reg-exp($p.p_container, 'LG CASE||LG BOX||LG PACK||LG PKG')
+ and reg-exp($p.p_container, 'LG CASE|LG BOX|LG PACK|LG PKG')
and $l.l_quantity >= 20 and $l.l_quantity <= 30
and $p.p_size >= 1 and $p.p_size <= 15
- and reg-exp($l.l_shipmode, 'AIR||AIR REG')
+ and ($l.l_shipmode = 'AIR' or $l.l_shipmode = 'AIR REG')
and $l.l_shipinstruct = 'DELIVER IN PERSON'
)
)
diff --git a/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/dataset/adapter/FileSystemBasedAdapter.java b/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/dataset/adapter/FileSystemBasedAdapter.java
index 45a827c..b8e9ef9 100644
--- a/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/dataset/adapter/FileSystemBasedAdapter.java
+++ b/asterix-external-data/src/main/java/edu/uci/ics/asterix/external/dataset/adapter/FileSystemBasedAdapter.java
@@ -37,7 +37,8 @@
protected final IAType sourceDatatype;
protected IHyracksTaskContext ctx;
- public FileSystemBasedAdapter(ITupleParserFactory parserFactory, IAType sourceDatatype, IHyracksTaskContext ctx) throws HyracksDataException {
+ public FileSystemBasedAdapter(ITupleParserFactory parserFactory, IAType sourceDatatype, IHyracksTaskContext ctx)
+ throws HyracksDataException {
this.tupleParser = parserFactory.createTupleParser(ctx);
this.sourceDatatype = sourceDatatype;
this.ctx = ctx;
@@ -48,5 +49,4 @@
InputStream in = getInputStream(partition);
tupleParser.parse(in, writer);
}
-
}
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
index 5fe095e..d19743a 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataNode.java
@@ -90,7 +90,6 @@
import edu.uci.ics.hyracks.dataflow.common.comm.io.ArrayTupleReference;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.dataflow.common.util.TupleUtils;
-import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.IIndex;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
@@ -99,6 +98,7 @@
import edu.uci.ics.hyracks.storage.am.common.api.IModificationOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.api.ITreeIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.TreeIndexException;
+import edu.uci.ics.hyracks.storage.am.common.exceptions.TreeIndexDuplicateKeyException;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.IndexOperation;
import edu.uci.ics.hyracks.storage.am.common.ophelpers.MultiComparator;
@@ -163,7 +163,7 @@
DataverseTupleTranslator tupleReaderWriter = new DataverseTupleTranslator(true);
ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(dataverse);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.DATAVERSE_DATASET, tuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A dataverse with this name " + dataverse.getDataverseName()
+ " already exists.", e);
} catch (Exception e) {
@@ -193,7 +193,7 @@
ITupleReference dataTypeTuple = createTuple(dataset.getDataverseName(), dataset.getItemTypeName(),
dataset.getDatasetName());
insertTupleIntoIndex(jobId, MetadataSecondaryIndexes.DATATYPENAME_ON_DATASET_INDEX, dataTypeTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A dataset with this name " + dataset.getDatasetName()
+ " already exists in dataverse '" + dataset.getDataverseName() + "'.", e);
} catch (Exception e) {
@@ -207,7 +207,7 @@
IndexTupleTranslator tupleWriter = new IndexTupleTranslator(true);
ITupleReference tuple = tupleWriter.getTupleFromMetadataEntity(index);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.INDEX_DATASET, tuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("An index with name '" + index.getIndexName() + "' already exists.", e);
} catch (Exception e) {
throw new MetadataException(e);
@@ -220,7 +220,7 @@
NodeTupleTranslator tupleReaderWriter = new NodeTupleTranslator(true);
ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(node);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.NODE_DATASET, tuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A node with name '" + node.getNodeName() + "' already exists.", e);
} catch (Exception e) {
throw new MetadataException(e);
@@ -233,7 +233,7 @@
NodeGroupTupleTranslator tupleReaderWriter = new NodeGroupTupleTranslator(true);
ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(nodeGroup);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.NODEGROUP_DATASET, tuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A nodegroup with name '" + nodeGroup.getNodeGroupName() + "' already exists.",
e);
} catch (Exception e) {
@@ -247,7 +247,7 @@
DatatypeTupleTranslator tupleReaderWriter = new DatatypeTupleTranslator(jobId, this, true);
ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(datatype);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.DATATYPE_DATASET, tuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A datatype with name '" + datatype.getDatatypeName() + "' already exists.", e);
} catch (Exception e) {
throw new MetadataException(e);
@@ -262,7 +262,7 @@
ITupleReference functionTuple = tupleReaderWriter.getTupleFromMetadataEntity(function);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.FUNCTION_DATASET, functionTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A function with this name " + function.getName() + " and arity "
+ function.getArity() + " already exists in dataverse '" + function.getDataverseName() + "'.", e);
} catch (Exception e) {
@@ -1120,7 +1120,7 @@
ITupleReference adapterTuple = tupleReaderWriter.getTupleFromMetadataEntity(adapter);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.DATASOURCE_ADAPTER_DATASET, adapterTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A adapter with this name " + adapter.getAdapterIdentifier().getAdapterName()
+ " already exists in dataverse '" + adapter.getAdapterIdentifier().getNamespace() + "'.", e);
} catch (Exception e) {
@@ -1203,7 +1203,7 @@
ITupleReference libraryTuple = tupleReaderWriter.getTupleFromMetadataEntity(library);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.LIBRARY_DATASET, libraryTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A library with this name " + library.getDataverseName()
+ " already exists in dataverse '" + library.getDataverseName() + "'.", e);
} catch (Exception e) {
@@ -1342,7 +1342,7 @@
ITupleReference feedPolicyTuple = tupleReaderWriter.getTupleFromMetadataEntity(feedPolicy);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.FEED_POLICY_DATASET, feedPolicyTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A feed policy with this name " + feedPolicy.getPolicyName()
+ " already exists in dataverse '" + feedPolicy.getPolicyName() + "'.", e);
} catch (Exception e) {
@@ -1431,7 +1431,7 @@
ITupleReference feedTuple = tupleReaderWriter.getTupleFromMetadataEntity(feed);
insertTupleIntoIndex(jobId, MetadataPrimaryIndexes.FEED_DATASET, feedTuple);
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
throw new MetadataException("A feed with this name " + feed.getFeedName()
+ " already exists in dataverse '" + feed.getDataverseName() + "'.", e);
} catch (Exception e) {
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
index 6c55f12..541d703 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
@@ -55,7 +55,7 @@
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
-import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
+import edu.uci.ics.hyracks.storage.am.common.exceptions.TreeIndexDuplicateKeyException;
/**
* Translates a Datatype metadata entity to an ITupleReference and vice versa.
@@ -437,7 +437,7 @@
mn.insertIntoDatatypeSecondaryIndex(jobId, topLevelType.getDataverseName(), typeName,
topLevelType.getDatatypeName());
- } catch (BTreeDuplicateKeyException e) {
+ } catch (TreeIndexDuplicateKeyException e) {
// The key may have been inserted by a previous DDL statement or by
// a previous nested type.
}
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/feeds/FeedMetaOperatorDescriptor.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/feeds/FeedMetaOperatorDescriptor.java
index f933504..d665a21 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/feeds/FeedMetaOperatorDescriptor.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/feeds/FeedMetaOperatorDescriptor.java
@@ -14,13 +14,12 @@
import edu.uci.ics.hyracks.api.dataflow.IOperatorDescriptor;
import edu.uci.ics.hyracks.api.dataflow.IOperatorNodePushable;
import edu.uci.ics.hyracks.api.dataflow.value.IRecordDescriptorProvider;
-import edu.uci.ics.hyracks.api.dataflow.value.RecordDescriptor;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.api.job.JobSpecification;
import edu.uci.ics.hyracks.dataflow.common.comm.io.FrameTupleAccessor;
import edu.uci.ics.hyracks.dataflow.std.base.AbstractSingleActivityOperatorDescriptor;
import edu.uci.ics.hyracks.dataflow.std.base.AbstractUnaryInputUnaryOutputOperatorNodePushable;
-import edu.uci.ics.hyracks.storage.am.btree.exceptions.BTreeDuplicateKeyException;
+import edu.uci.ics.hyracks.storage.am.common.exceptions.TreeIndexDuplicateKeyException;
public class FeedMetaOperatorDescriptor extends AbstractSingleActivityOperatorDescriptor {
@@ -148,7 +147,7 @@
}
private boolean handleException(Throwable exception) {
- if (exception instanceof BTreeDuplicateKeyException) {
+ if (exception instanceof TreeIndexDuplicateKeyException) {
if (resumeOldState) {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.warning("Received duplicate key exception but that is possible post recovery");
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADayTimeDurationSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADayTimeDurationSerializerDeserializer.java
index b016af0..8471056 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADayTimeDurationSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/ADayTimeDurationSerializerDeserializer.java
@@ -31,7 +31,7 @@
private static final long serialVersionUID = 1L;
- public static final ADayTimeDurationSerializerDeserializer INSTNACE = new ADayTimeDurationSerializerDeserializer();
+ public static final ADayTimeDurationSerializerDeserializer INSTANCE = new ADayTimeDurationSerializerDeserializer();
@SuppressWarnings("unchecked")
private static final ISerializerDeserializer<ADayTimeDuration> dayTimeDurationSerde = AqlSerializerDeserializerProvider.INSTANCE
@@ -56,7 +56,7 @@
}
}
- public static void parse(String durationString, DataOutput out) throws HyracksDataException {
+ public void parse(String durationString, DataOutput out) throws HyracksDataException {
try {
ADurationParserFactory.parseDuration(durationString, 0, durationString.length(), aDayTimeDuration,
ADurationParseOption.All);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
index 486f271..14ec491 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
@@ -101,10 +101,10 @@
return ADurationSerializerDeserializer.INSTANCE.deserialize(in);
}
case YEARMONTHDURATION: {
- return AYearMonthDurationerializerDeserializer.INSTANCE.deserialize(in);
+ return AYearMonthDurationSerializerDeserializer.INSTANCE.deserialize(in);
}
case DAYTIMEDURATION: {
- return ADayTimeDurationSerializerDeserializer.INSTNACE.deserialize(in);
+ return ADayTimeDurationSerializerDeserializer.INSTANCE.deserialize(in);
}
case INTERVAL: {
return AIntervalSerializerDeserializer.INSTANCE.deserialize(in);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationerializerDeserializer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationSerializerDeserializer.java
similarity index 89%
rename from asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationerializerDeserializer.java
rename to asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationSerializerDeserializer.java
index 79bf3c0..3cd6e66 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationerializerDeserializer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/dataflow/data/nontagged/serde/AYearMonthDurationSerializerDeserializer.java
@@ -27,11 +27,11 @@
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-public class AYearMonthDurationerializerDeserializer implements ISerializerDeserializer<AYearMonthDuration> {
+public class AYearMonthDurationSerializerDeserializer implements ISerializerDeserializer<AYearMonthDuration> {
private static final long serialVersionUID = 1L;
- public static final AYearMonthDurationerializerDeserializer INSTANCE = new AYearMonthDurationerializerDeserializer();
+ public static final AYearMonthDurationSerializerDeserializer INSTANCE = new AYearMonthDurationSerializerDeserializer();
@SuppressWarnings("unchecked")
private static final ISerializerDeserializer<AYearMonthDuration> yearMonthDurationSerde = AqlSerializerDeserializerProvider.INSTANCE
@@ -56,7 +56,7 @@
}
}
- public static void parse(String durationString, DataOutput out) throws HyracksDataException {
+ public void parse(String durationString, DataOutput out) throws HyracksDataException {
try {
ADurationParserFactory.parseDuration(durationString, 0, durationString.length(), aYearMonthDuration,
ADurationParseOption.All);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
index ff1a14c..36f94a6 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/formats/nontagged/AqlSerializerDeserializerProvider.java
@@ -44,7 +44,7 @@
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AStringSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.SerializerDeserializerUtil;
import edu.uci.ics.asterix.om.base.IAObject;
import edu.uci.ics.asterix.om.types.AOrderedListType;
@@ -129,10 +129,10 @@
return ADurationSerializerDeserializer.INSTANCE;
}
case YEARMONTHDURATION: {
- return AYearMonthDurationerializerDeserializer.INSTANCE;
+ return AYearMonthDurationSerializerDeserializer.INSTANCE;
}
case DAYTIMEDURATION: {
- return ADayTimeDurationSerializerDeserializer.INSTNACE;
+ return ADayTimeDurationSerializerDeserializer.INSTANCE;
}
case INTERVAL: {
return AIntervalSerializerDeserializer.INSTANCE;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
index 2200ea3..3a0a80a 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/ATimeParserFactory.java
@@ -181,11 +181,6 @@
}
}
- if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
- || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone hour " + timezoneHour);
- }
-
int temp_offset = (timeString.charAt(start + 3) == ':') ? 1 : 0;
for (int i = 0; i < 2; i++) {
@@ -197,15 +192,11 @@
}
}
- if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
- || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone minute " + timezoneMinute);
- }
+ timezone = (int) (timezoneHour * GregorianCalendarSystem.CHRONON_OF_HOUR + timezoneMinute
+ * GregorianCalendarSystem.CHRONON_OF_MINUTE);
- if (timeString.charAt(start) == '-') {
- timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
- } else {
- timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ if (timeString.charAt(start) == '+') {
+ timezone *= -1;
}
}
return timezone;
@@ -345,11 +336,6 @@
}
}
- if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
- || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone hour " + timezoneHour);
- }
-
int temp_offset = (timeString[start + 3] == ':') ? 1 : 0;
for (int i = 0; i < 2; i++) {
@@ -360,15 +346,11 @@
}
}
- if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
- || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone minute " + timezoneMinute);
- }
+ timezone = (int) (timezoneHour * GregorianCalendarSystem.CHRONON_OF_HOUR + timezoneMinute
+ * GregorianCalendarSystem.CHRONON_OF_MINUTE);
- if (timeString[start] == '-') {
- timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
- } else {
- timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ if (timeString[start] == '+') {
+ timezone *= -1;
}
}
return timezone;
@@ -508,11 +490,6 @@
}
}
- if (timezoneHour < GregorianCalendarSystem.TIMEZONE_HOUR_MIN
- || timezoneHour > GregorianCalendarSystem.TIMEZONE_HOUR_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone hour " + timezoneHour);
- }
-
int temp_offset = (timeString[start + 3] == ':') ? 1 : 0;
for (int i = 0; i < 2; i++) {
@@ -523,15 +500,11 @@
}
}
- if (timezoneMinute < GregorianCalendarSystem.TIMEZONE_MIN_MIN
- || timezoneMinute > GregorianCalendarSystem.TIMEZONE_MIN_MAX) {
- throw new HyracksDataException(timeErrorMessage + ": time zone minute " + timezoneMinute);
- }
+ timezone = (int) (timezoneHour * GregorianCalendarSystem.CHRONON_OF_HOUR + timezoneMinute
+ * GregorianCalendarSystem.CHRONON_OF_MINUTE);
- if (timeString[start] == '-') {
- timezone = (byte) -((timezoneHour * 4) + timezoneMinute / 15);
- } else {
- timezone = (byte) ((timezoneHour * 4) + timezoneMinute / 15);
+ if (timeString[start] == '+') {
+ timezone *= -1;
}
}
return timezone;
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/AsterixTemporalTypeParseException.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/AsterixTemporalTypeParseException.java
new file mode 100644
index 0000000..9354d5f
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/AsterixTemporalTypeParseException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.om.base.temporal;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+public class AsterixTemporalTypeParseException extends HyracksDataException {
+
+ private static final long serialVersionUID = 1L;
+
+ public AsterixTemporalTypeParseException() {
+ super();
+ }
+
+ public AsterixTemporalTypeParseException(Exception ex) {
+ super(ex);
+ }
+
+ public AsterixTemporalTypeParseException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java
new file mode 100644
index 0000000..bd74ad4
--- /dev/null
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java
@@ -0,0 +1,897 @@
+/*
+ * 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.om.base.temporal;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.TimeZone;
+
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+
+/**
+ * {@link DateTimeFormatUtils} provides the utility methods to parse and print a date/time/datetime
+ * value based on the given format string. The format string may contain the following <b>format characters</b> (note that
+ * format string is <b>case-sensitive</b>):
+ * <p/>
+ * - <b>Y</b>: a digit for the year field. At most 4 year format characters are allowed for a valid format string.<br/>
+ * - <b>M</b>: a digit or character for the month field. At most 3 month format characters are allowed for a valid format string. When three month format characters are used, the shorten month names (like JAN, FEB etc.) are expected in the string to be parsed. Otherwise digits are expected.<br/>
+ * - <b>D</b>: a digit for the day field. At most 2 day format characters are allowed.<br/>
+ * - <b>h</b>: a digit for the hour field. At most 2 hour format characters are allowed.<br/>
+ * - <b>m</b>: a digit for the minute field. At most 2 minute format characters are allowed.<br/>
+ * - <b>s</b>: a digit for the second field. At most 2 second format characters are allowed.<br/>
+ * - <b>n</b>: a digit for the millisecond field. At most 3 millisecond format characters are allowed.<br/>
+ * - <b>a</b>: the AM/PM field. At most 1 am/pm format character is allowed, and it matches with AM and PM case-insensitively. <br/>
+ * - <b>z</b>: the timezone field. At most 1 timezone format characters are allowed. The valid timezone string matching with this format character include:<br/>
+ * -- <b>Z</b>: a single upper-case character representing the UTC timezone;<br/>
+ * -- <b>[UTC|GMT]+xx[:]xx</b>: representing a timezone by providing the actual offset time from the UTC time;<br/>
+ * -- A string representation of a timezone like PST, Asia/Shanghai. The names of the timezones are following the Zoneinfo database provided by the JDK library. See {@link TimeZone} for more details on this.<br/>
+ * - <b>Separators</b>: separators that can be used to separate the different fields. Currently only the following characters can be used as separator: <b>-(hyphen), :(colon), /(solidus), .(period) and ,(comma)</b>.
+ * <p/>
+ * For the matching algorithm, both the format string and the data string are scanned from the beginning to the end, and the algorithm tried to match the format with the characters/digits/separators in the data string. The format string represents the <b>minimum</b> length of the required field (similar to the C-style printf formatting). This means that something like a year <it>1990</it> will match with the format strings <it>Y, YY, YYY and YYYY</it>.
+ * <p/>
+ * If the given string cannot be parsed by the given format string, an {@link AsterixTemporalTypeParseException} will be returned.
+ */
+public class DateTimeFormatUtils {
+
+ private final GregorianCalendarSystem CAL = GregorianCalendarSystem.getInstance();
+
+ // For time
+ private final char HOUR_CHAR = 'h';
+ private final char MINUTE_CHAR = 'm';
+ private final char SECOND_CHAR = 's';
+ private final char MILLISECOND_CHAR = 'n';
+ private final char AMPM_CHAR = 'a';
+ private final char TIMEZONE_CHAR = 'z';
+
+ private final int MAX_HOUR_CHARS = 2;
+ private final int MAX_MINUTE_CHARS = 2;
+ private final int MAX_SECOND_CHARS = 2;
+ private final int MAX_MILLISECOND_CHARS = 3;
+ private final int MAX_AMPM_CHARS = 1;
+ private final int MAX_TIMEZONE_CHARS = 1;
+
+ private enum DateTimeProcessState {
+ INIT,
+ YEAR,
+ MONTH,
+ DAY,
+ HOUR,
+ MINUTE,
+ SECOND,
+ MILLISECOND,
+ AMPM,
+ TIMEZONE,
+ SEPARATOR
+ }
+
+ // For date
+ private final char YEAR_CHAR = 'Y';
+ private final char MONTH_CHAR = 'M';
+ private final char DAY_CHAR = 'D';
+
+ private final int MAX_YEAR_CHARS = 4;
+ private final int MAX_MONTH_CHARS = 3;
+ private final int MAX_DAY_CHARS = 2;
+
+ private final byte[][] MONTH_NAMES = new byte[][] { "jan".getBytes(), "feb".getBytes(), "mar".getBytes(),
+ "apr".getBytes(), "may".getBytes(), "jun".getBytes(), "jul".getBytes(), "aug".getBytes(), "sep".getBytes(),
+ "oct".getBytes(), "nov".getBytes(), "dec".getBytes() };
+
+ private final byte[] UTC_BYTEARRAY = "utc".getBytes();
+ private final byte[] GMT_BYTEARRAY = "gmt".getBytes();
+
+ private final byte[] AM_BYTEARRAY = "am".getBytes();
+ private final byte[] PM_BYTEARRAY = "pm".getBytes();
+
+ // Separators, for both time and date
+ private final char HYPHEN_CHAR = '-';
+ private final char COLON_CHAR = ':';
+ private final char SOLIDUS_CHAR = '/';
+ private final char PERIOD_CHAR = '.';
+ private final char COMMA_CHAR = ',';
+ private final char T_CHAR = 'T';
+
+ private final int MS_PER_MINUTE = 60 * 1000;
+ private final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
+
+ private final byte TO_LOWER_OFFSET = 'A' - 'a';
+
+ private final String[] TZ_IDS = TimeZone.getAvailableIDs();
+ private final byte[][] TIMEZONE_IDS = new byte[TZ_IDS.length][];
+ {
+ Arrays.sort(TZ_IDS);
+ for (int i = 0; i < TIMEZONE_IDS.length; i++) {
+ TIMEZONE_IDS[i] = TZ_IDS[i].getBytes();
+ }
+ }
+
+ private final int[] TIMEZONE_OFFSETS = new int[TIMEZONE_IDS.length];
+ {
+ for (int i = 0; i < TIMEZONE_IDS.length; i++) {
+ TIMEZONE_OFFSETS[i] = TimeZone.getTimeZone(TZ_IDS[i]).getRawOffset();
+ }
+ }
+
+ private static class DateTimeFormatUtilsHolder {
+ private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils();
+ }
+
+ public static DateTimeFormatUtils getInstance() {
+ return DateTimeFormatUtilsHolder.INSTANCE;
+ }
+
+ private DateTimeFormatUtils() {
+ }
+
+ private int parseFormatField(byte[] format, int formatStart, int formatLength, int formatPointer, char formatChar,
+ int maxAllowedFormatCharCopied) {
+
+ int formatCharCopies = 0;
+
+ formatPointer++;
+ formatCharCopies++;
+ while (formatPointer < formatLength && format[formatStart + formatPointer] == formatChar) {
+ formatPointer++;
+ formatCharCopies++;
+ }
+ if (formatCharCopies > maxAllowedFormatCharCopied) {
+ throw new IllegalStateException("The format string for " + formatChar
+ + " is too long: expected no more than " + maxAllowedFormatCharCopied + " but got "
+ + formatCharCopies);
+ }
+
+ return formatCharCopies;
+ }
+
+ public enum DateTimeParseMode {
+ DATE_ONLY,
+ TIME_ONLY,
+ DATETIME
+ }
+
+ private boolean byteArrayEqualToString(byte[] barray, int start, int length, byte[] str) {
+ boolean equal = true;
+ if (length == str.length) {
+ for (int i = 0; i < length; i++) {
+ if (toLower(barray[start + i]) != str[i]) {
+ equal = false;
+ }
+ }
+ } else {
+ equal = false;
+ }
+ return equal;
+ }
+
+ private Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
+ @Override
+ public int compare(byte[] o1, byte[] o2) {
+ int i = 0;
+ for (; i < o1.length && i < o2.length; i++) {
+ if (o1[i] != o2[i]) {
+ return o1[i] - o2[i];
+ }
+ }
+ if (i < o1.length) {
+ return -1;
+ } else if (i < o2.length) {
+ return 1;
+ }
+ return 0;
+ }
+ };
+
+ private int monthIDSearch(byte[] barray, int start, int length) {
+ for (int i = 0; i < MONTH_NAMES.length; i++) {
+ if (byteArrayEqualToString(barray, start, length, MONTH_NAMES[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private int binaryTimezoneIDSearch(byte[] barray, int start, int length) {
+ return Arrays.binarySearch(TIMEZONE_IDS, 0, TIMEZONE_IDS.length,
+ Arrays.copyOfRange(barray, start, start + length), byteArrayComparator);
+ }
+
+ private int indexOf(byte[] barray, int start, int length, char c) {
+ int i = 0;
+ for (; i < length; i++) {
+ if (barray[start + i] == c) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private byte toLower(byte b) {
+ if (b >= 'A' && b <= 'Z') {
+ return (byte) (b - TO_LOWER_OFFSET);
+ }
+ return b;
+ }
+
+ private byte toUpper(byte b) {
+ if (b >= 'a' && b <= 'z') {
+ return (byte) (b + TO_LOWER_OFFSET);
+ }
+ return b;
+ }
+
+ public long parseDateTime(byte[] data, int dataStart, int dataLength, byte[] format, int formatStart,
+ int formatLength, DateTimeParseMode parseMode) throws AsterixTemporalTypeParseException {
+ int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, ms = 0, timezone = 0;
+
+ boolean negativeYear = false;
+ int formatCharCopies = 0;
+
+ int dataStringPointer = 0, formatPointer = 0;
+
+ byte separatorChar = '\0';
+
+ DateTimeProcessState processState = DateTimeProcessState.INIT;
+
+ int pointerMove = 0;
+
+ while (dataStringPointer < dataLength && formatPointer < formatLength) {
+ formatCharCopies = 0;
+ switch (format[formatStart + formatPointer]) {
+ case YEAR_CHAR:
+ processState = DateTimeProcessState.YEAR;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, YEAR_CHAR,
+ MAX_YEAR_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MONTH_CHAR:
+ processState = DateTimeProcessState.MONTH;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MONTH_CHAR,
+ MAX_MONTH_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case DAY_CHAR:
+ processState = DateTimeProcessState.DAY;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, DAY_CHAR,
+ MAX_DAY_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case HOUR_CHAR:
+ processState = DateTimeProcessState.HOUR;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, HOUR_CHAR,
+ MAX_HOUR_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MINUTE_CHAR:
+ processState = DateTimeProcessState.MINUTE;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MINUTE_CHAR,
+ MAX_MINUTE_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case SECOND_CHAR:
+ processState = DateTimeProcessState.SECOND;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, SECOND_CHAR,
+ MAX_SECOND_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MILLISECOND_CHAR:
+ processState = DateTimeProcessState.MILLISECOND;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MILLISECOND_CHAR,
+ MAX_MILLISECOND_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+
+ case AMPM_CHAR:
+ processState = DateTimeProcessState.AMPM;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, AMPM_CHAR,
+ MAX_AMPM_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+
+ case TIMEZONE_CHAR:
+ processState = DateTimeProcessState.TIMEZONE;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, TIMEZONE_CHAR,
+ MAX_TIMEZONE_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case ' ':
+ case HYPHEN_CHAR:
+ case COLON_CHAR:
+ case SOLIDUS_CHAR:
+ case PERIOD_CHAR:
+ case COMMA_CHAR:
+ case T_CHAR:
+ // separator
+ separatorChar = format[formatStart + formatPointer];
+ processState = DateTimeProcessState.SEPARATOR;
+ formatPointer++;
+ formatCharCopies++;
+ while (formatPointer < formatLength && format[formatStart + formatPointer] == separatorChar) {
+ formatPointer++;
+ formatCharCopies++;
+ }
+ break;
+
+ default:
+ throw new AsterixTemporalTypeParseException("Unexpected date format string at "
+ + (formatStart + formatPointer) + ": " + format[formatStart + formatPointer]);
+ }
+
+ // check whether the process state is valid for the parse mode
+
+ switch (processState) {
+ case YEAR:
+ case MONTH:
+ case DAY:
+ if (parseMode == DateTimeParseMode.TIME_ONLY) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected date format string when parsing a time value");
+ }
+ break;
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case MILLISECOND:
+ case AMPM:
+ case TIMEZONE:
+ if (parseMode == DateTimeParseMode.DATE_ONLY) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected time format string when parsing a date value");
+ }
+ break;
+ default:
+ // do nothing
+ }
+
+ switch (processState) {
+ case INIT:
+ break;
+ case YEAR:
+ if (dataStringPointer < dataLength && data[dataStart + dataStringPointer] == HYPHEN_CHAR) {
+ negativeYear = true;
+ dataStringPointer++;
+ }
+ case DAY:
+ int maxAllowedFormatCharCopies = (processState == DateTimeProcessState.YEAR) ? 4 : 2;
+ int parsedValue = 0;
+
+ int processedFieldsCount = 0;
+ for (int i = 0; i < formatCharCopies; i++) {
+ if (data[dataStart + dataStringPointer] < '0' || data[dataStart + dataStringPointer] > '9') {
+ throw new AsterixTemporalTypeParseException("Unexpected char for year field at "
+ + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+ }
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ processedFieldsCount++;
+ }
+ // for more digits
+ while (processedFieldsCount < maxAllowedFormatCharCopies && dataStringPointer < dataLength
+ && data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9') {
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ processedFieldsCount++;
+ }
+ if (processState == DateTimeProcessState.YEAR) {
+ year = parsedValue;
+ if (negativeYear) {
+ year *= -1;
+ }
+ } else {
+ day = parsedValue;
+ }
+ break;
+ case MONTH:
+ if (formatCharCopies == 3) {
+ // the month is in the text format
+ int monthNameMatch = monthIDSearch(data, dataStart + dataStringPointer, 3);
+ if (monthNameMatch >= 0) {
+ month = monthNameMatch + 1;
+ dataStringPointer += 3;
+ } else {
+ throw new AsterixTemporalTypeParseException("Unrecognizable month string "
+ + (char) data[dataStart + dataStringPointer] + " "
+ + (char) data[dataStart + dataStringPointer + 1] + " "
+ + (char) data[dataStart + dataStringPointer + 2]);
+ }
+ } else {
+ int processedMonthFieldsCount = 0;
+ for (int i = 0; i < formatCharCopies; i++) {
+ if (data[dataStart + dataStringPointer] < '0' || data[dataStart + dataStringPointer] > '9') {
+ throw new AsterixTemporalTypeParseException("Unexpected char for month field at "
+ + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+ }
+ month = month * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ if (processedMonthFieldsCount++ > 2) {
+ throw new AsterixTemporalTypeParseException("Unexpected char for month field at "
+ + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+ }
+ }
+ // if there are more than 2 digits for the day string
+ while (processedMonthFieldsCount < 2 && dataStringPointer < dataLength
+ && data[dataStart + dataStringPointer] >= '0'
+ && data[dataStart + dataStringPointer] <= '9') {
+ month = month * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ processedMonthFieldsCount++;
+ }
+ }
+ break;
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case MILLISECOND:
+ int processFieldsCount = 0;
+ int expectedMaxCount = (processState == DateTimeProcessState.MILLISECOND) ? 3 : 2;
+ parsedValue = 0;
+ for (int i = 0; i < formatCharCopies; i++) {
+ if (data[dataStart + dataStringPointer] < '0' || data[dataStart + dataStringPointer] > '9') {
+ throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
+ + " field at " + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ }
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ if (processFieldsCount++ > expectedMaxCount) {
+ throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
+ + " field at " + dataStringPointer + ": " + data[dataStart + dataStringPointer]);
+ }
+ }
+ // if there are more than formatCharCopies digits for the hour string
+ while (processFieldsCount < expectedMaxCount && dataStringPointer < dataLength
+ && data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9') {
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
+ dataStringPointer++;
+ processFieldsCount++;
+ }
+ if (processState == DateTimeProcessState.HOUR) {
+ hour = parsedValue;
+ } else if (processState == DateTimeProcessState.MINUTE) {
+ min = parsedValue;
+ } else if (processState == DateTimeProcessState.SECOND) {
+ sec = parsedValue;
+ } else if (processState == DateTimeProcessState.MILLISECOND) {
+ ms = parsedValue;
+ for (int i = processFieldsCount; i < 3; i++) {
+ ms *= 10;
+ }
+ }
+ break;
+ case TIMEZONE:
+ if (data[dataStart + dataStringPointer] == 'Z'
+ && ((dataStringPointer + 1 >= dataLength) || (data[dataStart + dataStringPointer + 1] < 'A'
+ && data[dataStart + dataStringPointer + 1] > 'Z'
+ && data[dataStart + dataStringPointer + 1] < 'a' && data[dataStart
+ + dataStringPointer + 1] > 'z'))) {
+ // UTC as Z
+ timezone = 0;
+ dataStringPointer++;
+ } else if ((data[dataStart + dataStringPointer] == '+' || data[dataStart + dataStringPointer] == '-')
+ || (dataStringPointer + 3 < dataLength && (data[dataStart + dataStringPointer + 3] == '+' || data[dataStart
+ + dataStringPointer + 3] == '-'))) {
+ // UTC+ or GMT+ format
+ if (dataStringPointer + 3 < dataLength
+ && (byteArrayEqualToString(data, dataStart + dataStringPointer, 3, UTC_BYTEARRAY) || byteArrayEqualToString(
+ data, dataStart + dataStringPointer, 3, GMT_BYTEARRAY))) {
+ dataStringPointer += 3;
+ }
+ // parse timezone as +zz:zz or +zzzz
+ boolean negativeTimeZone = false;
+ if (data[dataStart + dataStringPointer] == '-') {
+ negativeTimeZone = true;
+ dataStringPointer++;
+ } else if (data[dataStart + dataStringPointer] == '+') {
+ dataStringPointer++;
+ } else {
+ throw new AsterixTemporalTypeParseException(
+ "Incorrect timezone hour field: expecting sign + or - but got: "
+ + data[dataStart + dataStringPointer]);
+ }
+ // timezone hours
+ for (int i = 0; i < 2; i++) {
+ if (data[dataStart + dataStringPointer + i] >= '0'
+ && data[dataStart + dataStringPointer + i] <= '9') {
+ timezone += (data[dataStart + dataStringPointer + i] - '0') * MS_PER_HOUR;
+ } else {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected character for timezone hour field at "
+ + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ }
+ }
+ dataStringPointer += 2;
+ // skip the ":" separator
+ if (data[dataStart + dataStringPointer] == ':') {
+ dataStringPointer++;
+ }
+ // timezone minutes
+ for (int i = 0; i < 2; i++) {
+ if (data[dataStart + dataStringPointer + i] >= '0'
+ && data[dataStart + dataStringPointer + i] <= '9') {
+ timezone += (data[dataStart + dataStringPointer + i] - '0') * MS_PER_MINUTE;
+ } else {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected character for timezone minute field at "
+ + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ }
+ }
+ dataStringPointer += 2;
+ if (!negativeTimeZone) {
+ timezone *= -1;
+ }
+ } else {
+ // do lookup from the zoneinfor database
+ int timezoneEndField = dataStringPointer;
+ while (timezoneEndField < dataLength
+ && ((data[dataStart + timezoneEndField] >= '0' && data[dataStart + timezoneEndField] <= '9')
+ || (data[dataStart + timezoneEndField] >= 'a' && data[dataStart
+ + timezoneEndField] <= 'z')
+ || (data[dataStart + timezoneEndField] >= 'A' && data[dataStart
+ + timezoneEndField] <= 'Z')
+ || data[dataStart + timezoneEndField] == '/' || data[dataStart
+ + timezoneEndField] == '_')) {
+ timezoneEndField++;
+ }
+ int searchIdx = binaryTimezoneIDSearch(data, dataStart + dataStringPointer, timezoneEndField
+ - dataStringPointer);
+ if (searchIdx >= 0) {
+ timezone = TIMEZONE_OFFSETS[searchIdx];
+ } else {
+ throw new AsterixTemporalTypeParseException("Unexpected timezone string: "
+ + new String(Arrays.copyOfRange(data, dataStart + dataStringPointer, dataStart
+ + dataStringPointer)));
+ }
+ dataStringPointer = timezoneEndField;
+ }
+ break;
+ case AMPM:
+ if (dataStringPointer + 1 < dataLength) {
+ if (hour > 12 || hour <= 0) {
+ throw new IllegalStateException("Hour " + hour + " cannot be a time for AM.");
+ }
+ if (byteArrayEqualToString(data, dataStart + dataStringPointer, 2, AM_BYTEARRAY)) {
+ // do nothing
+ } else if (byteArrayEqualToString(data, dataStart + dataStringPointer, 2, PM_BYTEARRAY)) {
+ hour += 12;
+ if (hour == 24) {
+ hour = 0;
+ }
+ } else {
+ throw new AsterixTemporalTypeParseException("Unexpected string for AM/PM marker "
+ + new String(Arrays.copyOfRange(data, dataStart + dataStringPointer, dataStart
+ + dataStringPointer + 2)));
+ }
+ dataStringPointer += 2;
+ } else {
+ throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
+ }
+ break;
+ case SEPARATOR:
+ if (separatorChar == '\0') {
+ throw new AsterixTemporalTypeParseException("Incorrect separator char in date string as "
+ + data[dataStart + dataStringPointer]);
+ }
+ for (int i = 0; i < formatCharCopies; i++) {
+ if (data[dataStart + dataStringPointer] != separatorChar) {
+ throw new AsterixTemporalTypeParseException("Expecting separator " + separatorChar
+ + " but got " + data[dataStart + dataStringPointer]);
+ }
+ dataStringPointer++;
+ }
+ break;
+ default:
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected time format information when parsing a date value");
+ }
+ }
+
+ if (dataStringPointer < dataLength) {
+ throw new AsterixTemporalTypeParseException(
+ "The given data string is not fully parsed by the given format string");
+ }
+
+ if (formatPointer < formatLength) {
+ throw new AsterixTemporalTypeParseException(
+ "The given format string is not fully used for the given format string");
+ }
+
+ if (parseMode == DateTimeParseMode.TIME_ONLY) {
+ return CAL.getChronon(hour, min, sec, ms, timezone);
+ }
+ return CAL.getChronon(year, month, day, hour, min, sec, ms, timezone);
+ }
+
+ public void printDateTime(long chronon, int timezone, byte[] format, int formatStart, int formatLength,
+ Appendable appender, DateTimeParseMode parseMode) throws HyracksDataException {
+ int year = CAL.getYear(chronon);
+ int month = CAL.getMonthOfYear(chronon, year);
+ int day = CAL.getDayOfMonthYear(chronon, year, month);
+ int hour = CAL.getHourOfDay(chronon);
+ int min = CAL.getMinOfHour(chronon);
+ int sec = CAL.getSecOfMin(chronon);
+ int ms = CAL.getMillisOfSec(chronon);
+
+ int formatCharCopies = 0;
+
+ int formatPointer = 0;
+
+ byte separatorChar = '\0';
+
+ DateTimeProcessState processState = DateTimeProcessState.INIT;
+
+ int pointerMove = 0;
+
+ boolean usePM = false;
+ if (indexOf(format, formatStart, formatLength, 'a') >= 0) {
+ if (hour >= 12) {
+ usePM = true;
+ hour -= 12;
+ }
+ if (hour == 0) {
+ hour = 12;
+ }
+ }
+
+ while (formatPointer < formatLength) {
+
+ formatCharCopies = 0;
+
+ switch (format[formatStart + formatPointer]) {
+ case YEAR_CHAR:
+ processState = DateTimeProcessState.YEAR;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, YEAR_CHAR,
+ MAX_YEAR_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MONTH_CHAR:
+ processState = DateTimeProcessState.MONTH;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MONTH_CHAR,
+ MAX_MONTH_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case DAY_CHAR:
+ processState = DateTimeProcessState.DAY;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, DAY_CHAR,
+ MAX_DAY_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case HOUR_CHAR:
+ processState = DateTimeProcessState.HOUR;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, HOUR_CHAR,
+ MAX_HOUR_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MINUTE_CHAR:
+ processState = DateTimeProcessState.MINUTE;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MINUTE_CHAR,
+ MAX_MINUTE_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case SECOND_CHAR:
+ processState = DateTimeProcessState.SECOND;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, SECOND_CHAR,
+ MAX_SECOND_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case MILLISECOND_CHAR:
+ processState = DateTimeProcessState.MILLISECOND;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, MILLISECOND_CHAR,
+ MAX_MILLISECOND_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+
+ case AMPM_CHAR:
+ processState = DateTimeProcessState.AMPM;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, AMPM_CHAR,
+ MAX_AMPM_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+
+ case TIMEZONE_CHAR:
+ processState = DateTimeProcessState.TIMEZONE;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, TIMEZONE_CHAR,
+ MAX_TIMEZONE_CHARS);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
+ case ' ':
+ case HYPHEN_CHAR:
+ case COLON_CHAR:
+ case SOLIDUS_CHAR:
+ case PERIOD_CHAR:
+ case COMMA_CHAR:
+ case T_CHAR:
+ // separator
+ separatorChar = format[formatStart + formatPointer];
+ processState = DateTimeProcessState.SEPARATOR;
+ formatPointer++;
+ formatCharCopies++;
+ while (formatPointer < formatLength && format[formatStart + formatPointer] == separatorChar) {
+ formatPointer++;
+ formatCharCopies++;
+ }
+ break;
+
+ default:
+ throw new HyracksDataException("Unexpected format string at " + (formatStart + formatPointer)
+ + ": " + format[formatStart + formatPointer]);
+ }
+
+ // check whether the process state is valid for the parse mode
+
+ switch (processState) {
+ case YEAR:
+ case MONTH:
+ case DAY:
+ if (parseMode == DateTimeParseMode.TIME_ONLY) {
+ throw new HyracksDataException("Unexpected date format string when parsing a time value");
+ }
+ break;
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ case MILLISECOND:
+ case AMPM:
+ case TIMEZONE:
+ if (parseMode == DateTimeParseMode.DATE_ONLY) {
+ throw new HyracksDataException("Unexpected time format string when parsing a date value");
+ }
+ break;
+ default:
+ // do nothing
+ }
+
+ try {
+ switch (processState) {
+ case INIT:
+ break;
+ case YEAR:
+ if (year < 0) {
+ appender.append('-');
+ year *= -1;
+ }
+ case MONTH:
+ if (processState == DateTimeProcessState.MONTH && formatCharCopies == 3) {
+ for (byte b : MONTH_NAMES[month - 1]) {
+ appender.append((char) toUpper(b));
+ }
+ break;
+ }
+ case DAY:
+ int val = 0;
+ if (processState == DateTimeProcessState.YEAR) {
+ val = year;
+ } else if (processState == DateTimeProcessState.MONTH) {
+ val = month;
+ } else {
+ val = day;
+ }
+ int valFieldCount = (int) Math.ceil(Math.log10(val));
+ if (val == 1 || val == 0) {
+ valFieldCount = 1;
+ }
+ for (int i = 0; i < formatCharCopies - valFieldCount; i++) {
+ appender.append('0');
+ }
+ appender.append(String.valueOf(val));
+ break;
+ case HOUR:
+ case MINUTE:
+ case SECOND:
+ val = 0;
+ if (processState == DateTimeProcessState.HOUR) {
+ val = hour;
+ } else if (processState == DateTimeProcessState.MINUTE) {
+ val = min;
+ } else if (processState == DateTimeProcessState.SECOND) {
+ val = sec;
+ }
+
+ if (val < 10) {
+ for (int i = 0; i < formatCharCopies - 1; i++) {
+ appender.append('0');
+ }
+ }
+ appender.append(String.valueOf(val));
+ break;
+ case MILLISECOND:
+ int msFieldCount = (int) Math.ceil(Math.log10(ms));
+ for (int i = 0; i < 3 - msFieldCount; i++) {
+ appender.append('0');
+ }
+ if (formatCharCopies < 3) {
+
+ if (formatCharCopies == 1) {
+ if (ms % 100 == 0) {
+ // the tailing two zeros can be removed
+ ms = ms / 100;
+ } else if (ms % 10 == 0) {
+ // the tailing one zero can be removed
+ ms = ms / 10;
+ }
+ } else {
+ if (ms % 10 == 0) {
+ // the tailing one zero can be removed
+ ms = ms / 10;
+ }
+ }
+
+ }
+ appender.append(String.valueOf(ms));
+ break;
+ case TIMEZONE:
+ if (timezone == 0) {
+ appender.append('Z');
+ break;
+ }
+ if (timezone < 0) {
+ appender.append('-');
+ timezone *= -1;
+ }
+ int timezoneField = timezone / MS_PER_HOUR;
+ if (timezoneField < 10) {
+ appender.append('0');
+ }
+ appender.append(String.valueOf(timezoneField));
+ timezoneField = timezone % MS_PER_HOUR / MS_PER_MINUTE;
+ if (timezoneField < 10) {
+ appender.append('0');
+ }
+ appender.append(String.valueOf(timezoneField));
+ break;
+ case AMPM:
+ if (usePM) {
+ appender.append("PM");
+ } else {
+ appender.append("AM");
+ }
+ break;
+ case SEPARATOR:
+ if (separatorChar == '\0') {
+ throw new HyracksDataException(
+ "Incorrect separator: separator char is not initialized properly!");
+ }
+ for (int i = 0; i < formatCharCopies; i++) {
+ appender.append((char) separatorChar);
+ }
+ break;
+ default:
+ throw new HyracksDataException("Unexpected time state when printing a date value");
+ }
+ } catch (IOException ex) {
+ throw new HyracksDataException(ex);
+ }
+ }
+ }
+}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java
index e9271e5..d760292 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DurationArithmeticOperations.java
@@ -26,17 +26,27 @@
* <a
* href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">"XML: adding durations to dateTimes"</a>.
* <p/>
- * The basic algorithm is like this: duration is applied to the time point as two separated fields: year-month field
- * and day-time field. Year-month field is applied firstly by reserving the correct day within the month's range
- * (for example add 1M to 03-31 will return 04-30). Then day-time field is applied.
+ * The basic algorithm is like this: duration is applied to the time point as two separated fields: year-month field and day-time field. Year-month field is applied firstly by reserving the correct day within the month's range (for example add 1M to 03-31 will return 04-30). Then day-time field is applied.
* <p/>
*
* @param pointChronon
+ * The time instance where the duration will be added, represented as the milliseconds since the anchored time (00:00:00 for time type, 1970-01-01T00:00:00Z for datetime and date types).
* @param yearMonthDuration
+ * The year-month-duration to be added
* @param dayTimeDuration
+ * The day-time-duration to be added
* @return
*/
- public static long addDuration(long pointChronon, int yearMonthDuration, long dayTimeDuration) {
+ public static long addDuration(long pointChronon, int yearMonthDuration, long dayTimeDuration, boolean isTimeOnly) {
+
+ if (isTimeOnly) {
+ int rtnChronon = (int) ((pointChronon + dayTimeDuration) % GregorianCalendarSystem.CHRONON_OF_DAY);
+ if (rtnChronon < 0) {
+ rtnChronon += GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
+
+ return rtnChronon;
+ }
int year = calSystem.getYear(pointChronon);
int month = calSystem.getMonthOfYear(pointChronon, year);
@@ -75,13 +85,4 @@
return calSystem.getChronon(year, month, day, hour, min, sec, ms, 0) + dayTimeDuration;
}
- public static int addDuration(int pointChronon, long dayTimeDuration) {
- int rtnChronon = (int) ((pointChronon + dayTimeDuration) % GregorianCalendarSystem.CHRONON_OF_DAY);
- if (rtnChronon < 0) {
- rtnChronon += GregorianCalendarSystem.CHRONON_OF_DAY;
- }
-
- return rtnChronon;
- }
-
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
index 5d27fb0..3be0858 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -164,15 +164,8 @@
* @return
*/
public boolean validateTimeZone(int timezone) {
- short tzMin = (short) ((timezone % 4) * 15);
- if (tzMin < -60 || tzMin >= 60) {
- return false;
- }
-
- short tzHr = (short) (timezone / 4);
-
- if (tzHr < -12 && tzHr > 14) {
+ if (timezone < -12 * CHRONON_OF_DAY || timezone > 14 * CHRONON_OF_DAY) {
return false;
}
@@ -211,8 +204,8 @@
*/
public long getChronon(int year, int month, int day, int hour, int min, int sec, int millis, int timezone) {
// Added milliseconds for all fields but month and day
- long chrononTime = chrononizeBeginningOfYear(year) + (hour - timezone / 4) * CHRONON_OF_HOUR
- + (min - (timezone % 4) * 15) * CHRONON_OF_MINUTE + sec * CHRONON_OF_SECOND + millis;
+ long chrononTime = chrononizeBeginningOfYear(year) + hour * CHRONON_OF_HOUR + min * CHRONON_OF_MINUTE + sec
+ * CHRONON_OF_SECOND + millis + timezone;
// Added milliseconds for days of the month.
chrononTime += (day - 1 + DAYS_SINCE_MONTH_BEGIN_ORDI[month - 1]) * CHRONON_OF_DAY;
@@ -237,13 +230,13 @@
*/
public int getChronon(int hour, int min, int sec, int millis, int timezone) {
// Added milliseconds for all fields but month and day
- long chrononTime = (hour - timezone / 4) * CHRONON_OF_HOUR + (min - (timezone % 4) * 15) * CHRONON_OF_MINUTE
- + sec * CHRONON_OF_SECOND + millis;
- return (int)chrononTime;
+ long chrononTime = hour * CHRONON_OF_HOUR + min * CHRONON_OF_MINUTE + sec * CHRONON_OF_SECOND + millis
+ + timezone;
+ return (int) chrononTime;
}
public long adjustChrononByTimezone(long chronon, int timezone) {
- return chronon + timezone / 4 * CHRONON_OF_HOUR + (timezone % 4) * 15 * CHRONON_OF_MINUTE;
+ return chronon - timezone;
}
public static int getChrononInDays(long chronon) {
@@ -330,12 +323,12 @@
if (timezone == 0) {
sbder.append("Z");
} else {
- short tzMin = (short) ((timezone % 4) * 15);
+ int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
if (tzMin < 0) {
tzMin = (short) (-1 * tzMin);
}
- short tzHr = (short) (timezone / 4);
- sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
+ int tzHr = (int) (timezone / CHRONON_OF_HOUR);
+ sbder.append((tzHr >= 0 ? "-" : "+")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
.append(":").append(String.format("%02d", tzMin));
}
}
@@ -391,12 +384,12 @@
if (timezone == 0) {
sbder.append("Z");
} else {
- short tzMin = (short) ((timezone % 4) * 15);
+ int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
if (tzMin < 0) {
tzMin = (short) (-1 * tzMin);
}
- short tzHr = (short) (timezone / 4);
- sbder.append((tzHr >= 0 ? "+" : "-")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
+ int tzHr = (int) (timezone / CHRONON_OF_HOUR);
+ sbder.append((tzHr >= 0 ? "-" : "+")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
.append(String.format("%02d", tzMin));
}
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index 42acae6..540530e 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -55,10 +55,11 @@
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedFieldAccessByNameResultType;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedGetItemResultType;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedLocalAvgTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedMinMaxAggTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericAddSubMulDivTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericRoundHalfToEven2TypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericUnaryFunctionTypeComputer;
-import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSumTypeComputer;
+import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedNumericAggTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedSwitchCaseComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NonTaggedUnaryMinusTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.NotNullTypeComputer;
@@ -172,8 +173,6 @@
FunctionConstants.ASTERIX_NS, "closed-record-constructor", FunctionIdentifier.VARARGS);
public final static FunctionIdentifier OPEN_RECORD_CONSTRUCTOR = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "open-record-constructor", FunctionIdentifier.VARARGS);
- public final static FunctionIdentifier RECORD_TYPE_CONSTRUCTOR = new FunctionIdentifier(
- FunctionConstants.ASTERIX_NS, "record-type-constructor", FunctionIdentifier.VARARGS);
public final static FunctionIdentifier FIELD_ACCESS_BY_INDEX = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"field-access-by-index", 2);
public final static FunctionIdentifier FIELD_ACCESS_BY_NAME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -522,32 +521,22 @@
FunctionConstants.ASTERIX_NS, "get-interval-start", 1);
public static final FunctionIdentifier ACCESSOR_TEMPORAL_INTERVAL_END = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "get-interval-end", 1);
+ public static final FunctionIdentifier INTERVAL_BIN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-bin", 3);
// Temporal functions
public static final FunctionIdentifier DATE_FROM_UNIX_TIME_IN_DAYS = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "date-from-unix-time-in-days", 1);
public static final FunctionIdentifier DATE_FROM_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"get-date-from-datetime", 1);
- public final static FunctionIdentifier ADD_DATE_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "add-date-duration", 2);
- public final static FunctionIdentifier SUBTRACT_DATE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "subtract-date", 2);
public final static FunctionIdentifier TIME_FROM_UNIX_TIME_IN_MS = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "time-from-unix-time-in-ms", 1);
public final static FunctionIdentifier TIME_FROM_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"get-time-from-datetime", 1);
- public final static FunctionIdentifier SUBTRACT_TIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "subtract-time", 2);
- public final static FunctionIdentifier ADD_TIME_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "add-time-duration", 2);
public final static FunctionIdentifier DATETIME_FROM_UNIX_TIME_IN_MS = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "datetime-from-unix-time-in-ms", 1);
public final static FunctionIdentifier DATETIME_FROM_DATE_TIME = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "datetime-from-date-time", 2);
- public final static FunctionIdentifier SUBTRACT_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "subtract-datetime", 2);
- public final static FunctionIdentifier ADD_DATETIME_DURATION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "add-datetime-duration", 2);
public final static FunctionIdentifier CALENDAR_DURATION_FROM_DATETIME = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "calendar-duration-from-datetime", 2);
public final static FunctionIdentifier CALENDAR_DURATION_FROM_DATE = new FunctionIdentifier(
@@ -556,6 +545,20 @@
FunctionConstants.ASTERIX_NS, "adjust-time-for-timezone", 2);
public final static FunctionIdentifier ADJUST_DATETIME_FOR_TIMEZONE = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "adjust-datetime-for-timezone", 2);
+ public final static FunctionIdentifier DAY_OF_WEEK = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "day-of-week");
+ public final static FunctionIdentifier PARSE_DATE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "parse-date", 2);
+ public final static FunctionIdentifier PARSE_TIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "parse-time", 2);
+ public final static FunctionIdentifier PARSE_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "parse-datetime", 2);
+ public final static FunctionIdentifier PRINT_DATE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "print-date", 2);
+ public final static FunctionIdentifier PRINT_TIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "print-time", 2);
+ public final static FunctionIdentifier PRINT_DATETIME = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "print-datetime", 2);
public final static FunctionIdentifier GET_POINT_X_COORDINATE_ACCESSOR = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "get-x", 1);
@@ -616,20 +619,20 @@
// and then, Asterix builtin functions
addPrivateFunction(NOT_NULL, NotNullTypeComputer.INSTANCE);
addPrivateFunction(ANY_COLLECTION_MEMBER, NonTaggedCollectionMemberResultType.INSTANCE);
- addPrivateFunction(AVG, OptionalADoubleTypeComputer.INSTANCE);
+ addFunction(AVG, OptionalADoubleTypeComputer.INSTANCE);
addFunction(BOOLEAN_CONSTRUCTOR, UnaryBooleanOrNullFunctionTypeComputer.INSTANCE);
- addFunction(CARET, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+ addPrivateFunction(CARET, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
addFunction(CIRCLE_CONSTRUCTOR, OptionalACircleTypeComputer.INSTANCE);
addPrivateFunction(CLOSED_RECORD_CONSTRUCTOR, ClosedRecordConstructorResultType.INSTANCE);
addPrivateFunction(CONCAT_NON_NULL, ConcatNonNullTypeComputer.INSTANCE);
addFunction(CONTAINS, ABooleanTypeComputer.INSTANCE);
- addPrivateFunction(COUNT, AInt64TypeComputer.INSTANCE);
- addFunction(COUNTHASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+ addFunction(COUNT, AInt64TypeComputer.INSTANCE);
+ addPrivateFunction(COUNTHASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
addPrivateFunction(COUNTHASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
addFunction(CREATE_CIRCLE, ACircleTypeComputer.INSTANCE);
addFunction(CREATE_LINE, ALineTypeComputer.INSTANCE);
- addFunction(CREATE_MBR, ADoubleTypeComputer.INSTANCE);
+ addPrivateFunction(CREATE_MBR, ADoubleTypeComputer.INSTANCE);
addFunction(CREATE_POINT, APointTypeComputer.INSTANCE);
addFunction(CREATE_POLYGON, APolygonTypeComputer.INSTANCE);
addFunction(CREATE_RECTANGLE, ARectangleTypeComputer.INSTANCE);
@@ -664,7 +667,7 @@
addPrivateFunction(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
addPrivateFunction(GRAM_TOKENS, OrderedListOfAStringTypeComputer.INSTANCE);
addFunction(GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
- addFunction(HASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
+ addPrivateFunction(HASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
addPrivateFunction(HASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE);
addPrivateFunction(INDEX_SEARCH, new IResultTypeComputer() {
@@ -685,18 +688,18 @@
addPrivateFunction(LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
addPrivateFunction(MAKE_FIELD_INDEX_HANDLE, null); // TODO
addPrivateFunction(MAKE_FIELD_NAME_HANDLE, null); // TODO
- addPrivateFunction(MAX, NonTaggedSumTypeComputer.INSTANCE);
- addPrivateFunction(LOCAL_MAX, NonTaggedSumTypeComputer.INSTANCE);
- addPrivateFunction(MIN, NonTaggedSumTypeComputer.INSTANCE);
- addPrivateFunction(LOCAL_MIN, NonTaggedSumTypeComputer.INSTANCE);
+ addFunction(MAX, NonTaggedMinMaxAggTypeComputer.INSTANCE);
+ addPrivateFunction(LOCAL_MAX, NonTaggedMinMaxAggTypeComputer.INSTANCE);
+ addFunction(MIN, NonTaggedMinMaxAggTypeComputer.INSTANCE);
+ addPrivateFunction(LOCAL_MIN, NonTaggedMinMaxAggTypeComputer.INSTANCE);
addPrivateFunction(NON_EMPTY_STREAM, ABooleanTypeComputer.INSTANCE);
addFunction(NULL_CONSTRUCTOR, ANullTypeComputer.INSTANCE);
- addFunction(NUMERIC_UNARY_MINUS, NonTaggedUnaryMinusTypeComputer.INSTANCE);
- addFunction(NUMERIC_SUBTRACT, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
- addFunction(NUMERIC_MULTIPLY, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
- addFunction(NUMERIC_DIVIDE, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
- addFunction(NUMERIC_MOD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
- addFunction(NUMERIC_IDIV, AInt32TypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_UNARY_MINUS, NonTaggedUnaryMinusTypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_SUBTRACT, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_MULTIPLY, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_DIVIDE, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_MOD, NonTaggedNumericAddSubMulDivTypeComputer.INSTANCE);
+ addPrivateFunction(NUMERIC_IDIV, AInt32TypeComputer.INSTANCE);
addFunction(NUMERIC_ABS, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
addFunction(NUMERIC_CEILING, NonTaggedNumericUnaryFunctionTypeComputer.INSTANCE);
@@ -730,7 +733,6 @@
addPrivateFunction(PREFIX_LEN_JACCARD, AInt32TypeComputer.INSTANCE);
addFunction(RANGE, AInt32TypeComputer.INSTANCE);
addFunction(RECTANGLE_CONSTRUCTOR, OptionalARectangleTypeComputer.INSTANCE);
- // add(RECORD_TYPE_CONSTRUCTOR, null);
addFunction(SCALAR_AVG, ScalarVersionOfAggregateResultType.INSTANCE);
addFunction(SCALAR_COUNT, AInt64TypeComputer.INSTANCE);
@@ -744,8 +746,8 @@
addPrivateFunction(SERIAL_COUNT, AInt64TypeComputer.INSTANCE);
addPrivateFunction(SERIAL_GLOBAL_AVG, OptionalADoubleTypeComputer.INSTANCE);
addPrivateFunction(SERIAL_LOCAL_AVG, NonTaggedLocalAvgTypeComputer.INSTANCE);
- addPrivateFunction(SERIAL_SUM, NonTaggedSumTypeComputer.INSTANCE);
- addPrivateFunction(SERIAL_LOCAL_SUM, NonTaggedSumTypeComputer.INSTANCE);
+ addPrivateFunction(SERIAL_SUM, NonTaggedNumericAggTypeComputer.INSTANCE);
+ addPrivateFunction(SERIAL_LOCAL_SUM, NonTaggedNumericAggTypeComputer.INSTANCE);
addFunction(SIMILARITY_JACCARD, AFloatTypeComputer.INSTANCE);
addFunction(SIMILARITY_JACCARD_CHECK, OrderedListOfAnyTypeComputer.INSTANCE);
addPrivateFunction(SIMILARITY_JACCARD_SORTED, AFloatTypeComputer.INSTANCE);
@@ -801,8 +803,8 @@
}
});
addFunction(SUBSTRING, SubstringTypeComputer.INSTANCE);
- addPrivateFunction(SUM, NonTaggedSumTypeComputer.INSTANCE);
- addPrivateFunction(LOCAL_SUM, NonTaggedSumTypeComputer.INSTANCE);
+ addFunction(SUM, NonTaggedNumericAggTypeComputer.INSTANCE);
+ addPrivateFunction(LOCAL_SUM, NonTaggedNumericAggTypeComputer.INSTANCE);
addFunction(SWITCH_CASE, NonTaggedSwitchCaseComputer.INSTANCE);
addPrivateFunction(REG_EXP, ABooleanTypeComputer.INSTANCE);
addFunction(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE);
@@ -811,7 +813,7 @@
addFunction(TID, AInt32TypeComputer.INSTANCE);
addFunction(TIME_CONSTRUCTOR, OptionalATimeTypeComputer.INSTANCE);
- addFunction(TYPE_OF, null); // TODO
+ addPrivateFunction(TYPE_OF, null);
addPrivateFunction(UNORDERED_LIST_CONSTRUCTOR, UnorderedListConstructorResultType.INSTANCE);
addFunction(WORD_TOKENS, new IResultTypeComputer() {
@Override
@@ -835,16 +837,10 @@
// temporal functions
addFunction(DATE_FROM_UNIX_TIME_IN_DAYS, OptionalADateTypeComputer.INSTANCE);
addFunction(DATE_FROM_DATETIME, OptionalADateTypeComputer.INSTANCE);
- addFunction(ADD_DATE_DURATION, OptionalADateTypeComputer.INSTANCE);
- addFunction(SUBTRACT_DATE, OptionalADurationTypeComputer.INSTANCE);
addFunction(TIME_FROM_UNIX_TIME_IN_MS, OptionalATimeTypeComputer.INSTANCE);
addFunction(TIME_FROM_DATETIME, OptionalATimeTypeComputer.INSTANCE);
- addFunction(SUBTRACT_TIME, OptionalADurationTypeComputer.INSTANCE);
- addFunction(ADD_TIME_DURATION, OptionalATimeTypeComputer.INSTANCE);
addFunction(DATETIME_FROM_DATE_TIME, OptionalADateTimeTypeComputer.INSTANCE);
addFunction(DATETIME_FROM_UNIX_TIME_IN_MS, OptionalADateTimeTypeComputer.INSTANCE);
- addFunction(SUBTRACT_DATETIME, OptionalADurationTypeComputer.INSTANCE);
- addFunction(ADD_DATETIME_DURATION, OptionalADateTimeTypeComputer.INSTANCE);
addFunction(CALENDAR_DURATION_FROM_DATETIME, OptionalADurationTypeComputer.INSTANCE);
addFunction(CALENDAR_DURATION_FROM_DATE, OptionalADurationTypeComputer.INSTANCE);
addFunction(ADJUST_DATETIME_FOR_TIMEZONE, OptionalAStringTypeComputer.INSTANCE);
@@ -876,6 +872,14 @@
addFunction(MILLISECONDS_FROM_DAY_TIME_DURATION, OptionalAInt64TypeComputer.INSTANCE);
addFunction(GET_DAY_TIME_DURATION, OptionalADayTimeDurationTypeComputer.INSTANCE);
addFunction(GET_YEAR_MONTH_DURATION, OptionalAYearMonthDurationTypeComputer.INSTANCE);
+ addFunction(INTERVAL_BIN, OptionalAIntervalTypeComputer.INSTANCE);
+ addFunction(DAY_OF_WEEK, OptionalAInt32TypeComputer.INSTANCE);
+ addFunction(PARSE_DATE, OptionalADateTypeComputer.INSTANCE);
+ addFunction(PARSE_TIME, OptionalATimeTypeComputer.INSTANCE);
+ addFunction(PARSE_DATETIME, OptionalADateTimeTypeComputer.INSTANCE);
+ addFunction(PRINT_DATE, OptionalAStringTypeComputer.INSTANCE);
+ addFunction(PRINT_TIME, OptionalAStringTypeComputer.INSTANCE);
+ addFunction(PRINT_DATETIME, OptionalAStringTypeComputer.INSTANCE);
// interval constructors
addFunction(INTERVAL_CONSTRUCTOR_DATE, OptionalAIntervalTypeComputer.INSTANCE);
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedMinMaxAggTypeComputer.java
similarity index 88%
copy from asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java
copy to asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedMinMaxAggTypeComputer.java
index 2437da4..a6c39b6 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedMinMaxAggTypeComputer.java
@@ -30,13 +30,12 @@
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-public class NonTaggedSumTypeComputer implements IResultTypeComputer {
+public class NonTaggedMinMaxAggTypeComputer implements IResultTypeComputer {
+ private static final String errMsg = "Aggregator is not implemented for ";
- private static final String errMsg = "Sum aggregator is not implemented for ";
+ public static final NonTaggedMinMaxAggTypeComputer INSTANCE = new NonTaggedMinMaxAggTypeComputer();
- public static final NonTaggedSumTypeComputer INSTANCE = new NonTaggedSumTypeComputer();
-
- private NonTaggedSumTypeComputer() {
+ private NonTaggedMinMaxAggTypeComputer() {
}
@Override
@@ -79,6 +78,9 @@
case INT8:
unionList.add(BuiltinType.AINT8);
break;
+ case STRING:
+ unionList.add(BuiltinType.ASTRING);
+ break;
case ANY:
return BuiltinType.ANY;
default: {
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAddSubMulDivTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAddSubMulDivTypeComputer.java
index 6c46f3a..154ce65 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAddSubMulDivTypeComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAddSubMulDivTypeComputer.java
@@ -231,6 +231,111 @@
}
}
}
+ case DATE: {
+ switch (tag2) {
+ case DATE:
+ unionList.add(BuiltinType.ADURATION);
+ break;
+ case YEARMONTHDURATION:
+ case DAYTIMEDURATION:
+ case DURATION:
+ unionList.add(BuiltinType.ADATE);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
+ case TIME: {
+ switch (tag2) {
+ case TIME:
+ unionList.add(BuiltinType.ADURATION);
+ break;
+ case YEARMONTHDURATION:
+ case DAYTIMEDURATION:
+ case DURATION:
+ unionList.add(BuiltinType.ATIME);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
+ case DATETIME: {
+ switch (tag2) {
+ case DATETIME:
+ unionList.add(BuiltinType.ADURATION);
+ break;
+ case YEARMONTHDURATION:
+ case DAYTIMEDURATION:
+ case DURATION:
+ unionList.add(BuiltinType.ADATETIME);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
+ case DURATION: {
+ switch(tag2){
+ case DATE:
+ unionList.add(BuiltinType.ADATE);
+ break;
+ case TIME:
+ unionList.add(BuiltinType.ATIME);
+ break;
+ case DATETIME:
+ unionList.add(BuiltinType.ADATETIME);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
+ case YEARMONTHDURATION: {
+ switch(tag2){
+ case DATE:
+ unionList.add(BuiltinType.ADATE);
+ break;
+ case TIME:
+ unionList.add(BuiltinType.ATIME);
+ break;
+ case DATETIME:
+ unionList.add(BuiltinType.ADATETIME);
+ break;
+ case YEARMONTHDURATION:
+ unionList.add(BuiltinType.AYEARMONTHDURATION);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
+ case DAYTIMEDURATION: {
+ switch(tag2){
+ case DATE:
+ unionList.add(BuiltinType.ADATE);
+ break;
+ case TIME:
+ unionList.add(BuiltinType.ATIME);
+ break;
+ case DATETIME:
+ unionList.add(BuiltinType.ADATETIME);
+ break;
+ case DAYTIMEDURATION:
+ unionList.add(BuiltinType.ADAYTIMEDURATION);
+ break;
+ default: {
+ throw new NotImplementedException(errMsg + tag2);
+ }
+ }
+ break;
+ }
default: {
throw new NotImplementedException(errMsg + tag1);
}
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAggTypeComputer.java
similarity index 91%
rename from asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java
rename to asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAggTypeComputer.java
index 2437da4..7582785 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedSumTypeComputer.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/typecomputer/impl/NonTaggedNumericAggTypeComputer.java
@@ -30,13 +30,13 @@
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-public class NonTaggedSumTypeComputer implements IResultTypeComputer {
+public class NonTaggedNumericAggTypeComputer implements IResultTypeComputer {
- private static final String errMsg = "Sum aggregator is not implemented for ";
+ private static final String errMsg = "Aggregator is not implemented for ";
- public static final NonTaggedSumTypeComputer INSTANCE = new NonTaggedSumTypeComputer();
+ public static final NonTaggedNumericAggTypeComputer INSTANCE = new NonTaggedNumericAggTypeComputer();
- private NonTaggedSumTypeComputer() {
+ private NonTaggedNumericAggTypeComputer() {
}
@Override
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
index 03c4140..5070210 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateConstructorDescriptor.java
@@ -83,6 +83,13 @@
int stringLength = (serString[1] & 0xff << 8) + (serString[2] & 0xff << 0);
+ // the string to be parsed should be at least 8 characters: YYYYMMDD
+ if (stringLength < 8) {
+ throw new AlgebricksException(errorMessage
+ + ": the string length should be at least 8 (YYYYMMDD) but it is "
+ + stringLength);
+ }
+
int startOffset = 3;
while (serString[startOffset] == ' ') {
startOffset++;
@@ -111,8 +118,6 @@
}
} catch (IOException e1) {
throw new AlgebricksException(errorMessage);
- } catch (Exception e2) {
- throw new AlgebricksException(e2);
}
}
};
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
index 986b158..880de44 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ADateTimeConstructorDescriptor.java
@@ -82,7 +82,12 @@
if (serString[0] == SER_STRING_TYPE_TAG) {
int stringLength = (serString[1] & 0xff << 8) + (serString[2] & 0xff << 0);
-
+ // the string to be parsed should be at least 14 characters: YYYYMMDDhhmmss
+ if (stringLength < 14) {
+ throw new AlgebricksException(errorMessage
+ + ": the string length should be at least 14 (YYYYMMDDhhmmss) but it is "
+ + stringLength);
+ }
// +1 if it is negative (-)
short timeOffset = (short) ((serString[3] == '-') ? 1 : 0);
@@ -109,8 +114,6 @@
}
} catch (IOException e1) {
throw new AlgebricksException(errorMessage);
- } catch (Exception e2) {
- throw new AlgebricksException(e2);
}
}
};
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
index eb33cc4..9b17c90 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
@@ -122,7 +122,7 @@
if (argOut1.getByteArray()[0] == SER_DURATION_TYPE_TAG) {
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1),
- ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+ ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1), false);
} else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
// duration
int stringLength = (argOut1.getByteArray()[1] & 0xff << 8)
@@ -131,7 +131,7 @@
ADurationParserFactory.parseDuration(argOut1.getByteArray(), 3, stringLength,
aDuration, ADurationParseOption.All);
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
- aDuration.getMonths(), aDuration.getMilliseconds());
+ aDuration.getMonths(), aDuration.getMilliseconds(), false);
} else {
throw new AlgebricksException(FID.getName()
+ ": expects NULL/STRING/DURATION for the second argument, but got "
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
index f7b4cdd..ce4681a 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromDateTimeConstructorDescriptor.java
@@ -134,7 +134,7 @@
if (argOut1.getByteArray()[0] == SER_DURATION_TYPE_TAG) {
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1),
- ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+ ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1), false);
} else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
// duration
@@ -145,7 +145,7 @@
aDuration, ADurationParseOption.All);
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart,
- aDuration.getMonths(), aDuration.getMilliseconds());
+ aDuration.getMonths(), aDuration.getMilliseconds(), false);
} else {
throw new AlgebricksException(FID.getName()
+ ": expects NULL/STRING/DURATION for the second argument but got "
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
index 3f8e5a8..d4168e1 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/AIntervalStartFromTimeConstructorDescriptor.java
@@ -130,7 +130,7 @@
}
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart, 0,
- ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1));
+ ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1), false);
} else if (argOut1.getByteArray()[0] == SER_STRING_TYPE_TAG) {
// duration
@@ -147,7 +147,7 @@
}
intervalEnd = DurationArithmeticOperations.addDuration(intervalStart, 0,
- aDuration.getMilliseconds());
+ aDuration.getMilliseconds(), false);
} else {
throw new AlgebricksException("Wrong format for interval constructor from dates.");
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
index 1b3e7f6..d344d1c 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/constructors/ATimeConstructorDescriptor.java
@@ -83,6 +83,13 @@
int stringLength = (serString[1] & 0xff << 8) + (serString[2] & 0xff << 0);
+ // the string to be parsed should be at least 6 characters: hhmmss
+ if (stringLength < 6) {
+ throw new AlgebricksException(errorMessage
+ + ": the string length should be at least 6 (hhmmss) but it is "
+ + stringLength);
+ }
+
int chrononTimeInMs = ATimeParserFactory.parseTimePart(serString, 3, stringLength);
if (chrononTimeInMs < 0) {
@@ -99,8 +106,6 @@
}
} catch (IOException e1) {
throw new AlgebricksException(errorMessage);
- } catch (Exception e2) {
- throw new AlgebricksException(e2);
}
}
};
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
index 379b934..84b9a32 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
@@ -16,20 +16,31 @@
import java.io.DataOutput;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADayTimeDurationSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AMutableDate;
+import edu.uci.ics.asterix.om.base.AMutableDateTime;
import edu.uci.ics.asterix.om.base.AMutableDouble;
+import edu.uci.ics.asterix.om.base.AMutableDuration;
import edu.uci.ics.asterix.om.base.AMutableFloat;
import edu.uci.ics.asterix.om.base.AMutableInt16;
import edu.uci.ics.asterix.om.base.AMutableInt32;
import edu.uci.ics.asterix.om.base.AMutableInt64;
import edu.uci.ics.asterix.om.base.AMutableInt8;
+import edu.uci.ics.asterix.om.base.AMutableTime;
import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.asterix.om.types.EnumDeserializer;
@@ -51,6 +62,29 @@
abstract protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException;
+ /**
+ * abstract method for arithmetic operation between a time instance (date/time/datetime)
+ * and a duration (duration/year-month-duration/day-time-duration)
+ *
+ * @param chronon
+ * @param yearMonth
+ * @param dayTime
+ * @return
+ * @throws HyracksDataException
+ */
+ abstract protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException;
+
+ /**
+ * abstract method for arithmetic operation between two time instances (date/time/datetime)
+ *
+ * @param chronon0
+ * @param chronon1
+ * @return
+ * @throws HyracksDataException
+ */
+ abstract protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException;
+
@Override
public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
return new ICopyEvaluatorFactory() {
@@ -62,9 +96,10 @@
return new ICopyEvaluator() {
private DataOutput out = output.getDataOutput();
// one temp. buffer re-used by both children
- private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
- private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut);
- private ICopyEvaluator evalRight = args[1].createEvaluator(argOut);
+ private ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
+ private ICopyEvaluator evalLeft = args[0].createEvaluator(argOut0);
+ private ICopyEvaluator evalRight = args[1].createEvaluator(argOut1);
private double[] operandsFloating = new double[args.length];
private long[] operandsInteger = new long[args.length];
private int resultType;
@@ -81,6 +116,12 @@
protected AMutableInt32 aInt32 = new AMutableInt32(0);
protected AMutableInt16 aInt16 = new AMutableInt16((short) 0);
protected AMutableInt8 aInt8 = new AMutableInt8((byte) 0);
+
+ protected AMutableDuration aDuration = new AMutableDuration(0, 0);
+ protected AMutableDate aDate = new AMutableDate(0);
+ protected AMutableTime aTime = new AMutableTime(0);
+ protected AMutableDateTime aDatetime = new AMutableDateTime(0);
+
private ATypeTag typeTag;
@SuppressWarnings("rawtypes")
private ISerializerDeserializer serde;
@@ -93,11 +134,16 @@
resultType = 0;
int currentType = 0;
for (int i = 0; i < args.length; i++) {
- argOut.reset();
- if (i == 0)
+ ArrayBackedValueStorage argOut;
+ if (i == 0) {
+ argOut0.reset();
evalLeft.evaluate(tuple);
- else
+ argOut = argOut0;
+ } else {
+ argOut1.reset();
evalRight.evaluate(tuple);
+ argOut = argOut1;
+ }
typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut.getByteArray()[0]);
switch (typeTag) {
case INT8: {
@@ -144,6 +190,14 @@
argOut.getByteArray(), 1);
break;
}
+ case DATE:
+ case TIME:
+ case DATETIME:
+ case DURATION:
+ case YEARMONTHDURATION:
+ case DAYTIMEDURATION:
+ evaluateTemporalArthmeticOperation(typeTag, tuple);
+ return;
case NULL: {
serde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ANULL);
@@ -237,9 +291,236 @@
throw new AlgebricksException(hde);
}
}
+
+ @SuppressWarnings("unchecked")
+ private void evaluateTemporalArthmeticOperation(ATypeTag leftType, IFrameTupleReference tuple)
+ throws HyracksDataException, AlgebricksException {
+ argOut1.reset();
+ evalRight.evaluate(tuple);
+ ATypeTag rightType = EnumDeserializer.ATYPETAGDESERIALIZER
+ .deserialize(argOut1.getByteArray()[0]);
+
+ if (leftType == ATypeTag.NULL || rightType == ATypeTag.NULL) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ serde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (rightType == leftType) {
+
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADURATION);
+
+ long leftChronon = 0, rightChronon = 0, dayTime = 0;
+
+ int yearMonth = 0;
+
+ switch (leftType) {
+ case DATE:
+ leftChronon = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ rightChronon = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+
+ break;
+ case TIME:
+ leftChronon = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ rightChronon = ATimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+ break;
+ case DATETIME:
+ leftChronon = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ rightChronon = ADateTimeSerializerDeserializer
+ .getChronon(argOut1.getByteArray(), 1);
+ break;
+ case YEARMONTHDURATION:
+ yearMonth = (int) evaluateTimeInstanceArithmetic(
+ AYearMonthDurationSerializerDeserializer.getYearMonth(
+ argOut0.getByteArray(), 1),
+ AYearMonthDurationSerializerDeserializer.getYearMonth(
+ argOut1.getByteArray(), 1));
+ break;
+ case DAYTIMEDURATION:
+ leftChronon = ADayTimeDurationSerializerDeserializer.getDayTime(
+ argOut0.getByteArray(), 1);
+ rightChronon = ADayTimeDurationSerializerDeserializer.getDayTime(
+ argOut1.getByteArray(), 1);
+ break;
+ default:
+ throw new NotImplementedException();
+ }
+
+ dayTime = evaluateTimeInstanceArithmetic(leftChronon, rightChronon);
+
+ aDuration.setValue(yearMonth, dayTime);
+
+ serde.serialize(aDuration, out);
+
+ } else {
+ long chronon = 0, dayTime = 0;
+ int yearMonth = 0;
+ ATypeTag resultType = null;
+
+ boolean isTimeOnly = false;
+
+ switch (leftType) {
+ case TIME:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ATIME);
+ chronon = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ isTimeOnly = true;
+ resultType = ATypeTag.TIME;
+ switch (rightType) {
+ case DAYTIMEDURATION:
+ dayTime = ADayTimeDurationSerializerDeserializer.getDayTime(
+ argOut1.getByteArray(), 1);
+ break;
+ case DURATION:
+ dayTime = ADurationSerializerDeserializer.getDayTime(
+ argOut1.getByteArray(), 1);
+ yearMonth = ADurationSerializerDeserializer.getYearMonth(
+ argOut1.getByteArray(), 1);
+ break;
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a "
+ + rightType + " value is not supported.");
+ }
+ break;
+ case DATE:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATE);
+ resultType = ATypeTag.DATE;
+ chronon = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ case DATETIME:
+ if (leftType == ATypeTag.DATETIME) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATETIME);
+ resultType = ATypeTag.DATETIME;
+ chronon = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ }
+ switch (rightType) {
+ case DURATION:
+ yearMonth = ADurationSerializerDeserializer.getYearMonth(
+ argOut1.getByteArray(), 1);
+ dayTime = ADurationSerializerDeserializer.getDayTime(
+ argOut1.getByteArray(), 1);
+ break;
+ case YEARMONTHDURATION:
+ yearMonth = AYearMonthDurationSerializerDeserializer.getYearMonth(
+ argOut1.getByteArray(), 1);
+ break;
+ case DAYTIMEDURATION:
+ dayTime = ADayTimeDurationSerializerDeserializer.getDayTime(
+ argOut1.getByteArray(), 1);
+ break;
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a "
+ + rightType + " value is not supported.");
+ }
+ break;
+ case YEARMONTHDURATION:
+ yearMonth = AYearMonthDurationSerializerDeserializer.getYearMonth(
+ argOut0.getByteArray(), 1);
+ switch (rightType) {
+ case DATETIME:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATETIME);
+ resultType = ATypeTag.DATETIME;
+ chronon = ADateTimeSerializerDeserializer.getChronon(
+ argOut1.getByteArray(), 1);
+ break;
+ case DATE:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATE);
+ resultType = ATypeTag.DATE;
+ chronon = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ break;
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a "
+ + rightType + " value is not supported.");
+ }
+ break;
+ case DURATION:
+ yearMonth = ADurationSerializerDeserializer.getYearMonth(argOut0.getByteArray(), 1);
+ dayTime = ADurationSerializerDeserializer.getDayTime(argOut0.getByteArray(), 1);
+ case DAYTIMEDURATION:
+ if (leftType == ATypeTag.DAYTIMEDURATION) {
+ dayTime = ADayTimeDurationSerializerDeserializer.getDayTime(
+ argOut0.getByteArray(), 1);
+ }
+ switch (rightType) {
+ case DATETIME:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATETIME);
+ resultType = ATypeTag.DATETIME;
+ chronon = ADateTimeSerializerDeserializer.getChronon(
+ argOut1.getByteArray(), 1);
+ break;
+ case DATE:
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATE);
+ resultType = ATypeTag.DATE;
+ chronon = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ break;
+ case TIME:
+ if (yearMonth == 0) {
+ serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ATIME);
+ resultType = ATypeTag.TIME;
+ chronon = ATimeSerializerDeserializer.getChronon(
+ argOut1.getByteArray(), 1);
+ isTimeOnly = true;
+ break;
+ }
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a "
+ + rightType + " value is not supported.");
+ }
+ break;
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a " + rightType
+ + " value is not supported.");
+ }
+
+ chronon = evaluateTimeDurationArithmetic(chronon, yearMonth, dayTime, isTimeOnly);
+
+ switch (resultType) {
+ case DATE:
+
+ if (chronon < 0 && chronon % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
+ chronon = chronon / GregorianCalendarSystem.CHRONON_OF_DAY - 1;
+ } else {
+ chronon = chronon / GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
+ aDate.setValue((int) chronon);
+ serde.serialize(aDate, out);
+ break;
+ case TIME:
+ aTime.setValue((int) chronon);
+ serde.serialize(aTime, out);
+ break;
+ case DATETIME:
+ aDatetime.setValue(chronon);
+ serde.serialize(aDatetime, out);
+ break;
+ default:
+ throw new NotImplementedException(getIdentifier().getName()
+ + ": arithmetic operation between " + leftType + " and a " + rightType
+ + " value is not supported.");
+
+ }
+ }
+ }
};
}
};
}
-
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
index bb63d27..7cd96fa 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
@@ -14,6 +14,7 @@
*/
package edu.uci.ics.asterix.runtime.evaluators.functions;
+import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -49,4 +50,15 @@
protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException {
return lhs + rhs;
}
+
+ @Override
+ protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException {
+ return DurationArithmeticOperations.addDuration(chronon, yearMonth, dayTime, isTimeOnly);
+ }
+
+ @Override
+ protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+ throw new HyracksDataException("Undefined addition operation between two time instances.");
+ }
}
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
index 208c454..502c013 100644
--- 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
@@ -17,6 +17,7 @@
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.common.exceptions.NotImplementedException;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -61,4 +62,15 @@
return AsterixBuiltinFunctions.CARET;
}
+ @Override
+ protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException {
+ throw new NotImplementedException("Caret operation is not defined for temporal types");
+ }
+
+ @Override
+ protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+ throw new NotImplementedException("Caret operation is not defined for temporal types");
+ }
+
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
index 9b3b0e9..069007c 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
@@ -17,6 +17,7 @@
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.common.exceptions.NotImplementedException;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -45,4 +46,15 @@
protected double evaluateDouble(double lhs, double rhs) {
return lhs / rhs;
}
+
+ @Override
+ protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException {
+ throw new NotImplementedException("Divide operation is not defined for temporal types");
+ }
+
+ @Override
+ protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+ throw new NotImplementedException("Divide operation is not defined for temporal types");
+ }
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
index a95c693..92f15b4 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
@@ -17,6 +17,7 @@
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.common.exceptions.NotImplementedException;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -57,4 +58,15 @@
return lhs * rhs;
}
+
+ @Override
+ protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException {
+ throw new NotImplementedException("Multiply operation is not defined for temporal types");
+ }
+
+ @Override
+ protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+ throw new NotImplementedException("Multiply operation is not defined for temporal types");
+ }
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubDescriptor.java
new file mode 100644
index 0000000..84c308f
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/NumericSubDescriptor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.base.temporal.DurationArithmeticOperations;
+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 NumericSubDescriptor extends AbstractNumericArithmeticEval {
+
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new NumericSubDescriptor();
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return AsterixBuiltinFunctions.NUMERIC_SUBTRACT;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateInteger(long, long)
+ */
+ @Override
+ protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException {
+ long res = lhs - rhs;
+ if (lhs > 0) {
+ if (rhs < 0 && res < 0)
+ throw new HyracksDataException("Overflow adding " + lhs + " + " + rhs);
+ } else if (rhs > 0 && res > 0)
+ throw new HyracksDataException("Underflow adding " + lhs + " + " + rhs);
+ return res;
+ }
+
+ /* (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 lhs - rhs;
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateTimeDurationArithmetic(long, int, long, boolean)
+ */
+ @Override
+ protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly)
+ throws HyracksDataException {
+ return DurationArithmeticOperations.addDuration(chronon, -1 * yearMonth, -1 * dayTime, isTimeOnly);
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateTimeInstanceArithmetic(long, long)
+ */
+ @Override
+ protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException {
+ return evaluateInteger(chronon0, chronon1);
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDateDurationDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDateDurationDescriptor.java
deleted file mode 100644
index eccee9d..0000000
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDateDurationDescriptor.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.temporal;
-
-import java.io.DataOutput;
-
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
-import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import edu.uci.ics.asterix.om.base.ADate;
-import edu.uci.ics.asterix.om.base.AMutableDate;
-import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
-import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
-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.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.BuiltinType;
-import edu.uci.ics.asterix.om.types.EnumDeserializer;
-import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
-import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-public class AddDateDurationDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.ADD_DATE_DURATION;
-
- // allowed input types
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
- private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
- private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
-
- public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new AddDateDurationDescriptor();
- }
- };
-
- @Override
- public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
- return new ICopyEvaluatorFactory() {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
- return new ICopyEvaluator() {
-
- private DataOutput out = output.getDataOutput();
- private ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
- private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
- private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
- private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
-
- // possible output types
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ANULL);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ADATE);
-
- private AMutableDate aDate = new AMutableDate(0);
-
- @Override
- public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
- argOut0.reset();
- eval0.evaluate(tuple);
- argOut1.reset();
- eval1.evaluate(tuple);
-
- try {
- if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
- || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
- nullSerde.serialize(ANull.NULL, out);
- return;
- }
-
- if (argOut0.getByteArray()[0] != SER_DATE_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type DATE/NULL for parameter 0 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
- }
-
- if (argOut1.getByteArray()[0] != SER_DURATION_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type DURATION/NULL for parameter 1 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
- }
-
- // get duration fields: yearMonth field and dayTime field
- int yearMonth = ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1);
- long dayTime = ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1);
-
- // get date fields
- long datetimeChronon = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
- * GregorianCalendarSystem.CHRONON_OF_DAY;
-
- datetimeChronon = DurationArithmeticOperations.addDuration(datetimeChronon, yearMonth,
- dayTime);
-
- int dateChrononInDays = (int) (datetimeChronon / GregorianCalendarSystem.CHRONON_OF_DAY);
- if (dateChrononInDays < 0 && datetimeChronon % GregorianCalendarSystem.CHRONON_OF_DAY != 0) {
- dateChrononInDays -= 1;
- }
-
- aDate.setValue(dateChrononInDays);
-
- dateSerde.serialize(aDate, out);
-
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
- }
- }
- };
- }
- };
- }
-
- @Override
- public FunctionIdentifier getIdentifier() {
- return FID;
- }
-
-}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDatetimeDurationDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDatetimeDurationDescriptor.java
deleted file mode 100644
index 0037b38..0000000
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddDatetimeDurationDescriptor.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.temporal;
-
-import java.io.DataOutput;
-
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
-import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import edu.uci.ics.asterix.om.base.ADateTime;
-import edu.uci.ics.asterix.om.base.AMutableDateTime;
-import edu.uci.ics.asterix.om.base.ANull;
-import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
-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.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.BuiltinType;
-import edu.uci.ics.asterix.om.types.EnumDeserializer;
-import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
-import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
-import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
-import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
-import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
-import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
-import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-public class AddDatetimeDurationDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.ADD_DATETIME_DURATION;
-
- // allowed input types
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
- private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
- private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
-
- public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new AddDatetimeDurationDescriptor();
- }
- };
-
- /* (non-Javadoc)
- * @see edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor#createEvaluatorFactory(edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory[])
- */
- @Override
- public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
- return new ICopyEvaluatorFactory() {
-
- private static final long serialVersionUID = 1L;
-
- @Override
- public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
- return new ICopyEvaluator() {
-
- private DataOutput out = output.getDataOutput();
- private ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
- private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
- private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
- private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
-
- // possible output types
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ANULL);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ADATETIME);
-
- private AMutableDateTime aDatetime = new AMutableDateTime(0);
-
- @Override
- public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
- argOut0.reset();
- eval0.evaluate(tuple);
- argOut1.reset();
- eval1.evaluate(tuple);
-
- try {
- if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
- || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
- nullSerde.serialize(ANull.NULL, out);
- return;
- }
-
- if (argOut0.getByteArray()[0] != SER_DATETIME_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type DATETIME/NULL for parameter 0 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
- }
-
- if (argOut1.getByteArray()[0] != SER_DURATION_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type DURATION/NULL for parameter 1 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
- }
-
- // get duration fields: yearMonth field and dayTime field
- int yearMonth = ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1);
- long dayTime = ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1);
-
- // get date fields
- long datetimeChronon = ADateTimeSerializerDeserializer
- .getChronon(argOut0.getByteArray(), 1);
-
- datetimeChronon = DurationArithmeticOperations.addDuration(datetimeChronon, yearMonth,
- dayTime);
-
- aDatetime.setValue(datetimeChronon);
-
- datetimeSerde.serialize(aDatetime, out);
-
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
- }
- }
- };
- }
- };
- }
-
- /* (non-Javadoc)
- * @see edu.uci.ics.asterix.om.functions.IFunctionDescriptor#getIdentifier()
- */
- @Override
- public FunctionIdentifier getIdentifier() {
- return FID;
- }
-
-}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDuartionFromDateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDuartionFromDateDescriptor.java
index 9e603ed..9ef3f58 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDuartionFromDateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDuartionFromDateDescriptor.java
@@ -127,7 +127,7 @@
* GregorianCalendarSystem.CHRONON_OF_DAY;
long endingTimePoint = DurationArithmeticOperations.addDuration(startingTimePoint,
- yearMonthDurationInMonths, dayTimeDurationInMs);
+ yearMonthDurationInMonths, dayTimeDurationInMs, false);
if (startingTimePoint == endingTimePoint) {
aDuration.setValue(0, 0);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDurationFromDateTimeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDurationFromDateTimeDescriptor.java
index 10cc1c0..da5f195 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDurationFromDateTimeDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/CalendarDurationFromDateTimeDescriptor.java
@@ -141,7 +141,7 @@
1);
long endingTimePoint = DurationArithmeticOperations.addDuration(startingTimePoint,
- yearMonthDurationInMonths, dayTimeDurationInMs);
+ yearMonthDurationInMonths, dayTimeDurationInMs, false);
if (startingTimePoint == endingTimePoint) {
aDuration.setValue(0, 0);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
new file mode 100644
index 0000000..11ba264
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
@@ -0,0 +1,150 @@
+/*
+ * 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.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+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.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.DAY_OF_WEEK;
+
+ // allowed input types
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
+ private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
+
+ // Fixed week day anchor: Thursday, 1 January 1970
+ private final static int ANCHOR_WEEKDAY = 4;
+
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new DayOfWeekDescriptor();
+ }
+
+ };
+
+ @Override
+ public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+ return new ICopyEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new ICopyEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private ICopyEvaluator eval = args[0].createEvaluator(argOut);
+
+ // possible returning types
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+ try {
+ if (argOut.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ } else {
+ int daysSinceAnchor;
+ int reminder = 0;
+ if (argOut.getByteArray()[0] == SER_DATETIME_TYPE_TAG) {
+ daysSinceAnchor = (int) (ADateTimeSerializerDeserializer.getChronon(
+ argOut.getByteArray(), 1) / GregorianCalendarSystem.CHRONON_OF_DAY);
+ reminder = (int) (ADateTimeSerializerDeserializer.getChronon(argOut.getByteArray(),
+ 1) % GregorianCalendarSystem.CHRONON_OF_DAY);
+ } else if (argOut.getByteArray()[0] == SER_DATE_TYPE_TAG) {
+ daysSinceAnchor = ADateSerializerDeserializer.getChronon(argOut.getByteArray(), 1);
+ } else {
+ throw new AlgebricksException(
+ FID.getName()
+ + ": expects input type DATETIME/DATE/NULL but got "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getByteArray()[0]));
+ }
+
+ // adjust the day before 1970-01-01
+ if (daysSinceAnchor < 0 && reminder != 0) {
+ daysSinceAnchor -= 1;
+ }
+
+ // compute the weekday (0-based, and 0 = Sunday). Adjustment is needed as the anchor day is Thursday
+ int weekday = (daysSinceAnchor + ANCHOR_WEEKDAY) % 7;
+
+ // handle the negative weekday
+ if (weekday < 0) {
+ weekday += 7;
+ }
+
+ // convert from 0-based to 1-based (so 7 = Sunday)
+ if (weekday == 0) {
+ weekday = 7;
+ }
+
+ aInt32.setValue(weekday);
+
+ int32Serde.serialize(aInt32, out);
+ }
+ } catch (HyracksDataException hex) {
+ throw new AlgebricksException(hex);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java
new file mode 100644
index 0000000..98c1d16
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java
@@ -0,0 +1,282 @@
+/*
+ * 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.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADayTimeDurationSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInterval;
+import edu.uci.ics.asterix.om.base.AMutableInterval;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+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.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class IntervalBinDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new IntervalBinDescriptor();
+ }
+ };
+
+ @Override
+ public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+ return new ICopyEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new ICopyEvaluator() {
+
+ private final DataOutput out = output.getDataOutput();
+
+ private final ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
+ private final ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
+ private final ArrayBackedValueStorage argOut2 = new ArrayBackedValueStorage();
+
+ private final ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
+ private final ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
+ private final ICopyEvaluator eval2 = args[2].createEvaluator(argOut2);
+
+ private final AMutableInterval aInterval = new AMutableInterval(0, 0, (byte) -1);
+
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINTERVAL);
+
+ private final GregorianCalendarSystem GREG_CAL = GregorianCalendarSystem.getInstance();
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut0.reset();
+ eval0.evaluate(tuple);
+
+ ATypeTag type0 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]);
+
+ long chrononToBin = 0;
+ switch (type0) {
+ case DATE:
+ chrononToBin = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ break;
+ case TIME:
+ chrononToBin = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ break;
+ case DATETIME:
+ chrononToBin = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ break;
+ case NULL:
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return;
+ default:
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": the first argument should be DATE/TIME/DATETIME/NULL but got " + type0);
+
+ }
+
+ argOut1.reset();
+ eval1.evaluate(tuple);
+
+ ATypeTag type1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]);
+
+ if (type0 != type1) {
+ if (type0 != ATypeTag.NULL && type1 != ATypeTag.NULL)
+ throw new AlgebricksException(getIdentifier().getName() + ": expecting " + type0
+ + " for the second argument but got " + type1);
+ }
+
+ long chrononToStart = 0;
+ switch (type1) {
+ case DATE:
+ chrononToStart = ADateSerializerDeserializer.getChronon(argOut1.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ break;
+ case TIME:
+ chrononToStart = ATimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+ break;
+ case DATETIME:
+ chrononToStart = ADateTimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+ break;
+ case NULL:
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return;
+ default:
+ throw new AlgebricksException(getIdentifier().getName() + ": expecting " + type0
+ + " for the second argument but got " + type1);
+ }
+
+ argOut2.reset();
+ eval2.evaluate(tuple);
+
+ ATypeTag type2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut2.getByteArray()[0]);
+
+ int yearMonth = 0;
+ long dayTime = 0;
+ long binIndex, binStartChronon, binEndChronon;
+ switch (type2) {
+ case YEARMONTHDURATION:
+
+ yearMonth = AYearMonthDurationSerializerDeserializer.getYearMonth(
+ argOut2.getByteArray(), 1);
+
+ int yearStart = GREG_CAL.getYear(chrononToStart);
+ int monthStart = GREG_CAL.getMonthOfYear(chrononToStart, yearStart);
+ int yearToBin = GREG_CAL.getYear(chrononToBin);
+ int monthToBin = GREG_CAL.getMonthOfYear(chrononToBin, yearToBin);
+
+ int totalMonths = (yearToBin - yearStart) * 12 + (monthToBin - monthStart);
+
+ binIndex = totalMonths / yearMonth
+ + ((totalMonths < 0 && totalMonths % yearMonth != 0) ? -1 : 0);
+
+ if (binIndex > Integer.MAX_VALUE) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": Overflowing time value to be binned!");
+ }
+
+ if (binIndex < Integer.MIN_VALUE) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": Underflowing time value to be binned!");
+ }
+
+ break;
+
+ case DAYTIMEDURATION:
+ dayTime = ADayTimeDurationSerializerDeserializer.getDayTime(argOut2.getByteArray(), 1);
+
+ long totalChronon = chrononToBin - chrononToStart;
+
+ binIndex = totalChronon / dayTime
+ + ((totalChronon < 0 && totalChronon % dayTime != 0) ? -1 : 0);
+
+ break;
+ case NULL:
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return;
+ default:
+ throw new AlgebricksException(
+ getIdentifier().getName()
+ + ": expecting YEARMONTHDURATION/DAYTIMEDURATION for the thrid argument but got "
+ + type2);
+ }
+
+ switch (type0) {
+ case DATE:
+ binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * (int) binIndex, dayTime * binIndex, false);
+ binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * ((int) binIndex + 1), dayTime * (binIndex + 1), false);
+
+ binStartChronon = binStartChronon
+ / GregorianCalendarSystem.CHRONON_OF_DAY
+ + ((binStartChronon < 0 && binStartChronon
+ % GregorianCalendarSystem.CHRONON_OF_DAY != 0) ? -1 : 0);
+ binEndChronon = binEndChronon
+ / GregorianCalendarSystem.CHRONON_OF_DAY
+ + ((binEndChronon < 0 && binEndChronon % GregorianCalendarSystem.CHRONON_OF_DAY != 0) ? -1
+ : 0);
+ break;
+ case TIME:
+ if (yearMonth != 0) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": cannot create year-month bin for a time value");
+ }
+ binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * (int) binIndex, dayTime * binIndex, true);
+ binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * ((int) binIndex + 1), dayTime * (binIndex + 1), true);
+ break;
+ case DATETIME:
+ binStartChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * (int) binIndex, dayTime * binIndex, false);
+ binEndChronon = DurationArithmeticOperations.addDuration(chrononToStart, yearMonth
+ * ((int) binIndex + 1), dayTime * (binIndex + 1), false);
+ break;
+ case NULL:
+ try {
+ nullSerde.serialize(ANull.NULL, out);
+ } catch (HyracksDataException e) {
+ throw new AlgebricksException(e);
+ }
+ return;
+ default:
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": the first argument should be DATE/TIME/DATETIME/NULL but got " + type0);
+
+ }
+ aInterval.setValue(binStartChronon, binEndChronon, type0.serialize());
+ try {
+ intervalSerde.serialize(aInterval, out);
+ return;
+ } catch (HyracksDataException ex) {
+ throw new AlgebricksException(ex);
+ }
+
+ }
+ };
+ }
+
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+ */
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return AsterixBuiltinFunctions.INTERVAL_BIN;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java
index 9a66d45..d2f2b07 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/MonthsFromYearMonthDurationDescriptor.java
@@ -16,7 +16,7 @@
import java.io.DataOutput;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.AInt32;
import edu.uci.ics.asterix.om.base.AMutableInt32;
@@ -96,7 +96,7 @@
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
}
- aInt32.setValue(AYearMonthDurationerializerDeserializer.getYearMonth(
+ aInt32.setValue(AYearMonthDurationSerializerDeserializer.getYearMonth(
argOut0.getByteArray(), 1));
int32Serde.serialize(aInt32, out);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
new file mode 100644
index 0000000..782d424
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
@@ -0,0 +1,168 @@
+/*
+ * 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.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADate;
+import edu.uci.ics.asterix.om.base.AMutableDate;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
+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.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * <b>|(bar)</b> is a special separator used to separate different formatting options.
+ * Multiple format strings can be used by separating them using <b>|(bar)</b>, and the parsing will be successful only when the format string has the <b>exact</b> match with the given data string. This means that a time string like <it>08:23:12 AM</it> will not be valid for the format string <it>h:m:s</it> as there is no AM/PM format character in the format string.
+ * <p/>
+ */
+public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PARSE_DATE;
+
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
+
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ParseDateDescriptor();
+ }
+ };
+
+ @Override
+ public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+ return new ICopyEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new ICopyEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
+ private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
+ private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADate> dateSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATE);
+
+ private AMutableDate aDate = new AMutableDate(0);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut0.reset();
+ eval0.evaluate(tuple);
+ argOut1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
+ || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (argOut0.getByteArray()[0] != SER_STRING_TYPE_TAG
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects two strings but got ("
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ + ", "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
+ + ")");
+ }
+ int length0 = (argOut0.getByteArray()[1] & 0xff << 8)
+ + (argOut0.getByteArray()[2] & 0xff << 0);
+ int length1 = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ long chronon = 0;
+
+ int formatStart = 3;
+ int formatLength = 0;
+ boolean processSuccessfully = false;
+ while (!processSuccessfully && formatStart < 3 + length1) {
+ // search for "|"
+ formatLength = 0;
+ for (; formatStart + formatLength < 3 + length1; formatLength++) {
+ if (argOut1.getByteArray()[formatStart + formatLength] == '|') {
+ break;
+ }
+ }
+ try {
+ chronon = DT_UTILS.parseDateTime(argOut0.getByteArray(), 3, length0,
+ argOut1.getByteArray(), formatStart, formatLength,
+ DateTimeParseMode.DATE_ONLY);
+ } catch (AsterixTemporalTypeParseException ex) {
+ formatStart += formatLength + 1;
+ continue;
+ }
+ processSuccessfully = true;
+ }
+
+ if (!processSuccessfully) {
+ throw new HyracksDataException(
+ "parse-date: Failed to match with any given format string!");
+ }
+
+ aDate.setValue((int) (chronon / GregorianCalendarSystem.CHRONON_OF_DAY));
+ dateSerde.serialize(aDate, out);
+
+ } catch (HyracksDataException ex) {
+ throw new AlgebricksException(ex);
+ }
+ }
+ };
+ }
+
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+ */
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
new file mode 100644
index 0000000..89cfbe5
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
@@ -0,0 +1,162 @@
+/*
+ * 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.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADateTime;
+import edu.uci.ics.asterix.om.base.AMutableDateTime;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
+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.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PARSE_DATETIME;
+
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
+
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ParseDateTimeDescriptor();
+ }
+ };
+
+ @Override
+ public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+ return new ICopyEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new ICopyEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut0 = new ArrayBackedValueStorage();
+ private ArrayBackedValueStorage argOut1 = new ArrayBackedValueStorage();
+ private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
+ private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ADATETIME);
+
+ private AMutableDateTime aDateTime = new AMutableDateTime(0);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut0.reset();
+ eval0.evaluate(tuple);
+ argOut1.reset();
+ eval1.evaluate(tuple);
+
+ try {
+ if (argOut0.getByteArray()[0] == SER_NULL_TYPE_TAG
+ || argOut1.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ return;
+ }
+
+ if (argOut0.getByteArray()[0] != SER_STRING_TYPE_TAG
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects two strings but got ("
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ + ", "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
+ + ")");
+ }
+ int length0 = (argOut0.getByteArray()[1] & 0xff << 8)
+ + (argOut0.getByteArray()[2] & 0xff << 0);
+ int length1 = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ long chronon = 0;
+
+ int formatStart = 3;
+ int formatLength = 0;
+ boolean processSuccessfully = false;
+ while (!processSuccessfully && formatStart < 3 + length1) {
+ // search for "|"
+ formatLength = 0;
+ for (; formatStart + formatLength < 3 + length1; formatLength++) {
+ if (argOut1.getByteArray()[formatStart + formatLength] == '|') {
+ break;
+ }
+ }
+ try {
+ chronon = DT_UTILS.parseDateTime(argOut0.getByteArray(), 3, length0,
+ argOut1.getByteArray(), formatStart, formatLength,
+ DateTimeParseMode.DATETIME);
+ } catch (AsterixTemporalTypeParseException ex) {
+ formatStart += formatLength + 1;
+ continue;
+ }
+ processSuccessfully = true;
+ }
+
+ if (!processSuccessfully) {
+ throw new HyracksDataException(
+ "parse-date: Failed to match with any given format string!");
+ }
+
+ aDateTime.setValue(chronon);
+ datetimeSerde.serialize(aDateTime, out);
+
+ } catch (HyracksDataException ex) {
+ throw new AlgebricksException(ex);
+ }
+ }
+ };
+ }
+
+ };
+ }
+
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+ */
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddTimeDurationDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
similarity index 60%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddTimeDurationDescriptor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
index ca86379..8ee76e7 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/AddTimeDurationDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
@@ -16,13 +16,13 @@
import java.io.DataOutput;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADurationSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.AMutableTime;
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.base.ATime;
-import edu.uci.ics.asterix.om.base.temporal.DurationArithmeticOperations;
+import edu.uci.ics.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -40,27 +40,23 @@
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-public class AddTimeDurationDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.ADD_TIME_DURATION;
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PARSE_TIME;
- // allowed input types
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
- private final static byte SER_TIME_TYPE_TAG = ATypeTag.TIME.serialize();
- private final static byte SER_DURATION_TYPE_TAG = ATypeTag.DURATION.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
- return new AddTimeDurationDescriptor();
+ return new ParseTimeDescriptor();
}
};
- /* (non-Javadoc)
- * @see edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor#createEvaluatorFactory(edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory[])
- */
@Override
public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
return new ICopyEvaluatorFactory() {
@@ -77,7 +73,6 @@
private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
- // possible output types
@SuppressWarnings("unchecked")
private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ANULL);
@@ -101,49 +96,63 @@
return;
}
- if (argOut0.getByteArray()[0] != SER_TIME_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type TIME/NULL for parameter 0 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0]));
+ if (argOut0.getByteArray()[0] != SER_STRING_TYPE_TAG
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects two strings but got ("
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ + ", "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
+ + ")");
+ }
+ int length0 = (argOut0.getByteArray()[1] & 0xff << 8)
+ + (argOut0.getByteArray()[2] & 0xff << 0);
+ int length1 = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ long chronon = 0;
+
+ int formatStart = 3;
+ int formatLength = 0;
+ boolean processSuccessfully = false;
+ while (!processSuccessfully && formatStart < 3 + length1) {
+ // search for "|"
+ formatLength = 0;
+ for (; formatStart + formatLength < 3 + length1; formatLength++) {
+ if (argOut1.getByteArray()[formatStart + formatLength] == '|') {
+ break;
+ }
+ }
+ try {
+ chronon = DT_UTILS.parseDateTime(argOut0.getByteArray(), 3, length0,
+ argOut1.getByteArray(), formatStart, formatLength,
+ DateTimeParseMode.TIME_ONLY);
+ } catch (AsterixTemporalTypeParseException ex) {
+ formatStart += formatLength + 1;
+ continue;
+ }
+ processSuccessfully = true;
}
- if (argOut1.getByteArray()[0] != SER_DURATION_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects type DURATION/NULL for parameter 1 but got "
- + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0]));
+ if (!processSuccessfully) {
+ throw new HyracksDataException(
+ "parse-date: Failed to match with any given format string!");
}
- // get duration fields: yearMonth field and dayTime field
- int yearMonth = ADurationSerializerDeserializer.getYearMonth(argOut1.getByteArray(), 1);
-
- // cannot add a year-month duration to a time value
- if (yearMonth != 0) {
- throw new AlgebricksException(FID.getName()
- + ": a TIME value cannot be added by a DURATION value with year-month field.");
- }
-
- long dayTime = ADurationSerializerDeserializer.getDayTime(argOut1.getByteArray(), 1);
-
- // get time fields
- int timeChronon = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
-
- timeChronon = DurationArithmeticOperations.addDuration(timeChronon, dayTime);
-
- aTime.setValue(timeChronon);
-
+ aTime.setValue((int) chronon);
timeSerde.serialize(aTime, out);
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
+ } catch (HyracksDataException ex) {
+ throw new AlgebricksException(ex);
}
}
};
}
+
};
}
/* (non-Javadoc)
- * @see edu.uci.ics.asterix.om.functions.IFunctionDescriptor#getIdentifier()
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
*/
@Override
public FunctionIdentifier getIdentifier() {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDateDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
similarity index 71%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDateDescriptor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
index eaaf900..a48e44c 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDateDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
@@ -15,13 +15,14 @@
package edu.uci.ics.asterix.runtime.evaluators.functions.temporal;
import java.io.DataOutput;
+import java.io.IOException;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import edu.uci.ics.asterix.om.base.ADuration;
-import edu.uci.ics.asterix.om.base.AMutableDuration;
import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -34,25 +35,25 @@
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-public class SubtractDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class PrintDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.SUBTRACT_DATE;
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PRINT_DATE;
- // allowed input types
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
- return new SubtractDateDescriptor();
+ return new PrintDateDescriptor();
}
};
@@ -72,15 +73,11 @@
private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
- // possible output types
@SuppressWarnings("unchecked")
private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ANULL);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ADURATION);
- private AMutableDuration aDuration = new AMutableDuration(0, 0);
+ private StringBuilder sbder = new StringBuilder();
@Override
public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
@@ -97,31 +94,39 @@
}
if (argOut0.getByteArray()[0] != SER_DATE_TYPE_TAG
- && argOut1.getByteArray()[0] != SER_DATE_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects input type (DATE/NULL, DATE/NULL) but got ("
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects (DATE, STRING) but got ("
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ ", "
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
- + ").");
+ + ")");
}
- long durationChronon = (ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1) - ADateSerializerDeserializer
- .getChronon(argOut1.getByteArray(), 1)) * GregorianCalendarSystem.CHRONON_OF_DAY;
+ long chronon = ADateSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
+ int formatLength = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ sbder.delete(0, sbder.length());
+ DT_UTILS.printDateTime(chronon, 0, argOut1.getByteArray(), 3, formatLength, sbder,
+ DateTimeParseMode.DATE_ONLY);
- aDuration.setValue(0, durationChronon);
+ out.writeByte(ATypeTag.STRING.serialize());
+ out.writeUTF(sbder.toString());
- durationSerde.serialize(aDuration, out);
-
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
+ } catch (IOException ex) {
+ throw new AlgebricksException(ex);
}
}
};
}
+
};
}
+ /* (non-Javadoc)
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
+ */
@Override
public FunctionIdentifier getIdentifier() {
return FID;
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDatetimeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
similarity index 71%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDatetimeDescriptor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
index b43892d..9c507e3 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractDatetimeDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
@@ -15,12 +15,13 @@
package edu.uci.ics.asterix.runtime.evaluators.functions.temporal;
import java.io.DataOutput;
+import java.io.IOException;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import edu.uci.ics.asterix.om.base.ADuration;
-import edu.uci.ics.asterix.om.base.AMutableDuration;
import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -33,31 +34,28 @@
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-public class SubtractDatetimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class PrintDateTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.SUBTRACT_DATETIME;
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PRINT_DATETIME;
- // allowed input types
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
- return new SubtractDatetimeDescriptor();
+ return new PrintDateTimeDescriptor();
}
};
- /* (non-Javadoc)
- * @see edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor#createEvaluatorFactory(edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory[])
- */
@Override
public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
return new ICopyEvaluatorFactory() {
@@ -74,15 +72,11 @@
private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
- // possible output types
@SuppressWarnings("unchecked")
private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ANULL);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ADURATION);
- private AMutableDuration aDuration = new AMutableDuration(0, 0);
+ private StringBuilder sbder = new StringBuilder();
@Override
public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
@@ -99,34 +93,36 @@
}
if (argOut0.getByteArray()[0] != SER_DATETIME_TYPE_TAG
- && argOut1.getByteArray()[0] != SER_DATETIME_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects input type (DATETIME/NULL, DATETIME/NULL) but got ("
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects (DATETIME, STRING) but got ("
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ ", "
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
- + ").");
+ + ")");
}
+ long chronon = ADateTimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ int formatLength = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ sbder.delete(0, sbder.length());
+ DT_UTILS.printDateTime(chronon, 0, argOut1.getByteArray(), 3, formatLength, sbder,
+ DateTimeParseMode.DATETIME);
- long durationChronon = ADateTimeSerializerDeserializer
- .getChronon(argOut0.getByteArray(), 1)
- - ADateTimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+ out.writeByte(ATypeTag.STRING.serialize());
+ out.writeUTF(sbder.toString());
- aDuration.setValue(0, durationChronon);
-
- durationSerde.serialize(aDuration, out);
-
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
+ } catch (IOException ex) {
+ throw new AlgebricksException(ex);
}
}
};
}
+
};
}
/* (non-Javadoc)
- * @see edu.uci.ics.asterix.om.functions.IFunctionDescriptor#getIdentifier()
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
*/
@Override
public FunctionIdentifier getIdentifier() {
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractTimeDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
similarity index 71%
rename from asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractTimeDescriptor.java
rename to asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
index 24edca6..7d589a4 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/SubtractTimeDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
@@ -15,12 +15,13 @@
package edu.uci.ics.asterix.runtime.evaluators.functions.temporal;
import java.io.DataOutput;
+import java.io.IOException;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
-import edu.uci.ics.asterix.om.base.ADuration;
-import edu.uci.ics.asterix.om.base.AMutableDuration;
import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils;
+import edu.uci.ics.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
@@ -33,31 +34,28 @@
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
-import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-public class SubtractTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+public class PrintTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
- private final static long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = AsterixBuiltinFunctions.SUBTRACT_TIME;
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.PRINT_TIME;
- // allowed input types
- private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
private final static byte SER_TIME_TYPE_TAG = ATypeTag.TIME.serialize();
+ private final static byte SER_STRING_TYPE_TAG = ATypeTag.STRING.serialize();
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
- return new SubtractTimeDescriptor();
+ return new PrintTimeDescriptor();
}
};
- /* (non-Javadoc)
- * @see edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor#createEvaluatorFactory(edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory[])
- */
@Override
public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
return new ICopyEvaluatorFactory() {
@@ -74,15 +72,11 @@
private ICopyEvaluator eval0 = args[0].createEvaluator(argOut0);
private ICopyEvaluator eval1 = args[1].createEvaluator(argOut1);
- // possible output types
@SuppressWarnings("unchecked")
private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.ANULL);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADuration> durationSerde = AqlSerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.ADURATION);
- private AMutableDuration aDuration = new AMutableDuration(0, 0);
+ private StringBuilder sbder = new StringBuilder();
@Override
public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
@@ -99,33 +93,37 @@
}
if (argOut0.getByteArray()[0] != SER_TIME_TYPE_TAG
- && argOut1.getByteArray()[0] != SER_TIME_TYPE_TAG) {
- throw new AlgebricksException(FID.getName()
- + ": expects input type (TIME/NULL, TIME/NULL) but got ("
+ || argOut1.getByteArray()[0] != SER_STRING_TYPE_TAG) {
+ throw new AlgebricksException(getIdentifier().getName()
+ + ": expects (TIME, STRING) but got ("
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut0.getByteArray()[0])
+ ", "
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut1.getByteArray()[0])
- + ").");
+ + ")");
}
- int durationChronon = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1)
- - ATimeSerializerDeserializer.getChronon(argOut1.getByteArray(), 1);
+ long chronon = ATimeSerializerDeserializer.getChronon(argOut0.getByteArray(), 1);
+ int formatLength = (argOut1.getByteArray()[1] & 0xff << 8)
+ + (argOut1.getByteArray()[2] & 0xff << 0);
+ sbder.delete(0, sbder.length());
+ DT_UTILS.printDateTime(chronon, 0, argOut1.getByteArray(), 3, formatLength, sbder,
+ DateTimeParseMode.TIME_ONLY);
- aDuration.setValue(0, durationChronon);
+ out.writeByte(ATypeTag.STRING.serialize());
+ out.writeUTF(sbder.toString());
- durationSerde.serialize(aDuration, out);
-
- } catch (HyracksDataException hex) {
- throw new AlgebricksException(hex);
+ } catch (IOException ex) {
+ throw new AlgebricksException(ex);
}
}
};
}
+
};
}
/* (non-Javadoc)
- * @see edu.uci.ics.asterix.om.functions.IFunctionDescriptor#getIdentifier()
+ * @see edu.uci.ics.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
*/
@Override
public FunctionIdentifier getIdentifier() {
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 25737cd..011836a 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
@@ -174,6 +174,7 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundHalfToEven2Descriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.NumericRoundHalfToEvenDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.NumericSubDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.NumericSubtractDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.NumericUnaryMinusDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.OpenRecordConstructorDescriptor;
@@ -211,9 +212,6 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.SwitchCaseDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.UnorderedListConstructorDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.WordTokensDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.AddDateDurationDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.AddDatetimeDurationDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.AddTimeDurationDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.AdjustDateTimeForTimeZoneDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.AdjustTimeForTimeZoneDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.CalendarDuartionFromDateDescriptor;
@@ -225,6 +223,7 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DateFromUnixTimeInDaysDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DatetimeFromDateAndTimeDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DatetimeFromUnixTimeInMsDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DayOfWeekDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DayTimeDurationComparatorDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DurationEqualDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DurationFromMillisecondsDescriptor;
@@ -233,6 +232,7 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.GetYearMonthDurationDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalAfterDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalBeforeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalBinDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalCoveredByDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalCoversDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalEndedByDescriptor;
@@ -246,12 +246,12 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalOverlapsDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalStartedByDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.IntervalStartsDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.MillisecondsFromDayTimeDurationDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.MonthsFromYearMonthDurationDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.OverlapDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.SubtractDateDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.SubtractDatetimeDescriptor;
-import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.SubtractTimeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.ParseDateDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.ParseDateTimeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.ParseTimeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.PrintDateDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.PrintDateTimeDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.PrintTimeDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.TimeFromDatetimeDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.TimeFromUnixTimeInMsDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.YearMonthDurationComparatorDecriptor;
@@ -363,7 +363,7 @@
temp.add(NumericAddDescriptor.FACTORY);
temp.add(NumericDivideDescriptor.FACTORY);
temp.add(NumericMultiplyDescriptor.FACTORY);
- temp.add(NumericSubtractDescriptor.FACTORY);
+ temp.add(NumericSubDescriptor.FACTORY);
temp.add(NumericModuloDescriptor.FACTORY);
temp.add(NumericCaretDescriptor.FACTORY);
temp.add(IsNullDescriptor.FACTORY);
@@ -512,16 +512,10 @@
// Temporal functions
temp.add(DateFromUnixTimeInDaysDescriptor.FACTORY);
temp.add(DateFromDatetimeDescriptor.FACTORY);
- temp.add(AddDateDurationDescriptor.FACTORY);
- temp.add(SubtractDateDescriptor.FACTORY);
temp.add(TimeFromUnixTimeInMsDescriptor.FACTORY);
temp.add(TimeFromDatetimeDescriptor.FACTORY);
- temp.add(SubtractTimeDescriptor.FACTORY);
- temp.add(AddTimeDurationDescriptor.FACTORY);
temp.add(DatetimeFromUnixTimeInMsDescriptor.FACTORY);
temp.add(DatetimeFromDateAndTimeDescriptor.FACTORY);
- temp.add(SubtractDatetimeDescriptor.FACTORY);
- temp.add(AddDatetimeDurationDescriptor.FACTORY);
temp.add(CalendarDurationFromDateTimeDescriptor.FACTORY);
temp.add(CalendarDuartionFromDateDescriptor.FACTORY);
temp.add(AdjustDateTimeForTimeZoneDescriptor.FACTORY);
@@ -553,6 +547,14 @@
temp.add(DurationEqualDescriptor.FACTORY);
temp.add(GetYearMonthDurationDescriptor.FACTORY);
temp.add(GetDayTimeDurationDescriptor.FACTORY);
+ temp.add(IntervalBinDescriptor.FACTORY);
+ temp.add(DayOfWeekDescriptor.FACTORY);
+ temp.add(ParseDateDescriptor.FACTORY);
+ temp.add(ParseTimeDescriptor.FACTORY);
+ temp.add(ParseDateTimeDescriptor.FACTORY);
+ temp.add(PrintDateDescriptor.FACTORY);
+ temp.add(PrintTimeDescriptor.FACTORY);
+ temp.add(PrintDateTimeDescriptor.FACTORY);
// Interval constructor
temp.add(AIntervalFromDateConstructorDescriptor.FACTORY);
@@ -959,9 +961,9 @@
return AqlBinaryHashFunctionFamilyProvider.INSTANCE;
}
- @Override
- public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
- return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
- }
+ @Override
+ public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
+ return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
+ }
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/ADMDataParser.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/ADMDataParser.java
index 9271ebf..b8c8659 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/ADMDataParser.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/ADMDataParser.java
@@ -42,7 +42,7 @@
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.APolygonSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ARectangleSerializerDeserializer;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
-import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AYearMonthDurationSerializerDeserializer;
import edu.uci.ics.asterix.om.base.ABoolean;
import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.types.AOrderedListType;
@@ -375,7 +375,7 @@
private void parseYearMonthDuration(String duration, DataOutput out) throws AsterixException {
try {
- AYearMonthDurationerializerDeserializer.parse(duration, out);
+ AYearMonthDurationSerializerDeserializer.INSTANCE.parse(duration, out);
} catch (HyracksDataException e) {
throw new AsterixException(e);
}
@@ -383,7 +383,7 @@
private void parseDayTimeDuration(String duration, DataOutput out) throws AsterixException {
try {
- ADayTimeDurationSerializerDeserializer.parse(duration, out);
+ ADayTimeDurationSerializerDeserializer.INSTANCE.parse(duration, out);
} catch (HyracksDataException e) {
throw new AsterixException(e);
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataParser.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataParser.java
index 921dbf3..5a639dc 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataParser.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/operators/file/DelimitedDataParser.java
@@ -24,7 +24,9 @@
import edu.uci.ics.asterix.builders.IARecordBuilder;
import edu.uci.ics.asterix.builders.RecordBuilder;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ANullSerializerDeserializer;
import edu.uci.ics.asterix.om.base.AMutableString;
+import edu.uci.ics.asterix.om.base.ANull;
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
@@ -47,6 +49,8 @@
private int[] fldIds;
private ArrayBackedValueStorage[] nameBuffers;
+ private boolean areAllNullFields;
+
public DelimitedDataParser(ARecordType recordType, IValueParserFactory[] valueParserFactories, char fieldDelimter) {
this.recordType = recordType;
this.valueParserFactories = valueParserFactories;
@@ -97,29 +101,44 @@
@Override
public boolean parse(DataOutput out) throws AsterixException, IOException {
-
- if (cursor.nextRecord()) {
+ while (cursor.nextRecord()) {
recBuilder.reset(recordType);
recBuilder.init();
+ areAllNullFields = true;
for (int i = 0; i < valueParsers.length; ++i) {
if (!cursor.nextField()) {
break;
}
fieldValueBuffer.reset();
- fieldValueBufferOutput.writeByte(fieldTypeTags[i]);
- valueParsers[i]
- .parse(cursor.buffer, cursor.fStart, cursor.fEnd - cursor.fStart, fieldValueBufferOutput);
+
+ if (cursor.fStart == cursor.fEnd && recordType.getFieldTypes()[i].getTypeTag() != ATypeTag.STRING
+ && recordType.getFieldTypes()[i].getTypeTag() != ATypeTag.NULL) {
+ // if the field is empty and the type is optional, insert NULL
+ // note that string type can also process empty field as an empty string
+ if (recordType.getFieldTypes()[i].getTypeTag() != ATypeTag.UNION) {
+ throw new AsterixException("Field " + i + " cannot be NULL. ");
+ }
+ fieldValueBufferOutput.writeByte(ATypeTag.NULL.serialize());
+ ANullSerializerDeserializer.INSTANCE.serialize(ANull.NULL, out);
+ } else {
+ fieldValueBufferOutput.writeByte(fieldTypeTags[i]);
+ valueParsers[i].parse(cursor.buffer, cursor.fStart, cursor.fEnd - cursor.fStart,
+ fieldValueBufferOutput);
+ areAllNullFields = false;
+ }
if (fldIds[i] < 0) {
recBuilder.addField(nameBuffers[i], fieldValueBuffer);
} else {
recBuilder.addField(fldIds[i], fieldValueBuffer);
}
+
}
- recBuilder.write(out, true);
- return true;
- } else {
- return false;
+ if (!areAllNullFields) {
+ recBuilder.write(out, true);
+ return true;
+ }
}
+ return false;
}
protected void fieldNameToBytes(String fieldName, AMutableString str, ArrayBackedValueStorage buffer)
@@ -252,11 +271,13 @@
if (p >= end) {
int s = start;
eof = !readMore();
+ p -= (s - start);
if (eof) {
state = State.EOF;
+ fStart = start;
+ fEnd = p;
return true;
}
- p -= (s - start);
}
char ch = buffer[p];
if (ch == fieldDelimiter) {