Merge branch 'master' into salsubaiee/master_issue_596
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql
index 53e1285..9f9f0d2 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/parse_01/parse_01.3.query.aql
@@ -10,6 +10,8 @@
"date3": parse-date("-1234-01-01", "YYYY-MM-DD"),
"date4": parse-date("09/11/-1980", "D/M/Y"),
"date5": parse-date("09/11/-1990", "YY-M-D|MMM D Y|D/M/Y"),
+ "date6": parse-date("Mon Aug 19 2013", "W MMM D Y"),
+ "data7": parse-date("SKIPMEPLEASE Mon Aug SKIPME1ALSO 19 2013", "O W MMM O D Y"),
"time1": parse-time("8:23:49", "h:m:s"),
"time2": parse-time("8.19.23:32", "h.m.s:nn"),
"time3": parse-time("08.19.23:32 pm", "h.m.s:nn a"),
@@ -19,4 +21,6 @@
"datetime2": parse-datetime("12/30/-1203 03:48:27.392 PM Asia/Shanghai", "MM/DD/YYY hh:mm:ss.nnn a z"),
"datetime3": parse-datetime("1723-12-03T23:59:23.392Z", "YYYY-MM-DDThh:mm:ss.nnnz"),
"datetime4": parse-datetime("1723-12-03T23:59:23.392-04:00", "YYYY-MM-DDThh:mm:ss.nnnz"),
- "datetime5": parse-datetime("1723-12-03T23:59:23.392-04:00", "MMM DD YYYY h:m:s a|MM/DD/YYY hh:mm:ss.nnn a z|YYYY-MM-DDThh:mm:ss.nnnz") }
\ No newline at end of file
+ "datetime5": parse-datetime("1723-12-03T23:59:23.392-04:00", "MMM DD YYYY h:m:s a|MM/DD/YYY hh:mm:ss.nnn a z|YYYY-MM-DDThh:mm:ss.nnnz"),
+ "datetime6": parse-datetime("1970-01-01 Thu 23:59:23.392-04:00", "MMM DD YYYY h:m:s a|MM/DD/YYY hh:mm:ss.nnn a z|YYYY-MM-DD W hh:mm:ss.nnnz"),
+ "datetime7": parse-datetime("1723-12-03 What3v3r STRINGHERE 23:59:23.392-04:00", "MMM DD YYYY h:m:s a|MM/DD/YYY hh:mm:ss.nnn a z|YYYY-MM-DD O O hh:mm:ss.nnnz") }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm
index f86335c..dee2631 100644
--- a/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/parse_01/parse_01.1.adm
@@ -1 +1 @@
-{ "date1": date("2013-08-23"), "date2": date("-0012-08-12"), "date3": date("-1234-01-01"), "date4": date("-1980-11-09"), "date5": date("-1990-11-09"), "time1": time("08:23:49.000Z"), "time2": time("08:19:23.320Z"), "time3": time("20:19:23.320Z"), "time4": time("10:30:40.948Z"), "time5": time("10:30:40.948Z"), "datetime1": datetime("-1203-12-30T15:48:27.000Z"), "datetime2": datetime("-1203-12-30T23:48:27.392Z"), "datetime3": datetime("1723-12-03T23:59:23.392Z"), "datetime4": datetime("1723-12-04T03:59:23.392Z"), "datetime5": datetime("1723-12-04T03:59:23.392Z") }
\ No newline at end of file
+{ "date1": date("2013-08-23"), "date2": date("-0012-08-12"), "date3": date("-1234-01-01"), "date4": date("-1980-11-09"), "date5": date("-1990-11-09"), "date6": date("2013-08-19"), "data7": date("2013-08-19"), "time1": time("08:23:49.000Z"), "time2": time("08:19:23.320Z"), "time3": time("20:19:23.320Z"), "time4": time("10:30:40.948Z"), "time5": time("10:30:40.948Z"), "datetime1": datetime("-1203-12-30T15:48:27.000Z"), "datetime2": datetime("-1203-12-30T23:48:27.392Z"), "datetime3": datetime("1723-12-03T23:59:23.392Z"), "datetime4": datetime("1723-12-04T03:59:23.392Z"), "datetime5": datetime("1723-12-04T03:59:23.392Z"), "datetime6": datetime("1970-01-02T03:59:23.392Z"), "datetime7": datetime("1723-12-04T03:59:23.392Z") }
\ No newline at end of file
diff --git a/asterix-doc/src/site/markdown/install.md b/asterix-doc/src/site/markdown/install.md
index 4d53f75..9ba8ea3 100644
--- a/asterix-doc/src/site/markdown/install.md
+++ b/asterix-doc/src/site/markdown/install.md
@@ -880,3 +880,32 @@
##### Answer #####
It is recommended that MANAGIX_HOME is not on the NFS. Managix produces artifacts/logs on disk which are not required to be shared.
As such an overhead in creating the artifacts/logs on the NFS should be avoided.
+
+##### Question #####
+
+Question: How do we change the underlying code (apply a code patch) for an 'active' asterix instance?
+
+##### Answer #####
+
+At times, end-user (particularly asterix developer) may run into the need to altering the underlying code that is being run by an asterix instance. In the current version of managix, this can be achieved as follows:-
+
+Assume that you have an 'active' instance by the name a1 that is running version v1 of asterix.
+You have a revised version of asterix - v2 that fixes some bug(s).
+
+To upgrade asterix from v1 to v2:-
+
+step 1) managix stop -n a1
+
+step 2) managix shutdown
+
+step 3) copy asterix-server zip (version v2) to $MANAGIX_HOME/asterix/
+
+step 4) managix start -n a1
+
+a1 now is running on version v2.
+
+Limitations:-
+
+a) Obviously this wont work in a situation where v2 has made a change that is incompatible with earlier version, such altering schema.
+
+b) A change in asterix zip applies to all existing instances (after a restart) and subsequent instances that user creates.
diff --git a/asterix-doc/src/site/site.xml b/asterix-doc/src/site/site.xml
index 8c2a8a8..150544e 100644
--- a/asterix-doc/src/site/site.xml
+++ b/asterix-doc/src/site/site.xml
@@ -59,7 +59,7 @@
</links>
<menu name="Documentation">
- <item name="Installing AsterixDB using Managix" href="install.html"/>
+ <item name="Installing and Managing AsterixDB using Managix" href="install.html"/>
<item name="AsterixDB 101: An ADM and AQL Primer" href="aql/primer.html"/>
<item name="Asterix Data Model (ADM)" href="aql/datamodel.html"/>
<item name="Asterix Functions" href="aql/functions.html"/>
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java
index bd74ad4..f0ee739 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/base/temporal/DateTimeFormatUtils.java
@@ -38,7 +38,7 @@
* -- <b>Z</b>: a single upper-case character representing the UTC timezone;<br/>
* -- <b>[UTC|GMT]+xx[:]xx</b>: representing a timezone by providing the actual offset time from the UTC time;<br/>
* -- A string representation of a timezone like PST, Asia/Shanghai. The names of the timezones are following the Zoneinfo database provided by the JDK library. See {@link TimeZone} for more details on this.<br/>
- * - <b>Separators</b>: separators that can be used to separate the different fields. Currently only the following characters can be used as separator: <b>-(hyphen), :(colon), /(solidus), .(period) and ,(comma)</b>.
+ * - <b>Separators</b>: separators that can be used to separate the different fields. Currently only the following characters can be used as separator: <b>-(hyphen), :(colon), /(solidus), .(period) and ,(comma)</b>.
* <p/>
* For the matching algorithm, both the format string and the data string are scanned from the beginning to the end, and the algorithm tried to match the format with the characters/digits/separators in the data string. The format string represents the <b>minimum</b> length of the required field (similar to the C-style printf formatting). This means that something like a year <it>1990</it> will match with the format strings <it>Y, YY, YYY and YYYY</it>.
* <p/>
@@ -68,12 +68,14 @@
YEAR,
MONTH,
DAY,
+ WEEKDAY,
HOUR,
MINUTE,
SECOND,
MILLISECOND,
AMPM,
TIMEZONE,
+ SKIPPER,
SEPARATOR
}
@@ -81,15 +83,21 @@
private final char YEAR_CHAR = 'Y';
private final char MONTH_CHAR = 'M';
private final char DAY_CHAR = 'D';
+ private final char WEEKDAY_CHAR = 'W';
private final int MAX_YEAR_CHARS = 4;
private final int MAX_MONTH_CHARS = 3;
private final int MAX_DAY_CHARS = 2;
+ private final int MAX_WEEKDAY_CHAR = 1;
private final byte[][] MONTH_NAMES = new byte[][] { "jan".getBytes(), "feb".getBytes(), "mar".getBytes(),
"apr".getBytes(), "may".getBytes(), "jun".getBytes(), "jul".getBytes(), "aug".getBytes(), "sep".getBytes(),
"oct".getBytes(), "nov".getBytes(), "dec".getBytes() };
+ private final byte[][] WEEKDAY_FULL_NAMES = new byte[][] { "monday".getBytes(), "tuesday".getBytes(),
+ "wednesday".getBytes(), "thursday".getBytes(), "friday".getBytes(), "saturday".getBytes(),
+ "sunday".getBytes() };
+
private final byte[] UTC_BYTEARRAY = "utc".getBytes();
private final byte[] GMT_BYTEARRAY = "gmt".getBytes();
@@ -104,6 +112,10 @@
private final char COMMA_CHAR = ',';
private final char T_CHAR = 'T';
+ // Skipper, representing a field with characters and numbers that to be skipped
+ private final char SKIPPER_CHAR = 'O';
+ private final int MAX_SKIPPER_CHAR = 1;
+
private final int MS_PER_MINUTE = 60 * 1000;
private final int MS_PER_HOUR = 60 * MS_PER_MINUTE;
@@ -163,17 +175,26 @@
}
private boolean byteArrayEqualToString(byte[] barray, int start, int length, byte[] str) {
- boolean equal = true;
- if (length == str.length) {
+ if (length != str.length) {
+ return false;
+ } else {
+ return byteArrayBeingWithString(barray, start, length, str);
+ }
+ }
+
+ private boolean byteArrayBeingWithString(byte[] barray, int start, int length, byte[] str) {
+ boolean beginWith = true;
+ if (length <= str.length) {
for (int i = 0; i < length; i++) {
if (toLower(barray[start + i]) != str[i]) {
- equal = false;
+ beginWith = false;
+ break;
}
}
} else {
- equal = false;
+ beginWith = false;
}
- return equal;
+ return beginWith;
}
private Comparator<byte[]> byteArrayComparator = new Comparator<byte[]>() {
@@ -203,6 +224,15 @@
return -1;
}
+ private int weekdayIDSearch(byte[] barray, int start, int length) {
+ for (int i = 0; i < WEEKDAY_FULL_NAMES.length; i++) {
+ if (byteArrayBeingWithString(barray, start, length, WEEKDAY_FULL_NAMES[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
private int binaryTimezoneIDSearch(byte[] barray, int start, int length) {
return Arrays.binarySearch(TIMEZONE_IDS, 0, TIMEZONE_IDS.length,
Arrays.copyOfRange(barray, start, start + length), byteArrayComparator);
@@ -271,6 +301,13 @@
formatPointer += pointerMove;
formatCharCopies += pointerMove;
break;
+ case WEEKDAY_CHAR:
+ processState = DateTimeProcessState.WEEKDAY;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, WEEKDAY_CHAR,
+ MAX_WEEKDAY_CHAR);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
case HOUR_CHAR:
processState = DateTimeProcessState.HOUR;
pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, HOUR_CHAR,
@@ -315,6 +352,13 @@
formatPointer += pointerMove;
formatCharCopies += pointerMove;
break;
+ case SKIPPER_CHAR:
+ processState = DateTimeProcessState.SKIPPER;
+ pointerMove = parseFormatField(format, formatStart, formatLength, formatPointer, SKIPPER_CHAR,
+ MAX_SKIPPER_CHAR);
+ formatPointer += pointerMove;
+ formatCharCopies += pointerMove;
+ break;
case ' ':
case HYPHEN_CHAR:
case COLON_CHAR:
@@ -439,6 +483,22 @@
}
}
break;
+ case WEEKDAY:
+ int processedWeekdayFieldsCount = 0;
+ while ((data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'a' && data[dataStart
+ + dataStringPointer + processedWeekdayFieldsCount] <= 'z')
+ || (data[dataStart + dataStringPointer + processedWeekdayFieldsCount] >= 'A' && data[dataStart
+ + dataStringPointer + processedWeekdayFieldsCount] <= 'Z')) {
+ processedWeekdayFieldsCount++;
+ }
+ // match the weekday name
+ if (weekdayIDSearch(data, dataStart + dataStringPointer, processedWeekdayFieldsCount) < 0) {
+ throw new AsterixTemporalTypeParseException("Unexpected string for day-of-week: "
+ + (new String(Arrays.copyOfRange(data, dataStart + dataStringPointer, dataStart
+ + dataStringPointer + processedWeekdayFieldsCount))));
+ }
+ dataStringPointer += processedWeekdayFieldsCount;
+ break;
case HOUR:
case MINUTE:
case SECOND:
@@ -589,6 +649,14 @@
throw new AsterixTemporalTypeParseException("Cannot find valid AM/PM marker.");
}
break;
+ case SKIPPER:
+ // just skip all continuous character and numbers
+ while ((data[dataStart + dataStringPointer] >= 'a' && data[dataStart + dataStringPointer] <= 'z')
+ || (data[dataStart + dataStringPointer] >= 'A' && data[dataStart + dataStringPointer] <= 'Z')
+ || (data[dataStart + dataStringPointer] >= '0' && data[dataStart + dataStringPointer] <= '9')) {
+ dataStringPointer++;
+ }
+ break;
case SEPARATOR:
if (separatorChar == '\0') {
throw new AsterixTemporalTypeParseException("Incorrect separator char in date string as "