You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by sa...@apache.org on 2021/08/11 05:56:47 UTC

[hive] branch master updated: HIVE-25403: Fix from_unixtime() to consider leap seconds (Sruthi Mooriyathvariam, reviewed by Ashish Sharma, Adesh Rao, Sankar Hariappan)

This is an automated email from the ASF dual-hosted git repository.

sankarh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new 103ac9a  HIVE-25403: Fix from_unixtime() to consider leap seconds (Sruthi Mooriyathvariam, reviewed by Ashish Sharma, Adesh Rao, Sankar Hariappan)
103ac9a is described below

commit 103ac9ab352d15e63885f5b62d63f55011dcc01c
Author: Sruthi Mooriyathvariam <wa...@gmail.com>
AuthorDate: Wed Aug 11 11:26:36 2021 +0530

    HIVE-25403: Fix from_unixtime() to consider leap seconds (Sruthi Mooriyathvariam, reviewed by Ashish Sharma, Adesh Rao, Sankar Hariappan)
    
    Signed-off-by: Sankar Hariappan <sa...@apache.org>
    Closes (#2550)
---
 .../ql/udf/generic/GenericUDFFromUnixTime.java     |  96 ++++----------
 .../ql/udf/generic/TestGenericUDFFromUnixTime.java | 137 ++++++++++++++++++++
 ql/src/test/queries/clientpositive/foldts.q        |   8 +-
 ql/src/test/queries/clientpositive/udf5.q          |  29 +++++
 .../test/results/clientpositive/llap/foldts.q.out  |  27 ++++
 ql/src/test/results/clientpositive/llap/udf5.q.out | 142 +++++++++++++++++++++
 6 files changed, 370 insertions(+), 69 deletions(-)

diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFromUnixTime.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFromUnixTime.java
index 66418ac..fb634bc 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFromUnixTime.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFFromUnixTime.java
@@ -18,28 +18,26 @@
 
 package org.apache.hadoop.hive.ql.udf.generic;
 
-import java.text.SimpleDateFormat;
+import java.time.Instant;
 import java.time.ZoneId;
-import java.util.Date;
-import java.util.TimeZone;
-import org.apache.commons.lang3.StringUtils;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
 import org.apache.hadoop.hive.common.type.TimestampTZUtil;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.ql.exec.Description;
 import org.apache.hadoop.hive.ql.exec.MapredContext;
 import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
-import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
 import org.apache.hadoop.hive.ql.metadata.HiveException;
 import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
-import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
-import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter;
 import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.IntObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
 import org.apache.hadoop.io.Text;
+import static org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils.PrimitiveGrouping.STRING_GROUP;
 
 /**
  * GenericUDFFromUnixTime.
@@ -54,28 +52,19 @@ public class GenericUDFFromUnixTime extends GenericUDF {
 
   private transient IntObjectInspector inputIntOI;
   private transient LongObjectInspector inputLongOI;
-  private transient Converter inputTextConverter;
   private transient ZoneId timeZone;
   private transient final Text result = new Text();
-
-  private transient SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-  private transient String lastFormat = null;
-
+  private transient String lastFormat ="uuuu-MM-dd HH:mm:ss";
+  private transient DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(lastFormat);
+  private transient Converter[] converters = new Converter[2];
+  private transient PrimitiveObjectInspector.PrimitiveCategory[] inputTypes = new PrimitiveObjectInspector.PrimitiveCategory[2];
 
   @Override
   public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
-    if (arguments.length < 1) {
-      throw new UDFArgumentLengthException("The function " + getName().toUpperCase() +
-          "requires at least one argument");
-    }
-    if (arguments.length > 2) {
-      throw new UDFArgumentLengthException("Too many arguments for the function " + getName().toUpperCase());
-    }
-    for (ObjectInspector argument : arguments) {
-      if (argument.getCategory() != Category.PRIMITIVE) {
-        throw new UDFArgumentException(getName().toUpperCase() +
-            " only takes primitive types, got " + argument.getTypeName());
-      }
+    checkArgsSize(arguments, 1, 2);
+
+    for (int i = 0; i < arguments.length; i++) {
+      checkArgPrimitive(arguments, i);
     }
 
     PrimitiveObjectInspector arg0OI = (PrimitiveObjectInspector) arguments[0];
@@ -87,29 +76,19 @@ public class GenericUDFFromUnixTime extends GenericUDF {
         inputLongOI = (LongObjectInspector) arguments[0];
         break;
       default:
-        throw new UDFArgumentException("The function " + getName().toUpperCase()
-            + " takes only int/long types for first argument. Got Type:" + arg0OI.getPrimitiveCategory().name());
+        throw new UDFArgumentException("The function from_unixtime takes only int/long types for first argument. Got Type:"
+            + arg0OI.getPrimitiveCategory().name());
     }
 
     if (arguments.length == 2) {
-      PrimitiveObjectInspector arg1OI = (PrimitiveObjectInspector) arguments[1];
-      switch (arg1OI.getPrimitiveCategory()) {
-        case CHAR:
-        case VARCHAR:
-        case STRING:
-          inputTextConverter = ObjectInspectorConverters.getConverter(arg1OI,
-              PrimitiveObjectInspectorFactory.javaStringObjectInspector);
-          break;
-        default:
-          throw new UDFArgumentException("The function " + getName().toUpperCase()
-              + " takes only string type for second argument. Got Type:" + arg1OI.getPrimitiveCategory().name());
-      }
+      checkArgGroups(arguments, 1, inputTypes, STRING_GROUP);
+      obtainStringConverter(arguments, 1, inputTypes, converters);
     }
 
     if (timeZone == null) {
       timeZone = SessionState.get() == null ? new HiveConf().getLocalTimeZone() : SessionState.get().getConf()
               .getLocalTimeZone();
-      formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
+      FORMATTER.withZone(timeZone);
     }
 
     return PrimitiveObjectInspectorFactory.writableStringObjectInspector;
@@ -120,7 +99,7 @@ public class GenericUDFFromUnixTime extends GenericUDF {
     if (context != null) {
       String timeZoneStr = HiveConf.getVar(context.getJobConf(), HiveConf.ConfVars.HIVE_LOCAL_TIME_ZONE);
       timeZone = TimestampTZUtil.parseTimeZone(timeZoneStr);
-      formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
+      FORMATTER.withZone(timeZone);
     }
   }
 
@@ -130,46 +109,27 @@ public class GenericUDFFromUnixTime extends GenericUDF {
       return null;
     }
 
-    if (inputTextConverter != null) {
-      if (arguments[1].get() == null) {
-        return null;
-      }
-      String format = (String) inputTextConverter.convert(arguments[1].get());
+    if(arguments.length == 2) {
+      String format = getStringValue(arguments, 1, converters);
       if (format == null) {
         return null;
       }
       if (!format.equals(lastFormat)) {
-        formatter = new SimpleDateFormat(format);
-        formatter.setTimeZone(TimeZone.getTimeZone(timeZone));
+        FORMATTER = DateTimeFormatter.ofPattern(format);
         lastFormat = format;
       }
     }
 
-    // convert seconds to milliseconds
-    long unixtime;
-    if (inputIntOI != null) {
-      unixtime = inputIntOI.get(arguments[0].get());
-    } else {
-      unixtime = inputLongOI.get(arguments[0].get());
-    }
-
-    Date date = new Date(unixtime * 1000L);
-    result.set(formatter.format(date));
+    long unixTime = (inputIntOI != null) ? inputIntOI.get(arguments[0].get()) : inputLongOI.get(arguments[0].get());
+    Instant instant = Instant.ofEpochSecond(unixTime);
+    ZonedDateTime zonedDT = ZonedDateTime.ofInstant(instant, timeZone);
+    result.set(zonedDT.format(FORMATTER));
     return result;
   }
 
-  protected String getName() {
-    return "from_unixtime";
-  }
-
   @Override
   public String getDisplayString(String[] children) {
-    StringBuilder sb = new StringBuilder(32);
-    sb.append(getName());
-    sb.append('(');
-    sb.append(StringUtils.join(children, ", "));
-    sb.append(')');
-    return sb.toString();
+    return getStandardDisplayString("from_unixtime", children, ", ");
   }
-
 }
+
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFFromUnixTime.java b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFFromUnixTime.java
new file mode 100644
index 0000000..6032b74
--- /dev/null
+++ b/ql/src/test/org/apache/hadoop/hive/ql/udf/generic/TestGenericUDFFromUnixTime.java
@@ -0,0 +1,137 @@
+/*                                                                                                                                                                                     
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 at
+ *
+ *     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 org.apache.hadoop.hive.ql.udf.generic;
+
+import java.time.ZoneId;
+import org.apache.hadoop.hive.common.type.Date;
+import org.apache.hadoop.hive.common.type.Timestamp;
+import org.apache.hadoop.hive.common.type.TimestampTZ;
+import org.apache.hadoop.hive.common.type.TimestampTZUtil;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.ql.exec.MapredContext;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredJavaObject;
+import org.apache.hadoop.hive.ql.udf.generic.GenericUDF.DeferredObject;
+import org.apache.hadoop.hive.serde2.io.DateWritableV2;
+import org.apache.hadoop.hive.serde2.io.TimestampWritableV2;
+import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
+import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
+import org.apache.hadoop.io.LongWritable;
+import org.apache.hadoop.io.Text;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.apache.hadoop.mapred.JobConf;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.DateTimeFormatterBuilder;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+/**
+ * TestGenericUDFFromUnixTime.
+ */
+public class TestGenericUDFFromUnixTime {
+
+  public static void runAndVerify(GenericUDFFromUnixTime udf,
+      Object arg, Object expected) throws HiveException {
+    DeferredObject[] args = { new DeferredJavaObject(arg) };
+    Object result = udf.evaluate(args);
+    if (expected == null) {
+      assertNull(result);
+    } else {
+      assertEquals(expected.toString(), result.toString());
+    }
+  }
+
+  public static void runAndVerify(GenericUDFFromUnixTime udf,
+      Object arg1, Object arg2, Object expected) throws HiveException {
+    DeferredObject[] args = { new DeferredJavaObject(arg1), new DeferredJavaObject(arg2) };
+    Object result = udf.evaluate(args);
+
+    if (expected == null) {
+      assertNull(result);
+    } else {
+      assertEquals(expected.toString(), result.toString());
+    }
+  }
+
+  @Test
+  public void testTimestampDefaultTimezone() throws HiveException {
+    ObjectInspector valueLongOI = PrimitiveObjectInspectorFactory.writableLongObjectInspector;
+    GenericUDFFromUnixTime udf = new GenericUDFFromUnixTime();
+    ObjectInspector args[] = {valueLongOI};
+    udf.initialize(args);
+
+    Timestamp ts = Timestamp.valueOf("1470-01-01 00:00:00");
+    TimestampTZ tstz = TimestampTZUtil.convert(ts, ZoneId.systemDefault());
+
+    runAndVerify(udf,
+            new LongWritable(tstz.getEpochSecond()), new Text("1470-01-01 00:00:00"));
+
+    // test null values
+    runAndVerify(udf, null, null);
+  }
+
+  @Test
+  public void testTimestampOtherTimezone() throws HiveException {
+    ObjectInspector valueLongOI = PrimitiveObjectInspectorFactory.writableLongObjectInspector;
+    GenericUDFFromUnixTime udf = new GenericUDFFromUnixTime();
+    ObjectInspector args[] = {valueLongOI};
+    udf.initialize(args);
+
+    Timestamp ts = Timestamp.valueOf("1969-12-31 15:59:46");
+    TimestampTZ tstz1 = TimestampTZUtil.convert(ts, ZoneId.of("America/Los_Angeles"));
+    TimestampTZ tstz2 = TimestampTZUtil.convert(ts, ZoneId.of("America/New_York"));
+    TimestampTZ tstz3 = TimestampTZUtil.convert(ts, ZoneId.of("Europe/London"));
+    TimestampTZ tstz4 = TimestampTZUtil.convert(ts, ZoneId.of("Europe/Rome"));
+
+    runAndVerify(udf,
+            new LongWritable(tstz1.getEpochSecond()), new Text("1969-12-31 15:59:46"));
+    runAndVerify(udf,
+            new LongWritable(tstz2.getEpochSecond()), new Text("1969-12-31 12:59:46"));
+    runAndVerify(udf,
+            new LongWritable(tstz3.getEpochSecond()), new Text("1969-12-31 06:59:46"));
+    runAndVerify(udf,
+            new LongWritable(tstz4.getEpochSecond()), new Text("1969-12-31 06:59:46"));
+  }
+
+  @Test
+  public void testTimestampWithArg2() throws HiveException {
+    ObjectInspector valueLongOI = PrimitiveObjectInspectorFactory.writableLongObjectInspector;
+    ObjectInspector valueStringOI = PrimitiveObjectInspectorFactory.writableStringObjectInspector;
+    GenericUDFFromUnixTime udf = new GenericUDFFromUnixTime();
+    ObjectInspector args[] = {valueLongOI, valueStringOI};
+    udf.initialize(args);
+
+    Timestamp ts = Timestamp.valueOf("2010-01-13 11:57:40");
+    TimestampTZ tstz1 = TimestampTZUtil.convert(ts, ZoneId.systemDefault());
+
+    runAndVerify(udf,
+            new LongWritable(tstz1.getEpochSecond()), "MM/dd/yy HH:mm:ss", new Text("01/13/10 11:57:40"));
+    runAndVerify(udf,
+            new LongWritable(tstz1.getEpochSecond()), "EEEE", new Text("Wednesday"));
+    runAndVerify(udf,
+            new LongWritable(tstz1.getEpochSecond()), "yyyy-MM-dd'T'HH:mm:ssXXX", new Text("2010-01-13T11:57:40-08:00"));
+    runAndVerify(udf,
+            new LongWritable(tstz1.getEpochSecond()), "uuuu-MM-dd'T'HH:mm:ssXXX", new Text("2010-01-13T11:57:40-08:00"));
+  }
+}
+
diff --git a/ql/src/test/queries/clientpositive/foldts.q b/ql/src/test/queries/clientpositive/foldts.q
index a141bca..3737e67 100644
--- a/ql/src/test/queries/clientpositive/foldts.q
+++ b/ql/src/test/queries/clientpositive/foldts.q
@@ -25,12 +25,18 @@ select from_unixtime(to_unix_timestamp(ctimestamp1)) from alltypesorc limit 1;
 
 select from_unixtime(unix_timestamp(ctimestamp1) ,"yyyy-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
 
+select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
+
 set time zone Europe/Rome;
 
-select from_unixtime(to_unix_timestamp(ctimestamp1)) from alltypesorc limit 1; 
+select from_unixtime(to_unix_timestamp(ctimestamp1)) from alltypesorc limit 1;
 
 select from_unixtime(unix_timestamp(ctimestamp1) ,"yyyy-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
 
+select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
+
 select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone))) from alltypesorc limit 1;
 
 select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone)) ,"yyyy-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
