[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 <[email protected]> Contrib: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Till Westmann <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/8d284433 Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/8d284433 Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/8d284433 Branch: refs/heads/master Commit: 8d284433fc4e0e034ce2f032b256b04cb128680f Parents: c4eb7b1 Author: Dmitry Lychagin <[email protected]> Authored: Mon Mar 26 16:08:06 2018 -0700 Committer: Michael Blow <[email protected]> Committed: Mon Mar 26 20:52:41 2018 -0700 ---------------------------------------------------------------------- .../asterix/runtime/ParseDurationTest.java | 4 +- .../org/apache/asterix/common/api/Duration.java | 39 ++- .../src/main/markdown/sqlpp/3_query.md | 5 +- .../lang/common/util/CommonFunctionMapUtil.java | 96 +++---- .../om/base/temporal/DateTimeFormatUtils.java | 266 ++++++++++++------- .../temporal/DurationArithmeticOperations.java | 10 +- .../base/temporal/GregorianCalendarSystem.java | 148 +++++++++-- ...ervalStartFromDateConstructorDescriptor.java | 5 +- .../evaluators/functions/SleepDescriptor.java | 3 +- .../AdjustDateTimeForTimeZoneDescriptor.java | 2 +- .../AdjustTimeForTimeZoneDescriptor.java | 2 +- .../functions/temporal/DayOfWeekDescriptor.java | 31 +-- .../functions/temporal/ParseDateDescriptor.java | 49 ++-- .../temporal/ParseDateTimeDescriptor.java | 43 ++- .../functions/temporal/ParseTimeDescriptor.java | 43 ++- .../functions/temporal/PrintDateDescriptor.java | 16 +- .../temporal/PrintDateTimeDescriptor.java | 14 +- .../functions/temporal/PrintTimeDescriptor.java | 14 +- .../api/context/IHyracksJobletContext.java | 2 + .../control/cc/executor/JobExecutor.java | 3 +- .../control/common/base/INodeController.java | 2 +- .../control/common/ipc/CCNCFunctions.java | 16 +- .../common/ipc/NodeControllerRemoteProxy.java | 6 +- .../org/apache/hyracks/control/nc/Joblet.java | 10 +- .../hyracks/control/nc/NodeControllerIPCI.java | 2 +- .../hyracks/control/nc/work/StartTasksWork.java | 7 +- .../hyracks/test/support/TestJobletContext.java | 7 + 27 files changed, 521 insertions(+), 324 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ParseDurationTest.java ---------------------------------------------------------------------- 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 class ParseDurationTest { 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 @@ public class ParseDurationTest { 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)); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/Duration.java ---------------------------------------------------------------------- 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 @@ public enum Duration { 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 enum Duration { } 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 @@ public enum Duration { } 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 http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-doc/src/main/markdown/sqlpp/3_query.md ---------------------------------------------------------------------- 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 @@ The following is the equivalent rewritten query that will be generated by the co 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: http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java ---------------------------------------------------------------------- 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 @@ public class CommonFunctionMapUtil { 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 @@ public class CommonFunctionMapUtil { 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); + } } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DateTimeFormatUtils.java ---------------------------------------------------------------------- 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 @@ package org.apache.asterix.om.base.temporal; 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { private static final int MAX_TIMEZONE_CHARS = 1; private enum DateTimeProcessState { - INIT, YEAR, MONTH, DAY, @@ -124,13 +127,8 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { } }; - 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 final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils(); - private static class DateTimeFormatUtilsHolder { - private static final DateTimeFormatUtils INSTANCE = new DateTimeFormatUtils(); - - private DateTimeFormatUtilsHolder() { - } + public static DateTimeFormatUtils getInstance() { + return INSTANCE; } - public static DateTimeFormatUtils getInstance() { - return DateTimeFormatUtilsHolder.INSTANCE; + private DateTimeFormatUtils() { } private int parseFormatField(byte[] format, int formatStart, int formatLength, int formatPointer, char formatChar, @@ -274,20 +270,30 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { } switch (processState) { - case INIT: - break; case YEAR: if (dataStringPointer < dataLength && data[dataStart + dataStringPointer] == HYPHEN_CHAR) { negativeYear = true; @@ -435,8 +439,12 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { } // 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { } 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { } 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 @@ public class DateTimeFormatUtils { } 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); + } + if (outTimeZone != null) { + outTimeZone.setValue(timezone); } - return CAL.getChronon(year, month, day, hour, min, sec, ms, timezone); + return true; } public void printDateTime(long chronon, int timezone, byte[] format, int formatStart, int formatLength, @@ -720,15 +805,15 @@ public class DateTimeFormatUtils { 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 @@ public class DateTimeFormatUtils { try { switch (processState) { - case INIT: - break; case YEAR: if (year < 0) { appender.append('-'); @@ -945,12 +1028,13 @@ public class DateTimeFormatUtils { 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'); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/DurationArithmeticOperations.java ---------------------------------------------------------------------- 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 @@ public class DurationArithmeticOperations { 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; } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/base/temporal/GregorianCalendarSystem.java ---------------------------------------------------------------------- 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 class GregorianCalendarSystem implements ICalendarSystem { 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { */ 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { 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 class GregorianCalendarSystem implements ICalendarSystem { */ 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { } case MONTH: if (startField != Fields.MONTH) { - sbder.append("-"); + sbder.append('-'); } sbder.append(String.format("%02d", month)); if (untilField == Fields.MONTH) { @@ -295,7 +319,7 @@ public class GregorianCalendarSystem implements ICalendarSystem { } 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { } 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { } 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { } 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { int day = getDurationDay(milliseconds); if (!positive) { - 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('-'); + } + 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); + } + if (second != 0 || millisecond != 0) { + sbder.append('S'); } - sbder.append((second != 0 || millisecond != 0) ? "S" : ""); } /** @@ -617,6 +661,32 @@ public class GregorianCalendarSystem implements ICalendarSystem { } /** + * 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 @@ public class GregorianCalendarSystem implements ICalendarSystem { 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); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AIntervalStartFromDateConstructorDescriptor.java ---------------------------------------------------------------------- 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 0e1942e..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 @@ public class AIntervalStartFromDateConstructorDescriptor extends AbstractScalarF 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 @@ public class AIntervalStartFromDateConstructorDescriptor extends AbstractScalarF 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(), http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SleepDescriptor.java ---------------------------------------------------------------------- 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 @@ public class SleepDescriptor extends AbstractScalarFunctionDynamicDescriptor { @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 @@ public class SleepDescriptor extends AbstractScalarFunctionDynamicDescriptor { LOGGER.log(Level.INFO, ctx.getTaskAttemptId() + " done sleeping for " + time + " ms"); } } + + evalValue.evaluate(tuple, result); } }; } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustDateTimeForTimeZoneDescriptor.java ---------------------------------------------------------------------- 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 @@ public class AdjustDateTimeForTimeZoneDescriptor extends AbstractScalarFunctionD 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); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/AdjustTimeForTimeZoneDescriptor.java ---------------------------------------------------------------------- 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 @@ public class AdjustTimeForTimeZoneDescriptor extends AbstractScalarFunctionDynam 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); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java ---------------------------------------------------------------------- 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 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; 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 @@ public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor 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); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateDescriptor.java ---------------------------------------------------------------------- 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 java.io.DataOutput; 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 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; /** * <b>|(bar)</b> is a special separator used to separate different formatting options. - * Multiple format strings can be used by separating them using <b>|(bar)</b>, and the parsing will be successful only when the format string has the <b>exact</b> match with the given data string. This means that a time string like <it>08:23:12 AM</it> will not be valid for the format string <it>h:m:s</it> as there is no AM/PM format character in the format string. + * 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 class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseDateDescriptor extends AbstractScalarFunctionDynamicDescriptor */ @Override public FunctionIdentifier getIdentifier() { - return FID; + return BuiltinFunctions.PARSE_DATE; } - } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseDateTimeDescriptor.java ---------------------------------------------------------------------- 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 java.io.DataOutput; 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 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; 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 class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri 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 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri 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 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri 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 @@ public class ParseDateTimeDescriptor extends AbstractScalarFunctionDynamicDescri */ @Override public FunctionIdentifier getIdentifier() { - return FID; + return BuiltinFunctions.PARSE_DATETIME; } - } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/8d284433/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/temporal/ParseTimeDescriptor.java ---------------------------------------------------------------------- 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 @@ package org.apache.asterix.runtime.evaluators.functions.temporal; 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 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; 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 class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor 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 @@ public class ParseTimeDescriptor extends AbstractScalarFunctionDynamicDescriptor */ @Override public FunctionIdentifier getIdentifier() { - return FID; + return BuiltinFunctions.PARSE_TIME; } - }
