diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/PrimitiveObjectInspectorUtils.java b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/PrimitiveObjectInspectorUtils.java index 8a057d1dab..0bc5a72d41 100644 --- a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/PrimitiveObjectInspectorUtils.java +++ b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/primitive/PrimitiveObjectInspectorUtils.java @@ -18,55 +18,31 @@ package org.apache.hadoop.hive.serde2.objectinspector.primitive; -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.StandardCharsets; -import java.time.DateTimeException; -import java.time.ZoneId; -import java.util.HashMap; -import java.util.Map; - import org.apache.hadoop.hive.common.classification.InterfaceAudience; import org.apache.hadoop.hive.common.classification.InterfaceStability; -import org.apache.hadoop.hive.common.type.Date; -import org.apache.hadoop.hive.common.type.HiveChar; -import org.apache.hadoop.hive.common.type.HiveDecimal; -import org.apache.hadoop.hive.common.type.HiveIntervalDayTime; -import org.apache.hadoop.hive.common.type.HiveIntervalYearMonth; -import org.apache.hadoop.hive.common.type.HiveVarchar; -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.common.type.TimestampUtils; +import org.apache.hadoop.hive.common.type.*; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.io.ByteWritable; -import org.apache.hadoop.hive.serde2.io.DateWritableV2; +import org.apache.hadoop.hive.serde2.io.*; import org.apache.hadoop.hive.serde2.io.DoubleWritable; -import org.apache.hadoop.hive.serde2.io.HiveCharWritable; -import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable; -import org.apache.hadoop.hive.serde2.io.HiveIntervalDayTimeWritable; -import org.apache.hadoop.hive.serde2.io.HiveIntervalYearMonthWritable; -import org.apache.hadoop.hive.serde2.io.HiveVarcharWritable; import org.apache.hadoop.hive.serde2.io.ShortWritable; -import org.apache.hadoop.hive.serde2.io.TimestampLocalTZWritable; -import org.apache.hadoop.hive.serde2.io.TimestampWritableV2; import org.apache.hadoop.hive.serde2.lazy.LazyInteger; import org.apache.hadoop.hive.serde2.lazy.LazyLong; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory; -import org.apache.hadoop.io.BooleanWritable; -import org.apache.hadoop.io.BytesWritable; -import org.apache.hadoop.io.FloatWritable; -import org.apache.hadoop.io.IntWritable; -import org.apache.hadoop.io.LongWritable; -import org.apache.hadoop.io.NullWritable; -import org.apache.hadoop.io.Text; -import org.apache.hadoop.io.Writable; -import org.apache.hadoop.io.WritableUtils; +import org.apache.hadoop.io.*; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.StandardCharsets; +import java.time.DateTimeException; +import java.time.ZoneId; +import java.util.HashMap; +import java.util.Map; /** * ObjectInspectorFactory is the primary way to create new ObjectInspector @@ -1117,34 +1093,37 @@ public static Date getDate(Object o, PrimitiveObjectInspector oi) { Date result = null; switch (oi.getPrimitiveCategory()) { case VOID: - result = null; break; case STRING: StringObjectInspector soi = (StringObjectInspector) oi; String s = soi.getPrimitiveJavaObject(o).trim(); try { - result = Date.valueOf(s); - } catch (IllegalArgumentException e) { - Timestamp ts = getTimestampFromString(s); - if (ts != null) { - result = Date.ofEpochMilli(ts.toEpochMilli()); + if (s.length() == DATE_LENGTH) { + result = Date.valueOf(s); } else { - result = null; + Timestamp ts = getTimestampFromString(s); + if (ts != null) { + result = Date.ofEpochMilli(ts.toEpochMilli()); + } } + } catch (IllegalArgumentException e) { + // Do nothing } break; case CHAR: case VARCHAR: { String val = getString(o, oi).trim(); try { - result = Date.valueOf(val); - } catch (IllegalArgumentException e) { - Timestamp ts = getTimestampFromString(val); - if (ts != null) { - result = Date.ofEpochMilli(ts.toEpochMilli()); + if (val.length() == DATE_LENGTH) { + result = Date.valueOf(val); } else { - result = null; + Timestamp ts = getTimestampFromString(val); + if (ts != null) { + result = Date.ofEpochMilli(ts.toEpochMilli()); + } } + } catch (IllegalArgumentException e) { + // Do nothing } break; } @@ -1248,26 +1227,40 @@ public static Timestamp getTimestamp(Object o, PrimitiveObjectInspector inputOI, return result; } + private final static int DATE_LENGTH = "YYYY-MM-DD".length(); + private final static int TS_LENGTH = "yyyy-mm-dd hh:mm:ss".length(); + public static Timestamp getTimestampFromString(String s) { - Timestamp result; + Timestamp result = null; s = s.trim(); s = trimNanoTimestamp(s); + // Handle simpler cases directly avoiding exceptions try { - result = Timestamp.valueOf(s); - } catch (IllegalArgumentException e) { - // Let's try to parse it as timestamp with time zone and transform - try { - result = Timestamp.valueOf(TimestampTZUtil.parse(s).getZonedDateTime() - .toLocalDateTime().toString()); - } catch (DateTimeException e2) { - // Last try: we try to parse it as date and transform + if (s.length() == DATE_LENGTH) { + // Its a date! + return Timestamp.ofEpochMilli(Date.valueOf(s).toEpochMilli()); + } else if (s.contains(" ") && + (s.length() == TS_LENGTH || + (s.contains(".") && s.substring(0, s.indexOf('.')).length() == TS_LENGTH))) { + return Timestamp.valueOf(s); + } + // If a timestamp does not have a space, then it is likely zoned time. + if (s.contains("+") || !s.contains(" ")) { + // Timestamp with timezone + // Let's try to parse it as timestamp with time zone and transform try { - result = Timestamp.ofEpochMilli(Date.valueOf(s).toEpochMilli()); - } catch (IllegalArgumentException e3) { - result = null; + result = Timestamp.valueOf(TimestampTZUtil.parse(s).getZonedDateTime() + .toLocalDateTime().toString()); + } catch (DateTimeException e2) { + // Do nothing } + } else { + // Last attempt + result = Timestamp.ofEpochMilli(Date.valueOf(s).toEpochMilli()); } + } catch (IllegalArgumentException e) { + // Do nothing } return result; }