added interval-bin function with test cases for issue 546
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/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/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/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/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 65ef11f..95c002e 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -4322,6 +4322,21 @@
</test-case>
</test-group>
<test-group name="temporal">
+ <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>
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 f81de92..ab975fd 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
@@ -194,8 +194,7 @@
"numeric-idiv", 2);
public final static FunctionIdentifier CARET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "caret", 2);
- public final static FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
- "abs", 1);
+ public final static FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "abs", 1);
public final static FunctionIdentifier NUMERIC_CEILING = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"ceiling", 1);
public final static FunctionIdentifier NUMERIC_FLOOR = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -424,7 +423,8 @@
"interval-overlaps", 2);
public final static FunctionIdentifier INTERVAL_OVERLAPPED_BY = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "interval-overlapped-by", 2);
- public final static FunctionIdentifier OVERLAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "interval-overlapping", 2);
+ public final static FunctionIdentifier OVERLAP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "interval-overlapping", 2);
public final static FunctionIdentifier INTERVAL_STARTS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"interval-starts", 2);
public final static FunctionIdentifier INTERVAL_STARTED_BY = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
@@ -518,6 +518,8 @@
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(
@@ -855,6 +857,7 @@
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);
// interval constructors
addFunction(INTERVAL_CONSTRUCTOR_DATE, OptionalAIntervalTypeComputer.INSTANCE);
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..28ce0db
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/IntervalBinDescriptor.java
@@ -0,0 +1,276 @@
+/*
+ * 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]);
+
+ 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() + ": expecting " + type0
+ + " for the second argument but got " + type1);
+
+ }
+ 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/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 5646aa2..47555bd 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
@@ -230,6 +230,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;
@@ -537,6 +538,7 @@
temp.add(DurationEqualDescriptor.FACTORY);
temp.add(GetYearMonthDurationDescriptor.FACTORY);
temp.add(GetDayTimeDurationDescriptor.FACTORY);
+ temp.add(IntervalBinDescriptor.FACTORY);
// Interval constructor
temp.add(AIntervalFromDateConstructorDescriptor.FACTORY);
@@ -939,9 +941,9 @@
return AqlBinaryHashFunctionFamilyProvider.INSTANCE;
}
- @Override
- public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
- return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
- }
+ @Override
+ public IPredicateEvaluatorFactoryProvider getPredicateEvaluatorFactoryProvider() {
+ return AqlPredicateEvaluatorFactoryProvider.INSTANCE;
+ }
}