Add function for converting unix time in seconds

Change-Id: I96e3b81493058a26787c476a0c6d252e1f6b39a0
Reviewed-on: http://fulliautomatix.ics.uci.edu:8443/224
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Taewoo Kim <wangsaeu@gmail.com>
diff --git a/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
index fe0c099..a3e77b5 100644
--- a/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
+++ b/asterix-app/src/test/resources/runtimets/queries/temporal/datetime_functions/datetime_functions.3.query.aql
@@ -3,6 +3,8 @@
 
 let $dt1 := datetime-from-unix-time-in-ms(956007429)
 let $null1 := datetime-from-unix-time-in-ms(null)
+let $dtsecs := datetime-from-unix-time-in-secs(1356048000)
+let $nullsecs := datetime-from-unix-time-in-secs(null)
 let $d1 := date("1327-12-02")
 let $t1 := time("15:35:49.938-0800")
 let $dt2 := datetime-from-date-time($d1, $t1)
@@ -16,4 +18,4 @@
 let $null7 := $dt1 + null
 let $c1 := $dt1 = ($dt1 - $dt3) + $dt3
 
-return { "datetime1" : $dt1, "datetime2" : $dt2, "datetime3" : $dt3, "duration1" : $dr1, "c1" : $c1, "null1" : $null1, "null2" : $null2, "null3" : $null3, "null4" : $null4, "null5" : $null5, "null6" : $null6, "null7" : $null7 }
+return { "datetime1" : $dt1, "datetime1secs": $dtsecs, "datetime2" : $dt2, "datetime3" : $dt3, "duration1" : $dr1, "c1" : $c1, "null1" : $null1, "null1secs": $nullsecs, "null2" : $null2, "null3" : $null3, "null4" : $null4, "null5" : $null5, "null6" : $null6, "null7" : $null7 }
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
index 7f4d289..825958a 100644
--- a/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/datetime_functions/datetime_functions.1.adm
@@ -1,2 +1,2 @@
-[ { "datetime1": datetime("1970-01-12T01:33:27.429Z"), "datetime2": datetime("1327-12-02T23:35:49.938Z"), "datetime3": datetime("1327-12-02T23:35:49.938Z"), "duration1": duration("-P234526DT1H57M37.491S"), "c1": true, "null1": null, "null2": null, "null3": null, "null4": null, "null5": null, "null6": null, "null7": null }
+[ { "datetime1": datetime("1970-01-12T01:33:27.429Z"), "datetime1secs": datetime("2012-12-21T00:00:00.000Z"), "datetime2": datetime("1327-12-02T23:35:49.938Z"), "datetime3": datetime("1327-12-02T23:35:49.938Z"), "duration1": duration("-P234526DT1H57M37.491S"), "c1": true, "null1": null, "null1secs": null, "null2": null, "null3": null, "null4": null, "null5": null, "null6": null, "null7": null }
  ]
diff --git a/asterix-doc/src/site/markdown/aql/functions.md b/asterix-doc/src/site/markdown/aql/functions.md
index c870788..28a655e 100644
--- a/asterix-doc/src/site/markdown/aql/functions.md
+++ b/asterix-doc/src/site/markdown/aql/functions.md
@@ -1894,6 +1894,17 @@
  * Return Value:
     * A `datetime` value as the time after `numeric_expression` milliseconds since 1970-01-01T00:00:00Z.
 
+### datetime-from-unix-time-in-secs ###
+ * Syntax:
+
+        datetime-from-unix-time-in-secs(numeric_expression)
+
+ * Gets a datetime representing the time after `numeric_expression` seconds since 1970-01-01T00:00:00Z.
+ * Arguments:
+    * `numeric_expression`: A `int8`/`int16`/`int32`/`int64` value representing the number of seconds.
+ * Return Value:
+    * A `datetime` value as the time after `numeric_expression` seconds since 1970-01-01T00:00:00Z.
+
 
 ### datetime-from-date-time ###
 * Syntax:
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 25fbc86..3aa5cc1 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
@@ -632,6 +632,8 @@
             "get-time-from-datetime", 1);
     public final static FunctionIdentifier DATETIME_FROM_UNIX_TIME_IN_MS = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "datetime-from-unix-time-in-ms", 1);
