Merge branch 'yingyi/asterix_fix' of https://code.google.com/p/asterixdb into yingyi/asterix_fix
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql
new file mode 100644
index 0000000..f92bdd4
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.1.ddl.aql
@@ -0,0 +1,7 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
+
+drop dataverse test if exists;
+create dataverse test;
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql
new file mode 100644
index 0000000..cf8a1ae
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.2.update.aql
@@ -0,0 +1,4 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql
new file mode 100644
index 0000000..fc1e705
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/day_of_week_01/day_of_week_01.3.query.aql
@@ -0,0 +1,12 @@
+/**
+ * day-of-week test case: test the day-of-week function
+ * Expected result: success
+ **/
+
+use dataverse test;
+
+let $d1 := date("2013-08-06")
+let $d2 := date("-2013-08-06")
+let $dt1 := datetime("1913-08-06T15:53:28Z")
+let $dt2 := datetime("-1913-08-10T15:53:28Z")
+return { "1970-01-01": day-of-week(date("1970-01-01")), "2013-08-06": day-of-week($d1), "-2013-08-06": day-of-week($d2), "1913-08-06T15:53:28Z": day-of-week($dt1), "-1913-08-10T15:53:28Z": day-of-week($dt2), "null": day-of-week(null) }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm
new file mode 100644
index 0000000..dff4aa2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/day_of_week_01/day_of_week_01.1.adm
@@ -0,0 +1 @@
+{ "1970-01-01": 4, "2013-08-06": 2, "-2013-08-06": 4, "1913-08-06T15:53:28Z": 3, "-1913-08-10T15:53:28Z": 7, "null": null }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index 50948f2..3a2a44e 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -4343,7 +4343,12 @@
</test-case>
</test-group>
<test-group name="temporal">
- <test-case FilePath="temporal">
+ <test-case FilePath="temporal">
+ <compilation-unit name="day_of_week_01">
+ <output-dir compare="Text">day_of_week_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="temporal">
<compilation-unit name="interval_bin">
<output-dir compare="Text">interval_bin</output-dir>
</compilation-unit>
diff --git a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
index 43c43a3..41cf3c1 100644
--- a/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterix-om/src/main/java/edu/uci/ics/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -540,6 +540,8 @@
FunctionConstants.ASTERIX_NS, "adjust-time-for-timezone", 2);
public final static FunctionIdentifier ADJUST_DATETIME_FOR_TIMEZONE = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "adjust-datetime-for-timezone", 2);
+ public final static FunctionIdentifier DAY_OF_WEEK = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+ "day-of-week");
public final static FunctionIdentifier GET_POINT_X_COORDINATE_ACCESSOR = new FunctionIdentifier(
FunctionConstants.ASTERIX_NS, "get-x", 1);
@@ -855,6 +857,7 @@
addFunction(GET_DAY_TIME_DURATION, OptionalADayTimeDurationTypeComputer.INSTANCE);
addFunction(GET_YEAR_MONTH_DURATION, OptionalAYearMonthDurationTypeComputer.INSTANCE);
addFunction(INTERVAL_BIN, OptionalAIntervalTypeComputer.INSTANCE);
+ addFunction(DAY_OF_WEEK, OptionalAInt32TypeComputer.INSTANCE);
// interval constructors
addFunction(INTERVAL_CONSTRUCTOR_DATE, OptionalAIntervalTypeComputer.INSTANCE);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
new file mode 100644
index 0000000..11ba264
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DayOfWeekDescriptor.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.asterix.runtime.evaluators.functions.temporal;
+
+import java.io.DataOutput;
+
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateSerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.ADateTimeSerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.AInt32;
+import edu.uci.ics.asterix.om.base.AMutableInt32;
+import edu.uci.ics.asterix.om.base.ANull;
+import edu.uci.ics.asterix.om.base.temporal.GregorianCalendarSystem;
+import edu.uci.ics.asterix.om.functions.AsterixBuiltinFunctions;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptor;
+import edu.uci.ics.asterix.om.functions.IFunctionDescriptorFactory;
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.BuiltinType;
+import edu.uci.ics.asterix.om.types.EnumDeserializer;
+import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
+import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluator;
+import edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory;
+import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
+import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
+import edu.uci.ics.hyracks.data.std.api.IDataOutputProvider;
+import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
+import edu.uci.ics.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class DayOfWeekDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ private static final long serialVersionUID = 1L;
+ public final static FunctionIdentifier FID = AsterixBuiltinFunctions.DAY_OF_WEEK;
+
+ // allowed input types
+ private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+ private final static byte SER_DATETIME_TYPE_TAG = ATypeTag.DATETIME.serialize();
+ private final static byte SER_DATE_TYPE_TAG = ATypeTag.DATE.serialize();
+
+ // Fixed week day anchor: Thursday, 1 January 1970
+ private final static int ANCHOR_WEEKDAY = 4;
+
+ public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new DayOfWeekDescriptor();
+ }
+
+ };
+
+ @Override
+ public ICopyEvaluatorFactory createEvaluatorFactory(final ICopyEvaluatorFactory[] args) throws AlgebricksException {
+ return new ICopyEvaluatorFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public ICopyEvaluator createEvaluator(final IDataOutputProvider output) throws AlgebricksException {
+ return new ICopyEvaluator() {
+
+ private DataOutput out = output.getDataOutput();
+ private ArrayBackedValueStorage argOut = new ArrayBackedValueStorage();
+ private ICopyEvaluator eval = args[0].createEvaluator(argOut);
+
+ // possible returning types
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<AInt32> int32Serde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.AINT32);
+ private AMutableInt32 aInt32 = new AMutableInt32(0);
+
+ @SuppressWarnings("unchecked")
+ private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+ .getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple) throws AlgebricksException {
+ argOut.reset();
+ eval.evaluate(tuple);
+ try {
+ if (argOut.getByteArray()[0] == SER_NULL_TYPE_TAG) {
+ nullSerde.serialize(ANull.NULL, out);
+ } else {
+ int daysSinceAnchor;
+ int reminder = 0;
+ if (argOut.getByteArray()[0] == SER_DATETIME_TYPE_TAG) {
+ daysSinceAnchor = (int) (ADateTimeSerializerDeserializer.getChronon(
+ argOut.getByteArray(), 1) / GregorianCalendarSystem.CHRONON_OF_DAY);
+ reminder = (int) (ADateTimeSerializerDeserializer.getChronon(argOut.getByteArray(),
+ 1) % GregorianCalendarSystem.CHRONON_OF_DAY);
+ } else if (argOut.getByteArray()[0] == SER_DATE_TYPE_TAG) {
+ daysSinceAnchor = ADateSerializerDeserializer.getChronon(argOut.getByteArray(), 1);
+ } else {
+ throw new AlgebricksException(
+ FID.getName()
+ + ": expects input type DATETIME/DATE/NULL but got "
+ + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+ .getByteArray()[0]));
+ }
+
+ // 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;
+ }
+
+ // convert from 0-based to 1-based (so 7 = Sunday)
+ if (weekday == 0) {
+ weekday = 7;
+ }
+
+ aInt32.setValue(weekday);
+
+ int32Serde.serialize(aInt32, out);
+ }
+ } catch (HyracksDataException hex) {
+ throw new AlgebricksException(hex);
+ }
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return FID;
+ }
+
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
index 47555bd..a13eed3 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -222,6 +222,7 @@
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DateFromUnixTimeInDaysDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DatetimeFromDateAndTimeDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DatetimeFromUnixTimeInMsDescriptor;
+import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DayOfWeekDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DayTimeDurationComparatorDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DurationEqualDescriptor;
import edu.uci.ics.asterix.runtime.evaluators.functions.temporal.DurationFromMillisecondsDescriptor;
@@ -539,6 +540,7 @@
temp.add(GetYearMonthDurationDescriptor.FACTORY);
temp.add(GetDayTimeDurationDescriptor.FACTORY);
temp.add(IntervalBinDescriptor.FACTORY);
+ temp.add(DayOfWeekDescriptor.FACTORY);
// Interval constructor
temp.add(AIntervalFromDateConstructorDescriptor.FACTORY);