+
+select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1;
diff --git a/ql/src/test/queries/clientpositive/udf5.q b/ql/src/test/queries/clientpositive/udf5.q
index 43d6088..6336df8 100644
--- a/ql/src/test/queries/clientpositive/udf5.q
+++ b/ql/src/test/queries/clientpositive/udf5.q
@@ -13,6 +13,35 @@ SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'
 
 SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/yy HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14;
 
+EXPLAIN
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14;
+
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14;
+
+SELECT from_unixtime(unix_timestamp(cast('2010-01-13' as date)));
+
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/yy HH:mm:ss');
+
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss');
+
+select from_unixtime(unix_timestamp('2010-01-13 11:57:40'), 'EEEE');
+
+select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"yyyy-MM-dd'T'HH:mm:ssXXX") ;
+
+select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX") ;
+
+select from_unixtime(to_unix_timestamp(cast('2021-01-01' as date)));
+
+select from_unixtime(to_unix_timestamp(cast('1400-01-01' as date)));
+
+select from_unixtime(to_unix_timestamp(cast('1800-01-01' as date)));
+
+select from_unixtime(to_unix_timestamp(cast('1900-01-01' as date)));
+
+select from_unixtime(to_unix_timestamp(cast('2000-01-07' as date)));
+
+select from_unixtime(to_unix_timestamp(cast('0000-00-00' as date)));
+
 set time zone Europe/Rome;
 
 SELECT from_unixtime(1226446340), to_date(from_unixtime(1226446340)), day('2008-11-01'), month('2008-11-01'), year('2008-11-01'), day('2008-11-01 15:32:20'), month('2008-11-01 15:32:20'), year('2008-11-01 15:32:20') FROM dest1_n14;