+    public final static FunctionIdentifier DATETIME_FROM_UNIX_TIME_IN_SECS = new FunctionIdentifier(
+            FunctionConstants.ASTERIX_NS, "datetime-from-unix-time-in-secs", 1);
     public final static FunctionIdentifier DATETIME_FROM_DATE_TIME = new FunctionIdentifier(
             FunctionConstants.ASTERIX_NS, "datetime-from-date-time", 2);
     public final static FunctionIdentifier CALENDAR_DURATION_FROM_DATETIME = new FunctionIdentifier(
@@ -983,6 +985,7 @@
         addFunction(TIME_FROM_DATETIME, OptionalATimeTypeComputer.INSTANCE, true);
         addFunction(DATETIME_FROM_DATE_TIME, OptionalADateTimeTypeComputer.INSTANCE, true);
         addFunction(DATETIME_FROM_UNIX_TIME_IN_MS, OptionalADateTimeTypeComputer.INSTANCE, true);
+        addFunction(DATETIME_FROM_UNIX_TIME_IN_SECS, OptionalADateTimeTypeComputer.INSTANCE, true);
         addFunction(CALENDAR_DURATION_FROM_DATETIME, OptionalADurationTypeComputer.INSTANCE, true);
         addFunction(CALENDAR_DURATION_FROM_DATE, OptionalADurationTypeComputer.INSTANCE, true);
         addFunction(ADJUST_DATETIME_FOR_TIMEZONE, OptionalAStringTypeComputer.INSTANCE, true);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DatetimeFromUnixTimeInSecsDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DatetimeFromUnixTimeInSecsDescriptor.java
new file mode 100644
index 0000000..f5c3afb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/temporal/DatetimeFromUnixTimeInSecsDescriptor.java
@@ -0,0 +1,133 @@
+/*
+ * 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.AInt16SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import edu.uci.ics.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
+import edu.uci.ics.asterix.om.base.ADateTime;
+import edu.uci.ics.asterix.om.base.AMutableDateTime;
+import edu.uci.ics.asterix.om.base.ANull;
+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 DatetimeFromUnixTimeInSecsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    private final static long serialVersionUID = 1L;
+    public final static FunctionIdentifier FID = AsterixBuiltinFunctions.DATETIME_FROM_UNIX_TIME_IN_SECS;
+
+    // allowed input types
+    private final static byte SER_NULL_TYPE_TAG = ATypeTag.NULL.serialize();
+    private final static byte SER_INT8_TYPE_TAG = ATypeTag.INT8.serialize();
+    private final static byte SER_INT16_TYPE_TAG = ATypeTag.INT16.serialize();
+    private final static byte SER_INT32_TYPE_TAG = ATypeTag.INT32.serialize();
+    private final static byte SER_INT64_TYPE_TAG = ATypeTag.INT64.serialize();
+
+    public final static IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new DatetimeFromUnixTimeInSecsDescriptor();
+        }
+    };
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.runtime.base.IScalarFunctionDynamicDescriptor#createEvaluatorFactory(edu.uci.ics.hyracks.algebricks.runtime.base.ICopyEvaluatorFactory[])
+     */
+    @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 output types
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ADateTime> datetimeSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ADATETIME);
+                    @SuppressWarnings("unchecked")
+                    private ISerializerDeserializer<ANull> nullSerde = AqlSerializerDeserializerProvider.INSTANCE
+                            .getSerializerDeserializer(BuiltinType.ANULL);
+
+                    private AMutableDateTime aDatetime = new AMutableDateTime(0);
+
+                    @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 {
+                                if (argOut.getByteArray()[0] == SER_INT8_TYPE_TAG) {
+                                    aDatetime.setValue((AInt8SerializerDeserializer.getByte(argOut.getByteArray(), 1)*1000l));
+                                } else if (argOut.getByteArray()[0] == SER_INT16_TYPE_TAG) {
+                                    aDatetime.setValue((AInt16SerializerDeserializer.getShort(argOut.getByteArray(), 1)*1000l));
+                                } else if (argOut.getByteArray()[0] == SER_INT32_TYPE_TAG) {
+                                    aDatetime.setValue((AInt32SerializerDeserializer.getInt(argOut.getByteArray(), 1)*1000l));
+                                } else if (argOut.getByteArray()[0] == SER_INT64_TYPE_TAG) {
+                                    aDatetime.setValue((AInt64SerializerDeserializer.getLong(argOut.getByteArray(), 1)*1000l));
+                                } else {
+                                    throw new AlgebricksException(
+                                            FID.getName()
+                                                    + ": expects type INT8/INT16/INT32/INT64/NULL but got "
+                                                    + EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(argOut
+                                                            .getByteArray()[0]));
+                                }
+                                datetimeSerde.serialize(aDatetime, out);
+                            }
+                        } catch (HyracksDataException hex) {
+                            throw new AlgebricksException(hex);
+                        }
+                    }
+                };
+            }
+        };
+    }
+
+    /* (non-Javadoc)
+     * @see edu.uci.ics.asterix.om.functions.IFunctionDescriptor#getIdentifier()
+     */
+    @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 4ad3bf5..fb9c4d3 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
@@ -264,6 +264,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.DatetimeFromUnixTimeInSecsDescriptor;
 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;
@@ -606,6 +607,7 @@
         temp.add(TimeFromUnixTimeInMsDescriptor.FACTORY);
         temp.add(TimeFromDatetimeDescriptor.FACTORY);
         temp.add(DatetimeFromUnixTimeInMsDescriptor.FACTORY);
+        temp.add(DatetimeFromUnixTimeInSecsDescriptor.FACTORY);
         temp.add(DatetimeFromDateAndTimeDescriptor.FACTORY);
         temp.add(CalendarDurationFromDateTimeDescriptor.FACTORY);
         temp.add(CalendarDuartionFromDateDescriptor.FACTORY);