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

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


The following commit(s) were added to refs/heads/master by this push:
     new 82e5b05  Number based columns representing time in custom format 
cannot be used as timestamp column in Druid. (#9877)
82e5b05 is described below

commit 82e5b0573efffd6f87ce4aead6a05b0c1d7381c7
Author: Samarth Jain <sama...@apache.org>
AuthorDate: Mon May 18 11:17:28 2020 -0700

    Number based columns representing time in custom format cannot be used as 
timestamp column in Druid. (#9877)
    
    * Number based columns representing time in custom format cannot be used as 
timestamp column in Druid.
    
    Prior to this fix, if an integer column in parquet is storing dateint in 
format yyyyMMdd, it cannot be used as timestamp column in Druid as the 
timestamp parser interprets it as a number storing UTC time instead of treating 
it as a number representing time in yyyyMMdd format. Data formats like TSV or 
CSV don't suffer from this problem as the timestamp is passed in an as string 
which the timestamp parser is able to parse correctly.
---
 .../java/util/common/parsers/TimestampParser.java  | 13 ++++++-
 .../util/common/parsers/TimestampParserTest.java   | 44 ++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java
 
b/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java
index ecd06f8..e5a9520 100644
--- 
a/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java
+++ 
b/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java
@@ -122,11 +122,12 @@ public class TimestampParser
   {
     final Function<String, DateTime> stringFun = createTimestampParser(format);
     final Function<Number, DateTime> numericFun = 
createNumericTimestampParser(format);
+    final boolean isNumericFormat = isNumericFormat(format);
 
     return o -> {
       Preconditions.checkNotNull(o, "null timestamp");
 
-      if (o instanceof Number) {
+      if (o instanceof Number && isNumericFormat) {
         return numericFun.apply((Number) o);
       } else {
         return stringFun.apply(o.toString());
@@ -134,6 +135,16 @@ public class TimestampParser
     };
   }
 
+  private static boolean isNumericFormat(String format)
+  {
+    return "auto".equalsIgnoreCase(format)
+           || "millis".equalsIgnoreCase(format)
+           || "posix".equalsIgnoreCase(format)
+           || "micro".equalsIgnoreCase(format)
+           || "nano".equalsIgnoreCase(format)
+           || "ruby".equalsIgnoreCase(format);
+  }
+
   private static DateTimeFormatter createAutoParser()
   {
     final DateTimeFormatter offsetElement = new DateTimeFormatterBuilder()
diff --git 
a/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java
 
b/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java
index 9c0e66e..a5622d5 100644
--- 
a/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java
+++ 
b/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java
@@ -181,4 +181,48 @@ public class TimestampParserTest
                                    .getMillis()
     );
   }
+
+  @Test
+  public void testFormatsForNumberBasedTimestamp()
+  {
+    int yearMonthDate = 20200514;
+    DateTime expectedDt = DateTimes.of("2020-05-14T00:00:00.000Z");
+    Function<Object, DateTime> parser = 
TimestampParser.createObjectTimestampParser("yyyyMMdd");
+    Assert.assertEquals("Timestamp of format yyyyMMdd not parsed correctly",
+                        expectedDt, parser.apply(yearMonthDate));
+
+    int year = 2020;
+    expectedDt = DateTimes.of("2020-01-01T00:00:00.000Z");
+    parser = TimestampParser.createObjectTimestampParser("yyyy");
+    Assert.assertEquals("Timestamp of format yyyy not parsed correctly",
+                        expectedDt, parser.apply(year));
+
+    int yearMonth = 202010;
+    expectedDt = DateTimes.of("2020-10-01T00:00:00.000Z");
+    parser = TimestampParser.createObjectTimestampParser("yyyyMM");
+    Assert.assertEquals("Timestamp of format yyyy not parsed correctly",
+                        expectedDt, parser.apply(yearMonth));
+
+    // Friday, May 15, 2020 8:20:40 PM GMT
+    long millis = 1589574040000l;
+    expectedDt = DateTimes.of("2020-05-15T20:20:40.000Z");
+
+    parser = TimestampParser.createObjectTimestampParser("millis");
+    Assert.assertEquals("Timestamp of format millis not parsed correctly",
+                        expectedDt, parser.apply(millis));
+    parser = TimestampParser.createObjectTimestampParser("auto");
+    Assert.assertEquals("Timestamp of format auto not parsed correctly",
+                        expectedDt, parser.apply(millis));
+
+    int posix = 1589574040;
+    parser = TimestampParser.createObjectTimestampParser("posix");
+    Assert.assertEquals("Timestamp of format posix not parsed correctly",
+                        expectedDt, parser.apply(posix));
+
+    long micro = 1589574040000000l;
+    parser = TimestampParser.createObjectTimestampParser("micro");
+    Assert.assertEquals("Timestamp of format micro not parsed correctly",
+                        expectedDt, parser.apply(micro));
+
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@druid.apache.org
For additional commands, e-mail: commits-h...@druid.apache.org

Reply via email to