diff --git a/ql/src/test/results/clientpositive/llap/foldts.q.out b/ql/src/test/results/clientpositive/llap/foldts.q.out
index d784835..50555f3 100644
--- a/ql/src/test/results/clientpositive/llap/foldts.q.out
+++ b/ql/src/test/results/clientpositive/llap/foldts.q.out
@@ -194,6 +194,15 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@alltypesorc
 #### A masked pattern was here ####
 1969-12-31T15:59:46-08:00
+PREHOOK: query: select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+1969-12-31T15:59:46-08:00
 PREHOOK: query: select from_unixtime(to_unix_timestamp(ctimestamp1)) from alltypesorc limit 1
 PREHOOK: type: QUERY
 PREHOOK: Input: default@alltypesorc
@@ -212,6 +221,15 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@alltypesorc
 #### A masked pattern was here ####
 1969-12-31T15:59:46+01:00
+PREHOOK: query: select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(unix_timestamp(ctimestamp1) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+1969-12-31T15:59:46+01:00
 PREHOOK: query: select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone))) from alltypesorc limit 1
 PREHOOK: type: QUERY
 PREHOOK: Input: default@alltypesorc
@@ -230,3 +248,12 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@alltypesorc
 #### A masked pattern was here ####
 1970-01-01T00:59:46+01:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+PREHOOK: type: QUERY
+PREHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast(cast(ctimestamp1 as string) || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX") from alltypesorc limit 1
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@alltypesorc
+#### A masked pattern was here ####
+1970-01-01T00:59:46+01:00
diff --git a/ql/src/test/results/clientpositive/llap/udf5.q.out b/ql/src/test/results/clientpositive/llap/udf5.q.out
index 21ee1b6..9b23e45 100644
--- a/ql/src/test/results/clientpositive/llap/udf5.q.out
+++ b/ql/src/test/results/clientpositive/llap/udf5.q.out
@@ -83,6 +83,148 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@dest1_n14
 #### A masked pattern was here ####
 01/13/10 11:57:40	2010-01-13 11:57:40
+PREHOOK: query: EXPLAIN
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14
+PREHOOK: type: QUERY
+PREHOOK: Input: default@dest1_n14
+#### A masked pattern was here ####
+POSTHOOK: query: EXPLAIN
+SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@dest1_n14
+#### A masked pattern was here ####
+STAGE DEPENDENCIES:
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+      Processor Tree:
+        TableScan
+          alias: dest1_n14
+          Select Operator
+            expressions: '01/13/10 11:57:40' (type: string), '2010-01-13 11:57:40' (type: string)
+            outputColumnNames: _col0, _col1
+            ListSink
+
+PREHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14
+PREHOOK: type: QUERY
+PREHOOK: Input: default@dest1_n14
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss'), from_unixtime(unix_timestamp('2010-01-13 11:57:40')) from dest1_n14
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@dest1_n14
+#### A masked pattern was here ####
+01/13/10 11:57:40	2010-01-13 11:57:40
+PREHOOK: query: SELECT from_unixtime(unix_timestamp(cast('2010-01-13' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT from_unixtime(unix_timestamp(cast('2010-01-13' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+2010-01-13 00:00:00
+PREHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/yy HH:mm:ss')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/yy HH:mm:ss')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+01/13/10 11:57:40
+PREHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT from_unixtime(unix_timestamp('2010-01-13 11:57:40', 'yyyy-MM-dd HH:mm:ss'), 'MM/dd/uu HH:mm:ss')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+01/13/10 11:57:40
+PREHOOK: query: select from_unixtime(unix_timestamp('2010-01-13 11:57:40'), 'EEEE')
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(unix_timestamp('2010-01-13 11:57:40'), 'EEEE')
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+Wednesday
+PREHOOK: query: select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"yyyy-MM-dd'T'HH:mm:ssXXX")
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"yyyy-MM-dd'T'HH:mm:ssXXX")
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+2010-01-13T11:57:40-08:00
+PREHOOK: query: select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX")
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(unix_timestamp(cast('2010-01-13 11:57:40' || ' America/Los_Angeles' as timestamp with local time zone)) ,"uuuu-MM-dd'T'HH:mm:ssXXX")
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+2010-01-13T11:57:40-08:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('2021-01-01' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('2021-01-01' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+2021-01-01 00:00:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('1400-01-01' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('1400-01-01' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+1400-01-01 00:00:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('1800-01-01' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('1800-01-01' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+1800-01-01 00:00:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('1900-01-01' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('1900-01-01' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+1900-01-01 00:00:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('2000-01-07' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('2000-01-07' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+2000-01-07 00:00:00
+PREHOOK: query: select from_unixtime(to_unix_timestamp(cast('0000-00-00' as date)))
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+POSTHOOK: query: select from_unixtime(to_unix_timestamp(cast('0000-00-00' as date)))
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+#### A masked pattern was here ####
+NULL
 PREHOOK: query: SELECT from_unixtime(1226446340), to_date(from_unixtime(1226446340)), day('2008-11-01'), month('2008-11-01'), year('2008-11-01'), day('2008-11-01 15:32:20'), month('2008-11-01 15:32:20'), year('2008-11-01 15:32:20') FROM dest1_n14
 PREHOOK: type: QUERY
 PREHOOK: Input: default@dest1_n14