ASTERIXDB-1635 Fix for overlap-bins start for dates.
The fix involves two code changes and several sonar fixes.
The code changes are the following:
- DurationArithmeticOperations line 75:
When the month was zero, an index out of bound error occured in line 88 or 92.
The month value should be between 1 and 12.
- OverlapBinsDescriptor line 170:
The Gregorian Calendar is expecting a value in ms. When a date value comes in,
AsterixDB represents the value as the number of days from epoc. So the year
for a date basically allways translated to 1970. In lines 121, a condition
was added to check if the interval was a date, if so, convert the date to
ms.
Change-Id: I24122a84ef9edda4b05260af881c430177f1dc86
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1151
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Steven Jacobs <sjaco002@ucr.edu>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
index b94b5bf..47831e2 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
@@ -39,12 +39,16 @@
let $null6 := null + $dr1
let $null7 := $dt1 + null
let $c1 := $dt1 = ($dt1 - $dt3) + $dt3
+let $dt4 := $dt1 - duration("P1MT1S")
+let $dt5 := $dt1 + duration("P1MT1S")
return {
"datetime1" : $dt1,
"datetime1secs": $dtsecs1,
"datetime2" : $dt2,
"datetime3" : $dt3,
+ "datetime4" : $dt4,
+ "datetime5" : $dt5,
"unixms1" : $unixms1,
"unixsecs1": $unixsecs1,
"duration1" : $dr1,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/overlap_bins/overlap_bins.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/overlap_bins/overlap_bins.3.query.aql
index 8011ad6..bfb5527 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/overlap_bins/overlap_bins.3.query.aql
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/temporal/overlap_bins/overlap_bins.3.query.aql
@@ -25,5 +25,5 @@
let $itv2 := interval(date("1984-03-17"), date("2013-08-22"))
let $itv3 := interval(datetime("1800-01-01T23:59:48.938"), datetime("2015-07-26T13:28:30.218"))
return { "timebins": overlap-bins($itv1, time("00:00:00"), day-time-duration("PT30M")),
- "datebins": overlap-bins($itv2, date("1990-01-01"), year-month-duration("P20Y")),
+ "datebins": overlap-bins($itv2, date("1990-01-01"), year-month-duration("P10Y")),
"datetimebins": overlap-bins($itv3, datetime("1900-01-01T00:00:00.000"), year-month-duration("P100Y")) }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/datetime_functions/datetime_functions.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/datetime_functions/datetime_functions.3.query.sqlpp
index e28661a..de8398f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/datetime_functions/datetime_functions.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/datetime_functions/datetime_functions.3.query.sqlpp
@@ -26,6 +26,8 @@
, 'datetime1secs' : test.`datetime-from-unix-time-in-secs`(1356048000)
, 'datetime2' : test.`datetime-from-date-time`(test.date('1327-12-02'), test.time('15:35:49.938-0800'))
, 'datetime3' : (test.`datetime-from-unix-time-in-ms`(956007429) + (test.`datetime-from-date-time`(test.date('1327-12-02'),test.time('15:35:49.938-0800')) - test.`datetime-from-unix-time-in-ms`(956007429)))
+, 'datetime4' : test.`datetime-from-unix-time-in-ms`(956007429) - test.duration('P1MT1S')
+, 'datetime5' : test.`datetime-from-unix-time-in-ms`(956007429) + test.duration('P1MT1S')
, 'unixms1' : test.`unix-time-from-datetime-in-ms`(test.`datetime-from-unix-time-in-ms`(956007429))
, 'unixsecs1' : test.`unix-time-from-datetime-in-secs`(test.`datetime-from-unix-time-in-secs`(1356048000))
, 'duration1' : (test.`datetime-from-date-time`(test.date('1327-12-02'),test.time('15:35:49.938-0800')) - test.`datetime-from-unix-time-in-ms`(956007429))
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/overlap_bins/overlap_bins.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/overlap_bins/overlap_bins.3.query.sqlpp
index e42707f..90cd95e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/overlap_bins/overlap_bins.3.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/temporal/overlap_bins/overlap_bins.3.query.sqlpp
@@ -22,6 +22,6 @@
**/
{ 'timebins':`overlap-bins`(interval(time('17:23:37'),time('18:30:21')),time('00:00:00'),`day-time-duration`('PT30M')),
- 'datebins':`overlap-bins`(interval(date('1984-03-17'),date('2013-08-22')),date('1990-01-01'),`year-month-duration`('P20Y')),
+ 'datebins':`overlap-bins`(interval(date('1984-03-17'),date('2013-08-22')),date('1990-01-01'),`year-month-duration`('P10Y')),
'datetimebins':`overlap-bins`(interval(datetime('1800-01-01T23:59:48.938'),datetime('2015-07-26T13:28:30.218')),datetime('1900-01-01T00:00:00.000'),
`year-month-duration`('P100Y'))};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
index 6107bc2..5ed1acf 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
@@ -1 +1 @@
-{ "datetime1": datetime("1970-01-12T01:33:27.429Z"), "datetime1secs": datetime("2012-12-21T00:00:00.000Z"), "datetime2": datetime("1327-12-02T23:35:49.938Z"), "datetime3": datetime("1327-12-02T23:35:49.938Z"), "unixms1": 956007429, "unixsecs1": 1356048000, "duration1": duration("-P234526DT1H57M37.491S"), "c1": true, "null1": null, "null1secs": null, "nullunixms1": null, "nullunixsecs1": null, "null2": null, "null3": null, "null4": null, "null5": null, "null6": null, "null7": null }
+{ "datetime1": datetime("1970-01-12T01:33:27.429Z"), "datetime1secs": datetime("2012-12-21T00:00:00.000Z"), "datetime2": datetime("1327-12-02T23:35:49.938Z"), "datetime3": datetime("1327-12-02T23:35:49.938Z"), "datetime4": datetime("1969-12-12T01:33:26.429Z"), "datetime5": datetime("1970-02-12T01:33:28.429Z"), "unixms1": 956007429, "unixsecs1": 1356048000, "duration1": duration("-P234526DT1H57M37.491S"), "c1": true, "null1": null, "null1secs": null, "nullunixms1": null, "nullunixsecs1": null, "null2": null, "null3": null, "null4": null, "null5": null, "null6": null, "null7": null }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins/overlap_bins.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins/overlap_bins.1.adm
index 493a1ca..14f6aaea 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins/overlap_bins.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins/overlap_bins.1.adm
@@ -1 +1 @@
-{ "timebins": [ interval(time("17:00:00.000Z"), time("17:30:00.000Z")), interval(time("17:30:00.000Z"), time("18:00:00.000Z")), interval(time("18:00:00.000Z"), time("18:30:00.000Z")), interval(time("18:30:00.000Z"), time("19:00:00.000Z")) ], "datebins": [ interval(date("1970-01-01"), date("1990-01-01")), interval(date("1990-01-01"), date("2010-01-01")), interval(date("2010-01-01"), date("2030-01-01")) ], "datetimebins": [ interval(datetime("1800-01-01T00:00:00.000Z"), datetime("1900-01-01T00:00:00.000Z")), interval(datetime("1900-01-01T00:00:00.000Z"), datetime("2000-01-01T00:00:00.000Z")), interval(datetime("2000-01-01T00:00:00.000Z"), datetime("2100-01-01T00:00:00.000Z")) ] }
+{ "timebins": [ interval(time("17:00:00.000Z"), time("17:30:00.000Z")), interval(time("17:30:00.000Z"), time("18:00:00.000Z")), interval(time("18:00:00.000Z"), time("18:30:00.000Z")), interval(time("18:30:00.000Z"), time("19:00:00.000Z")) ], "datebins": [ interval(date("1980-01-01"), date("1990-01-01")), interval(date("1990-01-01"), date("2000-01-01")), interval(date("2000-01-01"), date("2010-01-01")), interval(date("2010-01-01"), date("2020-01-01")) ], "datetimebins": [ interval(datetime("1800-01-01T00:00:00.000Z"), datetime("1900-01-01T00:00:00.000Z")), interval(datetime("1900-01-01T00:00:00.000Z"), datetime("2000-01-01T00:00:00.000Z")), interval(datetime("2000-01-01T00:00:00.000Z"), datetime("2100-01-01T00:00:00.000Z")) ] }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/datetime_functions/datetime_functions.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/datetime_functions/datetime_functions.3.ast
index 1a36e5a..c9d1ded 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/datetime_functions/datetime_functions.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/datetime_functions/datetime_functions.3.ast
@@ -53,6 +53,32 @@
]
)
(
+ LiteralExpr [STRING] [datetime4]
+ :
+ OperatorExpr [
+ FunctionCall test.datetime-from-unix-time-in-ms@1[
+ LiteralExpr [LONG] [956007429]
+ ]
+ -
+ FunctionCall test.duration@1[
+ LiteralExpr [STRING] [P1MT1S]
+ ]
+ ]
+ )
+ (
+ LiteralExpr [STRING] [datetime5]
+ :
+ OperatorExpr [
+ FunctionCall test.datetime-from-unix-time-in-ms@1[
+ LiteralExpr [LONG] [956007429]
+ ]
+ +
+ FunctionCall test.duration@1[
+ LiteralExpr [STRING] [P1MT1S]
+ ]
+ ]
+ )
+ (
LiteralExpr [STRING] [unixms1]
:
FunctionCall test.unix-time-from-datetime-in-ms@1[
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/overlap_bins/overlap_bins.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/overlap_bins/overlap_bins.3.ast
index 962d9ff..01cd805 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/overlap_bins/overlap_bins.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/temporal/overlap_bins/overlap_bins.3.ast
@@ -36,7 +36,7 @@
LiteralExpr [STRING] [1990-01-01]
]
FunctionCall null.year-month-duration@1[
- LiteralExpr [STRING] [P20Y]
+ LiteralExpr [STRING] [P10Y]
]
]
)
diff --git a/asterixdb/asterix-doc/src/site/markdown/aql/functions.md b/asterixdb/asterix-doc/src/site/markdown/aql/functions.md
index b6f5538..81ef9c7 100644
--- a/asterixdb/asterix-doc/src/site/markdown/aql/functions.md
+++ b/asterixdb/asterix-doc/src/site/markdown/aql/functions.md
@@ -2310,7 +2310,7 @@
let $itv2 := interval(date("1984-03-17"), date("2013-08-22"))
let $itv3 := interval(datetime("1800-01-01T23:59:48.938"), datetime("2015-07-26T13:28:30.218"))
return { "timebins": overlap-bins($itv1, time("00:00:00"), day-time-duration("PT30M")),
- "datebins": overlap-bins($itv2, date("1990-01-01"), year-month-duration("P20Y")),
+ "datebins": overlap-bins($itv2, date("1990-01-01"), year-month-duration("P10Y")),
"datetimebins": overlap-bins($itv3, datetime("1900-01-01T00:00:00.000"), year-month-duration("P100Y")) }
* The expected result is:
@@ -2319,9 +2319,10 @@
interval(time("17:30:00.000Z"), time("18:00:00.000Z")),
interval(time("18:00:00.000Z"), time("18:30:00.000Z")),
interval(time("18:30:00.000Z"), time("19:00:00.000Z")) ],
- "datebins": [ interval(date("1970-01-01"), date("1990-01-01")),
- interval(date("1990-01-01"), date("2010-01-01")),
- interval(date("2010-01-01"), date("2030-01-01")) ],
+ "datebins": [ interval(date("1980-01-01"), date("1990-01-01")),
+ interval(date("1990-01-01"), date("2000-01-01")),
+ interval(date("2000-01-01"), date("2010-01-01")),
+ interval(date("2010-01-01"), date("2020-01-01")) ],
"datetimebins": [ interval(datetime("1800-01-01T00:00:00.000Z"), datetime("1900-01-01T00:00:00.000Z")),
interval(datetime("1900-01-01T00:00:00.000Z"), datetime("2000-01-01T00:00:00.000Z")),
interval(datetime("2000-01-01T00:00:00.000Z"), datetime("2100-01-01T00:00:00.000Z")) ] }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
index 8e33d44..1051458 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java
@@ -51,24 +51,24 @@
*/
public class DateTimeFormatUtils {
- private final GregorianCalendarSystem CAL = GregorianCalendarSystem.getInstance();
+ private static final GregorianCalendarSystem CAL = GregorianCalendarSystem.getInstance();
- private final Charset ENCODING = Charset.forName("UTF-8");
+ private static final Charset ENCODING = Charset.forName("UTF-8");
// 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 static final char HOUR_CHAR = 'h';
+ private static final char MINUTE_CHAR = 'm';
+ private static final char SECOND_CHAR = 's';
+ private static final char MILLISECOND_CHAR = 'n';
+ private static final char AMPM_CHAR = 'a';
+ private static 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 static final int MAX_HOUR_CHARS = 2;
+ private static final int MAX_MINUTE_CHARS = 2;
+ private static final int MAX_SECOND_CHARS = 2;
+ private static final int MAX_MILLISECOND_CHARS = 3;
+ private static final int MAX_AMPM_CHARS = 1;
+ private static final int MAX_TIMEZONE_CHARS = 1;
private enum DateTimeProcessState {
INIT,
@@ -87,52 +87,51 @@
}
// For date
- private final char YEAR_CHAR = 'Y';
- private final char MONTH_CHAR = 'M';
- private final char DAY_CHAR = 'D';
- private final char WEEKDAY_CHAR = 'W';
+ private static final char YEAR_CHAR = 'Y';
+ private static final char MONTH_CHAR = 'M';
+ private static final char DAY_CHAR = 'D';
+ private static final char WEEKDAY_CHAR = 'W';
- private final int MAX_YEAR_CHARS = 4;
- private final int MAX_MONTH_CHARS = 3;
- private final int MAX_DAY_CHARS = 2;
- private final int MAX_WEEKDAY_CHAR = 1;
+ private static final int MAX_YEAR_CHARS = 4;
+ private static final int MAX_MONTH_CHARS = 3;
+ private static final int MAX_DAY_CHARS = 2;
+ private static final int MAX_WEEKDAY_CHAR = 1;
- private final byte[][] MONTH_NAMES = new byte[][] { "jan".getBytes(ENCODING), "feb".getBytes(ENCODING),
+ private static final byte[][] MONTH_NAMES = new byte[][] { "jan".getBytes(ENCODING), "feb".getBytes(ENCODING),
"mar".getBytes(ENCODING), "apr".getBytes(ENCODING), "may".getBytes(ENCODING), "jun".getBytes(ENCODING),
"jul".getBytes(ENCODING), "aug".getBytes(ENCODING), "sep".getBytes(ENCODING), "oct".getBytes(ENCODING),
"nov".getBytes(ENCODING), "dec".getBytes(ENCODING) };
- private final byte[][] WEEKDAY_FULL_NAMES = new byte[][] { "monday".getBytes(ENCODING),
+ private static final byte[][] WEEKDAY_FULL_NAMES = new byte[][] { "monday".getBytes(ENCODING),
"tuesday".getBytes(ENCODING), "wednesday".getBytes(ENCODING), "thursday".getBytes(ENCODING),
"friday".getBytes(ENCODING), "saturday".getBytes(ENCODING), "sunday".getBytes(ENCODING) };
- private final byte[] UTC_BYTEARRAY = "utc".getBytes(ENCODING);
- private final byte[] GMT_BYTEARRAY = "gmt".getBytes(ENCODING);
+ private static final byte[] UTC_BYTEARRAY = "utc".getBytes(ENCODING);
+ private static final byte[] GMT_BYTEARRAY = "gmt".getBytes(ENCODING);
- private final byte[] AM_BYTEARRAY = "am".getBytes(ENCODING);
- private final byte[] PM_BYTEARRAY = "pm".getBytes(ENCODING);
+ private static final byte[] AM_BYTEARRAY = "am".getBytes(ENCODING);
+ private static final byte[] PM_BYTEARRAY = "pm".getBytes(ENCODING);
// 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 static final char HYPHEN_CHAR = '-';
+ private static final char COLON_CHAR = ':';
+ private static final char SOLIDUS_CHAR = '/';
+ private static final char PERIOD_CHAR = '.';
+ private static final char COMMA_CHAR = ',';
+ private static final char T_CHAR = 'T';
// Skipper, representing a field with characters and numbers that to be skipped
- private final char SKIPPER_CHAR = 'O';
- private final int MAX_SKIPPER_CHAR = 1;
+ private static final char SKIPPER_CHAR = 'O';
+ private static final int MAX_SKIPPER_CHAR = 1;
- private final int MS_PER_MINUTE = 60 * 1000;
- private final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
+ private static final int MS_PER_MINUTE = 60 * 1000;
+ private static final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
- private final byte TO_LOWER_OFFSET = 'A' - 'a';
+ private static final byte TO_LOWER_OFFSET = 'A' - 'a';
- private final String[] TZ_IDS = TimeZone.getAvailableIDs();
+ private static final String[] TZ_IDS = TimeZone.getAvailableIDs();
-
- private Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
+ private static Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
@Override
public int compare(byte[] o1, byte[] o2) {
int i = 0;
@@ -150,32 +149,35 @@
}
};
- private final byte[][] TIMEZONE_IDS = new byte[TZ_IDS.length][];
- {
+ private static final byte[][] TIMEZONE_IDS = new byte[TZ_IDS.length][];
+ static {
for (int i = 0; i < TIMEZONE_IDS.length; i++) {
TIMEZONE_IDS[i] = TZ_IDS[i].getBytes(ENCODING);
}
Arrays.sort(TIMEZONE_IDS, byteArrayComparator);
}
- private final int[] TIMEZONE_OFFSETS = new int[TIMEZONE_IDS.length];
- {
+ private static final int[] TIMEZONE_OFFSETS = new int[TIMEZONE_IDS.length];
+ static {
for (int i = 0; i < TIMEZONE_IDS.length; i++) {
TIMEZONE_OFFSETS[i] = TimeZone.getTimeZone(new String(TIMEZONE_IDS[i], ENCODING)).getRawOffset();
}
}
+ private DateTimeFormatUtils() {
+ }
+
private static class DateTimeFormatUtilsHolder {
private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils();
+
+ private DateTimeFormatUtilsHolder() {
+ }
}
public static DateTimeFormatUtils getInstance() {
return DateTimeFormatUtilsHolder.INSTANCE;
}
- private DateTimeFormatUtils() {
- }
-
private int parseFormatField(byte[] format, int formatStart, int formatLength, int formatPointer, char formatChar,
int maxAllowedFormatCharCopied) {
@@ -188,9 +190,9 @@
formatCharCopies++;
}
if (formatCharCopies > maxAllowedFormatCharCopied) {
- throw new IllegalStateException("The format string for " + formatChar
- + " is too long: expected no more than " + maxAllowedFormatCharCopied + " but got "
- + formatCharCopies);
+ throw new IllegalStateException(
+ "The format string for " + formatChar + " is too long: expected no more than "
+ + maxAllowedFormatCharCopied + " but got " + formatCharCopies);
}
return formatCharCopies;
@@ -442,7 +444,8 @@
}
// for more digits
while (processedFieldsCount < maxAllowedFormatCharCopies && dataStringPointer < dataLength
- && data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9') {
+ && data[dataStart + dataStringPointer] >= '0'
+ && data[dataStart + dataStringPointer] <= '9') {
parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
dataStringPointer++;
processedFieldsCount++;
@@ -464,15 +467,16 @@
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]);
+ 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') {
+ if (data[dataStart + dataStringPointer] < '0'
+ || data[dataStart + dataStringPointer] > '9') {
throw new AsterixTemporalTypeParseException("Unexpected char for month field at "
+ (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
}
@@ -495,17 +499,17 @@
break;
case WEEKDAY:
int processedWeekdayFieldsCount = 0;
- while ((data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'a' && data[dataStart
- + dataStringPointer + processedWeekdayFieldsCount] <= 'z')
- || (data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'A' && data[dataStart
- + dataStringPointer + processedWeekdayFieldsCount] <= 'Z')) {
+ while ((data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'a'
+ && data[dataStart + dataStringPointer + processedWeekdayFieldsCount] <= 'z')
+ || (data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'A'
+ && data[dataStart + dataStringPointer + processedWeekdayFieldsCount] <= 'Z')) {
processedWeekdayFieldsCount++;
}
// match the weekday name
if (weekdayIDSearch(data, dataStart + dataStringPointer, processedWeekdayFieldsCount) < 0) {
throw new AsterixTemporalTypeParseException("Unexpected string for day-of-week: "
- + (new String(Arrays.copyOfRange(data, dataStart + dataStringPointer, dataStart
- + dataStringPointer + processedWeekdayFieldsCount))));
+ + (new String(Arrays.copyOfRange(data, dataStart + dataStringPointer,
+ dataStart + dataStringPointer + processedWeekdayFieldsCount))));
}
dataStringPointer += processedWeekdayFieldsCount;
break;
@@ -531,7 +535,8 @@
}
// if there are more than formatCharCopies digits for the hour string
while (processFieldsCount < expectedMaxCount && dataStringPointer < dataLength
- && data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9') {
+ && data[dataStart + dataStringPointer] >= '0'
+ && data[dataStart + dataStringPointer] <= '9') {
parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
dataStringPointer++;
processFieldsCount++;
@@ -553,18 +558,19 @@
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'))) {
+ && 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] == '-'))) {
+ } 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))) {
+ 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
@@ -615,24 +621,24 @@
} 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] == '_')) {
+ 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);
+ 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
- + timezoneEndField)));
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected timezone string: " + new String(Arrays.copyOfRange(data,
+ dataStart + dataStringPointer, dataStart + timezoneEndField)));
}
dataStringPointer = timezoneEndField;
}
@@ -650,9 +656,9 @@
hour = 0;
}
} else {
- throw new AsterixTemporalTypeParseException("Unexpected string for AM/PM marker "
- + new String(Arrays.copyOfRange(data, dataStart + dataStringPointer, dataStart
- + dataStringPointer + 2)));
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected string for AM/PM marker " + new String(Arrays.copyOfRange(data,
+ dataStart + dataStringPointer, dataStart + dataStringPointer + 2)));
}
dataStringPointer += 2;
} else {
@@ -662,15 +668,17 @@
case SKIPPER:
// just skip all continuous character and numbers
while ((data[dataStart + dataStringPointer] >= 'a' && data[dataStart + dataStringPointer] <= 'z')
- || (data[dataStart + dataStringPointer] >= 'A' && data[dataStart + dataStringPointer] <= 'Z')
- || (data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9')) {
+ || (data[dataStart + dataStringPointer] >= 'A'
+ && data[dataStart + dataStringPointer] <= 'Z')
+ || (data[dataStart + dataStringPointer] >= '0'
+ && data[dataStart + dataStringPointer] <= '9')) {
dataStringPointer++;
}
break;
case SEPARATOR:
if (separatorChar == '\0') {
- throw new AsterixTemporalTypeParseException("Incorrect separator char in date string as "
- + data[dataStart + dataStringPointer]);
+ 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) {
@@ -822,8 +830,8 @@
break;
default:
- throw new HyracksDataException("Unexpected format string at " + (formatStart + formatPointer)
- + ": " + format[formatStart + formatPointer]);
+ throw new HyracksDataException("Unexpected format string at " + (formatStart + formatPointer) + ": "
+ + format[formatStart + formatPointer]);
}
// check whether the process state is valid for the parse mode
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
index 404bf42..2e32378 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java
@@ -23,18 +23,24 @@
*/
public class DurationArithmeticOperations {
- private final static GregorianCalendarSystem calSystem = GregorianCalendarSystem.getInstance();
+ private static final GregorianCalendarSystem GREG_CAL = GregorianCalendarSystem.getInstance();
+
+ private DurationArithmeticOperations() {
+ }
/**
* Add a duration (with yearMonth and dayTime) onto a time point. The algorithm works as described in
* <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).
+ * 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
@@ -54,19 +60,19 @@
return rtnChronon;
}
- int year = calSystem.getYear(pointChronon);
- int month = calSystem.getMonthOfYear(pointChronon, year);
- int day = calSystem.getDayOfMonthYear(pointChronon, year, month);
- int hour = calSystem.getHourOfDay(pointChronon);
- int min = calSystem.getMinOfHour(pointChronon);
- int sec = calSystem.getSecOfMin(pointChronon);
- int ms = calSystem.getMillisOfSec(pointChronon);
+ int year = GREG_CAL.getYear(pointChronon);
+ int month = GREG_CAL.getMonthOfYear(pointChronon, year);
+ int day = GREG_CAL.getDayOfMonthYear(pointChronon, year, month);
+ int hour = GREG_CAL.getHourOfDay(pointChronon);
+ int min = GREG_CAL.getMinOfHour(pointChronon);
+ int sec = GREG_CAL.getSecOfMin(pointChronon);
+ int ms = GREG_CAL.getMillisOfSec(pointChronon);
// Apply the year-month duration
int carry = yearMonthDuration / 12;
month += (yearMonthDuration % 12);
- if (month < 0) {
+ if (month < 1) {
month += 12;
carry -= 1;
} else if (month > 12) {
@@ -76,7 +82,7 @@
year += carry;
- boolean isLeapYear = calSystem.isLeapYear(year);
+ boolean isLeapYear = GREG_CAL.isLeapYear(year);
if (isLeapYear) {
if (day > GregorianCalendarSystem.DAYS_OF_MONTH_ORDI[month - 1]) {
@@ -88,7 +94,7 @@
}
}
- return calSystem.getChronon(year, month, day, hour, min, sec, ms, 0) + dayTimeDuration;
+ return GREG_CAL.getChronon(year, month, day, hour, min, sec, ms, 0) + dayTimeDuration;
}
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java
index 836408d..15229e2 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/OverlapBinsDescriptor.java
@@ -36,6 +36,7 @@
import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.typecomputer.impl.ADateTypeComputer;
import org.apache.asterix.om.types.AOrderedListType;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
@@ -95,7 +96,7 @@
private final ISerializerDeserializer<AInterval> intervalSerde = AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(BuiltinType.AINTERVAL);
- private final GregorianCalendarSystem GREG_CAL = GregorianCalendarSystem.getInstance();
+ private final GregorianCalendarSystem gregCalSys = GregorianCalendarSystem.getInstance();
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
@@ -109,13 +110,17 @@
ATypeTag type0 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]);
- long intervalStart = 0, intervalEnd = 0;
+ long intervalStart;
+ long intervalEnd;
byte intervalTypeTag;
if (type0 == ATypeTag.INTERVAL) {
intervalStart = AIntervalSerializerDeserializer.getIntervalStart(bytes0, offset0 + 1);
intervalEnd = AIntervalSerializerDeserializer.getIntervalEnd(bytes0, offset0 + 1);
intervalTypeTag = AIntervalSerializerDeserializer.getIntervalTimeType(bytes0, offset0 + 1);
+ if (intervalTypeTag == ATypeTag.SERIALIZED_DATE_TYPE_TAG) {
+ intervalStart = intervalStart * GregorianCalendarSystem.CHRONON_OF_DAY;
+ }
} else {
throw new AlgebricksException(getIdentifier().getName()
+ ": the first argument should be INTERVAL/NULL/MISSING but got " + type0);
@@ -130,7 +135,7 @@
+ type0 + "(" + intervalTypeTag + ") for the second argument but got " + type1);
}
- long anchorTime = 0;
+ long anchorTime;
switch (type1) {
case DATE:
anchorTime = ADateSerializerDeserializer.getChronon(bytes1, offset1 + 1)
@@ -160,10 +165,10 @@
case YEARMONTHDURATION:
yearMonth = AYearMonthDurationSerializerDeserializer.getYearMonth(bytes2, offset2 + 1);
- int yearStart = GREG_CAL.getYear(anchorTime);
- int monthStart = GREG_CAL.getMonthOfYear(anchorTime, yearStart);
- int yearToBin = GREG_CAL.getYear(intervalStart);
- int monthToBin = GREG_CAL.getMonthOfYear(intervalStart, yearToBin);
+ int yearStart = gregCalSys.getYear(anchorTime);
+ int monthStart = gregCalSys.getMonthOfYear(anchorTime, yearStart);
+ int yearToBin = gregCalSys.getYear(intervalStart);
+ int monthToBin = gregCalSys.getMonthOfYear(intervalStart, yearToBin);
int totalMonths = (yearToBin - yearStart) * 12 + (monthToBin - monthStart);
@@ -195,7 +200,8 @@
+ type2);
}
- long binStartChronon, binEndChronon;
+ long binStartChronon;
+ long binEndChronon;
int binOffset;
listBuilder.reset(intListType);
@@ -302,9 +308,6 @@
};
}
- /* (non-Javadoc)
- * @see org.apache.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier()
- */
@Override
public FunctionIdentifier getIdentifier() {
return AsterixBuiltinFunctions.OVERLAP_BINS;