diff --git a/pom.xml b/pom.xml
index 790bc74736c9..eb42c1b19e6d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -416,7 +416,7 @@
io.prestosql.hive
hive-apache
- 3.0.0-1
+ 3.1.1-1-SNAPSHOT
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursor.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursor.java
index a4f1c45fd45d..6ab6c1625238 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursor.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursor.java
@@ -18,6 +18,7 @@
import io.prestosql.hadoop.TextLineLengthLimitExceededException;
import io.prestosql.spi.PrestoException;
import io.prestosql.spi.block.Block;
+import io.prestosql.spi.connector.ConnectorSession;
import io.prestosql.spi.connector.RecordCursor;
import io.prestosql.spi.type.DecimalType;
import io.prestosql.spi.type.Decimals;
@@ -25,7 +26,9 @@
import io.prestosql.spi.type.TypeManager;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.common.type.Date;
import org.apache.hadoop.hive.common.type.HiveDecimal;
+import org.apache.hadoop.hive.common.type.Timestamp;
import org.apache.hadoop.hive.serde2.Deserializer;
import org.apache.hadoop.hive.serde2.SerDeException;
import org.apache.hadoop.hive.serde2.io.HiveCharWritable;
@@ -44,12 +47,10 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.math.BigInteger;
-import java.sql.Date;
-import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
-import java.util.concurrent.TimeUnit;
+import java.util.function.LongUnaryOperator;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
@@ -90,6 +91,7 @@ class GenericHiveRecordCursor
private final V value;
private final Deserializer deserializer;
+ private final LongUnaryOperator timestampConverter;
private final Type[] types;
private final HiveType[] hiveTypes;
@@ -107,7 +109,6 @@ class GenericHiveRecordCursor
private final boolean[] nulls;
private final long totalBytes;
- private final DateTimeZone hiveStorageTimeZone;
private long completedBytes;
private Object rowData;
@@ -121,6 +122,7 @@ public GenericHiveRecordCursor(
Properties splitSchema,
List columns,
DateTimeZone hiveStorageTimeZone,
+ ConnectorSession session,
TypeManager typeManager)
{
requireNonNull(path, "path is null");
@@ -129,17 +131,25 @@ public GenericHiveRecordCursor(
requireNonNull(splitSchema, "splitSchema is null");
requireNonNull(columns, "columns is null");
requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null");
+ requireNonNull(session, "session is null");
this.path = path;
this.recordReader = recordReader;
this.totalBytes = totalBytes;
this.key = recordReader.createKey();
this.value = recordReader.createValue();
- this.hiveStorageTimeZone = hiveStorageTimeZone;
this.deserializer = getDeserializer(configuration, splitSchema);
this.rowInspector = getTableObjectInspector(deserializer);
+ if (session.isLegacyTimestamp()) {
+ // convert using the real time zone for the underlying data
+ timestampConverter = millis -> hiveStorageTimeZone.convertLocalToUTC(millis, false);
+ }
+ else {
+ timestampConverter = LongUnaryOperator.identity();
+ }
+
int size = columns.size();
this.types = new Type[size];
@@ -280,35 +290,19 @@ private void parseLongColumn(int column)
else {
Object fieldValue = ((PrimitiveObjectInspector) fieldInspectors[column]).getPrimitiveJavaObject(fieldData);
checkState(fieldValue != null, "fieldValue should not be null");
- longs[column] = getLongExpressedValue(fieldValue, hiveStorageTimeZone);
+ longs[column] = getLongExpressedValue(fieldValue);
nulls[column] = false;
}
}
- private static long getLongExpressedValue(Object value, DateTimeZone hiveTimeZone)
+ private long getLongExpressedValue(Object value)
{
if (value instanceof Date) {
- long storageTime = ((Date) value).getTime();
- // convert date from VM current time zone to UTC
- long utcMillis = storageTime + DateTimeZone.getDefault().getOffset(storageTime);
- return TimeUnit.MILLISECONDS.toDays(utcMillis);
+ return ((Date) value).toEpochDay();
}
if (value instanceof Timestamp) {
- // The Hive SerDe parses timestamps using the default time zone of
- // this JVM, but the data might have been written using a different
- // time zone. We need to convert it to the configured time zone.
-
- // the timestamp that Hive parsed using the JVM time zone
- long parsedJvmMillis = ((Timestamp) value).getTime();
-
- // remove the JVM time zone correction from the timestamp
- DateTimeZone jvmTimeZone = DateTimeZone.getDefault();
- long hiveMillis = jvmTimeZone.convertUTCToLocal(parsedJvmMillis);
-
- // convert to UTC using the real time zone for the underlying data
- long utcMillis = hiveTimeZone.convertLocalToUTC(hiveMillis, false);
-
- return utcMillis;
+ long millis = ((Timestamp) value).toEpochMilli();
+ return timestampConverter.applyAsLong(millis);
}
if (value instanceof Float) {
return floatToRawIntBits(((Float) value));
@@ -451,7 +445,7 @@ private void parseObjectColumn(int column)
nulls[column] = true;
}
else {
- objects[column] = getBlockObject(types[column], fieldData, fieldInspectors[column]);
+ objects[column] = getBlockObject(types[column], fieldData, fieldInspectors[column], timestampConverter);
nulls[column] = false;
}
}
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursorProvider.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursorProvider.java
index c96ebe18cdc4..f91ab64727c0 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursorProvider.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/GenericHiveRecordCursorProvider.java
@@ -79,6 +79,7 @@ public Optional createRecordCursor(
schema,
columns,
hiveStorageTimeZone,
+ session,
typeManager));
}
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriteUtils.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriteUtils.java
index 590bf625a7fa..450df2f704f8 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriteUtils.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriteUtils.java
@@ -52,8 +52,10 @@
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.viewfs.ViewFileSystem;
+import org.apache.hadoop.hive.common.type.Date;
import org.apache.hadoop.hive.common.type.HiveDecimal;
import org.apache.hadoop.hive.common.type.HiveVarchar;
+import org.apache.hadoop.hive.common.type.Timestamp;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.ProtectMode;
import org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter;
@@ -61,11 +63,11 @@
import org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat;
import org.apache.hadoop.hive.serde2.SerDeException;
import org.apache.hadoop.hive.serde2.Serializer;
-import org.apache.hadoop.hive.serde2.io.DateWritable;
+import org.apache.hadoop.hive.serde2.io.DateWritableV2;
import org.apache.hadoop.hive.serde2.io.DoubleWritable;
import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
import org.apache.hadoop.hive.serde2.io.ShortWritable;
-import org.apache.hadoop.hive.serde2.io.TimestampWritable;
+import org.apache.hadoop.hive.serde2.io.TimestampWritableV2;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
@@ -86,12 +88,9 @@
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.Reporter;
-import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.math.BigInteger;
-import java.sql.Date;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -99,7 +98,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
-import java.util.concurrent.TimeUnit;
import static com.google.common.base.Strings.padEnd;
import static com.google.common.io.BaseEncoding.base16;
@@ -154,7 +152,6 @@
import static org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory.writableTimestampObjectInspector;
import static org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory.getCharTypeInfo;
import static org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory.getVarcharTypeInfo;
-import static org.joda.time.DateTimeZone.UTC;
public final class HiveWriteUtils
{
@@ -315,12 +312,10 @@ public static Object getField(Type type, Block block, int position)
return type.getSlice(block, position).getBytes();
}
if (DateType.DATE.equals(type)) {
- long days = type.getLong(block, position);
- return new Date(UTC.getMillisKeepLocal(DateTimeZone.getDefault(), TimeUnit.DAYS.toMillis(days)));
+ return Date.ofEpochDay(toIntExact(type.getLong(block, position)));
}
if (TimestampType.TIMESTAMP.equals(type)) {
- long millisUtc = type.getLong(block, position);
- return new Timestamp(millisUtc);
+ return Timestamp.ofEpochMilli(type.getLong(block, position));
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
@@ -933,7 +928,7 @@ public void setField(Block block, int position)
private static class DateFieldSetter
extends FieldSetter
{
- private final DateWritable value = new DateWritable();
+ private final DateWritableV2 value = new DateWritableV2();
public DateFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field)
{
@@ -951,7 +946,7 @@ public void setField(Block block, int position)
private static class TimestampFieldSetter
extends FieldSetter
{
- private final TimestampWritable value = new TimestampWritable();
+ private final TimestampWritableV2 value = new TimestampWritableV2();
public TimestampFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field)
{
@@ -961,8 +956,7 @@ public TimestampFieldSetter(SettableStructObjectInspector rowInspector, Object r
@Override
public void setField(Block block, int position)
{
- long millisUtc = TimestampType.TIMESTAMP.getLong(block, position);
- value.setTime(millisUtc);
+ value.set(Timestamp.ofEpochMilli(TimestampType.TIMESTAMP.getLong(block, position)));
rowInspector.setStructFieldData(row, field, value);
}
}
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursor.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursor.java
index 51539d5794fd..b715a1c8d512 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursor.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursor.java
@@ -13,6 +13,7 @@
*/
package io.prestosql.plugin.hive;
+import io.prestosql.spi.connector.ConnectorSession;
import io.prestosql.spi.type.TypeManager;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
@@ -51,9 +52,10 @@ public S3SelectRecordCursor(
Properties splitSchema,
List columns,
DateTimeZone hiveStorageTimeZone,
+ ConnectorSession session,
TypeManager typeManager)
{
- super(configuration, path, recordReader, totalBytes, updateSplitSchema(splitSchema, columns), columns, hiveStorageTimeZone, typeManager);
+ super(configuration, path, recordReader, totalBytes, updateSplitSchema(splitSchema, columns), columns, hiveStorageTimeZone, session, typeManager);
}
// since s3select only returns the required column, not the whole columns
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursorProvider.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursorProvider.java
index ed7be2695cc6..8ba2d3b7a142 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursorProvider.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/S3SelectRecordCursorProvider.java
@@ -87,7 +87,7 @@ public Optional createRecordCursor(
IonSqlQueryBuilder queryBuilder = new IonSqlQueryBuilder(typeManager);
String ionSqlQuery = queryBuilder.buildSql(columns, effectivePredicate);
S3SelectLineRecordReader recordReader = new S3SelectCsvRecordReader(configuration, clientConfig, path, start, length, schema, ionSqlQuery, s3ClientFactory);
- return Optional.of(new S3SelectRecordCursor(configuration, path, recordReader, length, schema, columns, hiveStorageTimeZone, typeManager));
+ return Optional.of(new S3SelectRecordCursor<>(configuration, path, recordReader, length, schema, columns, hiveStorageTimeZone, session, typeManager));
}
// unsupported serdes
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java
index 8dd8fb985493..807c98eec5d5 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/metastore/thrift/ThriftHiveMetastore.java
@@ -1307,7 +1307,8 @@ private PrivilegeBag buildPrivilegeBag(
new HiveObjectRef(TABLE, databaseName, tableName, null, null),
grantee.getName(),
fromPrestoPrincipalType(grantee.getType()),
- privilegeGrantInfo));
+ privilegeGrantInfo,
+ "SQL"));
}
return new PrivilegeBag(privilegeBagBuilder.build());
}
diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/SerDeUtils.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/SerDeUtils.java
index 07c6aa9e23f6..53afb19a2b0e 100644
--- a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/SerDeUtils.java
+++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/SerDeUtils.java
@@ -54,12 +54,10 @@
import org.apache.hadoop.hive.serde2.objectinspector.primitive.ShortObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.TimestampObjectInspector;
-import org.joda.time.DateTimeZone;
-import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.TimeUnit;
+import java.util.function.LongUnaryOperator;
import static com.google.common.base.Preconditions.checkArgument;
import static io.prestosql.spi.type.Chars.truncateToLengthAndTrimSpaces;
@@ -71,36 +69,37 @@ public final class SerDeUtils
{
private SerDeUtils() {}
- public static Block getBlockObject(Type type, Object object, ObjectInspector objectInspector)
+ public static Block getBlockObject(Type type, Object object, ObjectInspector objectInspector, LongUnaryOperator timestampConverter)
{
- return requireNonNull(serializeObject(type, null, object, objectInspector), "serialized result is null");
+ Block block = serializeObject(type, null, object, objectInspector, timestampConverter);
+ return requireNonNull(block, "serialized result is null");
}
- public static Block serializeObject(Type type, BlockBuilder builder, Object object, ObjectInspector inspector)
+ public static Block serializeObject(Type type, BlockBuilder builder, Object object, ObjectInspector inspector, LongUnaryOperator timestampConverter)
{
- return serializeObject(type, builder, object, inspector, true);
+ return serializeObject(type, builder, object, inspector, timestampConverter, true);
}
// This version supports optionally disabling the filtering of null map key, which should only be used for building test data sets
// that contain null map keys. For production, null map keys are not allowed.
@VisibleForTesting
- public static Block serializeObject(Type type, BlockBuilder builder, Object object, ObjectInspector inspector, boolean filterNullMapKeys)
+ public static Block serializeObject(Type type, BlockBuilder builder, Object object, ObjectInspector inspector, LongUnaryOperator timestampConverter, boolean filterNullMapKeys)
{
switch (inspector.getCategory()) {
case PRIMITIVE:
- serializePrimitive(type, builder, object, (PrimitiveObjectInspector) inspector);
+ serializePrimitive(type, builder, object, (PrimitiveObjectInspector) inspector, timestampConverter);
return null;
case LIST:
- return serializeList(type, builder, object, (ListObjectInspector) inspector);
+ return serializeList(type, builder, object, (ListObjectInspector) inspector, timestampConverter);
case MAP:
- return serializeMap(type, builder, object, (MapObjectInspector) inspector, filterNullMapKeys);
+ return serializeMap(type, builder, object, (MapObjectInspector) inspector, timestampConverter, filterNullMapKeys);
case STRUCT:
- return serializeStruct(type, builder, object, (StructObjectInspector) inspector);
+ return serializeStruct(type, builder, object, (StructObjectInspector) inspector, timestampConverter);
}
throw new RuntimeException("Unknown object inspector category: " + inspector.getCategory());
}
- private static void serializePrimitive(Type type, BlockBuilder builder, Object object, PrimitiveObjectInspector inspector)
+ private static void serializePrimitive(Type type, BlockBuilder builder, Object object, PrimitiveObjectInspector inspector, LongUnaryOperator timestampConverter)
{
requireNonNull(builder, "parent builder is null");
@@ -146,7 +145,7 @@ private static void serializePrimitive(Type type, BlockBuilder builder, Object o
DateType.DATE.writeLong(builder, formatDateAsLong(object, (DateObjectInspector) inspector));
return;
case TIMESTAMP:
- TimestampType.TIMESTAMP.writeLong(builder, formatTimestampAsLong(object, (TimestampObjectInspector) inspector));
+ TimestampType.TIMESTAMP.writeLong(builder, formatTimestampAsLong(object, (TimestampObjectInspector) inspector, timestampConverter));
return;
case BINARY:
VARBINARY.writeSlice(builder, Slices.wrappedBuffer(((BinaryObjectInspector) inspector).getPrimitiveJavaObject(object)));
@@ -165,7 +164,7 @@ private static void serializePrimitive(Type type, BlockBuilder builder, Object o
throw new RuntimeException("Unknown primitive type: " + inspector.getPrimitiveCategory());
}
- private static Block serializeList(Type type, BlockBuilder builder, Object object, ListObjectInspector inspector)
+ private static Block serializeList(Type type, BlockBuilder builder, Object object, ListObjectInspector inspector, LongUnaryOperator timestampConverter)
{
List> list = inspector.getList(object);
if (list == null) {
@@ -186,7 +185,7 @@ private static Block serializeList(Type type, BlockBuilder builder, Object objec
}
for (Object element : list) {
- serializeObject(elementType, currentBuilder, element, elementInspector);
+ serializeObject(elementType, currentBuilder, element, elementInspector, timestampConverter);
}
if (builder != null) {
@@ -199,7 +198,7 @@ private static Block serializeList(Type type, BlockBuilder builder, Object objec
}
}
- private static Block serializeMap(Type type, BlockBuilder builder, Object object, MapObjectInspector inspector, boolean filterNullMapKeys)
+ private static Block serializeMap(Type type, BlockBuilder builder, Object object, MapObjectInspector inspector, LongUnaryOperator timestampConverter, boolean filterNullMapKeys)
{
Map, ?> map = inspector.getMap(object);
if (map == null) {
@@ -225,8 +224,8 @@ private static Block serializeMap(Type type, BlockBuilder builder, Object object
for (Map.Entry, ?> entry : map.entrySet()) {
// Hive skips map entries with null keys
if (!filterNullMapKeys || entry.getKey() != null) {
- serializeObject(keyType, currentBuilder, entry.getKey(), keyInspector);
- serializeObject(valueType, currentBuilder, entry.getValue(), valueInspector);
+ serializeObject(keyType, currentBuilder, entry.getKey(), keyInspector, timestampConverter);
+ serializeObject(valueType, currentBuilder, entry.getValue(), valueInspector, timestampConverter);
}
}
@@ -239,7 +238,7 @@ private static Block serializeMap(Type type, BlockBuilder builder, Object object
}
}
- private static Block serializeStruct(Type type, BlockBuilder builder, Object object, StructObjectInspector inspector)
+ private static Block serializeStruct(Type type, BlockBuilder builder, Object object, StructObjectInspector inspector, LongUnaryOperator timestampConverter)
{
if (object == null) {
requireNonNull(builder, "parent builder is null").appendNull();
@@ -260,7 +259,7 @@ private static Block serializeStruct(Type type, BlockBuilder builder, Object obj
for (int i = 0; i < typeParameters.size(); i++) {
StructField field = allStructFieldRefs.get(i);
- serializeObject(typeParameters.get(i), currentBuilder, inspector.getStructFieldData(object, field), field.getFieldObjectInspector());
+ serializeObject(typeParameters.get(i), currentBuilder, inspector.getStructFieldData(object, field), field.getFieldObjectInspector(), timestampConverter);
}
builder.closeEntry();
@@ -272,6 +271,7 @@ private static Block serializeStruct(Type type, BlockBuilder builder, Object obj
}
}
+ @SuppressWarnings("deprecation")
private static long formatDateAsLong(Object object, DateObjectInspector inspector)
{
if (object instanceof LazyDate) {
@@ -280,27 +280,14 @@ private static long formatDateAsLong(Object object, DateObjectInspector inspecto
if (object instanceof DateWritable) {
return ((DateWritable) object).getDays();
}
-
- // Hive will return java.sql.Date at midnight in JVM time zone
- long millisLocal = inspector.getPrimitiveJavaObject(object).getTime();
- // Convert it to midnight in UTC
- long millisUtc = DateTimeZone.getDefault().getMillisKeepLocal(DateTimeZone.UTC, millisLocal);
- // Convert midnight UTC to days
- return TimeUnit.MILLISECONDS.toDays(millisUtc);
- }
-
- private static long formatTimestampAsLong(Object object, TimestampObjectInspector inspector)
- {
- Timestamp timestamp = getTimestamp(object, inspector);
- return timestamp.getTime();
+ return inspector.getPrimitiveJavaObject(object).toEpochDay();
}
- private static Timestamp getTimestamp(Object object, TimestampObjectInspector inspector)
+ private static long formatTimestampAsLong(Object object, TimestampObjectInspector inspector, LongUnaryOperator timestampConverter)
{
- // handle broken ObjectInspectors
if (object instanceof TimestampWritable) {
- return ((TimestampWritable) object).getTimestamp();
+ return ((TimestampWritable) object).getTimestamp().getTime();
}
- return inspector.getPrimitiveJavaObject(object);
+ return timestampConverter.applyAsLong(inspector.getPrimitiveJavaObject(object).toEpochMilli());
}
}
diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveClient.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveClient.java
index 81b8f44fa760..ea8a6b27ac6e 100644
--- a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveClient.java
+++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveClient.java
@@ -3898,6 +3898,18 @@ else if (rowNumber % 39 == 1) {
}
}
+ // ARRAY
+ index = columnIndex.get("t_array_timestamp");
+ if (index != null) {
+ if ((rowNumber % 43) == 0) {
+ assertNull(row.getField(index));
+ }
+ else {
+ SqlTimestamp expected = sqlTimestampOf(2011, 5, 6, 7, 8, 9, 123, timeZone, UTC_KEY, SESSION);
+ assertEquals(row.getField(index), ImmutableList.of(expected));
+ }
+ }
+
// ARRAY>
index = columnIndex.get("t_array_struct");
if (index != null) {
diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveFileFormats.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveFileFormats.java
index 84c203a9061c..e4f1c91f3b30 100644
--- a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveFileFormats.java
+++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveFileFormats.java
@@ -43,9 +43,11 @@
import io.prestosql.tests.StructuralTestUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
+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.HiveVarchar;
+import org.apache.hadoop.hive.common.type.Timestamp;
import org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter;
import org.apache.hadoop.hive.ql.io.HiveOutputFormat;
import org.apache.hadoop.hive.serde2.Serializer;
@@ -70,8 +72,6 @@
import java.lang.invoke.MethodHandle;
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.sql.Date;
-import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -148,15 +148,18 @@
@Test(groups = "hive")
public abstract class AbstractTestHiveFileFormats
{
+ protected static final DateTimeZone HIVE_STORAGE_TIME_ZONE = DateTimeZone.forID("America/Bahia_Banderas");
+
private static final double EPSILON = 0.001;
private static final long DATE_MILLIS_UTC = new DateTime(2011, 5, 6, 0, 0, UTC).getMillis();
private static final long DATE_DAYS = TimeUnit.MILLISECONDS.toDays(DATE_MILLIS_UTC);
private static final String DATE_STRING = DateTimeFormat.forPattern("yyyy-MM-dd").withZoneUTC().print(DATE_MILLIS_UTC);
- private static final Date SQL_DATE = new Date(UTC.getMillisKeepLocal(DateTimeZone.getDefault(), DATE_MILLIS_UTC));
+ private static final Date HIVE_DATE = Date.ofEpochMilli(DATE_MILLIS_UTC);
private static final long TIMESTAMP = new DateTime(2011, 5, 6, 7, 8, 9, 123).getMillis();
private static final String TIMESTAMP_STRING = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").print(TIMESTAMP);
+ private static final Timestamp HIVE_TIMESTAMP = Timestamp.ofEpochMilli(HIVE_STORAGE_TIME_ZONE.convertUTCToLocal(TIMESTAMP));
private static final String VARCHAR_MAX_LENGTH_STRING;
@@ -271,8 +274,8 @@ public abstract class AbstractTestHiveFileFormats
.add(new TestColumn("t_double", javaDoubleObjectInspector, 6.2, 6.2))
.add(new TestColumn("t_boolean_true", javaBooleanObjectInspector, true, true))
.add(new TestColumn("t_boolean_false", javaBooleanObjectInspector, false, false))
- .add(new TestColumn("t_date", javaDateObjectInspector, SQL_DATE, DATE_DAYS))
- .add(new TestColumn("t_timestamp", javaTimestampObjectInspector, new Timestamp(TIMESTAMP), TIMESTAMP))
+ .add(new TestColumn("t_date", javaDateObjectInspector, HIVE_DATE, DATE_DAYS))
+ .add(new TestColumn("t_timestamp", javaTimestampObjectInspector, HIVE_TIMESTAMP, TIMESTAMP))
.add(new TestColumn("t_decimal_precision_2", DECIMAL_INSPECTOR_PRECISION_2, WRITE_DECIMAL_PRECISION_2, EXPECTED_DECIMAL_PRECISION_2))
.add(new TestColumn("t_decimal_precision_4", DECIMAL_INSPECTOR_PRECISION_4, WRITE_DECIMAL_PRECISION_4, EXPECTED_DECIMAL_PRECISION_4))
.add(new TestColumn("t_decimal_precision_8", DECIMAL_INSPECTOR_PRECISION_8, WRITE_DECIMAL_PRECISION_8, EXPECTED_DECIMAL_PRECISION_8))
@@ -324,11 +327,11 @@ public abstract class AbstractTestHiveFileFormats
mapBlockOf(BOOLEAN, BOOLEAN, true, true)))
.add(new TestColumn("t_map_date",
getStandardMapObjectInspector(javaDateObjectInspector, javaDateObjectInspector),
- ImmutableMap.of(SQL_DATE, SQL_DATE),
+ ImmutableMap.of(HIVE_DATE, HIVE_DATE),
mapBlockOf(DateType.DATE, DateType.DATE, DATE_DAYS, DATE_DAYS)))
.add(new TestColumn("t_map_timestamp",
getStandardMapObjectInspector(javaTimestampObjectInspector, javaTimestampObjectInspector),
- ImmutableMap.of(new Timestamp(TIMESTAMP), new Timestamp(TIMESTAMP)),
+ ImmutableMap.of(HIVE_TIMESTAMP, HIVE_TIMESTAMP),
mapBlockOf(TimestampType.TIMESTAMP, TimestampType.TIMESTAMP, TIMESTAMP, TIMESTAMP)))
.add(new TestColumn("t_map_decimal_precision_2",
getStandardMapObjectInspector(DECIMAL_INSPECTOR_PRECISION_2, DECIMAL_INSPECTOR_PRECISION_2),
@@ -375,11 +378,11 @@ public abstract class AbstractTestHiveFileFormats
arrayBlockOf(createCharType(10), "test")))
.add(new TestColumn("t_array_date",
getStandardListObjectInspector(javaDateObjectInspector),
- ImmutableList.of(SQL_DATE),
+ ImmutableList.of(HIVE_DATE),
arrayBlockOf(DateType.DATE, DATE_DAYS)))
.add(new TestColumn("t_array_timestamp",
getStandardListObjectInspector(javaTimestampObjectInspector),
- ImmutableList.of(new Timestamp(TIMESTAMP)),
+ ImmutableList.of(HIVE_TIMESTAMP),
StructuralTestUtil.arrayBlockOf(TimestampType.TIMESTAMP, TIMESTAMP)))
.add(new TestColumn("t_array_decimal_precision_2",
getStandardListObjectInspector(DECIMAL_INSPECTOR_PRECISION_2),
@@ -488,7 +491,7 @@ protected List getColumnHandles(List testColumns)
return columns;
}
- public static FileSplit createTestFile(
+ public static FileSplit createTestFilePresto(
String filePath,
HiveStorageFormat storageFormat,
HiveCompressionCodec compressionCodec,
@@ -516,6 +519,7 @@ public static FileSplit createTestFile(
pageBuilder.getBlockBuilder(columnNumber),
testColumns.get(columnNumber).getWriteValue(),
testColumns.get(columnNumber).getObjectInspector(),
+ millis -> HIVE_STORAGE_TIME_ZONE.convertLocalToUTC(millis, false),
false);
}
}
@@ -545,7 +549,7 @@ public static FileSplit createTestFile(
return new FileSplit(new Path(filePath), 0, new File(filePath).length(), new String[0]);
}
- public static FileSplit createTestFile(
+ public static FileSplit createTestFileHive(
String filePath,
HiveStorageFormat storageFormat,
HiveCompressionCodec compressionCodec,
diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveTestUtils.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveTestUtils.java
index eddcabe44b8b..14626e8af9bc 100644
--- a/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveTestUtils.java
+++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveTestUtils.java
@@ -42,9 +42,12 @@
import io.prestosql.spi.type.TypeManager;
import io.prestosql.spi.type.TypeSignatureParameter;
import io.prestosql.testing.TestingConnectorSession;
+import org.apache.hadoop.hive.common.type.Timestamp;
import java.lang.invoke.MethodHandle;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
import java.util.List;
import java.util.Set;
@@ -179,4 +182,9 @@ public static boolean isDistinctFrom(MethodHandle handle, Block left, Block righ
throw new AssertionError(t);
}
}
+
+ public static Timestamp hiveTimestamp(LocalDateTime local)
+ {
+ return Timestamp.ofEpochSecond(local.toEpochSecond(ZoneOffset.UTC), local.getNano());
+ }
}
diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveBucketing.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveBucketing.java
index f320287a249e..6fe8461a3259 100644
--- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveBucketing.java
+++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveBucketing.java
@@ -136,7 +136,11 @@ private static void assertBucketEquals(List hiveTypeStrings, List