[NO ISSUE][RT] Add job start timestamp to the joblet context
- user model changes: no
- storage format changes: no
- interface changes: yes
Details:
- add job start timestamp to the joblet context
- make CommonFunctionMapUtil extensible by products
- enhance DateTimeFormatUtils.parseDateTime() to return
timezone information and not throw exception on invalid data
- add GregorianCalendarSystem.getDayOfYear(), getWeekOfYear()
- change sleep() to sleep first then evaluate the argument
- skip fractional trailing 0s when printing nano-duration
- fix documentation about using column aliases in GroupBy
Change-Id: I190663ec5e709584ef449f8279b1d2a5a0b099dd
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2511
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
index f2fb580..d20d72d 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java
@@ -136,7 +136,7 @@
public void testDurationFormatNanos() throws Exception {
Assert.assertEquals("123.456789012s", Duration.formatNanos(123456789012l));
Assert.assertEquals("12.345678901s", Duration.formatNanos(12345678901l));
- Assert.assertEquals("1.234567890s", Duration.formatNanos(1234567890l));
+ Assert.assertEquals("1.23456789s", Duration.formatNanos(1234567890l));
Assert.assertEquals("123.456789ms", Duration.formatNanos(123456789l));
Assert.assertEquals("12.345678ms", Duration.formatNanos(12345678l));
Assert.assertEquals("1.234567ms", Duration.formatNanos(1234567l));
@@ -147,7 +147,7 @@
Assert.assertEquals("12ns", Duration.formatNanos(12l));
Assert.assertEquals("1ns", Duration.formatNanos(1l));
Assert.assertEquals("-123.456789012s", Duration.formatNanos(-123456789012l));
- Assert.assertEquals("120.000000000s", Duration.formatNanos(120000000000l));
+ Assert.assertEquals("120s", Duration.formatNanos(120000000000l));
Assert.assertEquals("-12ns", Duration.formatNanos(-12l));
}
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
index 4338222..a8b43b7 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java
@@ -30,6 +30,8 @@
MICRO("µs", 3),
NANO("ns", 0);
+ static final Duration[] VALUES = values();
+
static final long NANOSECONDS = 1;
static final long MICROSECONDS = 1000 * NANOSECONDS;
static final long MILLISECONDS = 1000 * MICROSECONDS;
@@ -46,16 +48,29 @@
}
public static String formatNanos(long nanoTime) {
- final String strTime = String.valueOf(nanoTime);
+ StringBuilder sb = new StringBuilder();
+ formatNanos(nanoTime, sb);
+ return sb.toString();
+ }
+
+ public static void formatNanos(long nanoTime, StringBuilder out) {
+ final String strTime = String.valueOf(Math.abs(nanoTime));
final int len = strTime.length();
- for (Duration tu : Duration.values()) {
- if (len > tu.nanoDigits) {
- final String integer = strTime.substring(0, len - tu.nanoDigits);
- final String fractional = strTime.substring(len - tu.nanoDigits);
- return integer + (fractional.length() > 0 ? "." + fractional : "") + tu.unit;
+ for (Duration tu : VALUES) {
+ int n = len - tu.nanoDigits;
+ if (n > 0) {
+ if (nanoTime < 0) {
+ out.append('-');
+ }
+ out.append(strTime, 0, n);
+ int k = lastIndexOf(strTime, n, '1', '9');
+ if (k > 0) {
+ out.append('.').append(strTime, n, k + 1);
+ }
+ out.append(tu.unit);
+ break;
}
}
- return "illegal string value: " + strTime;
}
// ParseDuration parses a duration string.
@@ -233,4 +248,14 @@
}
return Triple.of(x, scale, s.substring(i));
}
+
+ private static int lastIndexOf(CharSequence seq, int fromIndex, char rangeStart, char rangeEnd) {
+ for (int i = seq.length() - 1; i >= fromIndex; i--) {
+ char c = seq.charAt(i);
+ if (c >= rangeStart && c <= rangeEnd) {
+ return i;
+ }
+ }
+ return -1;
+ }
}
\ No newline at end of file
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
index bcf3094..56103e5 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md
@@ -1200,13 +1200,14 @@
GROUP AS `$1`(msg AS msg);
### <a id="Column_aliases">Column Aliases</a>
-SQL++ also allows column aliases to be used as `GROUP BY` keys or `ORDER BY` keys.
+SQL++ also allows column aliases to be used as `ORDER BY` keys.
##### Example
SELECT msg.authorId AS aid, COUNT(*)
FROM GleambookMessages msg
- GROUP BY aid;
+ GROUP BY msg.authorId;
+ ORDER BY aid;
This query returns:
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
index 2aaf08f..3116521 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
@@ -32,66 +32,66 @@
private static final Map<String, String> FUNCTION_NAME_MAP = new HashMap<>();
static {
- FUNCTION_NAME_MAP.put("ceil", "ceiling"); //ceil, internal: ceiling
- FUNCTION_NAME_MAP.put("length", "string-length"); // length, internal: string-length
- FUNCTION_NAME_MAP.put("lower", "lowercase"); // lower, internal: lowercase
- FUNCTION_NAME_MAP.put("substr", "substring"); // substr, internal: substring
- FUNCTION_NAME_MAP.put("upper", "uppercase"); // upper, internal: uppercase
- FUNCTION_NAME_MAP.put("title", "initcap"); // title, internal: initcap
- FUNCTION_NAME_MAP.put("regexp_contains", "matches"); // regexp_contains, internal: matches
- FUNCTION_NAME_MAP.put("power", "caret"); //pow, internal: caret
- FUNCTION_NAME_MAP.put("int", "integer"); // int, internal: integer
+ addFunctionMapping("ceil", "ceiling"); //ceil, internal: ceiling
+ addFunctionMapping("length", "string-length"); // length, internal: string-length
+ addFunctionMapping("lower", "lowercase"); // lower, internal: lowercase
+ addFunctionMapping("substr", "substring"); // substr, internal: substring
+ addFunctionMapping("upper", "uppercase"); // upper, internal: uppercase
+ addFunctionMapping("title", "initcap"); // title, internal: initcap
+ addFunctionMapping("regexp_contains", "matches"); // regexp_contains, internal: matches
+ addFunctionMapping("power", "caret"); //pow, internal: caret
+ addFunctionMapping("int", "integer"); // int, internal: integer
// The "mapped-to" names are to be deprecated.
- FUNCTION_NAME_MAP.put("tinyint", "int8"); // tinyint, internal: int8
- FUNCTION_NAME_MAP.put("smallint", "int16"); // smallint, internal: int16
- FUNCTION_NAME_MAP.put("integer", "int32"); // integer, internal: int32
- FUNCTION_NAME_MAP.put("bigint", "int64"); // bigint, internal: int64
+ addFunctionMapping("tinyint", "int8"); // tinyint, internal: int8
+ addFunctionMapping("smallint", "int16"); // smallint, internal: int16
+ addFunctionMapping("integer", "int32"); // integer, internal: int32
+ addFunctionMapping("bigint", "int64"); // bigint, internal: int64
// Type functions.
- FUNCTION_NAME_MAP.put("isnull", "is-null"); // isnull, internal: is-null
- FUNCTION_NAME_MAP.put("ismissing", "is-missing"); // ismissing, internal: is-missing
- FUNCTION_NAME_MAP.put("isunknown", "is-unknown"); // isunknown, internal: is-unknown
- FUNCTION_NAME_MAP.put("isatomic", "is-atomic"); // isatomic, internal: is-atomic
- FUNCTION_NAME_MAP.put("isatom", "is-atomic"); // isatom, internal: is-atomic
- FUNCTION_NAME_MAP.put("isboolean", "is-boolean"); // isboolean, internal: is-boolean
- FUNCTION_NAME_MAP.put("isbool", "is-boolean"); // isbool, internal: is-boolean
- FUNCTION_NAME_MAP.put("isnumber", "is-number"); // isnumber, internal: is-number
- FUNCTION_NAME_MAP.put("isnum", "is-number"); // isnum, internal: is-number
- FUNCTION_NAME_MAP.put("isstring", "is-string"); // isstring, internal: is-string
- FUNCTION_NAME_MAP.put("isstr", "is-string"); // isstr, internal: is-string
- FUNCTION_NAME_MAP.put("isarray", "is-array"); // isarray, internal: is-array
- FUNCTION_NAME_MAP.put("isobject", "is-object"); // isobject, internal: is-object
- FUNCTION_NAME_MAP.put("isobj", "is-object"); // isobj, internal: is-object
- FUNCTION_NAME_MAP.put("ifmissing", "if-missing"); // ifmissing, internal: if-missing
- FUNCTION_NAME_MAP.put("ifnull", "if-null"); // ifnull, internal: if-null
- FUNCTION_NAME_MAP.put("ifmissingornull", "if-missing-or-null"); // ifmissingornull, internal: if-missing-or-null
- FUNCTION_NAME_MAP.put("ifinf", "if-inf"); // ifinf, internal: if-inf
- FUNCTION_NAME_MAP.put("ifnan", "if-nan"); // ifnan, internal: if-nan
- FUNCTION_NAME_MAP.put("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf
- FUNCTION_NAME_MAP.put("toboolean", "to-boolean"); // toboolean, internal: to-boolean
- FUNCTION_NAME_MAP.put("tostring", "to-string"); // tostring, internal: to-string
- FUNCTION_NAME_MAP.put("todouble", "to-double"); // todouble, internal: to-double
- FUNCTION_NAME_MAP.put("tobigint", "to-bigint"); // tobigint, internal: to-bigint
- FUNCTION_NAME_MAP.put("tonumber", "to-number"); // tonumber, internal: to-number
- FUNCTION_NAME_MAP.put("tonum", "to-number"); // tonum, internal: to-number
+ addFunctionMapping("isnull", "is-null"); // isnull, internal: is-null
+ addFunctionMapping("ismissing", "is-missing"); // ismissing, internal: is-missing
+ addFunctionMapping("isunknown", "is-unknown"); // isunknown, internal: is-unknown
+ addFunctionMapping("isatomic", "is-atomic"); // isatomic, internal: is-atomic
+ addFunctionMapping("isatom", "is-atomic"); // isatom, internal: is-atomic
+ addFunctionMapping("isboolean", "is-boolean"); // isboolean, internal: is-boolean
+ addFunctionMapping("isbool", "is-boolean"); // isbool, internal: is-boolean
+ addFunctionMapping("isnumber", "is-number"); // isnumber, internal: is-number
+ addFunctionMapping("isnum", "is-number"); // isnum, internal: is-number
+ addFunctionMapping("isstring", "is-string"); // isstring, internal: is-string
+ addFunctionMapping("isstr", "is-string"); // isstr, internal: is-string
+ addFunctionMapping("isarray", "is-array"); // isarray, internal: is-array
+ addFunctionMapping("isobject", "is-object"); // isobject, internal: is-object
+ addFunctionMapping("isobj", "is-object"); // isobj, internal: is-object
+ addFunctionMapping("ifmissing", "if-missing"); // ifmissing, internal: if-missing
+ addFunctionMapping("ifnull", "if-null"); // ifnull, internal: if-null
+ addFunctionMapping("ifmissingornull", "if-missing-or-null"); // ifmissingornull, internal: if-missing-or-null
+ addFunctionMapping("ifinf", "if-inf"); // ifinf, internal: if-inf
+ addFunctionMapping("ifnan", "if-nan"); // ifnan, internal: if-nan
+ addFunctionMapping("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf
+ addFunctionMapping("toboolean", "to-boolean"); // toboolean, internal: to-boolean
+ addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string
+ addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double
+ addFunctionMapping("tobigint", "to-bigint"); // tobigint, internal: to-bigint
+ addFunctionMapping("tonumber", "to-number"); // tonumber, internal: to-number
+ addFunctionMapping("tonum", "to-number"); // tonum, internal: to-number
// Object functions
// record-merge, internal: object-merge
- FUNCTION_NAME_MAP.put("record-merge", "object-merge");
+ addFunctionMapping("record-merge", "object-merge");
// record-concat, internal: object-concat
- FUNCTION_NAME_MAP.put("record-concat", "object-concat");
+ addFunctionMapping("record-concat", "object-concat");
// record-get-fields, internal: object-get-fields
- FUNCTION_NAME_MAP.put("record-get-fields", "object-get-fields");
+ addFunctionMapping("record-get-fields", "object-get-fields");
// record-get-field-value, internal: object-get-field-value
- FUNCTION_NAME_MAP.put("record-get-field-value", "object-get-field-value");
+ addFunctionMapping("record-get-field-value", "object-get-field-value");
// record-add-fields, internal: object-add-fields
- FUNCTION_NAME_MAP.put("record-add-fields", "object-add-fields");
+ addFunctionMapping("record-add-fields", "object-add-fields");
// record-remove-fields, internal: object-remove-fields
- FUNCTION_NAME_MAP.put("record-remove-fields", "object-remove-fields");
+ addFunctionMapping("record-remove-fields", "object-remove-fields");
// Array/Mutliset functions
- FUNCTION_NAME_MAP.put("array_length", "len");
+ addFunctionMapping("array_length", "len");
}
private CommonFunctionMapUtil() {
@@ -118,4 +118,8 @@
FunctionSignature newFs = new FunctionSignature(fs.getNamespace(), understoreName, fs.getArity());
return BuiltinFunctions.isBuiltinCompilerFunction(newFs, true) ? newFs : fs;
}
+
+ public static void addFunctionMapping(String alias, String functionName) {
+ FUNCTION_NAME_MAP.put(alias, functionName);
+ }
}
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 300d696..de98f2d 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
@@ -20,10 +20,14 @@
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TimeZone;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.api.exceptions.HyracksDataException;
/**
@@ -53,7 +57,7 @@
private static final GregorianCalendarSystem CAL = GregorianCalendarSystem.getInstance();
- private static final Charset ENCODING = Charset.forName("UTF-8");
+ private static final Charset ENCODING = StandardCharsets.UTF_8;
// For time
private static final char HOUR_CHAR = 'h';
@@ -71,7 +75,6 @@
private static final int MAX_TIMEZONE_CHARS = 1;
private enum DateTimeProcessState {
- INIT,
YEAR,
MONTH,
DAY,
@@ -124,13 +127,8 @@
private static final char SKIPPER_CHAR = 'O';
private static final int MAX_SKIPPER_CHAR = 1;
- private static final int MS_PER_MINUTE = 60 * 1000;
- private static final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
-
private static final byte TO_LOWER_OFFSET = 'A' - 'a';
- private static final String[] TZ_IDS = TimeZone.getAvailableIDs();
-
private static Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
@Override
public int compare(byte[] o1, byte[] o2) {
@@ -149,33 +147,31 @@
}
};
- private static final byte[][] TIMEZONE_IDS = new byte[TZ_IDS.length][];
+ private static final byte[][] TIMEZONE_IDS;
+ private static final int[] TIMEZONE_OFFSETS;
+
static {
- for (int i = 0; i < TIMEZONE_IDS.length; i++) {
- TIMEZONE_IDS[i] = TZ_IDS[i].getBytes(ENCODING);
+ String[] tzIds = TimeZone.getAvailableIDs();
+ int tzCount = tzIds.length;
+ TIMEZONE_IDS = new byte[tzCount][];
+ TIMEZONE_OFFSETS = new int[tzCount];
+
+ for (int i = 0; i < tzCount; i++) {
+ TIMEZONE_IDS[i] = tzIds[i].getBytes(ENCODING);
}
Arrays.sort(TIMEZONE_IDS, byteArrayComparator);
- }
-
- private static final int[] TIMEZONE_OFFSETS = new int[TIMEZONE_IDS.length];
- static {
- for (int i = 0; i < TIMEZONE_IDS.length; i++) {
+ for (int i = 0; i < tzCount; 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() {
- }
- }
+ private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils();
public static DateTimeFormatUtils getInstance() {
- return DateTimeFormatUtilsHolder.INSTANCE;
+ return INSTANCE;
+ }
+
+ private DateTimeFormatUtils() {
}
private int parseFormatField(byte[] format, int formatStart, int formatLength, int formatPointer, char formatChar,
@@ -274,20 +270,30 @@
return b;
}
- public long parseDateTime(byte[] data, int dataStart, int dataLength, byte[] format, int formatStart,
- int formatLength, DateTimeParseMode parseMode) throws AsterixTemporalTypeParseException {
+ public boolean parseDateTime(AMutableInt64 outChronon, byte[] data, int dataStart, int dataLength, byte[] format,
+ int formatStart, int formatLength, DateTimeParseMode parseMode, boolean raiseParseDataError)
+ throws AsterixTemporalTypeParseException {
+ return parseDateTime(outChronon, null, null, data, dataStart, dataLength, format, formatStart, formatLength,
+ parseMode, raiseParseDataError, (byte) '\0');
+ }
+
+ public boolean parseDateTime(AMutableInt64 outChronon, Mutable<Boolean> outTimeZoneExists,
+ AMutableInt32 outTimeZone, byte[] data, int dataStart, int dataLength, byte[] format, int formatStart,
+ int formatLength, DateTimeParseMode parseMode, boolean raiseParseDataError, byte altSeparatorChar)
+ throws AsterixTemporalTypeParseException {
int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, ms = 0, timezone = 0;
+ boolean timezoneExists = false;
boolean negativeYear = false;
- int formatCharCopies = 0;
+ int formatCharCopies;
int dataStringPointer = 0, formatPointer = 0;
byte separatorChar = '\0';
- DateTimeProcessState processState = DateTimeProcessState.INIT;
+ DateTimeProcessState processState;
- int pointerMove = 0;
+ int pointerMove;
while (dataStringPointer < dataLength && formatPointer < formatLength) {
formatCharCopies = 0;
@@ -421,8 +427,6 @@
}
switch (processState) {
- case INIT:
- break;
case YEAR:
if (dataStringPointer < dataLength && data[dataStart + dataStringPointer] == HYPHEN_CHAR) {
negativeYear = true;
@@ -435,8 +439,12 @@
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]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Unexpected char for year field at "
+ + (dataStart + dataStringPointer) + ": " + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer] - '0');
dataStringPointer++;
@@ -467,24 +475,38 @@
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]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unrecognizable month string " + (char) data[dataStart + dataStringPointer]
+ + " " + (char) data[dataStart + dataStringPointer + 1] + " "
+ + (char) data[dataStart + dataStringPointer + 2]);
+ } else {
+ return false;
+ }
}
} 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]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected char for month field at " + (dataStart + dataStringPointer)
+ + ": " + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
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 (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected char for month field at " + (dataStart + dataStringPointer)
+ + ": " + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
}
// if there are more than 2 digits for the day string
@@ -507,9 +529,13 @@
}
// 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))));
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Unexpected string for day-of-week: "
+ + new String(data, dataStart + dataStringPointer,
+ dataStart + dataStringPointer + processedWeekdayFieldsCount, ENCODING));
+ } else {
+ return false;
+ }
}
dataStringPointer += processedWeekdayFieldsCount;
break;
@@ -522,15 +548,25 @@
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]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Unexpected char for " + processState.name()
+ + " field at " + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
+
}
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 (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected char for " + processState.name() + " field at " + dataStringPointer
+ + ": " + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
}
// if there are more than formatCharCopies digits for the hour string
@@ -581,20 +617,29 @@
} else if (data[dataStart + dataStringPointer] == '+') {
dataStringPointer++;
} else {
- throw new AsterixTemporalTypeParseException(
- "Incorrect timezone hour field: expecting sign + or - but got: "
- + data[dataStart + dataStringPointer]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Incorrect timezone hour field: expecting sign + or - but got: "
+ + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
+ parsedValue = 0;
// 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;
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer + i] - '0');
} else {
- throw new AsterixTemporalTypeParseException(
- "Unexpected character for timezone hour field at "
- + (dataStart + dataStringPointer) + ": "
- + data[dataStart + dataStringPointer]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected character for timezone hour field at "
+ + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
}
dataStringPointer += 2;
@@ -602,18 +647,25 @@
if (data[dataStart + dataStringPointer] == ':') {
dataStringPointer++;
}
+ timezone = (int) (parsedValue * GregorianCalendarSystem.CHRONON_OF_HOUR);
+ parsedValue = 0;
// 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;
+ parsedValue = parsedValue * 10 + (data[dataStart + dataStringPointer + i] - '0');
} else {
- throw new AsterixTemporalTypeParseException(
- "Unexpected character for timezone minute field at "
- + (dataStart + dataStringPointer) + ": "
- + data[dataStart + dataStringPointer]);
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Unexpected character for timezone minute field at "
+ + (dataStart + dataStringPointer) + ": "
+ + data[dataStart + dataStringPointer]);
+ } else {
+ return false;
+ }
}
}
+ timezone += (int) (parsedValue * GregorianCalendarSystem.CHRONON_OF_MINUTE);
dataStringPointer += 2;
if (!negativeTimeZone) {
timezone *= -1;
@@ -636,17 +688,26 @@
if (searchIdx >= 0) {
timezone = TIMEZONE_OFFSETS[searchIdx];
} else {
- throw new AsterixTemporalTypeParseException(
- "Unexpected timezone string: " + new String(Arrays.copyOfRange(data,
- dataStart + dataStringPointer, dataStart + timezoneEndField)));
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Unexpected timezone string: " + new String(
+ data, dataStart + dataStringPointer, dataStart + timezoneEndField, ENCODING));
+ } else {
+ return false;
+ }
}
dataStringPointer = timezoneEndField;
}
+ timezoneExists = true;
break;
case AMPM:
if (dataStringPointer + 1 < dataLength) {
if (hour > 12 || hour <= 0) {
- throw new IllegalStateException("Hour " + hour + " cannot be a time for AM.");
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Hour " + hour + " cannot be a time for AM/PM.");
+ } else {
+ return false;
+ }
}
if (byteArrayEqualToString(data, dataStart + dataStringPointer, 2, AM_BYTEARRAY)) {
// do nothing
@@ -656,13 +717,21 @@
hour = 0;
}
} else {
- throw new AsterixTemporalTypeParseException(
- "Unexpected string for AM/PM marker " + new String(Arrays.copyOfRange(data,
- dataStart + dataStringPointer, dataStart + dataStringPointer + 2)));
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Unexpected string for AM/PM marker "
+ + new String(data, dataStart + dataStringPointer,
+ dataStart + dataStringPointer + 2, ENCODING));
+ } else {
+ return false;
+ }
}
dataStringPointer += 2;
} else {
- throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
+ } else {
+ return false;
+ }
}
break;
case SKIPPER:
@@ -676,14 +745,16 @@
}
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]);
+ byte b = data[dataStart + dataStringPointer];
+ boolean match = b == separatorChar || (altSeparatorChar != '\0' && b == altSeparatorChar);
+ if (!match) {
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "Expecting separator " + separatorChar + " but got " + b);
+ } else {
+ return false;
+ }
}
dataStringPointer++;
}
@@ -695,19 +766,33 @@
}
if (dataStringPointer < dataLength) {
- throw new AsterixTemporalTypeParseException(
- "The given data string is not fully parsed by the given format string");
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "The given data string is not fully parsed by the given format string");
+ } else {
+ return false;
+ }
}
if (formatPointer < formatLength) {
- throw new AsterixTemporalTypeParseException(
- "The given format string is not fully used for the given format string");
+ if (raiseParseDataError) {
+ throw new AsterixTemporalTypeParseException(
+ "The given format string is not fully used for the given data string");
+ } else {
+ return false;
+ }
}
- if (parseMode == DateTimeParseMode.TIME_ONLY) {
- return CAL.getChronon(hour, min, sec, ms, timezone);
+ long chronon = parseMode == DateTimeParseMode.TIME_ONLY ? CAL.getChronon(hour, min, sec, ms, timezone)
+ : CAL.getChronon(year, month, day, hour, min, sec, ms, timezone);
+ outChronon.setValue(chronon);
+ if (outTimeZoneExists != null) {
+ outTimeZoneExists.setValue(timezoneExists);
}
- return CAL.getChronon(year, month, day, hour, min, sec, ms, timezone);
+ if (outTimeZone != null) {
+ outTimeZone.setValue(timezone);
+ }
+ return true;
}
public void printDateTime(long chronon, int timezone, byte[] format, int formatStart, int formatLength,
@@ -720,15 +805,15 @@
int sec = CAL.getSecOfMin(chronon);
int ms = CAL.getMillisOfSec(chronon);
- int formatCharCopies = 0;
+ int formatCharCopies;
int formatPointer = 0;
byte separatorChar = '\0';
- DateTimeProcessState processState = DateTimeProcessState.INIT;
+ DateTimeProcessState processState;
- int pointerMove = 0;
+ int pointerMove;
boolean usePM = false;
if (indexOf(format, formatStart, formatLength, 'a') >= 0) {
@@ -860,8 +945,6 @@
try {
switch (processState) {
- case INIT:
- break;
case YEAR:
if (year < 0) {
appender.append('-');
@@ -945,12 +1028,13 @@
appender.append('-');
timezone *= -1;
}
- int timezoneField = timezone / MS_PER_HOUR;
+ int timezoneField = (int) (timezone / GregorianCalendarSystem.CHRONON_OF_HOUR);
if (timezoneField < 10) {
appender.append('0');
}
appender.append(String.valueOf(timezoneField));
- timezoneField = timezone % MS_PER_HOUR / MS_PER_MINUTE;
+ timezoneField = (int) (timezone % GregorianCalendarSystem.CHRONON_OF_HOUR
+ / GregorianCalendarSystem.CHRONON_OF_MINUTE);
if (timezoneField < 10) {
appender.append('0');
}
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 2e32378..a50adc6 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
@@ -69,14 +69,14 @@
int ms = GREG_CAL.getMillisOfSec(pointChronon);
// Apply the year-month duration
- int carry = yearMonthDuration / 12;
- month += (yearMonthDuration % 12);
+ int carry = yearMonthDuration / GregorianCalendarSystem.MONTHS_IN_A_YEAR;
+ month += (yearMonthDuration % GregorianCalendarSystem.MONTHS_IN_A_YEAR);
if (month < 1) {
- month += 12;
+ month += GregorianCalendarSystem.MONTHS_IN_A_YEAR;
carry -= 1;
- } else if (month > 12) {
- month -= 12;
+ } else if (month > GregorianCalendarSystem.MONTHS_IN_A_YEAR) {
+ month -= GregorianCalendarSystem.MONTHS_IN_A_YEAR;
carry += 1;
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
index dd711a8..ab07620 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java
@@ -64,11 +64,14 @@
public static final int[] DAYS_SINCE_MONTH_BEGIN_ORDI = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ public static final int MONTHS_IN_A_YEAR = 12;
+ public static final int DAYS_IN_A_WEEK = 7;
+
public static final long CHRONON_OF_SECOND = 1000;
public static final long CHRONON_OF_MINUTE = 60 * CHRONON_OF_SECOND;
public static final long CHRONON_OF_HOUR = 60 * CHRONON_OF_MINUTE;
public static final long CHRONON_OF_DAY = 24 * CHRONON_OF_HOUR;
- public static final int MONTHS_IN_A_YEAR = 12;
+ public static final long CHRONON_OF_WEEK = DAYS_IN_A_WEEK * CHRONON_OF_DAY;
/**
* Minimum feasible value of each field
@@ -104,6 +107,9 @@
*/
private static final int DAYS_0000_TO_1970 = 719527;
+ // Fixed week day anchor: Thursday, 1 January 1970
+ private final static int ANCHOR_WEEKDAY = 4;
+
private static final GregorianCalendarSystem instance = new GregorianCalendarSystem();
private GregorianCalendarSystem() {
@@ -247,7 +253,7 @@
return chronon - timezone;
}
- public static int getChrononInDays(long chronon) {
+ public int getChrononInDays(long chronon) {
if (chronon >= 0) {
return (int) (chronon / CHRONON_OF_DAY);
} else {
@@ -274,6 +280,24 @@
*/
public void getExtendStringRepUntilField(long chrononTime, int timezone, Appendable sbder, Fields startField,
Fields untilField, boolean withTimezone) throws IOException {
+ getExtendStringRepUntilField(chrononTime, timezone, sbder, startField, untilField, withTimezone, 'T');
+ }
+
+ /**
+ * Get the extended string representation of the given UTC chronon time under the given time zone. Only fields
+ * before
+ * the given field index will be returned.
+ * <p/>
+ * The extended string representation is like:<br/>
+ * [-]YYYY-MM-DDThh:mm:ss.xxx[Z|[+|-]hh:mm]
+ *
+ * @param chrononTime
+ * @param timezone
+ * @param sbder
+ * @param untilField
+ */
+ public void getExtendStringRepUntilField(long chrononTime, int timezone, Appendable sbder, Fields startField,
+ Fields untilField, boolean withTimezone, char dateTimeSeparator) throws IOException {
int year = getYear(chrononTime);
int month = getMonthOfYear(chrononTime, year);
@@ -287,7 +311,7 @@
}
case MONTH:
if (startField != Fields.MONTH) {
- sbder.append("-");
+ sbder.append('-');
}
sbder.append(String.format("%02d", month));
if (untilField == Fields.MONTH) {
@@ -295,7 +319,7 @@
}
case DAY:
if (startField != Fields.DAY) {
- sbder.append("-");
+ sbder.append('-');
}
sbder.append(String.format("%02d", getDayOfMonthYear(chrononTime, year, month)));
if (untilField == Fields.DAY) {
@@ -303,7 +327,7 @@
}
case HOUR:
if (startField != Fields.HOUR) {
- sbder.append("T");
+ sbder.append(dateTimeSeparator);
}
sbder.append(String.format("%02d", getHourOfDay(chrononTime)));
if (untilField == Fields.HOUR) {
@@ -311,7 +335,7 @@
}
case MINUTE:
if (startField != Fields.MINUTE) {
- sbder.append(":");
+ sbder.append(':');
}
sbder.append(String.format("%02d", getMinOfHour(chrononTime)));
if (untilField == Fields.MINUTE) {
@@ -319,25 +343,29 @@
}
case SECOND:
if (startField != Fields.SECOND) {
- sbder.append(":");
+ sbder.append(':');
}
sbder.append(String.format("%02d", getSecOfMin(chrononTime)));
+ if (untilField == Fields.SECOND) {
+ break;
+ }
+ case MILLISECOND:
+ if (startField != Fields.MILLISECOND) {
+ sbder.append('.');
+ }
// add millisecond as the precision fields of a second
- sbder.append(".").append(String.format("%03d", getMillisOfSec(chrononTime)));
+ sbder.append(String.format("%03d", getMillisOfSec(chrononTime)));
break;
}
if (withTimezone) {
if (timezone == 0) {
- sbder.append("Z");
+ sbder.append('Z');
} else {
- int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
- if (tzMin < 0) {
- tzMin = (short) (-1 * tzMin);
- }
+ int tzMin = (int) ((timezone % CHRONON_OF_HOUR) / CHRONON_OF_MINUTE);
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));
+ sbder.append(tzHr >= 0 ? '-' : '+').append(String.format("%02d", tzHr < 0 ? -tzHr : tzHr)).append(':')
+ .append(String.format("%02d", tzMin < 0 ? -tzMin : tzMin));
}
}
}
@@ -390,14 +418,14 @@
if (withTimezone) {
if (timezone == 0) {
- sbder.append("Z");
+ sbder.append('Z');
} else {
int tzMin = (int) (timezone % CHRONON_OF_HOUR / CHRONON_OF_MINUTE);
if (tzMin < 0) {
tzMin = (short) (-1 * tzMin);
}
int tzHr = (int) (timezone / CHRONON_OF_HOUR);
- sbder.append((tzHr >= 0 ? "-" : "+")).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
+ sbder.append((tzHr >= 0 ? '-' : '+')).append(String.format("%02d", (tzHr < 0 ? -tzHr : tzHr)))
.append(String.format("%02d", tzMin));
}
}
@@ -434,20 +462,36 @@
int day = getDurationDay(milliseconds);
if (!positive) {
- sbder.append("-");
+ sbder.append('-');
}
- sbder.append("P");
- sbder.append((year != 0) ? year + "Y" : "");
- sbder.append((month != 0) ? month + "M" : "");
- sbder.append((day != 0) ? day + "D" : "");
- sbder.append((hour != 0 || minute != 0 || second != 0 || millisecond != 0) ? "T" : "");
- sbder.append((hour != 0) ? hour + "H" : "");
- sbder.append((minute != 0) ? minute + "M" : "");
- sbder.append((second != 0 || millisecond != 0) ? second : "");
+ sbder.append('P');
+ if (year != 0) {
+ sbder.append(year).append('Y');
+ }
+ if (month != 0) {
+ sbder.append(month).append('M');
+ }
+ if (day != 0) {
+ sbder.append(day).append('D');
+ }
+ if (hour != 0 || minute != 0 || second != 0 || millisecond != 0) {
+ sbder.append('T');
+ }
+ if (hour != 0) {
+ sbder.append(hour).append('H');
+ }
+ if (minute != 0) {
+ sbder.append(minute).append('M');
+ }
+ if (second != 0 || millisecond != 0) {
+ sbder.append(second);
+ }
if (millisecond > 0) {
- sbder.append("." + millisecond);
+ sbder.append('.').append(millisecond);
}
- sbder.append((second != 0 || millisecond != 0) ? "S" : "");
+ if (second != 0 || millisecond != 0) {
+ sbder.append('S');
+ }
}
/**
@@ -617,6 +661,32 @@
}
/**
+ * Get the day number in the year for the input chronon time.
+ * @param millis
+ * @param year
+ * @return
+ */
+ public int getDayOfYear(long millis, int year) {
+ long dateMillis = chrononizeBeginningOfYear(year);
+ return (int) ((millis - dateMillis) / CHRONON_OF_DAY) + 1;
+ }
+
+ /**
+ * Get the week number in the year for the input chronon time.
+ * @param millis
+ * @param year
+ * @return
+ */
+ public int getWeekOfYear(long millis, int year) {
+ int doy = getDayOfYear(millis, year);
+ int week = doy / DAYS_IN_A_WEEK;
+ if (doy % DAYS_IN_A_WEEK > 0) {
+ week++;
+ }
+ return week;
+ }
+
+ /**
* Get the hour of the day for the given chronon time.
*
* @param millis
@@ -692,6 +762,26 @@
return ms;
}
+ /**
+ * Get the day of week for the given chronon time. 0 (Sunday) to 7 (Saturday)
+ *
+ * @param millis
+ * @return
+ */
+ public int getDayOfWeek(long millis) {
+ long daysSinceAnchor = getChrononInDays(millis);
+
+ // compute the weekday (0-based, and 0 = Sunday). Adjustment is needed as the anchor day is Thursday.
+ int weekday = (int) ((daysSinceAnchor + ANCHOR_WEEKDAY) % DAYS_IN_A_WEEK);
+
+ // handle the negative weekday
+ if (weekday < 0) {
+ weekday += DAYS_IN_A_WEEK;
+ }
+
+ return weekday;
+ }
+
public int getDurationMonth(int months) {
return (months % 12);
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
index 0e1942ec..e2a3614 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java
@@ -87,6 +87,7 @@
private ISerializerDeserializer<AInterval> intervalSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINTERVAL);
private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final GregorianCalendarSystem cal = GregorianCalendarSystem.getInstance();
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
@@ -142,8 +143,8 @@
ATypeTag.SERIALIZED_DATE_TYPE_TAG, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
}
- intervalStart = GregorianCalendarSystem.getChrononInDays(intervalStart);
- intervalEnd = GregorianCalendarSystem.getChrononInDays(intervalEnd);
+ intervalStart = cal.getChrononInDays(intervalStart);
+ intervalEnd = cal.getChrononInDays(intervalEnd);
if (intervalEnd < intervalStart) {
throw new InvalidDataFormatException(getIdentifier(),
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
index 8bced98..c2a11bb 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java
@@ -57,7 +57,6 @@
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
- evalValue.evaluate(tuple, result);
evalTime.evaluate(tuple, argTime);
final byte[] bytes = argTime.getByteArray();
@@ -76,6 +75,8 @@
LOGGER.log(Level.INFO, ctx.getTaskAttemptId() + " done sleeping for " + time + " ms");
}
}
+
+ evalValue.evaluate(tuple, result);
}
};
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
index 6db6a46..4b326d9 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java
@@ -121,7 +121,7 @@
Fields.MILLISECOND, true);
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- utf8Writer.writeUTF8(sbder.toString(), out);
+ utf8Writer.writeUTF8(sbder, out);
} catch (IOException e1) {
throw new HyracksDataException(e1);
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
index 6e8eb19..c8dc4ce 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java
@@ -119,7 +119,7 @@
Fields.MILLISECOND, true);
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- writer.writeUTF8(sbder.toString(), out);
+ writer.writeUTF8(sbder, out);
} catch (IOException e1) {
throw new HyracksDataException(e1);
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
index 6a3e128..7bb4265 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
@@ -47,8 +47,6 @@
public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
public final static FunctionIdentifier FID = BuiltinFunctions.DAY_OF_WEEK;
- // Fixed week day anchor: Thursday, 1 January 1970
- private final static int ANCHOR_WEEKDAY = 4;
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@@ -73,6 +71,8 @@
private IPointable argPtr = new VoidPointable();
private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
+ private GregorianCalendarSystem cal = GregorianCalendarSystem.getInstance();
+
// possible returning types
@SuppressWarnings("unchecked")
private ISerializerDeserializer<AInt64> int64Serde =
@@ -87,37 +87,22 @@
byte[] bytes = argPtr.getByteArray();
int offset = argPtr.getStartOffset();
- int daysSinceAnchor;
- int reminder = 0;
+ long chronon;
if (bytes[offset] == ATypeTag.SERIALIZED_DATETIME_TYPE_TAG) {
- daysSinceAnchor = (int) (ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1)
- / GregorianCalendarSystem.CHRONON_OF_DAY);
- reminder = (int) (ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1)
- % GregorianCalendarSystem.CHRONON_OF_DAY);
+ chronon = ADateTimeSerializerDeserializer.getChronon(bytes, offset + 1);
} else if (bytes[offset] == ATypeTag.SERIALIZED_DATE_TYPE_TAG) {
- daysSinceAnchor = ADateSerializerDeserializer.getChronon(bytes, offset + 1);
+ chronon = ADateSerializerDeserializer.getChronon(bytes, offset + 1)
+ * GregorianCalendarSystem.CHRONON_OF_DAY;
} else {
throw new TypeMismatchException(getIdentifier(), 0, bytes[offset],
ATypeTag.SERIALIZED_DATETIME_TYPE_TAG, ATypeTag.SERIALIZED_DATE_TYPE_TAG);
}
- // 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;
- }
+ int weekday = cal.getDayOfWeek(chronon);
// convert from 0-based to 1-based (so 7 = Sunday)
if (weekday == 0) {
- weekday = 7;
+ weekday = GregorianCalendarSystem.DAYS_IN_A_WEEK;
}
aInt64.setValue(weekday);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
index e463eed..f8d5cf7 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java
@@ -23,10 +23,10 @@
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.ADate;
import org.apache.asterix.om.base.AMutableDate;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import org.apache.asterix.om.base.AMutableInt64;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
-import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
+import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -49,14 +49,15 @@
/**
* <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.
+ * 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.
*/
public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_DATE;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
- public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
return new ParseDateDescriptor();
@@ -72,20 +73,23 @@
public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
return new IScalarEvaluator() {
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable argPtr0 = new VoidPointable();
- private IPointable argPtr1 = new VoidPointable();
- private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
- private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ private final DataOutput out = resultStorage.getDataOutput();
+ private final IPointable argPtr0 = new VoidPointable();
+ private final IPointable argPtr1 = new VoidPointable();
+ private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+ private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
@SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADate> dateSerde =
+ private final ISerializerDeserializer<ADate> dateSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATE);
- private AMutableDate aDate = new AMutableDate(0);
+ private final AMutableInt64 aInt64 = new AMutableInt64(0);
+ private final AMutableDate aDate = new AMutableDate(0);
private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -115,7 +119,6 @@
utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
int start1 = utf8Ptr.getCharStartOffset();
int length1 = utf8Ptr.getUTF8Length();
- long chronon = 0;
int formatStart = start1;
int formatLength;
@@ -128,19 +131,14 @@
break;
}
}
- try {
- chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
- formatLength, DateTimeParseMode.DATE_ONLY);
- } catch (AsterixTemporalTypeParseException ex) {
- formatStart += formatLength + 1;
- continue;
- }
- processSuccessfully = true;
+ processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+ formatStart, formatLength, DateTimeParseMode.DATE_ONLY, false);
+ formatStart += formatLength + 1;
}
if (!processSuccessfully) {
throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_DATE_TYPE_TAG);
}
- aDate.setValue((int) (chronon / GregorianCalendarSystem.CHRONON_OF_DAY));
+ aDate.setValue((int) (aInt64.getLongValue() / GregorianCalendarSystem.CHRONON_OF_DAY));
dateSerde.serialize(aDate, out);
result.set(resultStorage);
}
@@ -155,7 +153,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PARSE_DATE;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
index a391529..8bb1a20 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java
@@ -23,7 +23,7 @@
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.ADateTime;
import org.apache.asterix.om.base.AMutableDateTime;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
+import org.apache.asterix.om.base.AMutableInt64;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import org.apache.asterix.om.functions.BuiltinFunctions;
@@ -48,10 +48,8 @@
public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_DATETIME;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
- public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@Override
public IFunctionDescriptor createFunctionDescriptor() {
return new ParseDateTimeDescriptor();
@@ -67,20 +65,23 @@
public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
return new IScalarEvaluator() {
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable argPtr0 = new VoidPointable();
- private IPointable argPtr1 = new VoidPointable();
- private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
- private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ private final DataOutput out = resultStorage.getDataOutput();
+ private final IPointable argPtr0 = new VoidPointable();
+ private final IPointable argPtr1 = new VoidPointable();
+ private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+ private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
@SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADateTime> datetimeSerde =
+ private final ISerializerDeserializer<ADateTime> datetimeSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATETIME);
- private AMutableDateTime aDateTime = new AMutableDateTime(0);
+ private final AMutableInt64 aInt64 = new AMutableInt64(0);
+ private final AMutableDateTime aDateTime = new AMutableDateTime(0);
private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -109,7 +110,6 @@
utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
int start1 = utf8Ptr.getCharStartOffset();
int length1 = utf8Ptr.getUTF8Length();
- long chronon = 0;
int formatStart = start1;
int formatLength;
@@ -122,21 +122,15 @@
break;
}
}
- try {
- chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
- formatLength, DateTimeParseMode.DATETIME);
- } catch (AsterixTemporalTypeParseException ex) {
- formatStart += formatLength + 1;
- continue;
- }
- processSuccessfully = true;
+ processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+ formatStart, formatLength, DateTimeParseMode.DATETIME, false);
+ formatStart += formatLength + 1;
}
-
if (!processSuccessfully) {
throw new InvalidDataFormatException(getIdentifier(),
ATypeTag.SERIALIZED_DATETIME_TYPE_TAG);
}
- aDateTime.setValue(chronon);
+ aDateTime.setValue(aInt64.getLongValue());
datetimeSerde.serialize(aDateTime, out);
result.set(resultStorage);
}
@@ -151,7 +145,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PARSE_DATETIME;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
index 948c779..6b9488d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java
@@ -21,9 +21,9 @@
import java.io.DataOutput;
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
import org.apache.asterix.om.base.AMutableTime;
import org.apache.asterix.om.base.ATime;
-import org.apache.asterix.om.base.temporal.AsterixTemporalTypeParseException;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
import org.apache.asterix.om.functions.BuiltinFunctions;
@@ -48,11 +48,8 @@
public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PARSE_TIME;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-
@Override
public IFunctionDescriptor createFunctionDescriptor() {
return new ParseTimeDescriptor();
@@ -68,20 +65,23 @@
public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
return new IScalarEvaluator() {
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable argPtr0 = new VoidPointable();
- private IPointable argPtr1 = new VoidPointable();
- private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
- private IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ private final DataOutput out = resultStorage.getDataOutput();
+ private final IPointable argPtr0 = new VoidPointable();
+ private final IPointable argPtr1 = new VoidPointable();
+ private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+ private final IScalarEvaluator eval1 = args[1].createScalarEvaluator(ctx);
@SuppressWarnings("unchecked")
- private ISerializerDeserializer<ATime> timeSerde =
+ private final ISerializerDeserializer<ATime> timeSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ATIME);
- private AMutableTime aTime = new AMutableTime(0);
+ private final AMutableInt64 aInt64 = new AMutableInt64(0);
+ private final AMutableTime aTime = new AMutableTime(0);
private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -110,7 +110,6 @@
utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
int start1 = utf8Ptr.getCharStartOffset();
int length1 = utf8Ptr.getUTF8Length();
- long chronon = 0;
int formatStart = start1;
int formatLength;
@@ -123,21 +122,14 @@
break;
}
}
- try {
- chronon = DT_UTILS.parseDateTime(bytes0, start0, length0, bytes1, formatStart,
- formatLength, DateTimeParseMode.TIME_ONLY);
- } catch (AsterixTemporalTypeParseException ex) {
- formatStart += formatLength + 1;
- continue;
- }
- processSuccessfully = true;
+ processSuccessfully = util.parseDateTime(aInt64, bytes0, start0, length0, bytes1,
+ formatStart, formatLength, DateTimeParseMode.TIME_ONLY, false);
+ formatStart += formatLength + 1;
}
-
if (!processSuccessfully) {
throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
}
-
- aTime.setValue((int) chronon);
+ aTime.setValue((int) aInt64.getLongValue());
timeSerde.serialize(aTime, out);
result.set(resultStorage);
}
@@ -152,7 +144,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PARSE_TIME;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
index 1ddb7e8..2879576 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateDescriptor.java
@@ -23,14 +23,14 @@
import org.apache.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
-import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
@@ -45,8 +45,6 @@
public class PrintDateDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PRINT_DATE;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@@ -76,6 +74,8 @@
private StringBuilder sbder = new StringBuilder();
private final UTF8StringWriter utf8Writer = new UTF8StringWriter();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -101,11 +101,11 @@
int formatLength = UTF8StringUtil.getUTFLength(bytes1, offset1 + 1);
int offset = UTF8StringUtil.getNumBytesToStoreLength(formatLength);
sbder.delete(0, sbder.length());
- DT_UTILS.printDateTime(chronon, 0, bytes1, offset1 + 1 + offset, formatLength, sbder,
+ util.printDateTime(chronon, 0, bytes1, offset1 + 1 + offset, formatLength, sbder,
DateTimeParseMode.DATE_ONLY);
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- utf8Writer.writeUTF8(sbder.toString(), out);
+ utf8Writer.writeUTF8(sbder, out);
} catch (IOException ex) {
throw new HyracksDataException(ex);
}
@@ -113,7 +113,6 @@
}
};
}
-
};
}
@@ -122,7 +121,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PRINT_DATE;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
index b9f6e50..6f22bf1 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintDateTimeDescriptor.java
@@ -24,12 +24,12 @@
import org.apache.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
@@ -44,8 +44,6 @@
public class PrintDateTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PRINT_DATETIME;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@@ -75,6 +73,8 @@
private UTF8StringWriter utf8Writer = new UTF8StringWriter();
private UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -100,11 +100,11 @@
utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
int formatLength = utf8Ptr.getUTF8Length();
sbder.delete(0, sbder.length());
- DT_UTILS.printDateTime(chronon, 0, utf8Ptr.getByteArray(), utf8Ptr.getCharStartOffset(),
+ util.printDateTime(chronon, 0, utf8Ptr.getByteArray(), utf8Ptr.getCharStartOffset(),
formatLength, sbder, DateTimeParseMode.DATETIME);
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- utf8Writer.writeUTF8(sbder.toString(), out);
+ utf8Writer.writeUTF8(sbder, out);
} catch (IOException ex) {
throw new HyracksDataException(ex);
}
@@ -112,7 +112,6 @@
}
};
}
-
};
}
@@ -121,7 +120,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PRINT_DATETIME;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
index 51c9dcd..0e7004f 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/PrintTimeDescriptor.java
@@ -24,12 +24,12 @@
import org.apache.asterix.dataflow.data.nontagged.serde.ATimeSerializerDeserializer;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils;
import org.apache.asterix.om.base.temporal.DateTimeFormatUtils.DateTimeParseMode;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
import org.apache.asterix.om.functions.BuiltinFunctions;
import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
@@ -44,8 +44,6 @@
public class PrintTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public final static FunctionIdentifier FID = BuiltinFunctions.PRINT_TIME;
- private final static DateTimeFormatUtils DT_UTILS = DateTimeFormatUtils.getInstance();
public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
@@ -74,6 +72,8 @@
private final UTF8StringWriter writer = new UTF8StringWriter();
private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
+ private final DateTimeFormatUtils util = DateTimeFormatUtils.getInstance();
+
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
resultStorage.reset();
@@ -100,11 +100,11 @@
utf8Ptr.set(bytes1, offset1 + 1, len1 - 1);
int formatLength = utf8Ptr.getUTF8Length();
sbder.delete(0, sbder.length());
- DT_UTILS.printDateTime(chronon, 0, utf8Ptr.getByteArray(), utf8Ptr.getCharStartOffset(),
+ util.printDateTime(chronon, 0, utf8Ptr.getByteArray(), utf8Ptr.getCharStartOffset(),
formatLength, sbder, DateTimeParseMode.TIME_ONLY);
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- writer.writeUTF8(sbder.toString(), out);
+ writer.writeUTF8(sbder, out);
} catch (IOException ex) {
throw new HyracksDataException(ex);
}
@@ -112,7 +112,6 @@
}
};
}
-
};
}
@@ -121,7 +120,6 @@
*/
@Override
public FunctionIdentifier getIdentifier() {
- return FID;
+ return BuiltinFunctions.PRINT_TIME;
}
-
}
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/context/IHyracksJobletContext.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/context/IHyracksJobletContext.java
index 1100335..7a59926 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/context/IHyracksJobletContext.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/context/IHyracksJobletContext.java
@@ -31,6 +31,8 @@
JobId getJobId();
+ long getJobStartTime();
+
ICounterContext getCounterContext();
Object getGlobalJobData();
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/executor/JobExecutor.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/executor/JobExecutor.java
index ac06344..5245571 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/executor/JobExecutor.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/main/java/org/apache/hyracks/control/cc/executor/JobExecutor.java
@@ -518,7 +518,8 @@
byte[] jagBytes = changed ? acgBytes : null;
node.getNodeController().startTasks(deploymentId, jobId, jagBytes, taskDescriptors,
connectorPolicies, jobRun.getFlags(),
- ccs.createOrGetJobParameterByteStore(jobId).getParameterMap(), deployedJobSpecId);
+ ccs.createOrGetJobParameterByteStore(jobId).getParameterMap(), deployedJobSpecId,
+ jobRun.getStartTime());
}
}
} catch (Exception e) {
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
index 9ec55f4..92764a7 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/base/INodeController.java
@@ -38,7 +38,7 @@
public interface INodeController {
void startTasks(DeploymentId deploymentId, JobId jobId, byte[] planBytes,
List<TaskAttemptDescriptor> taskDescriptors, Map<ConnectorDescriptorId, IConnectorPolicy> connectorPolicies,
- Set<JobFlag> flags, Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId)
+ Set<JobFlag> flags, Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId, long startTime)
throws Exception;
void abortTasks(JobId jobId, List<TaskAttemptId> tasks) throws Exception;
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
index c10c8981..8e02936 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/CCNCFunctions.java
@@ -764,11 +764,12 @@
private final Set<JobFlag> flags;
private final Map<byte[], byte[]> jobParameters;
private final DeployedJobSpecId deployedJobSpecId;
+ private final long jobStartTime;
public StartTasksFunction(DeploymentId deploymentId, JobId jobId, byte[] planBytes,
List<TaskAttemptDescriptor> taskDescriptors,
Map<ConnectorDescriptorId, IConnectorPolicy> connectorPolicies, Set<JobFlag> flags,
- Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId) {
+ Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId, long jobStartTime) {
this.deploymentId = deploymentId;
this.jobId = jobId;
this.planBytes = planBytes;
@@ -777,6 +778,7 @@
this.flags = flags;
this.jobParameters = jobParameters;
this.deployedJobSpecId = deployedJobSpecId;
+ this.jobStartTime = jobStartTime;
}
@Override
@@ -816,6 +818,10 @@
return flags;
}
+ public long getJobStartTime() {
+ return jobStartTime;
+ }
+
public static Object deserialize(ByteBuffer buffer, int length) throws Exception {
ByteArrayInputStream bais = new ByteArrayInputStream(buffer.array(), buffer.position(), length);
DataInputStream dis = new DataInputStream(bais);
@@ -885,8 +891,10 @@
deployedJobSpecId = DeployedJobSpecId.create(dis);
}
+ long jobStartTime = dis.readLong();
+
return new StartTasksFunction(deploymentId, jobId, planBytes, taskDescriptors, connectorPolicies, flags,
- jobParameters, deployedJobSpecId);
+ jobParameters, deployedJobSpecId, jobStartTime);
}
public static void serialize(OutputStream out, Object object) throws Exception {
@@ -935,11 +943,13 @@
}
//write deployed job spec id
- dos.writeBoolean(fn.getDeployedJobSpecId() == null ? false : true);
+ dos.writeBoolean(fn.getDeployedJobSpecId() != null);
if (fn.getDeployedJobSpecId() != null) {
fn.getDeployedJobSpecId().writeFields(dos);
}
+ //write job start time
+ dos.writeLong(fn.jobStartTime);
}
}
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
index 429cb26..b78e53f 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/ipc/NodeControllerRemoteProxy.java
@@ -63,10 +63,10 @@
@Override
public void startTasks(DeploymentId deploymentId, JobId jobId, byte[] planBytes,
List<TaskAttemptDescriptor> taskDescriptors, Map<ConnectorDescriptorId, IConnectorPolicy> connectorPolicies,
- Set<JobFlag> flags, Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId)
- throws Exception {
+ Set<JobFlag> flags, Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId,
+ long jobStartTime) throws Exception {
StartTasksFunction stf = new StartTasksFunction(deploymentId, jobId, planBytes, taskDescriptors,
- connectorPolicies, flags, jobParameters, deployedJobSpecId);
+ connectorPolicies, flags, jobParameters, deployedJobSpecId, jobStartTime);
ipcHandle.send(-1, stf, null);
}
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/Joblet.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/Joblet.java
index 8790434..55bc192 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/Joblet.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/Joblet.java
@@ -103,9 +103,11 @@
private final IJobletEventListenerFactory jobletEventListenerFactory;
+ private final long jobStartTime;
+
public Joblet(NodeControllerService nodeController, DeploymentId deploymentId, JobId jobId,
INCServiceContext serviceCtx, ActivityClusterGraph acg,
- IJobletEventListenerFactory jobletEventListenerFactory) {
+ IJobletEventListenerFactory jobletEventListenerFactory, long jobStartTime) {
this.nodeController = nodeController;
this.serviceCtx = serviceCtx;
this.deploymentId = deploymentId;
@@ -131,6 +133,7 @@
}
IGlobalJobDataFactory gjdf = acg.getGlobalJobDataFactory();
globalJobData = gjdf != null ? gjdf.createGlobalJobData(this) : null;
+ this.jobStartTime = jobStartTime;
}
@Override
@@ -151,6 +154,11 @@
return env;
}
+ @Override
+ public long getJobStartTime() {
+ return jobStartTime;
+ }
+
public void addTask(Task task) {
taskMap.put(task.getTaskAttemptId(), task);
}
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerIPCI.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerIPCI.java
index f55e250..735f7cf 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerIPCI.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NodeControllerIPCI.java
@@ -65,7 +65,7 @@
ncs.getWorkQueue()
.schedule(new StartTasksWork(ncs, stf.getDeploymentId(), stf.getJobId(), stf.getPlanBytes(),
stf.getTaskDescriptors(), stf.getConnectorPolicies(), stf.getFlags(),
- stf.getJobParameters(), stf.getDeployedJobSpecId()));
+ stf.getJobParameters(), stf.getDeployedJobSpecId(), stf.getJobStartTime()));
return;
case ABORT_TASKS:
CCNCFunctions.AbortTasksFunction atf = (CCNCFunctions.AbortTasksFunction) fn;
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/StartTasksWork.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/StartTasksWork.java
index 6a5785a..660621e 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/StartTasksWork.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/work/StartTasksWork.java
@@ -95,10 +95,12 @@
private final Map<byte[], byte[]> jobParameters;
+ private final long jobStartTime;
+
public StartTasksWork(NodeControllerService ncs, DeploymentId deploymentId, JobId jobId, byte[] acgBytes,
List<TaskAttemptDescriptor> taskDescriptors,
Map<ConnectorDescriptorId, IConnectorPolicy> connectorPoliciesMap, Set<JobFlag> flags,
- Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId) {
+ Map<byte[], byte[]> jobParameters, DeployedJobSpecId deployedJobSpecId, long jobStartTime) {
this.ncs = ncs;
this.deploymentId = deploymentId;
this.jobId = jobId;
@@ -108,6 +110,7 @@
this.connectorPoliciesMap = connectorPoliciesMap;
this.flags = flags;
this.jobParameters = jobParameters;
+ this.jobStartTime = jobStartTime;
}
@Override
@@ -212,7 +215,7 @@
}
listenerFactory.updateListenerJobParameters(ncs.createOrGetJobParameterByteStore(jobId));
}
- ji = new Joblet(ncs, deploymentId, jobId, appCtx, acg, listenerFactory);
+ ji = new Joblet(ncs, deploymentId, jobId, appCtx, acg, listenerFactory, jobStartTime);
jobletMap.put(jobId, ji);
}
return ji;
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/TestJobletContext.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/TestJobletContext.java
index 1d38d3d..b022b15 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/TestJobletContext.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/TestJobletContext.java
@@ -39,6 +39,7 @@
private final FrameManager frameManger;
private JobId jobId;
private WorkspaceFileFactory fileFactory;
+ private final long jobStartTime;
public TestJobletContext(int frameSize, INCServiceContext serviceContext, JobId jobId) throws HyracksException {
this.frameSize = frameSize;
@@ -46,6 +47,7 @@
this.jobId = jobId;
fileFactory = new WorkspaceFileFactory(this, (IIOManager) getIOManager());
this.frameManger = new FrameManager(frameSize);
+ this.jobStartTime = System.currentTimeMillis();
}
ByteBuffer allocateFrame() throws HyracksDataException {
@@ -113,6 +115,11 @@
}
@Override
+ public long getJobStartTime() {
+ return jobStartTime;
+ }
+
+ @Override
public Object getGlobalJobData() {
return null;
}