From 1d6207faba7e20fbedadeeee3e648ff4b3277d2d Mon Sep 17 00:00:00 2001 From: NeerajUnnikrishnan Date: Mon, 7 Jun 2021 11:21:38 -0400 Subject: [PATCH] Fix for timestamp semantics --- .../carbondata/CarbondataFileWriter.java | 12 +- .../plugin/carbondata/CarbondataMetadata.java | 9 +- .../carbondata/CarbondataMetadataFactory.java | 23 +- .../carbondata/CarbondataWriterFactory.java | 3 +- .../datacenter/TestDataCenterMetadata.java | 6 - .../plugin/greenplum/GreenPlumSqlClient.java | 4 +- .../greenplum/TestGreenPlumTypeMapping.java | 26 +- .../hbase/client/TestingConnectorSession.java | 6 - .../plugin/opengauss/OpenGaussClient.java | 4 +- .../hetu/core/plugin/oracle/OracleClient.java | 34 +- pom.xml | 2 +- .../prestosql/plugin/jdbc/BaseJdbcClient.java | 2 +- .../plugin/jdbc/StandardColumnMappings.java | 67 +- .../plugin/jdbc/TestJdbcQueryBuilder.java | 11 +- .../ElasticsearchPageSource.java | 16 +- .../ElasticsearchPageSourceProvider.java | 1 - .../decoders/TimestampDecoder.java | 9 +- .../plugin/hive/GenericHiveRecordCursor.java | 35 +- .../hive/GenericHiveRecordCursorProvider.java | 3 - .../prestosql/plugin/hive/HiveBucketing.java | 22 +- .../io/prestosql/plugin/hive/HiveConfig.java | 82 +- .../prestosql/plugin/hive/HiveMetadata.java | 29 +- .../plugin/hive/HiveMetadataFactory.java | 21 - .../prestosql/plugin/hive/HivePageSink.java | 2 +- .../plugin/hive/HivePageSinkProvider.java | 4 + .../prestosql/plugin/hive/HivePageSource.java | 5 +- .../plugin/hive/HivePageSourceFactory.java | 2 - .../plugin/hive/HivePageSourceProvider.java | 14 +- .../plugin/hive/HivePartitionManager.java | 12 +- .../plugin/hive/HiveRecordCursor.java | 5 +- .../plugin/hive/HiveRecordCursorProvider.java | 2 - .../hive/HiveSelectivePageSourceFactory.java | 2 - .../plugin/hive/HiveSplitSource.java | 2 +- .../io/prestosql/plugin/hive/HiveUtil.java | 21 +- .../prestosql/plugin/hive/HiveWriteUtils.java | 444 +----- .../plugin/hive/HiveWriterFactory.java | 5 + .../prestosql/plugin/hive/OrcFileWriter.java | 3 - .../plugin/hive/OrcFileWriterFactory.java | 6 - .../plugin/hive/ParquetRecordWriterUtil.java | 128 -- .../plugin/hive/RcFileFileWriterFactory.java | 12 +- .../plugin/hive/RecordFileWriter.java | 15 +- .../plugin/hive/S3SelectRecordCursor.java | 4 +- .../hive/S3SelectRecordCursorProvider.java | 4 +- .../metastore/thrift/ThriftHiveMetastore.java | 3 +- .../plugin/hive/orc/OrcPageSourceFactory.java | 9 +- .../hive/orc/OrcSelectivePageSource.java | 2 - .../orc/OrcSelectivePageSourceFactory.java | 10 +- .../parquet/ParquetPageSourceFactory.java | 12 +- .../hive/parquet/ParquetRecordWriter.java | 108 ++ .../hive/rcfile/RcFilePageSourceFactory.java | 13 +- .../plugin/hive/util/FieldSetterFactory.java | 488 +++++++ .../plugin/hive/util/HiveBucketingV1.java | 13 - .../plugin/hive/util/SerDeUtils.java | 25 +- .../plugin/hive/util/Statistics.java | 15 +- .../plugin/hive/util/TempFileWriter.java | 2 - .../plugin/hive/AbstractTestHive.java | 34 +- .../hive/AbstractTestHiveFileFormats.java | 30 +- .../plugin/hive/AbstractTestHiveLocal.java | 3 +- .../plugin/hive/HiveQueryRunner.java | 3 +- .../prestosql/plugin/hive/HiveTestUtils.java | 17 +- .../plugin/hive/TestColumnTypeCacheable.java | 4 +- .../plugin/hive/TestHiveBucketing.java | 46 +- .../prestosql/plugin/hive/TestHiveConfig.java | 13 +- .../plugin/hive/TestHiveFileFormats.java | 150 +- .../prestosql/plugin/hive/TestHiveUtil.java | 4 +- .../plugin/hive/TestHiveWriterFactory.java | 2 + .../hive/TestOrcPageSourceMemoryTracking.java | 2 - .../plugin/hive/benchmark/FileFormat.java | 21 +- .../hive/orc/TestOrcAcidPageSource.java | 2 - .../parquet/AbstractTestParquetReader.java | 16 +- .../plugin/hive/parquet/ParquetTester.java | 5 +- .../parquet/TestParquetPageSourceFactory.java | 6 +- .../parquet/write/TestDataWritableWriter.java | 7 +- .../TestMetastoreHiveStatisticsProvider.java | 5 +- .../plugin/hive/util/TestSerDeUtils.java | 13 +- .../read_test/all_datatypes_json.json | 188 +++ .../io/prestosql/FullConnectorSession.java | 9 - .../io/prestosql/SystemSessionProperties.java | 11 - .../operator/scalar/ArrayToJsonCast.java | 7 +- .../operator/scalar/DateTimeFunctions.java | 182 +-- .../operator/scalar/FormatFunction.java | 13 +- .../operator/scalar/JsonOperators.java | 2 +- .../operator/scalar/MapToJsonCast.java | 7 +- .../operator/scalar/RowToJsonCast.java | 7 +- .../operator/scalar/SequenceFunction.java | 2 +- .../sql/analyzer/ExpressionAnalyzer.java | 7 +- .../sql/analyzer/FeaturesConfig.java | 17 +- .../sql/planner/LiteralInterpreter.java | 14 +- .../SqlToRowExpressionTranslator.java | 26 +- .../testing/DateTimeTestingUtils.java | 73 +- .../prestosql/testing/MaterializedResult.java | 2 +- .../testing/TestingConnectorSession.java | 14 +- .../java/io/prestosql/type/DateOperators.java | 12 +- .../io/prestosql/type/DateTimeOperators.java | 27 +- .../java/io/prestosql/type/TimeOperators.java | 33 +- .../type/TimeWithTimeZoneOperators.java | 24 +- .../io/prestosql/type/TimestampOperators.java | 81 +- .../type/TimestampWithTimeZoneOperators.java | 44 +- .../main/java/io/prestosql/util/JsonUtil.java | 39 +- .../scalar/TestDateTimeFunctions.java | 52 +- .../scalar/TestDateTimeFunctionsBase.java | 1220 ----------------- .../scalar/TestDateTimeFunctionsLegacy.java | 95 -- .../sql/TestExpressionInterpreter.java | 25 +- .../sql/analyzer/TestFeaturesConfig.java | 3 - .../sql/gen/TestExpressionCompiler.java | 32 +- .../io/prestosql/type/TestArrayOperators.java | 109 +- .../test/java/io/prestosql/type/TestDate.java | 162 ++- .../java/io/prestosql/type/TestDateBase.java | 180 --- .../io/prestosql/type/TestDateLegacy.java | 23 - .../prestosql/type/TestDateTimeOperators.java | 256 +++- .../type/TestDateTimeOperatorsBase.java | 258 ---- .../type/TestDateTimeOperatorsLegacy.java | 248 ---- .../io/prestosql/type/TestJsonOperators.java | 2 +- .../io/prestosql/type/TestMapOperators.java | 17 +- .../io/prestosql/type/TestRowOperators.java | 3 +- .../test/java/io/prestosql/type/TestTime.java | 23 - .../java/io/prestosql/type/TestTimeBase.java | 13 +- .../io/prestosql/type/TestTimeLegacy.java | 23 - .../prestosql/type/TestTimeWithTimeZone.java | 205 ++- .../type/TestTimeWithTimeZoneBase.java | 228 --- .../type/TestTimeWithTimeZoneLegacy.java | 48 - .../java/io/prestosql/type/TestTimestamp.java | 262 +++- .../io/prestosql/type/TestTimestampBase.java | 275 ---- .../prestosql/type/TestTimestampLegacy.java | 65 - .../type/TestTimestampWithTimeZone.java | 353 ++++- .../type/TestTimestampWithTimeZoneBase.java | 363 ----- .../type/TestTimestampWithTimeZoneLegacy.java | 53 - .../prestosql/plugin/mysql/MySqlClient.java | 2 +- .../orc/AbstractOrcRecordReader.java | 8 +- .../main/java/io/prestosql/orc/OrcReader.java | 22 +- .../io/prestosql/orc/OrcRecordReader.java | 4 +- .../main/java/io/prestosql/orc/OrcWriter.java | 13 +- .../main/java/io/prestosql/orc/Stripe.java | 10 +- .../java/io/prestosql/orc/StripeReader.java | 16 +- .../ExceptionWrappingMetadataReader.java | 5 +- .../orc/metadata/MetadataReader.java | 3 +- .../orc/metadata/OrcMetadataReader.java | 6 +- .../orc/metadata/OrcMetadataWriter.java | 6 +- .../prestosql/orc/metadata/StripeFooter.java | 7 +- .../orc/reader/AbstractColumnReader.java | 2 +- .../AbstractDecimalSelectiveColumnReader.java | 2 +- .../reader/AbstractNumericColumnReader.java | 2 +- .../orc/reader/BooleanColumnReader.java | 2 +- .../reader/BooleanSelectiveColumnReader.java | 2 +- .../orc/reader/ByteColumnReader.java | 2 +- .../orc/reader/CachingColumnReader.java | 6 +- .../DataCachingSelectiveColumnReader.java | 4 +- .../orc/reader/DecimalColumnReader.java | 2 +- .../orc/reader/DoubleColumnReader.java | 2 +- .../reader/DoubleSelectiveColumnReader.java | 2 +- .../orc/reader/FloatColumnReader.java | 2 +- .../reader/FloatSelectiveColumnReader.java | 2 +- .../orc/reader/ListColumnReader.java | 4 +- .../orc/reader/LongSelectiveColumnReader.java | 2 +- .../prestosql/orc/reader/MapColumnReader.java | 6 +- .../ResultCachingSelectiveColumnReader.java | 8 +- .../orc/reader/SelectiveColumnReaders.java | 2 +- .../orc/reader/SliceColumnReader.java | 4 +- .../reader/SliceDictionaryColumnReader.java | 2 +- .../SliceDictionarySelectiveColumnReader.java | 2 +- .../orc/reader/SliceDirectColumnReader.java | 2 +- .../SliceDirectSelectiveColumnReader.java | 2 +- .../reader/SliceSelectiveColumnReader.java | 4 +- .../orc/reader/StructColumnReader.java | 4 +- .../orc/reader/TimestampColumnReader.java | 51 +- .../TimestampSelectiveColumnReader.java | 7 +- .../prestosql/orc/writer/ColumnWriters.java | 10 +- .../orc/writer/TimestampColumnWriter.java | 8 +- .../prestosql/orc/AbstractTestOrcReader.java | 16 +- .../prestosql/orc/BenchmarkColumnReaders.java | 5 +- .../test/java/io/prestosql/orc/OrcTester.java | 42 +- .../orc/TestCachingColumnReader.java | 5 +- .../java/io/prestosql/orc/TestOrcWriter.java | 5 +- .../io/prestosql/orc/TestReadBloomFilter.java | 9 +- .../prestosql/orc/TestSelectiveOrcReader.java | 3 +- .../prestosql/orc/TestStructColumnReader.java | 2 - .../io/prestosql/orc/TestingOrcPredicate.java | 2 +- .../parquet/TestParquetTimestampUtils.java | 9 +- .../postgresql/BasePostgreSqlClient.java | 2 +- .../plugin/postgresql/PostgreSqlClient.java | 2 +- .../plugin/postgresql/TypeUtils.java | 5 - .../postgresql/TestPostgreSqlTypeMapping.java | 26 +- .../tests/hive/TestHiveTableStatistics.java | 2 +- .../rcfile/binary/BinaryRcFileEncoding.java | 12 +- .../rcfile/binary/TimestampEncoding.java | 16 +- .../rcfile/text/TextRcFileEncoding.java | 11 +- .../rcfile/text/TimestampEncoding.java | 13 +- .../rcfile/AbstractTestRcFileReader.java | 14 +- .../io/prestosql/rcfile/RcFileTester.java | 94 +- .../rcfile/TestRcFileReaderManual.java | 3 +- .../AbstractDateTimeJsonValueProvider.java | 8 +- .../json/CustomDateTimeJsonFieldDecoder.java | 28 +- .../decoder/json/ISO8601JsonFieldDecoder.java | 10 +- ...illisecondsSinceEpochJsonFieldDecoder.java | 7 + .../decoder/json/RFC2822JsonFieldDecoder.java | 27 +- .../SecondsSinceEpochJsonFieldDecoder.java | 8 + .../TestCustomDateTimeJsonFieldDecoder.java | 5 +- .../json/TestRFC2822JsonFieldDecoder.java | 3 +- .../spi/connector/ConnectorSession.java | 2 - .../io/prestosql/spi/type/SqlTimestamp.java | 54 +- .../java/io/prestosql/spi/type/TimeType.java | 8 +- .../io/prestosql/spi/type/TimestampType.java | 12 +- .../io/prestosql/spi/util/DateTimeUtils.java | 23 +- .../prestosql/spi/block/TestingSession.java | 6 - .../functions/TeradataDateFunctions.java | 13 +- .../functions/TestTeradataDateFunctions.java | 2 +- .../tests/AbstractTestAggregations.java | 12 +- .../tests/TestCachedSqlQueryExecution.java | 4 - 208 files changed, 3022 insertions(+), 5399 deletions(-) delete mode 100644 presto-hive/src/main/java/io/prestosql/plugin/hive/ParquetRecordWriterUtil.java create mode 100644 presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetRecordWriter.java create mode 100644 presto-hive/src/main/java/io/prestosql/plugin/hive/util/FieldSetterFactory.java create mode 100644 presto-kafka/src/test/resources/read_test/all_datatypes_json.json delete mode 100644 presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestDateBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestDateLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTime.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimeLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimestampBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimestampLegacy.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneBase.java delete mode 100644 presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneLegacy.java diff --git a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataFileWriter.java b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataFileWriter.java index 6715c4518..8b502ee34 100755 --- a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataFileWriter.java +++ b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataFileWriter.java @@ -18,7 +18,7 @@ import com.google.gson.Gson; import io.prestosql.plugin.hive.HiveACIDWriteType; import io.prestosql.plugin.hive.HiveFileWriter; import io.prestosql.plugin.hive.HiveType; -import io.prestosql.plugin.hive.HiveWriteUtils; +import io.prestosql.plugin.hive.util.FieldSetterFactory; import io.prestosql.spi.Page; import io.prestosql.spi.PrestoException; import io.prestosql.spi.block.Block; @@ -64,6 +64,7 @@ import org.apache.hadoop.mapred.Reporter; import org.apache.hadoop.mapred.TaskAttemptID; import org.apache.hadoop.mapreduce.TaskType; import org.apache.log4j.Logger; +import org.joda.time.DateTimeZone; import java.io.IOException; import java.io.UncheckedIOException; @@ -104,7 +105,7 @@ public class CarbondataFileWriter private final Object row; private final SettableStructObjectInspector tableInspector; private final List structFields; - private final HiveWriteUtils.FieldSetter[] setters; + private final FieldSetterFactory.FieldSetter[] setters; private final Properties properties; private final Optional acidOptions; private final HiveACIDWriteType acidWriteType; @@ -183,9 +184,12 @@ public class CarbondataFileWriter row = tableInspector.create(); - setters = new HiveWriteUtils.FieldSetter[structFields.size()]; + setters = new FieldSetterFactory.FieldSetter[structFields.size()]; + + FieldSetterFactory fieldSetterFactory = new FieldSetterFactory(DateTimeZone.UTC); + for (int i = 0; i < setters.length; i++) { - setters[i] = HiveWriteUtils.createFieldSetter(tableInspector, row, structFields.get(i), + setters[i] = fieldSetterFactory.create(tableInspector, row, structFields.get(i), fileColumnTypes.get(structFields.get(i).getFieldID())); } diff --git a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadata.java b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadata.java index a9c512e56..773ad1b87 100755 --- a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadata.java +++ b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadata.java @@ -142,7 +142,6 @@ import org.apache.hadoop.mapreduce.TaskType; import org.apache.hadoop.mapreduce.task.JobContextImpl; import org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl; import org.apache.log4j.Logger; -import org.joda.time.DateTimeZone; import java.io.File; import java.io.IOException; @@ -248,8 +247,8 @@ public class CarbondataMetadata } public CarbondataMetadata(SemiTransactionalHiveMetastore metastore, - HdfsEnvironment hdfsEnvironment, HivePartitionManager partitionManager, DateTimeZone timeZone, - boolean allowCorruptWritesForTesting, boolean writesToNonManagedTablesEnabled, + HdfsEnvironment hdfsEnvironment, HivePartitionManager partitionManager, + boolean writesToNonManagedTablesEnabled, boolean createsOfNonManagedTablesEnabled, boolean tableCreatesWithLocationAllowed, TypeManager typeManager, LocationService locationService, JsonCodec partitionUpdateCodec, @@ -259,7 +258,7 @@ public class CarbondataMetadata CarbondataTableReader carbondataTableReader, String carbondataTableStore, long carbondataMajorVacuumSegSize, long carbondataMinorVacuumSegCount, ScheduledExecutorService executorService, ScheduledExecutorService hiveMetastoreClientService) { - super(metastore, hdfsEnvironment, partitionManager, timeZone, allowCorruptWritesForTesting, + super(metastore, hdfsEnvironment, partitionManager, writesToNonManagedTablesEnabled, createsOfNonManagedTablesEnabled, tableCreatesWithLocationAllowed, typeManager, locationService, partitionUpdateCodec, typeTranslator, hetuVersion, hiveStatisticsProvider, accessControlMetadata, false, 2, 0.0, executorService, @@ -1145,8 +1144,6 @@ public class CarbondataMetadata @Override public CarbondataOutputTableHandle beginCreateTable(ConnectorSession session, ConnectorTableMetadata tableMetadata, Optional layout) { - verifyJvmTimeZone(); - // get the root directory for the database SchemaTableName schemaTableName = tableMetadata.getTable(); String schemaName = schemaTableName.getSchemaName(); diff --git a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadataFactory.java b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadataFactory.java index 74db8398e..48a1d4560 100755 --- a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadataFactory.java +++ b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataMetadataFactory.java @@ -37,7 +37,6 @@ import io.prestosql.plugin.hive.metastore.SemiTransactionalHiveMetastore; import io.prestosql.plugin.hive.security.AccessControlMetadataFactory; import io.prestosql.plugin.hive.statistics.MetastoreHiveStatisticsProvider; import io.prestosql.spi.type.TypeManager; -import org.joda.time.DateTimeZone; import java.util.Optional; import java.util.concurrent.ExecutorService; @@ -50,7 +49,6 @@ public class CarbondataMetadataFactory extends HiveMetadataFactory { private static final Logger log = Logger.get(HiveMetadataFactory.class); - private final boolean allowCorruptWritesForTesting; private final boolean skipDeletionForAlter; private final boolean skipTargetCleanupOnRollback; private final boolean writesToNonManagedTablesEnabled; @@ -60,7 +58,6 @@ public class CarbondataMetadataFactory private final HiveMetastore metastore; private final HdfsEnvironment hdfsEnvironment; private final HivePartitionManager partitionManager; - private final DateTimeZone timeZone; private final TypeManager typeManager; private final LocationService locationService; private final BoundedExecutor renameExecution; @@ -93,9 +90,8 @@ public class CarbondataMetadataFactory AccessControlMetadataFactory accessControlMetadataFactory, CarbondataTableReader carbondataTableReader) { - this(metastore, hdfsEnvironment, partitionManager, carbondataConfig.getDateTimeZone(), + this(metastore, hdfsEnvironment, partitionManager, carbondataConfig.getMaxConcurrentFileRenames(), - carbondataConfig.getAllowCorruptWritesForTesting(), carbondataConfig.isSkipDeletionForAlter(), carbondataConfig.isSkipTargetCleanupOnRollback(), true, @@ -112,9 +108,9 @@ public class CarbondataMetadataFactory } public CarbondataMetadataFactory(HiveMetastore metastore, HdfsEnvironment hdfsEnvironment, - HivePartitionManager partitionManager, DateTimeZone timeZone, + HivePartitionManager partitionManager, int maxConcurrentFileRenames, - boolean allowCorruptWritesForTesting, boolean skipDeletionForAlter, + boolean skipDeletionForAlter, boolean skipTargetCleanupOnRollback, boolean writesToNonManagedTablesEnabled, boolean createsOfNonManagedTablesEnabled, boolean tableCreatesWithLocationAllowed, long perTransactionCacheMaximumSize, @@ -133,9 +129,7 @@ public class CarbondataMetadataFactory super(metastore, hdfsEnvironment, partitionManager, - timeZone, maxConcurrentFileRenames, - allowCorruptWritesForTesting, skipDeletionForAlter, skipTargetCleanupOnRollback, writesToNonManagedTablesEnabled, @@ -157,7 +151,6 @@ public class CarbondataMetadataFactory 2, 0.0, false, Optional.of(new Duration(5, TimeUnit.MINUTES)), hmsWriteBatchSize); - this.allowCorruptWritesForTesting = allowCorruptWritesForTesting; this.skipDeletionForAlter = skipDeletionForAlter; this.skipTargetCleanupOnRollback = skipTargetCleanupOnRollback; this.writesToNonManagedTablesEnabled = writesToNonManagedTablesEnabled; @@ -167,7 +160,6 @@ public class CarbondataMetadataFactory this.metastore = requireNonNull(metastore, "metastore is null"); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.partitionManager = requireNonNull(partitionManager, "partitionManager is null"); - this.timeZone = requireNonNull(timeZone, "timeZone is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.locationService = requireNonNull(locationService, "locationService is null"); this.partitionUpdateCodec = requireNonNull(partitionUpdateCodec, "partitionUpdateCodec is null"); @@ -176,13 +168,6 @@ public class CarbondataMetadataFactory this.hetuVersion = requireNonNull(hetuVersion, "hetuVersion is null"); this.accessControlMetadataFactory = requireNonNull(accessControlMetadataFactory, "accessControlMetadataFactory is null"); - if (!allowCorruptWritesForTesting && !timeZone.equals(DateTimeZone.getDefault())) { - log.warn( - "Hive writes are disabled. To write data to Hive, your JVM timezone must match the " + - "Hive storage timezone. Add -Duser.timezone=%s to your JVM arguments", - timeZone.getID()); - } - this.renameExecution = new BoundedExecutor(executorService, maxConcurrentFileRenames); this.vacuumExecutorService = requireNonNull(vacuumExecutorService, "vacuumExecutorService is null"); this.hiveMetastoreClientService = requireNonNull(hiveMetastoreClientService, "hiveMetastoreClientService is null"); @@ -218,8 +203,6 @@ public class CarbondataMetadataFactory return new CarbondataMetadata(metastore, this.hdfsEnvironment, this.partitionManager, - this.timeZone, - this.allowCorruptWritesForTesting, this.writesToNonManagedTablesEnabled, this.createsOfNonManagedTablesEnabled, this.tableCreatesWithLocationAllowed, diff --git a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataWriterFactory.java b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataWriterFactory.java index f1012a179..f8efec4e4 100755 --- a/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataWriterFactory.java +++ b/hetu-carbondata/src/main/java/io/hetu/core/plugin/carbondata/CarbondataWriterFactory.java @@ -47,6 +47,7 @@ import java.util.Set; import static java.util.Objects.requireNonNull; import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.META_TABLE_LOCATION; +import static org.joda.time.DateTimeZone.UTC; public class CarbondataWriterFactory extends HiveWriterFactory @@ -87,7 +88,7 @@ public class CarbondataWriterFactory additionalTableParameters, bucketCount, sortedBy, locationHandle, locationService, queryId, pageSinkMetadataProvider, typeManager, hdfsEnvironment, pageSorter, sortBufferSize, - maxOpenSortFiles, immutablePartitions, session, nodeManager, + maxOpenSortFiles, immutablePartitions, UTC, session, nodeManager, eventClient, hiveSessionProperties, hiveWriterStats, orcFileWriterFactory); this.additionalJobConf = requireNonNull(additionalJobConf, "Additional JobConf is null"); diff --git a/hetu-datacenter/src/test/java/io/hetu/core/plugin/datacenter/TestDataCenterMetadata.java b/hetu-datacenter/src/test/java/io/hetu/core/plugin/datacenter/TestDataCenterMetadata.java index 1f7afdbf9..dab4b75b0 100644 --- a/hetu-datacenter/src/test/java/io/hetu/core/plugin/datacenter/TestDataCenterMetadata.java +++ b/hetu-datacenter/src/test/java/io/hetu/core/plugin/datacenter/TestDataCenterMetadata.java @@ -104,12 +104,6 @@ public class TestDataCenterMetadata return 0; } - @Override - public boolean isLegacyTimestamp() - { - return false; - } - @Override public T getProperty(String name, Class type) { diff --git a/hetu-greenplum/src/main/java/io/hetu/core/plugin/greenplum/GreenPlumSqlClient.java b/hetu-greenplum/src/main/java/io/hetu/core/plugin/greenplum/GreenPlumSqlClient.java index fbef73c7f..7a977a9a5 100644 --- a/hetu-greenplum/src/main/java/io/hetu/core/plugin/greenplum/GreenPlumSqlClient.java +++ b/hetu-greenplum/src/main/java/io/hetu/core/plugin/greenplum/GreenPlumSqlClient.java @@ -412,7 +412,7 @@ public class GreenPlumSqlClient return Optional.of(typedVarcharColumnMapping(jdbcTypeName)); } if (typeHandle.getJdbcType() == Types.TIMESTAMP) { - return Optional.of(timestampColumnMapping(session)); + return Optional.of(timestampColumnMapping()); } if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) { if (!typeHandle.getArrayDimensions().isPresent()) { @@ -447,7 +447,7 @@ public class GreenPlumSqlClient return WriteMapping.sliceMapping("bytea", varbinaryWriteFunction()); } if (TIMESTAMP.equals(type)) { - return WriteMapping.longMapping("timestamp", timestampWriteFunction(session)); + return WriteMapping.longMapping("timestamp", timestampWriteFunction()); } if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) { return WriteMapping.longMapping("timestamp with time zone", timestampWithTimeZoneWriteFunction()); diff --git a/hetu-greenplum/src/test/java/io/hetu/core/plugin/greenplum/TestGreenPlumTypeMapping.java b/hetu-greenplum/src/test/java/io/hetu/core/plugin/greenplum/TestGreenPlumTypeMapping.java index baadebd00..bf20478dc 100644 --- a/hetu-greenplum/src/test/java/io/hetu/core/plugin/greenplum/TestGreenPlumTypeMapping.java +++ b/hetu-greenplum/src/test/java/io/hetu/core/plugin/greenplum/TestGreenPlumTypeMapping.java @@ -522,7 +522,7 @@ public class TestGreenPlumTypeMapping } @Test(dataProvider = "testTimestampDataProvider") - public void testTimestamp(boolean legacyTimestamp, boolean insertWithPresto) + public void testTimestamp(boolean insertWithPresto) { // using two non-JVM zones so that we don't need to worry what Postgres system zone is for (ZoneId sessionZone : ImmutableList.of(ZoneOffset.UTC, jvmZone, vilnius, kathmandu, ZoneId.of(TestingSession.DEFAULT_TIME_ZONE_KEY.getId()))) { @@ -534,17 +534,16 @@ public class TestGreenPlumTypeMapping if (!insertWithPresto) { // when writing, Postgres JDBC driver converts LocalDateTime to string representing date-time in JVM zone - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, epoch); // epoch also is a gap in JVM zone - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInJvmZone1); - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInJvmZone2); + addTimestampTestIfSupported(tests, epoch); // epoch also is a gap in JVM zone + addTimestampTestIfSupported(tests, timeGapInJvmZone1); + addTimestampTestIfSupported(tests, timeGapInJvmZone2); } - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInVilnius); - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInKathmandu); + addTimestampTestIfSupported(tests, timeGapInVilnius); + addTimestampTestIfSupported(tests, timeGapInKathmandu); Session session = Session.builder(getQueryRunner().getDefaultSession()) .setTimeZoneKey(TimeZoneKey.getTimeZoneKey(sessionZone.getId())) - .setSystemProperty("legacy_timestamp", Boolean.toString(legacyTimestamp)) .build(); if (insertWithPresto) { @@ -556,13 +555,8 @@ public class TestGreenPlumTypeMapping } } - private void addTimestampTestIfSupported(DataTypeTest tests, boolean legacyTimestamp, ZoneId sessionZone, LocalDateTime dateTime) + private void addTimestampTestIfSupported(DataTypeTest tests, LocalDateTime dateTime) { - if (legacyTimestamp && isGap(sessionZone, dateTime)) { - // in legacy timestamp semantics we cannot represent this dateTime - return; - } - tests.addRoundTrip(timestampDataType(), dateTime); } @@ -570,10 +564,8 @@ public class TestGreenPlumTypeMapping public Object[][] testTimestampDataProvider() { return new Object[][] { - {true, true}, - {false, true}, - {true, false}, - {false, false}, + {true}, + {false}, }; } diff --git a/hetu-hbase/src/test/java/io/hetu/core/plugin/hbase/client/TestingConnectorSession.java b/hetu-hbase/src/test/java/io/hetu/core/plugin/hbase/client/TestingConnectorSession.java index af7b82794..f18a285b3 100644 --- a/hetu-hbase/src/test/java/io/hetu/core/plugin/hbase/client/TestingConnectorSession.java +++ b/hetu-hbase/src/test/java/io/hetu/core/plugin/hbase/client/TestingConnectorSession.java @@ -87,12 +87,6 @@ public class TestingConnectorSession return 0; } - @Override - public boolean isLegacyTimestamp() - { - return false; - } - @Override public T getProperty(String name, Class type) { diff --git a/hetu-opengauss/src/main/java/io/hetu/core/plugin/opengauss/OpenGaussClient.java b/hetu-opengauss/src/main/java/io/hetu/core/plugin/opengauss/OpenGaussClient.java index c688ad269..5aae0931b 100644 --- a/hetu-opengauss/src/main/java/io/hetu/core/plugin/opengauss/OpenGaussClient.java +++ b/hetu-opengauss/src/main/java/io/hetu/core/plugin/opengauss/OpenGaussClient.java @@ -70,7 +70,7 @@ public class OpenGaussClient return WriteMapping.sliceMapping("bytea", varbinaryWriteFunction()); } if (TIMESTAMP.equals(type)) { - return WriteMapping.longMapping("timestamp", timestampWriteFunctionUsingSqlTimestamp(session)); + return WriteMapping.longMapping("timestamp", timestampWriteFunctionUsingSqlTimestamp()); } if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) { return WriteMapping.longMapping("timestamp with time zone", timestampWithTimeZoneWriteFunction()); @@ -140,7 +140,7 @@ public class OpenGaussClient return Optional.of(typedVarcharColumnMapping(jdbcTypeName)); } if (typeHandle.getJdbcType() == Types.TIMESTAMP) { - return Optional.of(timestampColumnMappingUsingSqlTimestamp(session)); + return Optional.of(timestampColumnMappingUsingSqlTimestamp()); } if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) { if (!typeHandle.getArrayDimensions().isPresent()) { diff --git a/hetu-oracle/src/main/java/io/hetu/core/plugin/oracle/OracleClient.java b/hetu-oracle/src/main/java/io/hetu/core/plugin/oracle/OracleClient.java index bf3b6912c..f9085812b 100644 --- a/hetu-oracle/src/main/java/io/hetu/core/plugin/oracle/OracleClient.java +++ b/hetu-oracle/src/main/java/io/hetu/core/plugin/oracle/OracleClient.java @@ -73,7 +73,6 @@ import java.sql.Timestamp; import java.sql.Types; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -271,7 +270,6 @@ public class OracleClient /** * timestamp with time zone * - * @param connectorSession connectorSession * @return LongWriteFunction * @deprecated This method uses {@link java.sql.Timestamp} and the class cannot * represent date-time value when JVM zone had @@ -281,28 +279,11 @@ public class OracleClient * supports {@link LocalDateTime}, use */ @Deprecated - public static LongWriteFunction timestampWithTimeZoneWriteFunctionUsingSqlTimestamp( - ConnectorSession connectorSession) + public static LongWriteFunction timestampWithTimeZoneWriteFunctionUsingSqlTimestamp() { - if (connectorSession.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(connectorSession.getTimeZoneKey().getId()); - return (statement, index, value) -> setTimestampWithTimeZoneLegacy(statement, index, value, sessionZone); - } return (statement, index, value) -> setTimestampWithTimeZone(statement, index, value); } - private static void setTimestampWithTimeZoneLegacy(PreparedStatement statement, int index, long value, - ZoneId sessionZone) - { - try { - statement.setTimestamp(index, new Timestamp(DateTimeEncoding.unpackMillisUtc( - fromHetuLegacyTimestamp(value, sessionZone).atZone(sessionZone).toInstant().toEpochMilli()))); - } - catch (SQLException e) { - throw new PrestoException(JDBC_ERROR, "Hetu Oracle connector failed to set Timestamp With Time Zone Legacy"); - } - } - private static void setTimestampWithTimeZone(PreparedStatement statement, int index, long value) { try { @@ -314,11 +295,6 @@ public class OracleClient } } - private static LocalDateTime fromHetuLegacyTimestamp(long value, ZoneId sessionZone) - { - return Instant.ofEpochMilli(value).atZone(sessionZone).toLocalDateTime(); - } - private static LocalDateTime fromHetuTimestamp(long value) { return Instant.ofEpochMilli(value).atZone(UTC).toLocalDateTime(); @@ -558,7 +534,7 @@ public class OracleClient break; case OracleTypes.TIMESTAMP: - columnMapping = Optional.of(timestampColumnMappingUsingSqlTimestamp(session)); + columnMapping = Optional.of(timestampColumnMappingUsingSqlTimestamp()); break; // the following two data type is not supported because of oracle.sql.TIMESTAMPTZ @@ -680,14 +656,14 @@ public class OracleClient return WriteMapping.sliceMapping("BLOB", varbinaryWriteFunction()); } else if (TIMESTAMP.equals(type)) { - return WriteMapping.longMapping("TIMESTAMP", timestampWriteFunctionUsingSqlTimestamp(session)); + return WriteMapping.longMapping("TIMESTAMP", timestampWriteFunctionUsingSqlTimestamp()); } else if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) { return WriteMapping.longMapping("TIMESTAMP(3) WITH TIME ZONE", - timestampWithTimeZoneWriteFunctionUsingSqlTimestamp(session)); + timestampWithTimeZoneWriteFunctionUsingSqlTimestamp()); } else if (DATE.equals(type)) { - return WriteMapping.longMapping("DATE", timestampWriteFunctionUsingSqlTimestamp(session)); + return WriteMapping.longMapping("DATE", timestampWriteFunctionUsingSqlTimestamp()); } else { throw new PrestoException(NOT_SUPPORTED, "Unsupported column type: " + type.getDisplayName()); diff --git a/pom.xml b/pom.xml index e9bb1755f..74368df81 100644 --- a/pom.xml +++ b/pom.xml @@ -514,7 +514,7 @@ io.prestosql.hive hive-apache - 3.0.0-2 + 3.1.2-1 diff --git a/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/BaseJdbcClient.java b/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/BaseJdbcClient.java index eeb115bcb..c4b540123 100644 --- a/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/BaseJdbcClient.java +++ b/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/BaseJdbcClient.java @@ -316,7 +316,7 @@ public class BaseJdbcClient @Override public Optional toPrestoType(ConnectorSession session, Connection connection, JdbcTypeHandle typeHandle) { - return jdbcTypeToPrestoType(session, typeHandle); + return jdbcTypeToPrestoType(typeHandle); } @Override diff --git a/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/StandardColumnMappings.java b/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/StandardColumnMappings.java index 13a75371a..a21316f8a 100644 --- a/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/StandardColumnMappings.java +++ b/presto-base-jdbc/src/main/java/io/prestosql/plugin/jdbc/StandardColumnMappings.java @@ -16,7 +16,6 @@ package io.prestosql.plugin.jdbc; import com.google.common.base.CharMatcher; import com.google.common.primitives.Shorts; import com.google.common.primitives.SignedBytes; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.type.CharType; import io.prestosql.spi.type.DecimalType; import io.prestosql.spi.type.Decimals; @@ -35,7 +34,6 @@ import java.sql.Timestamp; import java.sql.Types; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.Optional; import static com.google.common.base.Preconditions.checkArgument; @@ -287,42 +285,23 @@ public final class StandardColumnMappings * {@link #timestampColumnMapping} instead. */ @Deprecated - public static ColumnMapping timestampColumnMappingUsingSqlTimestamp(ConnectorSession session) + public static ColumnMapping timestampColumnMappingUsingSqlTimestamp() { - if (session.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(session.getTimeZoneKey().getId()); - return ColumnMapping.longMapping( - TIMESTAMP, - (resultSet, columnIndex) -> { - Timestamp timestamp = resultSet.getTimestamp(columnIndex); - return toPrestoLegacyTimestamp(timestamp.toLocalDateTime(), sessionZone); - }, - timestampWriteFunctionUsingSqlTimestamp(session)); - } - return ColumnMapping.longMapping( TIMESTAMP, (resultSet, columnIndex) -> { Timestamp timestamp = resultSet.getTimestamp(columnIndex); return toPrestoTimestamp(timestamp.toLocalDateTime()); }, - timestampWriteFunctionUsingSqlTimestamp(session)); + timestampWriteFunctionUsingSqlTimestamp()); } - public static ColumnMapping timestampColumnMapping(ConnectorSession session) + public static ColumnMapping timestampColumnMapping() { - if (session.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(session.getTimeZoneKey().getId()); - return ColumnMapping.longMapping( - TIMESTAMP, - (resultSet, columnIndex) -> toPrestoLegacyTimestamp(resultSet.getObject(columnIndex, LocalDateTime.class), sessionZone), - timestampWriteFunction(session)); - } - return ColumnMapping.longMapping( TIMESTAMP, (resultSet, columnIndex) -> toPrestoTimestamp(resultSet.getObject(columnIndex, LocalDateTime.class)), - timestampWriteFunction(session)); + timestampWriteFunction()); } /** @@ -332,33 +311,14 @@ public final class StandardColumnMappings * {@link #timestampWriteFunction} instead. */ @Deprecated - public static LongWriteFunction timestampWriteFunctionUsingSqlTimestamp(ConnectorSession connectorSession) + public static LongWriteFunction timestampWriteFunctionUsingSqlTimestamp() { - if (connectorSession.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(connectorSession.getTimeZoneKey().getId()); - return (statement, index, value) -> statement.setTimestamp(index, Timestamp.valueOf(fromPrestoLegacyTimestamp(value, sessionZone))); - } return (statement, index, value) -> statement.setTimestamp(index, Timestamp.valueOf(fromPrestoTimestamp(value))); } - public static LongWriteFunction timestampWriteFunction(ConnectorSession session) + public static LongWriteFunction timestampWriteFunction() { - if (session.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(session.getTimeZoneKey().getId()); - return (statement, index, value) -> statement.setObject(index, fromPrestoLegacyTimestamp(value, sessionZone)); - } - return (statement, index, value) -> { - statement.setObject(index, fromPrestoTimestamp(value)); - }; - } - - /** - * @deprecated applicable in legacy timestamp semantics only - */ - @Deprecated - private static long toPrestoLegacyTimestamp(LocalDateTime localDateTime, ZoneId sessionZone) - { - return localDateTime.atZone(sessionZone).toInstant().toEpochMilli(); + return (statement, index, value) -> statement.setObject(index, fromPrestoTimestamp(value)); } private static long toPrestoTimestamp(LocalDateTime localDateTime) @@ -366,21 +326,12 @@ public final class StandardColumnMappings return localDateTime.atZone(UTC).toInstant().toEpochMilli(); } - /** - * @deprecated applicable in legacy timestamp semantics only - */ - @Deprecated - private static LocalDateTime fromPrestoLegacyTimestamp(long value, ZoneId sessionZone) - { - return Instant.ofEpochMilli(value).atZone(sessionZone).toLocalDateTime(); - } - private static LocalDateTime fromPrestoTimestamp(long value) { return Instant.ofEpochMilli(value).atZone(UTC).toLocalDateTime(); } - public static Optional jdbcTypeToPrestoType(ConnectorSession session, JdbcTypeHandle type) + public static Optional jdbcTypeToPrestoType(JdbcTypeHandle type) { int columnSize = type.getColumnSize(); switch (type.getJdbcType()) { @@ -444,7 +395,7 @@ public final class StandardColumnMappings case Types.TIMESTAMP: // TODO default to `timestampColumnMapping` - return Optional.of(timestampColumnMappingUsingSqlTimestamp(session)); + return Optional.of(timestampColumnMappingUsingSqlTimestamp()); } return Optional.empty(); } diff --git a/presto-base-jdbc/src/test/java/io/prestosql/plugin/jdbc/TestJdbcQueryBuilder.java b/presto-base-jdbc/src/test/java/io/prestosql/plugin/jdbc/TestJdbcQueryBuilder.java index 26483a4be..a47ac046e 100644 --- a/presto-base-jdbc/src/test/java/io/prestosql/plugin/jdbc/TestJdbcQueryBuilder.java +++ b/presto-base-jdbc/src/test/java/io/prestosql/plugin/jdbc/TestJdbcQueryBuilder.java @@ -22,8 +22,6 @@ import io.prestosql.spi.predicate.Range; import io.prestosql.spi.predicate.SortedRangeSet; import io.prestosql.spi.predicate.TupleDomain; import io.prestosql.spi.type.CharType; -import io.prestosql.spi.type.SqlTimestamp; -import io.prestosql.testing.DateTimeTestingUtils; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -64,16 +62,15 @@ import static io.prestosql.spi.type.IntegerType.INTEGER; import static io.prestosql.spi.type.RealType.REAL; import static io.prestosql.spi.type.SmallintType.SMALLINT; import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.lang.Float.floatToRawIntBits; import static java.lang.String.format; import static java.time.temporal.ChronoUnit.DAYS; import static java.util.function.Function.identity; -import static org.joda.time.DateTimeZone.UTC; import static org.testng.Assert.assertEquals; @Test(singleThreaded = true) @@ -398,11 +395,7 @@ public class TestJdbcQueryBuilder private static long toPrestoTimestamp(int year, int month, int day, int hour, int minute, int second) { - SqlTimestamp sqlTimestamp = DateTimeTestingUtils.sqlTimestampOf(year, month, day, hour, minute, second, 0, UTC, UTC_KEY, SESSION); - if (SESSION.isLegacyTimestamp()) { - return sqlTimestamp.getMillisUtc(); - } - return sqlTimestamp.getMillis(); + return sqlTimestampOf(year, month, day, hour, minute, second, 0).getMillis(); } private static Timestamp toTimestamp(int year, int month, int day, int hour, int minute, int second) diff --git a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSource.java b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSource.java index bc4319bfc..797c6f5d8 100644 --- a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSource.java +++ b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSource.java @@ -38,7 +38,6 @@ import io.prestosql.spi.block.Block; import io.prestosql.spi.block.BlockBuilder; import io.prestosql.spi.block.PageBuilderStatus; import io.prestosql.spi.connector.ConnectorPageSource; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.type.ArrayType; import io.prestosql.spi.type.RowType; import io.prestosql.spi.type.Type; @@ -89,7 +88,6 @@ public class ElasticsearchPageSource public ElasticsearchPageSource( ElasticsearchClient client, - ConnectorSession session, ElasticsearchTableHandle table, ElasticsearchSplit split, List columns) @@ -99,7 +97,7 @@ public class ElasticsearchPageSource this.columns = ImmutableList.copyOf(columns); - decoders = createDecoders(session, columns); + decoders = createDecoders(columns); // When the _source field is requested, we need to bypass column pruning when fetching the document boolean needAllFields = columns.stream() @@ -252,7 +250,7 @@ public class ElasticsearchPageSource } } - private List createDecoders(ConnectorSession session, List columns) + private List createDecoders(List columns) { return columns.stream() .map(column -> { @@ -268,12 +266,12 @@ public class ElasticsearchPageSource return new SourceColumnDecoder(); } - return createDecoder(session, column.getName(), column.getType()); + return createDecoder(column.getName(), column.getType()); }) .collect(toImmutableList()); } - private Decoder createDecoder(ConnectorSession session, String path, Type type) + private Decoder createDecoder(String path, Type type) { if (type.equals(VARCHAR)) { return new VarcharDecoder(path); @@ -282,7 +280,7 @@ public class ElasticsearchPageSource return new VarbinaryDecoder(path); } else if (type.equals(TIMESTAMP)) { - return new TimestampDecoder(session, path); + return new TimestampDecoder(path); } else if (type.equals(BOOLEAN)) { return new BooleanDecoder(path); @@ -312,7 +310,7 @@ public class ElasticsearchPageSource RowType rowType = (RowType) type; List decoders = rowType.getFields().stream() - .map(field -> createDecoder(session, appendPath(path, field.getName().get()), field.getType())) + .map(field -> createDecoder(appendPath(path, field.getName().get()), field.getType())) .collect(toImmutableList()); List fieldNames = rowType.getFields().stream() @@ -324,7 +322,7 @@ public class ElasticsearchPageSource } if (type instanceof ArrayType) { Type elementType = ((ArrayType) type).getElementType(); - return new ArrayDecoder(path, createDecoder(session, path, elementType)); + return new ArrayDecoder(path, createDecoder(path, elementType)); } throw new UnsupportedOperationException("Type not supported: " + type); diff --git a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSourceProvider.java b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSourceProvider.java index f67d8ebfa..84408dbb5 100644 --- a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSourceProvider.java +++ b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/ElasticsearchPageSourceProvider.java @@ -47,7 +47,6 @@ public class ElasticsearchPageSourceProvider return new ElasticsearchPageSource( client, - session, (ElasticsearchTableHandle) table, (ElasticsearchSplit) split, columns.stream() .map(ElasticsearchColumnHandle.class::cast) diff --git a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/decoders/TimestampDecoder.java b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/decoders/TimestampDecoder.java index 5008dbc22..c1b907bd1 100644 --- a/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/decoders/TimestampDecoder.java +++ b/presto-elasticsearch/src/main/java/io/prestosql/elasticsearch/decoders/TimestampDecoder.java @@ -15,12 +15,11 @@ package io.prestosql.elasticsearch.decoders; import io.prestosql.spi.PrestoException; import io.prestosql.spi.block.BlockBuilder; -import io.prestosql.spi.connector.ConnectorSession; import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.search.SearchHit; import java.time.LocalDateTime; -import java.time.ZoneId; +import java.time.ZoneOffset; import java.util.function.Supplier; import static io.prestosql.spi.StandardErrorCode.TYPE_MISMATCH; @@ -32,12 +31,10 @@ public class TimestampDecoder implements Decoder { private final String path; - private final ZoneId zoneId; - public TimestampDecoder(ConnectorSession session, String path) + public TimestampDecoder(String path) { this.path = path; - this.zoneId = ZoneId.of(session.getTimeZoneKey().getId()); } @Override @@ -53,7 +50,7 @@ public class TimestampDecoder else { TIMESTAMP.writeLong(output, ISO_DATE_TIME.parse(documentField.getValue(), LocalDateTime::from) - .atZone(zoneId) + .atOffset(ZoneOffset.UTC) .toInstant() .toEpochMilli()); } 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 6bb598df1..c78c5d3b9 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 @@ -26,7 +26,9 @@ import io.prestosql.spi.type.Type; 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; @@ -40,17 +42,13 @@ import org.apache.hadoop.io.BytesWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Writable; import org.apache.hadoop.mapred.RecordReader; -import org.joda.time.DateTimeZone; 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 static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; @@ -105,7 +103,6 @@ class GenericHiveRecordCursor private final boolean[] nulls; private final long totalBytes; - private final DateTimeZone hiveStorageTimeZone; private long completedBytes; private Object rowData; @@ -118,7 +115,6 @@ class GenericHiveRecordCursor long totalBytes, Properties splitSchema, List columns, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager) { requireNonNull(path, "path is null"); @@ -126,14 +122,12 @@ class GenericHiveRecordCursor checkArgument(totalBytes >= 0, "totalBytes is negative"); requireNonNull(splitSchema, "splitSchema is null"); requireNonNull(columns, "columns is null"); - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone 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); @@ -278,35 +272,18 @@ class GenericHiveRecordCursor 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; + return ((Timestamp) value).toEpochMilli(); } if (value instanceof Float) { return floatToRawIntBits(((Float) value)); 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 2204f6fda..0b9dcc31d 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 @@ -22,7 +22,6 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Writable; import org.apache.hadoop.mapred.RecordReader; -import org.joda.time.DateTimeZone; import javax.inject.Inject; @@ -57,7 +56,6 @@ public class GenericHiveRecordCursorProvider Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, boolean s3SelectPushdownEnabled, Map customSplitInfo) @@ -80,7 +78,6 @@ public class GenericHiveRecordCursorProvider length, schema, columns, - hiveStorageTimeZone, typeManager)); }); } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveBucketing.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveBucketing.java index 716bfacc4..66f815c68 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveBucketing.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveBucketing.java @@ -170,7 +170,7 @@ public final class HiveBucketing return Optional.empty(); } - if (containsTimestampBucketedV2(table.getStorage().getBucketProperty().get(), table)) { + if (bucketedOnTimestamp(table.getStorage().getBucketProperty().get(), table)) { return Optional.empty(); } @@ -269,35 +269,27 @@ public final class HiveBucketing } } - public static boolean containsTimestampBucketedV2(HiveBucketProperty bucketProperty, Table table) + public static boolean bucketedOnTimestamp(HiveBucketProperty bucketProperty, Table table) { - switch (bucketProperty.getBucketingVersion()) { - case BUCKETING_V1: - return false; - case BUCKETING_V2: - break; - default: - throw new IllegalArgumentException("Unsupported bucketing version: " + bucketProperty.getBucketingVersion()); - } return bucketProperty.getBucketedBy().stream() .map(columnName -> table.getColumn(columnName) .orElseThrow(() -> new IllegalArgumentException(format("Cannot find column '%s' in %s", columnName, table)))) .map(Column::getType) .map(HiveType::getTypeInfo) - .anyMatch(HiveBucketing::containsTimestampBucketedV2); + .anyMatch(HiveBucketing::bucketedOnTimestamp); } - private static boolean containsTimestampBucketedV2(TypeInfo type) + private static boolean bucketedOnTimestamp(TypeInfo type) { switch (type.getCategory()) { case PRIMITIVE: return ((PrimitiveTypeInfo) type).getPrimitiveCategory() == TIMESTAMP; case LIST: - return containsTimestampBucketedV2(((ListTypeInfo) type).getListElementTypeInfo()); + return bucketedOnTimestamp(((ListTypeInfo) type).getListElementTypeInfo()); case MAP: MapTypeInfo mapTypeInfo = (MapTypeInfo) type; - // Note: we do not check map value type because HiveBucketingV2#hashOfMap hashes map values with v1 - return containsTimestampBucketedV2(mapTypeInfo.getMapKeyTypeInfo()); + return bucketedOnTimestamp(mapTypeInfo.getMapKeyTypeInfo()) || + bucketedOnTimestamp(mapTypeInfo.getMapValueTypeInfo()); default: // TODO: support more types, e.g. ROW throw new UnsupportedOperationException("Computation of Hive bucket hashCode is not supported for Hive category: " + type.getCategory()); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveConfig.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveConfig.java index 6f5301dcf..fd2650c99 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveConfig.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveConfig.java @@ -57,13 +57,12 @@ import static java.util.concurrent.TimeUnit.MINUTES; "hive.optimized-reader.enabled", "hive.orc.optimized-writer.enabled", "hive.rcfile-optimized-writer.enabled", + "hive.time-zone", }) public class HiveConfig { private static final Splitter SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings(); - private String timeZone = TimeZone.getDefault().getID(); - private DataSize maxSplitSize = new DataSize(64, MEGABYTE); private int maxPartitionsPerScan = 100_000; private int maxOutstandingSplits = 1_000; @@ -115,6 +114,9 @@ public class HiveConfig private DataSize textMaxLineLength = new DataSize(100, MEGABYTE); + private String orcLegacyTimeZone = TimeZone.getDefault().getID(); + + private String parquetTimeZone = TimeZone.getDefault().getID(); private boolean useParquetColumnNames; private boolean failOnCorruptedParquetStatistics = true; private DataSize parquetMaxReadBlockSize = new DataSize(16, MEGABYTE); @@ -150,6 +152,7 @@ public class HiveConfig private Duration orcRowDataCacheTtl = new Duration(4, HOURS); private DataSize orcRowDataCacheMaximumWeight = new DataSize(20, GIGABYTE); + private String rcfileTimeZone = TimeZone.getDefault().getID(); private boolean rcfileWriterValidate; private HiveMetastoreAuthenticationType hiveMetastoreAuthenticationType = HiveMetastoreAuthenticationType.NONE; @@ -334,24 +337,6 @@ public class HiveConfig return recursiveDirWalkerEnabled; } - public DateTimeZone getDateTimeZone() - { - return DateTimeZone.forTimeZone(TimeZone.getTimeZone(timeZone)); - } - - @NotNull - public String getTimeZone() - { - return timeZone; - } - - @Config("hive.time-zone") - public HiveConfig setTimeZone(String id) - { - this.timeZone = (id != null) ? id : TimeZone.getDefault().getID(); - return this; - } - @NotNull public DataSize getMaxSplitSize() { @@ -947,6 +932,25 @@ public class HiveConfig return this; } + public DateTimeZone getRcfileDateTimeZone() + { + return DateTimeZone.forTimeZone(TimeZone.getTimeZone(rcfileTimeZone)); + } + + @NotNull + public String getRcfileTimeZone() + { + return rcfileTimeZone; + } + + @Config("hive.rcfile.time-zone") + @ConfigDescription("Time zone for RCFile binary read and write") + public HiveConfig setRcfileTimeZone(String rcfileTimeZone) + { + this.rcfileTimeZone = rcfileTimeZone; + return this; + } + public boolean isRcfileWriterValidate() { return rcfileWriterValidate; @@ -988,6 +992,44 @@ public class HiveConfig return this; } + public DateTimeZone getOrcLegacyDateTimeZone() + { + return DateTimeZone.forTimeZone(TimeZone.getTimeZone(orcLegacyTimeZone)); + } + + @NotNull + public String getOrcLegacyTimeZone() + { + return orcLegacyTimeZone; + } + + @Config("hive.orc.time-zone") + @ConfigDescription("Time zone for legacy ORC files that do not contain a time zone") + public HiveConfig setOrcLegacyTimeZone(String orcLegacyTimeZone) + { + this.orcLegacyTimeZone = orcLegacyTimeZone; + return this; + } + + public DateTimeZone getParquetDateTimeZone() + { + return DateTimeZone.forTimeZone(TimeZone.getTimeZone(parquetTimeZone)); + } + + @NotNull + public String getParquetTimeZone() + { + return parquetTimeZone; + } + + @Config("hive.parquet.time-zone") + @ConfigDescription("Time zone for Parquet read and write") + public HiveConfig setParquetTimeZone(String parquetTimeZone) + { + this.parquetTimeZone = parquetTimeZone; + return this; + } + public boolean isUseParquetColumnNames() { return useParquetColumnNames; diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadata.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadata.java index 24789ee94..43536bd0c 100755 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadata.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadata.java @@ -104,7 +104,6 @@ import org.apache.hadoop.hive.ql.io.AcidUtils; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.OpenCSVSerde; import org.apache.hadoop.mapred.JobConf; -import org.joda.time.DateTimeZone; import java.io.File; import java.io.IOException; @@ -141,7 +140,7 @@ import static com.google.common.collect.ImmutableMap.toImmutableMap; import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Streams.stream; -import static io.prestosql.plugin.hive.HiveBucketing.containsTimestampBucketedV2; +import static io.prestosql.plugin.hive.HiveBucketing.bucketedOnTimestamp; import static io.prestosql.plugin.hive.HiveErrorCode.HIVE_FILESYSTEM_ERROR; import static io.prestosql.plugin.hive.HiveStorageFormat.ORC; import static io.prestosql.plugin.hive.HiveTableProperties.IS_EXTERNAL_TABLE; @@ -218,11 +217,9 @@ public class HiveMetadata private static final String CSV_QUOTE_KEY = OpenCSVSerde.QUOTECHAR; private static final String CSV_ESCAPE_KEY = OpenCSVSerde.ESCAPECHAR; - private final boolean allowCorruptWritesForTesting; protected final SemiTransactionalHiveMetastore metastore; protected final HdfsEnvironment hdfsEnvironment; private final HivePartitionManager partitionManager; - private final DateTimeZone timeZone; protected final TypeManager typeManager; protected final LocationService locationService; private final JsonCodec partitionUpdateCodec; @@ -247,8 +244,6 @@ public class HiveMetadata SemiTransactionalHiveMetastore metastore, HdfsEnvironment hdfsEnvironment, HivePartitionManager partitionManager, - DateTimeZone timeZone, - boolean allowCorruptWritesForTesting, boolean writesToNonManagedTablesEnabled, boolean createsOfNonManagedTablesEnabled, boolean tableCreatesWithLocationAllowed, @@ -266,12 +261,9 @@ public class HiveMetadata Optional vacuumCollectorInterval, ScheduledExecutorService hiveMetastoreClientService) { - this.allowCorruptWritesForTesting = allowCorruptWritesForTesting; - this.metastore = requireNonNull(metastore, "metastore is null"); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.partitionManager = requireNonNull(partitionManager, "partitionManager is null"); - this.timeZone = requireNonNull(timeZone, "timeZone is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.locationService = requireNonNull(locationService, "locationService is null"); this.partitionUpdateCodec = requireNonNull(partitionUpdateCodec, "partitionUpdateCodec is null"); @@ -1162,7 +1154,6 @@ public class HiveMetadata @Override public ConnectorTableHandle beginStatisticsCollection(ConnectorSession session, ConnectorTableHandle tableHandle) { - verifyJvmTimeZone(); SchemaTableName tableName = ((HiveTableHandle) tableHandle).getSchemaTableName(); metastore.getTable(new HiveIdentity(session), tableName.getSchemaName(), tableName.getTableName()) .orElseThrow(() -> new TableNotFoundException(tableName)); @@ -1232,8 +1223,6 @@ public class HiveMetadata @Override public HiveOutputTableHandle beginCreateTable(ConnectorSession session, ConnectorTableMetadata tableMetadata, Optional layout) { - verifyJvmTimeZone(); - if (getExternalLocation(tableMetadata.getProperties()) != null || isExternalTable(tableMetadata.getProperties())) { throw new PrestoException(NOT_SUPPORTED, "External tables cannot be created using CREATE TABLE AS"); } @@ -1534,8 +1523,6 @@ public class HiveMetadata private HiveInsertTableHandle beginInsertUpdateInternal(ConnectorSession session, ConnectorTableHandle tableHandle, Optional partition, HiveACIDWriteType writeType) { - verifyJvmTimeZone(); - HiveIdentity identity = new HiveIdentity(session); SchemaTableName tableName = ((HiveTableHandle) tableHandle).getSchemaTableName(); Table table = metastore.getTable(identity, tableName.getSchemaName(), tableName.getTableName()) @@ -1855,7 +1842,6 @@ public class HiveMetadata long rowCount = basicStatistics.getRowCount().orElseThrow(() -> new IllegalArgumentException("rowCount not present")); Map columnStatistics = Statistics.fromComputedStatistics( session, - timeZone, computedColumnStatistics, columnTypes, rowCount); @@ -2458,8 +2444,8 @@ public class HiveMetadata private Optional getInsertTableLayoutInternal(ConnectorSession session, Table table) { if (table.getStorage().getBucketProperty().isPresent()) { - if (containsTimestampBucketedV2(table.getStorage().getBucketProperty().get(), table)) { - throw new PrestoException(NOT_SUPPORTED, "Table bucketing version not supported for writing when bucketing on timestamp type"); + if (bucketedOnTimestamp(table.getStorage().getBucketProperty().get(), table)) { + throw new PrestoException(NOT_SUPPORTED, "Writing to tables bucketed on timestamp not supported"); } } @@ -2665,15 +2651,6 @@ public class HiveMetadata return accessControlMetadata.listTablePrivileges(session, listTables(session, schemaTablePrefix)); } - protected void verifyJvmTimeZone() - { - if (!allowCorruptWritesForTesting && !timeZone.equals(DateTimeZone.getDefault())) { - throw new PrestoException(HiveErrorCode.HIVE_TIMEZONE_MISMATCH, format( - "To write Hive data, your JVM timezone must match the Hive storage timezone. Add -Duser.timezone=%s to your JVM arguments.", - timeZone.getID())); - } - } - public static HiveStorageFormat extractHiveStorageFormat(Table table) { StorageFormat storageFormat = table.getStorage().getStorageFormat(); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadataFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadataFactory.java index d24f4274e..703921e65 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadataFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveMetadataFactory.java @@ -15,7 +15,6 @@ package io.prestosql.plugin.hive; import io.airlift.concurrent.BoundedExecutor; import io.airlift.json.JsonCodec; -import io.airlift.log.Logger; import io.airlift.units.Duration; import io.prestosql.plugin.hive.metastore.CachingHiveMetastore; import io.prestosql.plugin.hive.metastore.HiveMetastore; @@ -24,7 +23,6 @@ import io.prestosql.plugin.hive.security.AccessControlMetadataFactory; import io.prestosql.plugin.hive.statistics.MetastoreHiveStatisticsProvider; import io.prestosql.plugin.hive.statistics.TableColumnStatistics; import io.prestosql.spi.type.TypeManager; -import org.joda.time.DateTimeZone; import javax.inject.Inject; @@ -41,12 +39,9 @@ import static java.util.Objects.requireNonNull; public class HiveMetadataFactory implements Supplier { - private static final Logger log = Logger.get(HiveMetadataFactory.class); - protected final Map statsCache = new ConcurrentHashMap(); protected final Map> samplePartitionCache = new ConcurrentHashMap(); - private final boolean allowCorruptWritesForTesting; private final boolean skipDeletionForAlter; private final boolean skipTargetCleanupOnRollback; private final boolean writesToNonManagedTablesEnabled; @@ -56,7 +51,6 @@ public class HiveMetadataFactory private final HiveMetastore metastore; private final HdfsEnvironment hdfsEnvironment; private final HivePartitionManager partitionManager; - private final DateTimeZone timeZone; private final TypeManager typeManager; private final LocationService locationService; private final JsonCodec partitionUpdateCodec; @@ -97,9 +91,7 @@ public class HiveMetadataFactory metastore, hdfsEnvironment, partitionManager, - hiveConfig.getDateTimeZone(), hiveConfig.getMaxConcurrentFileRenames(), - hiveConfig.getAllowCorruptWritesForTesting(), hiveConfig.isSkipDeletionForAlter(), hiveConfig.isSkipTargetCleanupOnRollback(), hiveConfig.getWritesToNonManagedTablesEnabled(), @@ -129,9 +121,7 @@ public class HiveMetadataFactory HiveMetastore metastore, HdfsEnvironment hdfsEnvironment, HivePartitionManager partitionManager, - DateTimeZone timeZone, int maxConcurrentFileRenames, - boolean allowCorruptWritesForTesting, boolean skipDeletionForAlter, boolean skipTargetCleanupOnRollback, boolean writesToNonManagedTablesEnabled, @@ -156,7 +146,6 @@ public class HiveMetadataFactory Optional vacuumCollectorInterval, int hmsWriteBatchSize) { - this.allowCorruptWritesForTesting = allowCorruptWritesForTesting; this.skipDeletionForAlter = skipDeletionForAlter; this.skipTargetCleanupOnRollback = skipTargetCleanupOnRollback; this.writesToNonManagedTablesEnabled = writesToNonManagedTablesEnabled; @@ -167,7 +156,6 @@ public class HiveMetadataFactory this.metastore = requireNonNull(metastore, "metastore is null"); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.partitionManager = requireNonNull(partitionManager, "partitionManager is null"); - this.timeZone = requireNonNull(timeZone, "timeZone is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.locationService = requireNonNull(locationService, "locationService is null"); this.partitionUpdateCodec = requireNonNull(partitionUpdateCodec, "partitionUpdateCodec is null"); @@ -177,13 +165,6 @@ public class HiveMetadataFactory this.hiveTransactionHeartbeatInterval = requireNonNull(hiveTransactionHeartbeatInterval, "hiveTransactionHeartbeatInterval is null"); this.vacuumCleanupRecheckInterval = requireNonNull(vacuumCleanupRecheckInterval, "vacuumCleanupInterval is null"); - if (!allowCorruptWritesForTesting && !timeZone.equals(DateTimeZone.getDefault())) { - log.warn("Hive writes are disabled. " + - "To write data to Hive, your JVM timezone must match the Hive storage timezone. " + - "Add -Duser.timezone=%s to your JVM arguments", - timeZone.getID()); - } - renameExecution = new BoundedExecutor(executorService, maxConcurrentFileRenames); this.hiveVacuumService = requireNonNull(hiveVacuumService, "hiveVacuumService is null"); this.heartbeatService = requireNonNull(heartbeatService, "heartbeatService is null"); @@ -215,8 +196,6 @@ public class HiveMetadataFactory metastore, hdfsEnvironment, partitionManager, - timeZone, - allowCorruptWritesForTesting, writesToNonManagedTablesEnabled, createsOfNonManagedTablesEnabled, tableCreatesWithLocationAllowed, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSink.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSink.java index cc514a18f..43f5dd70c 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSink.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSink.java @@ -524,7 +524,7 @@ public class HivePageSink for (int i = 0; i < partitionKeys.size(); i++) { HivePartitionKey partitionKey = partitionKeys.get(i); Type type = partitionTypes.get(i); - Object partitionColumnValue = HiveUtil.typedPartitionKey(partitionKey.getValue(), type, partitionKey.getName(), null); + Object partitionColumnValue = HiveUtil.typedPartitionKey(partitionKey.getValue(), type, partitionKey.getName()); RunLengthEncodedBlock block = RunLengthEncodedBlock.create(type, partitionColumnValue, 1); type.appendTo(block, 0, builder.getBlockBuilder(i)); } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSinkProvider.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSinkProvider.java index 3ba6a5f59..f38a21761 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSinkProvider.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSinkProvider.java @@ -39,6 +39,7 @@ import io.prestosql.spi.connector.ConnectorUpdateTableHandle; import io.prestosql.spi.connector.ConnectorVacuumTableHandle; import io.prestosql.spi.type.TypeManager; import org.apache.hadoop.hive.ql.io.AcidUtils; +import org.joda.time.DateTimeZone; import javax.inject.Inject; @@ -74,6 +75,7 @@ public class HivePageSinkProvider private final HiveWriterStats hiveWriterStats; private final OrcFileWriterFactory orcFileWriterFactory; private final long perTransactionMetastoreCacheMaximumSize; + private final DateTimeZone parquetTimeZone; @Inject public HivePageSinkProvider( @@ -111,6 +113,7 @@ public class HivePageSinkProvider this.hiveWriterStats = requireNonNull(hiveWriterStats, "stats is null"); this.orcFileWriterFactory = requireNonNull(orcFileWriterFactory, "orcFileWriterFactory is null"); this.perTransactionMetastoreCacheMaximumSize = config.getPerTransactionMetastoreCacheMaximumSize(); + this.parquetTimeZone = config.getParquetDateTimeZone(); } @Override @@ -186,6 +189,7 @@ public class HivePageSinkProvider writerSortBufferSize, maxOpenSortFiles, immutablePartitions, + parquetTimeZone, session, nodeManager, eventClient, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSource.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSource.java index 6bf9d6e9c..5eda3c585 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSource.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSource.java @@ -39,7 +39,6 @@ import io.prestosql.spi.type.TypeManager; import io.prestosql.spi.type.TypeUtils; import it.unimi.dsi.fastutil.ints.IntArrayList; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; -import org.joda.time.DateTimeZone; import java.io.IOException; import java.io.UncheckedIOException; @@ -88,14 +87,12 @@ public class HivePageSource public HivePageSource( List columnMappings, Optional bucketAdaptation, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, ConnectorPageSource delegate, Optional dynamicFilterSupplier, ConnectorSession session, List partitionKeys) { - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.delegate = requireNonNull(delegate, "delegate is null"); @@ -129,7 +126,7 @@ public class HivePageSource } if (columnMapping.getKind() == PREFILLED) { - prefilledValues[columnIndex] = typedPartitionKey(columnMapping.getPrefilledValue(), type, name, hiveStorageTimeZone); + prefilledValues[columnIndex] = typedPartitionKey(columnMapping.getPrefilledValue(), type, name); } } this.coercers = coercers.build(); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceFactory.java index 8b12dc613..33016fc18 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceFactory.java @@ -21,7 +21,6 @@ import io.prestosql.spi.heuristicindex.SplitMetadata; import io.prestosql.spi.predicate.TupleDomain; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; -import org.joda.time.DateTimeZone; import java.util.List; import java.util.Optional; @@ -39,7 +38,6 @@ public interface HivePageSourceFactory Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, Optional dynamicFilterSupplier, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceProvider.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceProvider.java index ea89abd49..25d4ae2f6 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceProvider.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePageSourceProvider.java @@ -51,7 +51,6 @@ import io.prestosql.spi.type.TypeManager; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.eclipse.jetty.util.URIUtil; -import org.joda.time.DateTimeZone; import javax.inject.Inject; @@ -82,7 +81,6 @@ import static java.util.stream.Collectors.toList; public class HivePageSourceProvider implements ConnectorPageSourceProvider { - private final DateTimeZone hiveStorageTimeZone; private final HdfsEnvironment hdfsEnvironment; private final Set cursorProviders; private final TypeManager typeManager; @@ -104,7 +102,6 @@ public class HivePageSourceProvider Set selectivePageSourceFactories) { requireNonNull(hiveConfig, "hiveConfig is null"); - this.hiveStorageTimeZone = hiveConfig.getDateTimeZone(); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.cursorProviders = ImmutableSet.copyOf(requireNonNull(cursorProviders, "cursorProviders is null")); this.pageSourceFactories = ImmutableSet.copyOf( @@ -215,7 +212,7 @@ public class HivePageSourceProvider */ if (hiveTable.isSuitableToPush()) { return createSelectivePageSource(selectivePageSourceFactories, configuration, - session, hiveSplit, assignUniqueIndicesToPartitionColumns(hiveColumns), hiveStorageTimeZone, typeManager, + session, hiveSplit, assignUniqueIndicesToPartitionColumns(hiveColumns), typeManager, dynamicFilterSupplier, hiveSplit.getDeleteDeltaLocations(), hiveSplit.getStartRowOffsetOfFile(), indexOptional, hiveSplit.isCacheable(), @@ -241,7 +238,6 @@ public class HivePageSourceProvider hiveTable.getCompactEffectivePredicate().intersect(predicate), hiveColumns, hiveSplit.getPartitionKeys(), - hiveStorageTimeZone, typeManager, hiveSplit.getColumnCoercions(), hiveSplit.getBucketConversion(), @@ -303,7 +299,6 @@ public class HivePageSourceProvider ConnectorSession session, HiveSplit split, List columns, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, Optional dynamicFilterSupplier, Optional deleteDeltaLocations, @@ -369,7 +364,6 @@ public class HivePageSourceProvider outputColumns, effectivePredicate, additionPredicates, - hiveStorageTimeZone, deleteDeltaLocations, startRowOffsetOfFile, indexes, @@ -381,7 +375,6 @@ public class HivePageSourceProvider return new HivePageSource( columnMappings, Optional.empty(), - hiveStorageTimeZone, typeManager, pageSource.get(), dynamicFilterSupplier, @@ -407,7 +400,6 @@ public class HivePageSourceProvider TupleDomain effectivePredicate, List hiveColumns, List partitionKeys, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, Map columnCoercions, Optional bucketConversion, @@ -445,7 +437,6 @@ public class HivePageSourceProvider schema, toColumnHandles(regularAndInterimColumnMappings, true), effectivePredicate, - hiveStorageTimeZone, dynamicFilterSupplier, deleteDeltaLocations, startRowOffsetOfFile, @@ -458,7 +449,6 @@ public class HivePageSourceProvider new HivePageSource( columnMappings, bucketAdaptation, - hiveStorageTimeZone, typeManager, pageSource.get(), dynamicFilterSupplier, @@ -481,7 +471,6 @@ public class HivePageSourceProvider schema, toColumnHandles(regularAndInterimColumnMappings, doCoercion), effectivePredicate, - hiveStorageTimeZone, typeManager, s3SelectPushdownEnabled, customSplitInfo); @@ -510,7 +499,6 @@ public class HivePageSourceProvider HiveRecordCursor hiveRecordCursor = new HiveRecordCursor( columnMappings, - hiveStorageTimeZone, typeManager, delegate); List columnTypes = hiveColumns.stream() diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePartitionManager.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePartitionManager.java index bf4a21140..9fa33fa16 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePartitionManager.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HivePartitionManager.java @@ -50,7 +50,6 @@ import io.prestosql.spi.type.Type; import io.prestosql.spi.type.TypeManager; import io.prestosql.spi.type.VarcharType; import org.apache.hadoop.hive.common.FileUtils; -import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; @@ -80,7 +79,6 @@ public class HivePartitionManager { private static final String PARTITION_VALUE_WILDCARD = ""; - private final DateTimeZone timeZone; private final int maxPartitions; private final boolean assumeCanonicalPartitionKeys; private final int domainCompactionThreshold; @@ -93,7 +91,6 @@ public class HivePartitionManager { this( typeManager, - hiveConfig.getDateTimeZone(), hiveConfig.getMaxPartitionsPerScan(), hiveConfig.isAssumeCanonicalPartitionKeys(), hiveConfig.getDomainCompactionThreshold()); @@ -101,12 +98,10 @@ public class HivePartitionManager public HivePartitionManager( TypeManager typeManager, - DateTimeZone timeZone, int maxPartitions, boolean assumeCanonicalPartitionKeys, int domainCompactionThreshold) { - this.timeZone = requireNonNull(timeZone, "timeZone is null"); checkArgument(maxPartitions >= 1, "maxPartitions must be at least 1"); this.maxPartitions = maxPartitions; this.assumeCanonicalPartitionKeys = assumeCanonicalPartitionKeys; @@ -267,7 +262,7 @@ public class HivePartitionManager TupleDomain constraintSummary, Predicate> constraint) { - HivePartition partition = parsePartition(tableName, partitionId, partitionColumns, partitionColumnTypes, timeZone); + HivePartition partition = parsePartition(tableName, partitionId, partitionColumns, partitionColumnTypes); if (partitionMatches(partitionColumns, constraintSummary, constraint, partition)) { return Optional.of(partition); @@ -360,14 +355,13 @@ public class HivePartitionManager SchemaTableName tableName, String partitionName, List partitionColumns, - List partitionColumnTypes, - DateTimeZone timeZone) + List partitionColumnTypes) { List partitionValues = extractPartitionValues(partitionName); ImmutableMap.Builder builder = ImmutableMap.builder(); for (int i = 0; i < partitionColumns.size(); i++) { HiveColumnHandle column = partitionColumns.get(i); - NullableValue parsedValue = parsePartitionValue(partitionName, partitionValues.get(i), partitionColumnTypes.get(i), timeZone); + NullableValue parsedValue = parsePartitionValue(partitionName, partitionValues.get(i), partitionColumnTypes.get(i)); builder.put(column, parsedValue); } Map values = builder.build(); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursor.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursor.java index b56a38508..55d65a2c0 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursor.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursor.java @@ -20,7 +20,6 @@ import io.prestosql.spi.connector.RecordCursor; import io.prestosql.spi.type.DecimalType; import io.prestosql.spi.type.Type; import io.prestosql.spi.type.TypeManager; -import org.joda.time.DateTimeZone; import java.util.List; @@ -72,13 +71,11 @@ public class HiveRecordCursor public HiveRecordCursor( List columnMappings, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, RecordCursor delegate) { requireNonNull(columnMappings, "columns is null"); requireNonNull(typeManager, "typeManager is null"); - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); this.delegate = requireNonNull(delegate, "delegate is null"); this.columnMappings = columnMappings; @@ -139,7 +136,7 @@ public class HiveRecordCursor longs[columnIndex] = datePartitionKey(columnValue, name); } else if (TIMESTAMP.equals(type)) { - longs[columnIndex] = timestampPartitionKey(columnValue, hiveStorageTimeZone, name); + longs[columnIndex] = timestampPartitionKey(columnValue, name); } else if (isShortDecimal(type)) { longs[columnIndex] = shortDecimalPartitionKey(columnValue, (DecimalType) type, name); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursorProvider.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursorProvider.java index 4006668a8..dbf08a483 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursorProvider.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveRecordCursorProvider.java @@ -19,7 +19,6 @@ import io.prestosql.spi.predicate.TupleDomain; import io.prestosql.spi.type.TypeManager; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; -import org.joda.time.DateTimeZone; import java.util.List; import java.util.Map; @@ -38,7 +37,6 @@ public interface HiveRecordCursorProvider Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, boolean s3SelectPushdownEnabled, Map customSplitInfo); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSelectivePageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSelectivePageSourceFactory.java index 9f8de193f..e4c54daab 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSelectivePageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSelectivePageSourceFactory.java @@ -20,7 +20,6 @@ import io.prestosql.spi.heuristicindex.IndexMetadata; import io.prestosql.spi.predicate.TupleDomain; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; -import org.joda.time.DateTimeZone; import java.util.List; import java.util.Map; @@ -42,7 +41,6 @@ public interface HiveSelectivePageSourceFactory List outputColumns, TupleDomain domainPredicate, Optional>> additionPredicates, - DateTimeZone hiveStorageTimeZone, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, Optional> indexes, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSplitSource.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSplitSource.java index f522f1a6c..f719df70e 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSplitSource.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveSplitSource.java @@ -510,7 +510,7 @@ class HiveSplitSource nullableValue = NullableValue.asNull(columnMetadata.getType()); } else { - nullableValue = HiveUtil.parsePartitionValue(columnMetadata.getName(), partitionStringValue, columnMetadata.getType(), hiveConfig.getDateTimeZone()); + nullableValue = HiveUtil.parsePartitionValue(columnMetadata.getName(), partitionStringValue, columnMetadata.getType()); } return domain.includesNullableValue(nullableValue.getValue()); }); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveUtil.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveUtil.java index e8e333037..1e115b926 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveUtil.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveUtil.java @@ -85,7 +85,6 @@ import org.apache.hadoop.mapred.Reporter; import org.apache.hadoop.mapred.TextInputFormat; import org.apache.hadoop.util.ReflectionUtils; import org.apache.hudi.hadoop.realtime.HoodieRealtimeFileSplit; -import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatterBuilder; @@ -123,7 +122,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.transform; -import static io.prestosql.plugin.hive.HiveBucketing.containsTimestampBucketedV2; +import static io.prestosql.plugin.hive.HiveBucketing.bucketedOnTimestamp; import static io.prestosql.plugin.hive.HiveColumnHandle.bucketColumnHandle; import static io.prestosql.plugin.hive.util.CustomSplitConversionUtils.recreateSplitWithCustomInfo; import static io.prestosql.spi.StandardErrorCode.GENERIC_INTERNAL_ERROR; @@ -378,9 +377,9 @@ public final class HiveUtil return TimeUnit.MILLISECONDS.toDays(millis); } - public static long parseHiveTimestamp(String value, DateTimeZone timeZone) + public static long parseHiveTimestamp(String value) { - return HIVE_TIMESTAMP_PARSER.withZone(timeZone).parseMillis(value); + return HIVE_TIMESTAMP_PARSER.parseMillis(value); } public static boolean isSplittable(InputFormat inputFormat, FileSystem fileSystem, Path path) @@ -525,7 +524,7 @@ public final class HiveUtil isCharType(type); } - public static NullableValue parsePartitionValue(String partitionName, String value, Type type, DateTimeZone timeZone) + public static NullableValue parsePartitionValue(String partitionName, String value, Type type) { verifyPartitionTypeSupported(partitionName, type); @@ -611,7 +610,7 @@ public final class HiveUtil if (isNull) { return NullableValue.asNull(TIMESTAMP); } - return NullableValue.of(TIMESTAMP, timestampPartitionKey(value, timeZone, partitionName)); + return NullableValue.of(TIMESTAMP, timestampPartitionKey(value, partitionName)); } if (REAL.equals(type)) { @@ -808,10 +807,10 @@ public final class HiveUtil } } - public static long timestampPartitionKey(String value, DateTimeZone zone, String name) + public static long timestampPartitionKey(String value, String name) { try { - return parseHiveTimestamp(value, zone); + return parseHiveTimestamp(value); } catch (IllegalArgumentException e) { throw new PrestoException(HiveErrorCode.HIVE_INVALID_PARTITION_VALUE, format("Invalid partition value '%s' for TIMESTAMP partition key: %s", value, name)); @@ -880,7 +879,7 @@ public final class HiveUtil // add hidden columns columns.add(HiveColumnHandle.pathColumnHandle()); if (table.getStorage().getBucketProperty().isPresent()) { - if (!containsTimestampBucketedV2(table.getStorage().getBucketProperty().get(), table)) { + if (!bucketedOnTimestamp(table.getStorage().getBucketProperty().get(), table)) { columns.add(bucketColumnHandle()); } } @@ -1025,7 +1024,7 @@ public final class HiveUtil } } - public static Object typedPartitionKey(String value, Type type, String name, DateTimeZone hiveStorageTimeZone) + public static Object typedPartitionKey(String value, Type type, String name) { byte[] bytes = value.getBytes(UTF_8); @@ -1063,7 +1062,7 @@ public final class HiveUtil return datePartitionKey(value, name); } else if (type.equals(TIMESTAMP)) { - return timestampPartitionKey(value, hiveStorageTimeZone, name); + return timestampPartitionKey(value, name); } else if (isShortDecimal(type)) { return shortDecimalPartitionKey(value, (DecimalType) type, name); 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 41f2d9ad7..6bf6cc7ad 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 @@ -24,6 +24,7 @@ import io.prestosql.plugin.hive.metastore.Partition; import io.prestosql.plugin.hive.metastore.SemiTransactionalHiveMetastore; import io.prestosql.plugin.hive.metastore.Storage; import io.prestosql.plugin.hive.metastore.Table; +import io.prestosql.plugin.hive.parquet.ParquetRecordWriter; import io.prestosql.plugin.hive.s3.HiveS3Module; import io.prestosql.plugin.hive.s3.PrestoS3FileSystem; import io.prestosql.spi.Page; @@ -56,8 +57,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.hdfs.DistributedFileSystem; +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; @@ -66,37 +69,21 @@ import org.apache.hadoop.hive.ql.io.HiveOutputFormat; 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.ByteWritable; -import org.apache.hadoop.hive.serde2.io.DateWritable; -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.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory; -import org.apache.hadoop.hive.serde2.objectinspector.SettableStructObjectInspector; -import org.apache.hadoop.hive.serde2.objectinspector.StructField; import org.apache.hadoop.hive.serde2.typeinfo.DecimalTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.ListTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.MapTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; -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.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; @@ -104,7 +91,6 @@ import java.util.List; 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; @@ -118,7 +104,6 @@ import static java.lang.Float.intBitsToFloat; import static java.lang.Math.toIntExact; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Objects.requireNonNull; import static java.util.UUID.randomUUID; import static java.util.stream.Collectors.toList; import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.COMPRESSRESULT; @@ -150,7 +135,6 @@ import static org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveO 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 { @@ -173,7 +157,7 @@ public final class HiveWriteUtils try { boolean compress = HiveConf.getBoolVar(conf, COMPRESSRESULT); if (outputFormatName.equals(MapredParquetOutputFormat.class.getName())) { - return ParquetRecordWriterUtil.createParquetWriter(target, conf, properties, session); + return ParquetRecordWriter.create(target, conf, properties, session); } Object writer = Class.forName(outputFormatName).getConstructor().newInstance(); return ((HiveOutputFormat) writer).getHiveRecordWriter(conf, target, Text.class, compress, properties, Reporter.NULL); @@ -318,12 +302,10 @@ public final class HiveWriteUtils 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; @@ -742,335 +724,7 @@ public final class HiveWriteUtils throw new IllegalArgumentException("unsupported type: " + type); } - public static FieldSetter createFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) - { - if (type.equals(BooleanType.BOOLEAN)) { - return new BooleanFieldSetter(rowInspector, row, field); - } - - if (type.equals(BigintType.BIGINT)) { - return new BigintFieldBuilder(rowInspector, row, field); - } - - if (type.equals(IntegerType.INTEGER)) { - return new IntFieldSetter(rowInspector, row, field); - } - - if (type.equals(SmallintType.SMALLINT)) { - return new SmallintFieldSetter(rowInspector, row, field); - } - - if (type.equals(TinyintType.TINYINT)) { - return new TinyintFieldSetter(rowInspector, row, field); - } - - if (type.equals(RealType.REAL)) { - return new FloatFieldSetter(rowInspector, row, field); - } - - if (type.equals(DoubleType.DOUBLE)) { - return new DoubleFieldSetter(rowInspector, row, field); - } - - if (type instanceof VarcharType) { - return new VarcharFieldSetter(rowInspector, row, field, type); - } - - if (type instanceof CharType) { - return new CharFieldSetter(rowInspector, row, field, type); - } - - if (type.equals(VarbinaryType.VARBINARY)) { - return new BinaryFieldSetter(rowInspector, row, field); - } - - if (type.equals(DateType.DATE)) { - return new DateFieldSetter(rowInspector, row, field); - } - - if (type.equals(TimestampType.TIMESTAMP)) { - return new TimestampFieldSetter(rowInspector, row, field); - } - - if (type instanceof DecimalType) { - DecimalType decimalType = (DecimalType) type; - return new DecimalFieldSetter(rowInspector, row, field, decimalType); - } - - if (isArrayType(type)) { - return new ArrayFieldSetter(rowInspector, row, field, type.getTypeParameters().get(0)); - } - - if (isMapType(type)) { - return new MapFieldSetter(rowInspector, row, field, type.getTypeParameters().get(0), type.getTypeParameters().get(1)); - } - - if (isRowType(type)) { - return new RowFieldSetter(rowInspector, row, field, type.getTypeParameters()); - } - - throw new IllegalArgumentException("unsupported type: " + type); - } - - public abstract static class FieldSetter - { - protected final SettableStructObjectInspector rowInspector; - protected final Object row; - protected final StructField field; - - protected FieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - this.rowInspector = requireNonNull(rowInspector, "rowInspector is null"); - this.row = requireNonNull(row, "row is null"); - this.field = requireNonNull(field, "field is null"); - } - - public abstract void setField(Block block, int position); - } - - private static class BooleanFieldSetter - extends FieldSetter - { - private final BooleanWritable value = new BooleanWritable(); - - public BooleanFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(BooleanType.BOOLEAN.getBoolean(block, position)); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class BigintFieldBuilder - extends FieldSetter - { - private final LongWritable value = new LongWritable(); - - public BigintFieldBuilder(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(BigintType.BIGINT.getLong(block, position)); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class IntFieldSetter - extends FieldSetter - { - private final IntWritable value = new IntWritable(); - - public IntFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(toIntExact(IntegerType.INTEGER.getLong(block, position))); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class SmallintFieldSetter - extends FieldSetter - { - private final ShortWritable value = new ShortWritable(); - - public SmallintFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(Shorts.checkedCast(SmallintType.SMALLINT.getLong(block, position))); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class TinyintFieldSetter - extends FieldSetter - { - private final ByteWritable value = new ByteWritable(); - - public TinyintFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(SignedBytes.checkedCast(TinyintType.TINYINT.getLong(block, position))); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class DoubleFieldSetter - extends FieldSetter - { - private final DoubleWritable value = new DoubleWritable(); - - public DoubleFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(DoubleType.DOUBLE.getDouble(block, position)); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class FloatFieldSetter - extends FieldSetter - { - private final FloatWritable value = new FloatWritable(); - - public FloatFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(intBitsToFloat((int) RealType.REAL.getLong(block, position))); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class VarcharFieldSetter - extends FieldSetter - { - private final Text value = new Text(); - private final Type type; - - public VarcharFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) - { - super(rowInspector, row, field); - this.type = type; - } - - @Override - public void setField(Block block, int position) - { - value.set(type.getSlice(block, position).getBytes()); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class CharFieldSetter - extends FieldSetter - { - private final Text value = new Text(); - private final Type type; - - public CharFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) - { - super(rowInspector, row, field); - this.type = type; - } - - @Override - public void setField(Block block, int position) - { - value.set(type.getSlice(block, position).getBytes()); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class BinaryFieldSetter - extends FieldSetter - { - private final BytesWritable value = new BytesWritable(); - - public BinaryFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - byte[] bytes = VarbinaryType.VARBINARY.getSlice(block, position).getBytes(); - value.set(bytes, 0, bytes.length); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class DateFieldSetter - extends FieldSetter - { - private final DateWritable value = new DateWritable(); - - public DateFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - value.set(toIntExact(DateType.DATE.getLong(block, position))); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class TimestampFieldSetter - extends FieldSetter - { - private final TimestampWritable value = new TimestampWritable(); - - public TimestampFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) - { - super(rowInspector, row, field); - } - - @Override - public void setField(Block block, int position) - { - long millisUtc = TimestampType.TIMESTAMP.getLong(block, position); - value.setTime(millisUtc); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static class DecimalFieldSetter - extends FieldSetter - { - private final HiveDecimalWritable value = new HiveDecimalWritable(); - private final DecimalType decimalType; - - public DecimalFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, DecimalType decimalType) - { - super(rowInspector, row, field); - this.decimalType = decimalType; - } - - @Override - public void setField(Block block, int position) - { - value.set(getHiveDecimal(decimalType, block, position)); - rowInspector.setStructFieldData(row, field, value); - } - } - - private static HiveDecimal getHiveDecimal(DecimalType decimalType, Block block, int position) + public static HiveDecimal getHiveDecimal(DecimalType decimalType, Block block, int position) { BigInteger unscaledValue; if (decimalType.isShort()) { @@ -1081,88 +735,4 @@ public final class HiveWriteUtils } return HiveDecimal.create(unscaledValue, decimalType.getScale()); } - - private static class ArrayFieldSetter - extends FieldSetter - { - private final Type elementType; - - public ArrayFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type elementType) - { - super(rowInspector, row, field); - this.elementType = requireNonNull(elementType, "elementType is null"); - } - - @Override - public void setField(Block block, int position) - { - Block arrayBlock = block.getObject(position, Block.class); - - List list = new ArrayList<>(arrayBlock.getPositionCount()); - for (int i = 0; i < arrayBlock.getPositionCount(); i++) { - Object element = getField(elementType, arrayBlock, i); - list.add(element); - } - - rowInspector.setStructFieldData(row, field, list); - } - } - - private static class MapFieldSetter - extends FieldSetter - { - private final Type keyType; - private final Type valueType; - - public MapFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type keyType, Type valueType) - { - super(rowInspector, row, field); - this.keyType = requireNonNull(keyType, "keyType is null"); - this.valueType = requireNonNull(valueType, "valueType is null"); - } - - @Override - public void setField(Block block, int position) - { - Block mapBlock = block.getObject(position, Block.class); - Map map = new HashMap<>(mapBlock.getPositionCount() * 2); - for (int i = 0; i < mapBlock.getPositionCount(); i += 2) { - Object key = getField(keyType, mapBlock, i); - Object value = getField(valueType, mapBlock, i + 1); - map.put(key, value); - } - - rowInspector.setStructFieldData(row, field, map); - } - } - - private static class RowFieldSetter - extends FieldSetter - { - private final List fieldTypes; - - public RowFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, List fieldTypes) - { - super(rowInspector, row, field); - this.fieldTypes = ImmutableList.copyOf(fieldTypes); - } - - @Override - public void setField(Block block, int position) - { - Block rowBlock = block.getObject(position, Block.class); - - // TODO reuse row object and use FieldSetters, like we do at the top level - // Ideally, we'd use the same recursive structure starting from the top, but - // this requires modeling row types in the same way we model table rows - // (multiple blocks vs all fields packed in a single block) - List value = new ArrayList<>(fieldTypes.size()); - for (int i = 0; i < fieldTypes.size(); i++) { - Object element = getField(fieldTypes.get(i), rowBlock, i); - value.add(element); - } - - rowInspector.setStructFieldData(row, field, value); - } - } } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriterFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriterFactory.java index 66d3ef43d..728347eed 100755 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriterFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/HiveWriterFactory.java @@ -60,6 +60,7 @@ import org.apache.hadoop.io.compress.CompressionCodec; import org.apache.hadoop.io.compress.DefaultCodec; import org.apache.hadoop.mapred.JobConf; import org.apache.hive.common.util.ReflectionUtil; +import org.joda.time.DateTimeZone; import java.io.IOException; import java.security.Principal; @@ -141,6 +142,7 @@ public class HiveWriterFactory private final int maxOpenSortFiles; private final boolean immutablePartitions; private final InsertExistingPartitionsBehavior insertExistingPartitionsBehavior; + private final DateTimeZone parquetTimeZone; private final ConnectorSession session; private final OptionalInt bucketCount; @@ -182,6 +184,7 @@ public class HiveWriterFactory DataSize sortBufferSize, int maxOpenSortFiles, boolean immutablePartitions, + DateTimeZone parquetTimeZone, ConnectorSession session, NodeManager nodeManager, EventClient eventClient, @@ -231,6 +234,7 @@ public class HiveWriterFactory if (immutablePartitions) { checkArgument(insertExistingPartitionsBehavior != InsertExistingPartitionsBehavior.APPEND, "insertExistingPartitionsBehavior cannot be APPEND"); } + this.parquetTimeZone = requireNonNull(parquetTimeZone, "parquetTimeZone is null"); this.acidWriteType = acidWriteType; // divide input columns into partition and data columns @@ -654,6 +658,7 @@ public class HiveWriterFactory partitionStorageFormat.getEstimatedWriterSystemMemoryUsage(), conf, typeManager, + parquetTimeZone, session); } if (isTxnTable) { diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriter.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriter.java index aaaf410aa..fcbf4465d 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriter.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriter.java @@ -41,7 +41,6 @@ import org.apache.hadoop.hive.ql.io.BucketCodec; import org.apache.hadoop.ipc.RemoteException; import org.apache.orc.impl.AcidStats; import org.apache.orc.impl.OrcAcidUtils; -import org.joda.time.DateTimeZone; import org.openjdk.jol.info.ClassLayout; import java.io.IOException; @@ -102,7 +101,6 @@ public class OrcFileWriter boolean writeLegacyVersion, int[] fileInputColumnIndexes, Map metadata, - DateTimeZone hiveStorageTimeZone, Optional> validationInputFactory, OrcWriteValidationMode validationMode, OrcWriterStats stats, @@ -122,7 +120,6 @@ public class OrcFileWriter options, writeLegacyVersion, metadata, - hiveStorageTimeZone, validationInputFactory.isPresent(), validationMode, stats, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriterFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriterFactory.java index c58304597..abf57e148 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriterFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/OrcFileWriterFactory.java @@ -38,7 +38,6 @@ import org.apache.hadoop.hive.ql.io.AcidUtils; import org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat; import org.apache.hadoop.mapred.JobConf; import org.apache.orc.OrcConf; -import org.joda.time.DateTimeZone; import org.weakref.jmx.Flatten; import org.weakref.jmx.Managed; @@ -62,7 +61,6 @@ import static java.util.stream.Collectors.toList; public class OrcFileWriterFactory implements HiveFileWriterFactory { - private final DateTimeZone hiveStorageTimeZone; private final HdfsEnvironment hdfsEnvironment; private final TypeManager typeManager; private final NodeVersion nodeVersion; @@ -84,7 +82,6 @@ public class OrcFileWriterFactory hdfsEnvironment, typeManager, nodeVersion, - requireNonNull(hiveConfig, "hiveConfig is null").getDateTimeZone(), hiveConfig.isOrcWriteLegacyVersion(), readStats, requireNonNull(config, "config is null").toOrcWriterOptions()); @@ -94,7 +91,6 @@ public class OrcFileWriterFactory HdfsEnvironment hdfsEnvironment, TypeManager typeManager, NodeVersion nodeVersion, - DateTimeZone hiveStorageTimeZone, boolean writeLegacyVersion, FileFormatDataSourceStats readStats, OrcWriterOptions orcWriterOptions) @@ -102,7 +98,6 @@ public class OrcFileWriterFactory this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.nodeVersion = requireNonNull(nodeVersion, "nodeVersion is null"); - this.hiveStorageTimeZone = requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); this.writeLegacyVersion = writeLegacyVersion; this.readStats = requireNonNull(readStats, "stats is null"); this.orcWriterOptions = requireNonNull(orcWriterOptions, "orcWriterOptions is null"); @@ -224,7 +219,6 @@ public class OrcFileWriterFactory .put(HiveMetadata.PRESTO_QUERY_ID_NAME, session.getQueryId()) .put("hive.acid.version", String.valueOf(AcidUtils.OrcAcidVersion.ORC_ACID_VERSION)) .build(), - hiveStorageTimeZone, validationInputFactory, HiveSessionProperties.getOrcOptimizedWriterValidateMode(session), stats, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/ParquetRecordWriterUtil.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/ParquetRecordWriterUtil.java deleted file mode 100644 index 51a537407..000000000 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/ParquetRecordWriterUtil.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 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 io.prestosql.plugin.hive; - -import com.google.common.base.Splitter; -import io.prestosql.spi.connector.ConnectorSession; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.Path; -import org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter; -import org.apache.hadoop.hive.ql.io.IOConstants; -import org.apache.hadoop.hive.ql.io.parquet.convert.HiveSchemaConverter; -import org.apache.hadoop.hive.ql.io.parquet.write.DataWritableWriteSupport; -import org.apache.hadoop.hive.ql.io.parquet.write.ParquetRecordWriterWrapper; -import org.apache.hadoop.hive.serde2.io.ParquetHiveRecord; -import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; -import org.apache.hadoop.io.Writable; -import org.apache.hadoop.mapred.JobConf; -import org.apache.hadoop.mapred.Reporter; -import org.apache.parquet.hadoop.ParquetFileWriter; -import org.apache.parquet.hadoop.ParquetOutputFormat; -import org.apache.parquet.hadoop.ParquetRecordWriter; -import org.apache.parquet.schema.MessageType; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Properties; - -import static io.prestosql.plugin.hive.HiveSessionProperties.getParquetWriterBlockSize; -import static io.prestosql.plugin.hive.HiveSessionProperties.getParquetWriterPageSize; -import static org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils.getTypeInfosFromTypeString; - -public final class ParquetRecordWriterUtil -{ - private static final Field REAL_WRITER_FIELD; - private static final Field INTERNAL_WRITER_FIELD; - private static final Field FILE_WRITER_FIELD; - - static { - try { - REAL_WRITER_FIELD = ParquetRecordWriterWrapper.class.getDeclaredField("realWriter"); - INTERNAL_WRITER_FIELD = ParquetRecordWriter.class.getDeclaredField("internalWriter"); - FILE_WRITER_FIELD = INTERNAL_WRITER_FIELD.getType().getDeclaredField("parquetFileWriter"); - - REAL_WRITER_FIELD.setAccessible(true); - INTERNAL_WRITER_FIELD.setAccessible(true); - FILE_WRITER_FIELD.setAccessible(true); - } - catch (ReflectiveOperationException e) { - throw new AssertionError(e); - } - } - - private ParquetRecordWriterUtil() {} - - public static RecordWriter createParquetWriter(Path target, JobConf conf, Properties properties, ConnectorSession session) - throws IOException, ReflectiveOperationException - { - conf.setLong(ParquetOutputFormat.BLOCK_SIZE, getParquetWriterBlockSize(session).toBytes()); - conf.setLong(ParquetOutputFormat.PAGE_SIZE, getParquetWriterPageSize(session).toBytes()); - - RecordWriter recordWriter = createParquetWriter(target, conf, properties); - - Object realWriter = REAL_WRITER_FIELD.get(recordWriter); - Object internalWriter = INTERNAL_WRITER_FIELD.get(realWriter); - ParquetFileWriter fileWriter = (ParquetFileWriter) FILE_WRITER_FIELD.get(internalWriter); - - return new RecordFileWriter.ExtendedRecordWriter() - { - private long length; - - @Override - public long getWrittenBytes() - { - return length; - } - - @Override - public void write(Writable value) - throws IOException - { - recordWriter.write(value); - length = fileWriter.getPos(); - } - - @Override - public void close(boolean abort) - throws IOException - { - recordWriter.close(abort); - if (!abort) { - length = target.getFileSystem(conf).getFileStatus(target).getLen(); - } - } - }; - } - - private static RecordWriter createParquetWriter(Path target, JobConf conf, Properties properties) - throws IOException - { - if (conf.get(DataWritableWriteSupport.PARQUET_HIVE_SCHEMA) == null) { - List columnNames = Splitter.on(',').splitToList(properties.getProperty(IOConstants.COLUMNS)); - List columnTypes = getTypeInfosFromTypeString(properties.getProperty(IOConstants.COLUMNS_TYPES)); - MessageType schema = HiveSchemaConverter.convert(columnNames, columnTypes); - setParquetSchema(conf, schema); - } - - ParquetOutputFormat outputFormat = new ParquetOutputFormat<>(new DataWritableWriteSupport()); - - return new ParquetRecordWriterWrapper(outputFormat, conf, target.toString(), Reporter.NULL, properties); - } - - public static void setParquetSchema(Configuration conf, MessageType schema) - { - DataWritableWriteSupport.setSchema(schema, conf); - } -} diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/RcFileFileWriterFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/RcFileFileWriterFactory.java index 46edef82e..6265b8c7c 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/RcFileFileWriterFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/RcFileFileWriterFactory.java @@ -52,7 +52,7 @@ import static java.util.stream.Collectors.toList; public class RcFileFileWriterFactory implements HiveFileWriterFactory { - private final DateTimeZone hiveStorageTimeZone; + private final DateTimeZone timeZone; private final HdfsEnvironment hdfsEnvironment; private final TypeManager typeManager; private final NodeVersion nodeVersion; @@ -66,20 +66,20 @@ public class RcFileFileWriterFactory HiveConfig hiveConfig, FileFormatDataSourceStats stats) { - this(hdfsEnvironment, typeManager, nodeVersion, requireNonNull(hiveConfig, "hiveConfig is null").getDateTimeZone(), stats); + this(hdfsEnvironment, typeManager, nodeVersion, requireNonNull(hiveConfig, "hiveConfig is null").getRcfileDateTimeZone(), stats); } public RcFileFileWriterFactory( HdfsEnvironment hdfsEnvironment, TypeManager typeManager, NodeVersion nodeVersion, - DateTimeZone hiveStorageTimeZone, + DateTimeZone timeZone, FileFormatDataSourceStats stats) { this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.nodeVersion = requireNonNull(nodeVersion, "nodeVersion is null"); - this.hiveStorageTimeZone = requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); + this.timeZone = requireNonNull(timeZone, "timeZone is null"); this.stats = requireNonNull(stats, "stats is null"); } @@ -98,10 +98,10 @@ public class RcFileFileWriterFactory RcFileEncoding rcFileEncoding; if (LazyBinaryColumnarSerDe.class.getName().equals(storageFormat.getSerDe())) { - rcFileEncoding = new BinaryRcFileEncoding(); + rcFileEncoding = new BinaryRcFileEncoding(timeZone); } else if (ColumnarSerDe.class.getName().equals(storageFormat.getSerDe())) { - rcFileEncoding = RcFilePageSourceFactory.createTextVectorEncoding(schema, hiveStorageTimeZone); + rcFileEncoding = RcFilePageSourceFactory.createTextVectorEncoding(schema); } else { return Optional.empty(); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/RecordFileWriter.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/RecordFileWriter.java index 8aa66fc29..16e41cfc9 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/RecordFileWriter.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/RecordFileWriter.java @@ -15,8 +15,9 @@ package io.prestosql.plugin.hive; import com.google.common.collect.ImmutableList; import io.airlift.units.DataSize; -import io.prestosql.plugin.hive.HiveWriteUtils.FieldSetter; import io.prestosql.plugin.hive.metastore.StorageFormat; +import io.prestosql.plugin.hive.parquet.ParquetRecordWriter; +import io.prestosql.plugin.hive.util.FieldSetterFactory; import io.prestosql.spi.Page; import io.prestosql.spi.PrestoException; import io.prestosql.spi.block.Block; @@ -31,6 +32,7 @@ import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.SettableStructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.StructField; import org.apache.hadoop.mapred.JobConf; +import org.joda.time.DateTimeZone; import org.openjdk.jol.info.ClassLayout; import java.io.IOException; @@ -43,7 +45,6 @@ import static io.prestosql.plugin.hive.HiveErrorCode.HIVE_WRITER_CLOSE_ERROR; import static io.prestosql.plugin.hive.HiveErrorCode.HIVE_WRITER_DATA_ERROR; import static io.prestosql.plugin.hive.HiveUtil.getColumnNames; import static io.prestosql.plugin.hive.HiveUtil.getColumnTypes; -import static io.prestosql.plugin.hive.HiveWriteUtils.createFieldSetter; import static io.prestosql.plugin.hive.HiveWriteUtils.createRecordWriter; import static io.prestosql.plugin.hive.HiveWriteUtils.getRowColumnInspectors; import static io.prestosql.plugin.hive.HiveWriteUtils.initializeSerializer; @@ -64,7 +65,7 @@ public class RecordFileWriter private final SettableStructObjectInspector tableInspector; private final List structFields; private final Object row; - private final FieldSetter[] setters; + private final FieldSetterFactory.FieldSetter[] setters; private final long estimatedWriterSystemMemoryUsage; private boolean committed; @@ -77,6 +78,7 @@ public class RecordFileWriter DataSize estimatedWriterSystemMemoryUsage, JobConf conf, TypeManager typeManager, + DateTimeZone parquetTimeZone, ConnectorSession session) { this.path = requireNonNull(path, "path is null"); @@ -104,9 +106,12 @@ public class RecordFileWriter row = tableInspector.create(); - setters = new FieldSetter[structFields.size()]; + DateTimeZone timeZone = (recordWriter instanceof ParquetRecordWriter) ? parquetTimeZone : DateTimeZone.UTC; + FieldSetterFactory fieldSetterFactory = new FieldSetterFactory(timeZone); + + setters = new FieldSetterFactory.FieldSetter[structFields.size()]; for (int i = 0; i < setters.length; i++) { - setters[i] = createFieldSetter(tableInspector, row, structFields.get(i), fileColumnTypes.get(structFields.get(i).getFieldID())); + setters[i] = fieldSetterFactory.create(tableInspector, row, structFields.get(i), fileColumnTypes.get(structFields.get(i).getFieldID())); } this.estimatedWriterSystemMemoryUsage = estimatedWriterSystemMemoryUsage.toBytes(); 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 51539d579..4e030a6b8 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 @@ -18,7 +18,6 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Writable; import org.apache.hadoop.mapred.RecordReader; -import org.joda.time.DateTimeZone; import java.util.ArrayList; import java.util.List; @@ -50,10 +49,9 @@ class S3SelectRecordCursor long totalBytes, Properties splitSchema, List columns, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager) { - super(configuration, path, recordReader, totalBytes, updateSplitSchema(splitSchema, columns), columns, hiveStorageTimeZone, typeManager); + super(configuration, path, recordReader, totalBytes, updateSplitSchema(splitSchema, columns), columns, 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 79c334136..ce55a2f65 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 @@ -23,7 +23,6 @@ import io.prestosql.spi.type.TypeManager; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe; -import org.joda.time.DateTimeZone; import javax.inject.Inject; @@ -67,7 +66,6 @@ public class S3SelectRecordCursorProvider Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, TypeManager typeManager, boolean s3SelectPushdownEnabled, Map customSplitInfo) @@ -88,7 +86,7 @@ public class S3SelectRecordCursorProvider IonSqlQueryBuilder queryBuilder = new IonSqlQueryBuilder(typeManager); String ionSqlQuery = queryBuilder.buildSql(columns, effectivePredicate); S3SelectLineRecordReader recordReader = new S3SelectCsvRecordReader(configuration, hiveConfig, 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, 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 6acc044a9..53648deda 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 @@ -1772,7 +1772,8 @@ public class ThriftHiveMetastore new HiveObjectRef(TABLE, databaseName, tableName, null, null), grantee.getName(), ThriftMetastoreUtil.fromPrestoPrincipalType(grantee.getType()), - privilegeGrantInfo)); + privilegeGrantInfo, + "SQL")); } return new PrivilegeBag(privilegeBagBuilder.build()); } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcPageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcPageSourceFactory.java index 86307598c..06f7b4be5 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcPageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcPageSourceFactory.java @@ -135,6 +135,7 @@ public class OrcPageSourceFactory private final FileFormatDataSourceStats stats; private final OrcCacheStore orcCacheStore; private final int domainCompactionThreshold; + private final DateTimeZone legacyTimeZone; @Inject public OrcPageSourceFactory(TypeManager typeManager, HiveConfig config, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats, OrcCacheStore orcCacheStore) @@ -146,6 +147,7 @@ public class OrcPageSourceFactory this.stats = requireNonNull(stats, "stats is null"); this.orcCacheStore = orcCacheStore; this.domainCompactionThreshold = config.getDomainCompactionThreshold(); + this.legacyTimeZone = requireNonNull(config, "hiveConfig is null").getOrcLegacyDateTimeZone(); } @Override @@ -159,7 +161,6 @@ public class OrcPageSourceFactory Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, Optional dynamicFilters, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, @@ -194,7 +195,7 @@ public class OrcPageSourceFactory useOrcColumnNames, isFullAcidTable(Maps.fromProperties(schema)), effectivePredicate, - hiveStorageTimeZone, + legacyTimeZone, typeManager, getOrcMaxMergeDistance(session), getOrcMaxBufferSize(session), @@ -228,7 +229,7 @@ public class OrcPageSourceFactory boolean useOrcColumnNames, boolean isFullAcid, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, TypeManager typeManager, DataSize maxMergeDistance, DataSize maxBufferSize, @@ -394,7 +395,7 @@ public class OrcPageSourceFactory predicateBuilder.build(), start, length, - hiveStorageTimeZone, + legacyFileTimeZone, systemMemoryUsage, INITIAL_BATCH_SIZE, exception -> handleException(orcDataSource.getId(), exception), diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSource.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSource.java index dc7418e70..4c131951f 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSource.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSource.java @@ -23,7 +23,6 @@ import io.prestosql.plugin.hive.HivePageSourceProvider.ColumnMapping; import io.prestosql.spi.Page; import io.prestosql.spi.PrestoException; import io.prestosql.spi.connector.ConnectorPageSource; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.type.Type; import io.prestosql.spi.type.TypeManager; @@ -53,7 +52,6 @@ public class OrcSelectivePageSource OrcDataSource orcDataSource, AggregatedMemoryContext systemMemoryContext, FileFormatDataSourceStats stats, - ConnectorSession session, List columnMappings, TypeManager typeManager) { diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSourceFactory.java index e93bd9535..37a3ddf02 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/orc/OrcSelectivePageSourceFactory.java @@ -137,6 +137,7 @@ public class OrcSelectivePageSourceFactory private final HdfsEnvironment hdfsEnvironment; private final FileFormatDataSourceStats stats; private final OrcCacheStore orcCacheStore; + private final DateTimeZone legacyTimeZone; @Inject public OrcSelectivePageSourceFactory(TypeManager typeManager, HiveConfig config, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats, OrcCacheStore orcCacheStore) @@ -147,6 +148,7 @@ public class OrcSelectivePageSourceFactory this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.stats = requireNonNull(stats, "stats is null"); this.orcCacheStore = orcCacheStore; + this.legacyTimeZone = requireNonNull(config, "hiveConfig is null").getOrcLegacyDateTimeZone(); } @Override @@ -163,7 +165,6 @@ public class OrcSelectivePageSourceFactory List outputColumns, TupleDomain domainPredicate, Optional>> additionPredicates, - DateTimeZone hiveStorageTimeZone, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, Optional> indexes, @@ -207,7 +208,7 @@ public class OrcSelectivePageSourceFactory prefilledValues, outputColumns, domainPredicate, - hiveStorageTimeZone, + legacyTimeZone, typeManager, getOrcMaxMergeDistance(session), getOrcMaxBufferSize(session), @@ -281,7 +282,7 @@ public class OrcSelectivePageSourceFactory prefilledValues, outputColumns, domainPredicate, - hiveStorageTimeZone, + legacyTimeZone, typeManager, getOrcMaxMergeDistance(session), getOrcMaxBufferSize(session), @@ -485,7 +486,7 @@ public class OrcSelectivePageSourceFactory Map typedPrefilledValues = new HashMap<>(); for (Map.Entry prefilledValue : prefilledValues.entrySet()) { typedPrefilledValues.put(Integer.valueOf(prefilledValue.getKey().toString()), - typedPartitionKey(prefilledValue.getValue().toString(), columnTypes.get(prefilledValue.getKey()), columnNames.get(prefilledValue.getKey()), hiveStorageTimeZone)); + typedPartitionKey(prefilledValue.getValue().toString(), columnTypes.get(prefilledValue.getKey()), columnNames.get(prefilledValue.getKey()))); } // Convert the predicate to each column id wise. Will be used to associate as filter with each column reader @@ -546,7 +547,6 @@ public class OrcSelectivePageSourceFactory // isFullAcid && indexes.isPresent(), systemMemoryUsage, stats, - session, columnMappings, typeManager); } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetPageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetPageSourceFactory.java index 87b0fab66..3e1466a4e 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetPageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetPageSourceFactory.java @@ -28,6 +28,7 @@ import io.prestosql.plugin.hive.DeleteDeltaLocations; import io.prestosql.plugin.hive.FileFormatDataSourceStats; import io.prestosql.plugin.hive.HdfsEnvironment; import io.prestosql.plugin.hive.HiveColumnHandle; +import io.prestosql.plugin.hive.HiveConfig; import io.prestosql.plugin.hive.HivePageSourceFactory; import io.prestosql.spi.PrestoException; import io.prestosql.spi.connector.ConnectorPageSource; @@ -97,13 +98,15 @@ public class ParquetPageSourceFactory private final TypeManager typeManager; private final HdfsEnvironment hdfsEnvironment; private final FileFormatDataSourceStats stats; + private final DateTimeZone timeZone; @Inject - public ParquetPageSourceFactory(TypeManager typeManager, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats) + public ParquetPageSourceFactory(TypeManager typeManager, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats, HiveConfig hiveConfig) { this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.stats = requireNonNull(stats, "stats is null"); + timeZone = requireNonNull(hiveConfig, "hiveConfig is null").getParquetDateTimeZone(); } @Override @@ -117,7 +120,6 @@ public class ParquetPageSourceFactory Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, Optional dynamicFilter, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, @@ -147,7 +149,8 @@ public class ParquetPageSourceFactory getParquetMaxReadBlockSize(session), typeManager, effectivePredicate, - stats)); + stats, + timeZone)); } public static ParquetPageSource createParquetPageSource( @@ -165,7 +168,8 @@ public class ParquetPageSourceFactory DataSize maxReadBlockSize, TypeManager typeManager, TupleDomain effectivePredicate, - FileFormatDataSourceStats stats) + FileFormatDataSourceStats stats, + DateTimeZone timeZone) { AggregatedMemoryContext systemMemoryContext = newSimpleAggregatedMemoryContext(); diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetRecordWriter.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetRecordWriter.java new file mode 100644 index 000000000..2ce996dc5 --- /dev/null +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/parquet/ParquetRecordWriter.java @@ -0,0 +1,108 @@ +/* + * 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 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 io.prestosql.plugin.hive.parquet; + +import io.prestosql.plugin.hive.RecordFileWriter.ExtendedRecordWriter; +import io.prestosql.spi.connector.ConnectorSession; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter; +import org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat; +import org.apache.hadoop.hive.ql.io.parquet.write.ParquetRecordWriterWrapper; +import org.apache.hadoop.io.Text; +import org.apache.hadoop.io.Writable; +import org.apache.hadoop.mapred.JobConf; +import org.apache.hadoop.mapred.Reporter; +import org.apache.parquet.hadoop.ParquetFileWriter; +import org.apache.parquet.hadoop.ParquetOutputFormat; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Properties; + +import static io.prestosql.plugin.hive.HiveSessionProperties.getParquetWriterBlockSize; +import static io.prestosql.plugin.hive.HiveSessionProperties.getParquetWriterPageSize; +import static java.util.Objects.requireNonNull; + +public final class ParquetRecordWriter + implements ExtendedRecordWriter +{ + private static final Field REAL_WRITER_FIELD; + private static final Field INTERNAL_WRITER_FIELD; + private static final Field FILE_WRITER_FIELD; + + static { + try { + REAL_WRITER_FIELD = ParquetRecordWriterWrapper.class.getDeclaredField("realWriter"); + INTERNAL_WRITER_FIELD = org.apache.parquet.hadoop.ParquetRecordWriter.class.getDeclaredField("internalWriter"); + FILE_WRITER_FIELD = INTERNAL_WRITER_FIELD.getType().getDeclaredField("parquetFileWriter"); + + REAL_WRITER_FIELD.setAccessible(true); + INTERNAL_WRITER_FIELD.setAccessible(true); + FILE_WRITER_FIELD.setAccessible(true); + } + catch (ReflectiveOperationException e) { + throw new AssertionError(e); + } + } + + public static RecordWriter create(Path target, JobConf conf, Properties properties, ConnectorSession session) + throws IOException, ReflectiveOperationException + { + conf.setLong(ParquetOutputFormat.BLOCK_SIZE, getParquetWriterBlockSize(session).toBytes()); + conf.setLong(ParquetOutputFormat.PAGE_SIZE, getParquetWriterPageSize(session).toBytes()); + + RecordWriter recordWriter = new MapredParquetOutputFormat() + .getHiveRecordWriter(conf, target, Text.class, false, properties, Reporter.NULL); + + Object realWriter = REAL_WRITER_FIELD.get(recordWriter); + Object internalWriter = INTERNAL_WRITER_FIELD.get(realWriter); + ParquetFileWriter fileWriter = (ParquetFileWriter) FILE_WRITER_FIELD.get(internalWriter); + + return new ParquetRecordWriter(recordWriter, fileWriter); + } + + private final RecordWriter recordWriter; + private final ParquetFileWriter fileWriter; + private long length; + + private ParquetRecordWriter(RecordWriter recordWriter, ParquetFileWriter fileWriter) + { + this.recordWriter = requireNonNull(recordWriter, "recordWriter is null"); + this.fileWriter = requireNonNull(fileWriter, "fileWriter is null"); + } + + @Override + public long getWrittenBytes() + { + return length; + } + + @Override + public void write(Writable value) + throws IOException + { + recordWriter.write(value); + length = fileWriter.getPos(); + } + + @Override + public void close(boolean abort) + throws IOException + { + recordWriter.close(abort); + if (!abort) { + length = fileWriter.getPos(); + } + } +} diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/rcfile/RcFilePageSourceFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/rcfile/RcFilePageSourceFactory.java index 51e6800c6..a55aa8ec0 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/rcfile/RcFilePageSourceFactory.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/rcfile/RcFilePageSourceFactory.java @@ -22,6 +22,7 @@ import io.prestosql.plugin.hive.DeleteDeltaLocations; import io.prestosql.plugin.hive.FileFormatDataSourceStats; import io.prestosql.plugin.hive.HdfsEnvironment; import io.prestosql.plugin.hive.HiveColumnHandle; +import io.prestosql.plugin.hive.HiveConfig; import io.prestosql.plugin.hive.HivePageSourceFactory; import io.prestosql.rcfile.AircompressorCodecFactory; import io.prestosql.rcfile.HadoopCodecFactory; @@ -86,13 +87,15 @@ public class RcFilePageSourceFactory private final TypeManager typeManager; private final HdfsEnvironment hdfsEnvironment; private final FileFormatDataSourceStats stats; + private final DateTimeZone timeZone; @Inject - public RcFilePageSourceFactory(TypeManager typeManager, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats) + public RcFilePageSourceFactory(TypeManager typeManager, HdfsEnvironment hdfsEnvironment, FileFormatDataSourceStats stats, HiveConfig hiveConfig) { this.typeManager = requireNonNull(typeManager, "typeManager is null"); this.hdfsEnvironment = requireNonNull(hdfsEnvironment, "hdfsEnvironment is null"); this.stats = requireNonNull(stats, "stats is null"); + this.timeZone = requireNonNull(hiveConfig, "hiveConfig is null").getRcfileDateTimeZone(); } @Override @@ -106,7 +109,6 @@ public class RcFilePageSourceFactory Properties schema, List columns, TupleDomain effectivePredicate, - DateTimeZone hiveStorageTimeZone, Optional dynamicFilters, Optional deleteDeltaLocations, Optional startRowOffsetOfFile, @@ -118,10 +120,10 @@ public class RcFilePageSourceFactory RcFileEncoding rcFileEncoding; String deserializerClassName = getDeserializerClassName(schema); if (deserializerClassName.equals(LazyBinaryColumnarSerDe.class.getName())) { - rcFileEncoding = new BinaryRcFileEncoding(); + rcFileEncoding = new BinaryRcFileEncoding(timeZone); } else if (deserializerClassName.equals(ColumnarSerDe.class.getName())) { - rcFileEncoding = createTextVectorEncoding(schema, hiveStorageTimeZone); + rcFileEncoding = createTextVectorEncoding(schema); } else { return Optional.empty(); @@ -188,7 +190,7 @@ public class RcFilePageSourceFactory return format("Error opening Hive split %s (offset=%s, length=%s): %s", path, start, length, t.getMessage()); } - public static TextRcFileEncoding createTextVectorEncoding(Properties schema, DateTimeZone hiveStorageTimeZone) + public static TextRcFileEncoding createTextVectorEncoding(Properties schema) { // separators int nestingLevels; @@ -227,7 +229,6 @@ public class RcFilePageSourceFactory } return new TextRcFileEncoding( - hiveStorageTimeZone, nullSequence, separators, escapeByte, diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/FieldSetterFactory.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/FieldSetterFactory.java new file mode 100644 index 000000000..821707a41 --- /dev/null +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/FieldSetterFactory.java @@ -0,0 +1,488 @@ +/* + * 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 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 io.prestosql.plugin.hive.util; + +import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Shorts; +import com.google.common.primitives.SignedBytes; +import io.prestosql.plugin.hive.HiveWriteUtils; +import io.prestosql.spi.block.Block; +import io.prestosql.spi.type.BigintType; +import io.prestosql.spi.type.BooleanType; +import io.prestosql.spi.type.CharType; +import io.prestosql.spi.type.DateType; +import io.prestosql.spi.type.DecimalType; +import io.prestosql.spi.type.DoubleType; +import io.prestosql.spi.type.IntegerType; +import io.prestosql.spi.type.RealType; +import io.prestosql.spi.type.SmallintType; +import io.prestosql.spi.type.TimestampType; +import io.prestosql.spi.type.TinyintType; +import io.prestosql.spi.type.Type; +import io.prestosql.spi.type.VarbinaryType; +import io.prestosql.spi.type.VarcharType; +import org.apache.hadoop.hive.common.type.Timestamp; +import org.apache.hadoop.hive.serde2.io.ByteWritable; +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.TimestampWritableV2; +import org.apache.hadoop.hive.serde2.objectinspector.SettableStructObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.StructField; +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.Text; +import org.joda.time.DateTimeZone; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static io.prestosql.plugin.hive.HiveUtil.isArrayType; +import static io.prestosql.plugin.hive.HiveUtil.isMapType; +import static io.prestosql.plugin.hive.HiveUtil.isRowType; +import static io.prestosql.plugin.hive.HiveWriteUtils.getHiveDecimal; +import static java.lang.Float.intBitsToFloat; +import static java.lang.Math.toIntExact; +import static java.util.Objects.requireNonNull; + +public final class FieldSetterFactory +{ + private final DateTimeZone timeZone; + + public FieldSetterFactory(DateTimeZone timeZone) + { + this.timeZone = requireNonNull(timeZone, "timeZone is null"); + } + + public FieldSetter create(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) + { + if (type.equals(BooleanType.BOOLEAN)) { + return new BooleanFieldSetter(rowInspector, row, field); + } + + if (type.equals(BigintType.BIGINT)) { + return new BigintFieldBuilder(rowInspector, row, field); + } + + if (type.equals(IntegerType.INTEGER)) { + return new IntFieldSetter(rowInspector, row, field); + } + + if (type.equals(SmallintType.SMALLINT)) { + return new SmallintFieldSetter(rowInspector, row, field); + } + + if (type.equals(TinyintType.TINYINT)) { + return new TinyintFieldSetter(rowInspector, row, field); + } + + if (type.equals(RealType.REAL)) { + return new FloatFieldSetter(rowInspector, row, field); + } + + if (type.equals(DoubleType.DOUBLE)) { + return new DoubleFieldSetter(rowInspector, row, field); + } + + if (type instanceof VarcharType) { + return new VarcharFieldSetter(rowInspector, row, field, type); + } + + if (type instanceof CharType) { + return new CharFieldSetter(rowInspector, row, field, type); + } + + if (type.equals(VarbinaryType.VARBINARY)) { + return new BinaryFieldSetter(rowInspector, row, field); + } + + if (type.equals(DateType.DATE)) { + return new DateFieldSetter(rowInspector, row, field); + } + + if (type.equals(TimestampType.TIMESTAMP)) { + return new TimestampFieldSetter(rowInspector, row, field, timeZone); + } + + if (type instanceof DecimalType) { + DecimalType decimalType = (DecimalType) type; + return new DecimalFieldSetter(rowInspector, row, field, decimalType); + } + + if (isArrayType(type)) { + return new ArrayFieldSetter(rowInspector, row, field, type.getTypeParameters().get(0)); + } + + if (isMapType(type)) { + return new MapFieldSetter(rowInspector, row, field, type.getTypeParameters().get(0), type.getTypeParameters().get(1)); + } + + if (isRowType(type)) { + return new RowFieldSetter(rowInspector, row, field, type.getTypeParameters()); + } + + throw new IllegalArgumentException("unsupported type: " + type); + } + + public abstract static class FieldSetter + { + protected final SettableStructObjectInspector rowInspector; + protected final Object row; + protected final StructField field; + + private FieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + this.rowInspector = requireNonNull(rowInspector, "rowInspector is null"); + this.row = requireNonNull(row, "row is null"); + this.field = requireNonNull(field, "field is null"); + } + + public abstract void setField(Block block, int position); + } + + private static class BooleanFieldSetter + extends FieldSetter + { + private final BooleanWritable value = new BooleanWritable(); + + public BooleanFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(BooleanType.BOOLEAN.getBoolean(block, position)); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class BigintFieldBuilder + extends FieldSetter + { + private final LongWritable value = new LongWritable(); + + public BigintFieldBuilder(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(BigintType.BIGINT.getLong(block, position)); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class IntFieldSetter + extends FieldSetter + { + private final IntWritable value = new IntWritable(); + + public IntFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(toIntExact(IntegerType.INTEGER.getLong(block, position))); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class SmallintFieldSetter + extends FieldSetter + { + private final ShortWritable value = new ShortWritable(); + + public SmallintFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(Shorts.checkedCast(SmallintType.SMALLINT.getLong(block, position))); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class TinyintFieldSetter + extends FieldSetter + { + private final ByteWritable value = new ByteWritable(); + + public TinyintFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(SignedBytes.checkedCast(TinyintType.TINYINT.getLong(block, position))); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class DoubleFieldSetter + extends FieldSetter + { + private final DoubleWritable value = new DoubleWritable(); + + public DoubleFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(DoubleType.DOUBLE.getDouble(block, position)); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class FloatFieldSetter + extends FieldSetter + { + private final FloatWritable value = new FloatWritable(); + + public FloatFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(intBitsToFloat((int) RealType.REAL.getLong(block, position))); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class VarcharFieldSetter + extends FieldSetter + { + private final Text value = new Text(); + private final Type type; + + public VarcharFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) + { + super(rowInspector, row, field); + this.type = type; + } + + @Override + public void setField(Block block, int position) + { + value.set(type.getSlice(block, position).getBytes()); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class CharFieldSetter + extends FieldSetter + { + private final Text value = new Text(); + private final Type type; + + public CharFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type type) + { + super(rowInspector, row, field); + this.type = type; + } + + @Override + public void setField(Block block, int position) + { + value.set(type.getSlice(block, position).getBytes()); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class BinaryFieldSetter + extends FieldSetter + { + private final BytesWritable value = new BytesWritable(); + + public BinaryFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + byte[] bytes = VarbinaryType.VARBINARY.getSlice(block, position).getBytes(); + value.set(bytes, 0, bytes.length); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class DateFieldSetter + extends FieldSetter + { + private final DateWritableV2 value = new DateWritableV2(); + + public DateFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field) + { + super(rowInspector, row, field); + } + + @Override + public void setField(Block block, int position) + { + value.set(toIntExact(DateType.DATE.getLong(block, position))); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class TimestampFieldSetter + extends FieldSetter + { + private final DateTimeZone timeZone; + private final TimestampWritableV2 value = new TimestampWritableV2(); + + public TimestampFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, DateTimeZone timeZone) + { + super(rowInspector, row, field); + this.timeZone = requireNonNull(timeZone, "timeZone is null"); + } + + @Override + public void setField(Block block, int position) + { + long epochMilli = TimestampType.TIMESTAMP.getLong(block, position); + epochMilli = timeZone.convertLocalToUTC(epochMilli, false); + value.set(Timestamp.ofEpochMilli(epochMilli)); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class DecimalFieldSetter + extends FieldSetter + { + private final HiveDecimalWritable value = new HiveDecimalWritable(); + private final DecimalType decimalType; + + public DecimalFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, DecimalType decimalType) + { + super(rowInspector, row, field); + this.decimalType = decimalType; + } + + @Override + public void setField(Block block, int position) + { + value.set(getHiveDecimal(decimalType, block, position)); + rowInspector.setStructFieldData(row, field, value); + } + } + + private static class ArrayFieldSetter + extends FieldSetter + { + private final Type elementType; + + public ArrayFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type elementType) + { + super(rowInspector, row, field); + this.elementType = requireNonNull(elementType, "elementType is null"); + } + + @Override + public void setField(Block block, int position) + { + Block arrayBlock = (Block) block.getObject(position, Block.class); + + List list = new ArrayList<>(arrayBlock.getPositionCount()); + for (int i = 0; i < arrayBlock.getPositionCount(); i++) { + Object element = HiveWriteUtils.getField(elementType, arrayBlock, i); + list.add(element); + } + + rowInspector.setStructFieldData(row, field, list); + } + } + + private static class MapFieldSetter + extends FieldSetter + { + private final Type keyType; + private final Type valueType; + + public MapFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, Type keyType, Type valueType) + { + super(rowInspector, row, field); + this.keyType = requireNonNull(keyType, "keyType is null"); + this.valueType = requireNonNull(valueType, "valueType is null"); + } + + @Override + public void setField(Block block, int position) + { + Block mapBlock = (Block) block.getObject(position, Block.class); + Map map = new HashMap<>(mapBlock.getPositionCount() * 2); + for (int i = 0; i < mapBlock.getPositionCount(); i += 2) { + Object key = HiveWriteUtils.getField(keyType, mapBlock, i); + Object value = HiveWriteUtils.getField(valueType, mapBlock, i + 1); + map.put(key, value); + } + + rowInspector.setStructFieldData(row, field, map); + } + } + + private static class RowFieldSetter + extends FieldSetter + { + private final List fieldTypes; + + public RowFieldSetter(SettableStructObjectInspector rowInspector, Object row, StructField field, List fieldTypes) + { + super(rowInspector, row, field); + this.fieldTypes = ImmutableList.copyOf(fieldTypes); + } + + @Override + public void setField(Block block, int position) + { + Block rowBlock = (Block) block.getObject(position, Block.class); + + // TODO reuse row object and use FieldSetters, like we do at the top level + // Ideally, we'd use the same recursive structure starting from the top, but + // this requires modeling row types in the same way we model table rows + // (multiple blocks vs all fields packed in a single block) + List value = new ArrayList<>(fieldTypes.size()); + for (int i = 0; i < fieldTypes.size(); i++) { + Object element = HiveWriteUtils.getField(fieldTypes.get(i), rowBlock, i); + value.add(element); + } + + rowInspector.setStructFieldData(row, field, value); + } + } +} diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/HiveBucketingV1.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/HiveBucketingV1.java index 0d6991d1d..5a94e833f 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/HiveBucketingV1.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/HiveBucketingV1.java @@ -109,8 +109,6 @@ public final class HiveBucketingV1 case DATE: // day offset from 1970-01-01 return toIntExact(prestoType.getLong(block, position)); - case TIMESTAMP: - return hashTimestamp(prestoType.getLong(block, position)); default: throw new UnsupportedOperationException("Computation of Hive bucket hashCode is not supported for Hive primitive category: " + primitiveCategory); } @@ -161,8 +159,6 @@ public final class HiveBucketingV1 case DATE: // day offset from 1970-01-01 return toIntExact((long) value); - case TIMESTAMP: - return hashTimestamp((long) value); default: throw new UnsupportedOperationException("Computation of Hive bucket hashCode is not supported for Hive primitive category: " + primitiveCategory); } @@ -176,15 +172,6 @@ public final class HiveBucketingV1 } } - @SuppressWarnings("NumericCastThatLosesPrecision") - private static int hashTimestamp(long epochMillis) - { - long seconds = (Math.floorDiv(epochMillis, 1000L) << 30); - long nanos = Math.floorMod(epochMillis, 1000) * 1_000_000L; - long secondsAndNanos = seconds | nanos; - return (int) ((secondsAndNanos >>> 32) ^ secondsAndNanos); - } - private static int hashOfMap(MapTypeInfo type, Block singleMapBlock) { TypeInfo keyTypeInfo = type.getMapKeyTypeInfo(); 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 07c6aa9e2..6346b54e6 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,9 @@ import org.apache.hadoop.hive.serde2.objectinspector.primitive.LongObjectInspect 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 static com.google.common.base.Preconditions.checkArgument; import static io.prestosql.spi.type.Chars.truncateToLengthAndTrimSpaces; @@ -73,7 +70,8 @@ public final class SerDeUtils public static Block getBlockObject(Type type, Object object, ObjectInspector objectInspector) { - return requireNonNull(serializeObject(type, null, object, objectInspector), "serialized result is null"); + Block block = serializeObject(type, null, object, objectInspector); + return requireNonNull(block, "serialized result is null"); } public static Block serializeObject(Type type, BlockBuilder builder, Object object, ObjectInspector inspector) @@ -272,6 +270,7 @@ public final class SerDeUtils } } + @SuppressWarnings("deprecation") private static long formatDateAsLong(Object object, DateObjectInspector inspector) { if (object instanceof LazyDate) { @@ -281,26 +280,14 @@ public final class SerDeUtils 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); + return inspector.getPrimitiveJavaObject(object).toEpochDay(); } private static long formatTimestampAsLong(Object object, TimestampObjectInspector inspector) { - Timestamp timestamp = getTimestamp(object, inspector); - return timestamp.getTime(); - } - - private static Timestamp getTimestamp(Object object, TimestampObjectInspector inspector) - { - // handle broken ObjectInspectors if (object instanceof TimestampWritable) { - return ((TimestampWritable) object).getTimestamp(); + return ((TimestampWritable) object).getTimestamp().getTime(); } - return inspector.getPrimitiveJavaObject(object); + return inspector.getPrimitiveJavaObject(object).toEpochMilli(); } } diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/Statistics.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/Statistics.java index e4261be32..f89a7f126 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/Statistics.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/Statistics.java @@ -33,7 +33,6 @@ import io.prestosql.spi.type.DecimalType; import io.prestosql.spi.type.SqlDate; import io.prestosql.spi.type.SqlDecimal; import io.prestosql.spi.type.Type; -import org.joda.time.DateTimeZone; import java.math.BigDecimal; import java.time.LocalDate; @@ -331,7 +330,6 @@ public final class Statistics public static Map fromComputedStatistics( ConnectorSession session, - DateTimeZone timeZone, Map computedStatistics, Map columnTypes, long rowCount) @@ -344,12 +342,11 @@ public final class Statistics return result.entrySet() .stream() .collect(toImmutableMap(Entry::getKey, - entry -> createHiveColumnStatistics(session, timeZone, entry.getValue(), columnTypes.get(entry.getKey()), rowCount))); + entry -> createHiveColumnStatistics(session, entry.getValue(), columnTypes.get(entry.getKey()), rowCount))); } private static HiveColumnStatistics createHiveColumnStatistics( ConnectorSession session, - DateTimeZone timeZone, Map computedStatistics, Type columnType, long rowCount) @@ -360,7 +357,7 @@ public final class Statistics // We ask the engine to compute either both or neither verify(computedStatistics.containsKey(MIN_VALUE) == computedStatistics.containsKey(MAX_VALUE)); if (computedStatistics.containsKey(MIN_VALUE)) { - setMinMax(session, timeZone, columnType, computedStatistics.get(MIN_VALUE), computedStatistics.get(MAX_VALUE), result); + setMinMax(session, columnType, computedStatistics.get(MIN_VALUE), computedStatistics.get(MAX_VALUE), result); } // MAX_VALUE_SIZE_IN_BYTES @@ -400,7 +397,7 @@ public final class Statistics return result.build(); } - private static void setMinMax(ConnectorSession session, DateTimeZone timeZone, Type type, Block min, Block max, HiveColumnStatistics.Builder result) + private static void setMinMax(ConnectorSession session, Type type, Block min, Block max, HiveColumnStatistics.Builder result) { if (type.equals(BIGINT) || type.equals(INTEGER) || type.equals(SMALLINT) || type.equals(TINYINT)) { result.setIntegerStatistics(new IntegerStatistics(getIntegerValue(session, type, min), getIntegerValue(session, type, max))); @@ -412,7 +409,7 @@ public final class Statistics result.setDateStatistics(new DateStatistics(getDateValue(session, type, min), getDateValue(session, type, max))); } else if (type.equals(TIMESTAMP)) { - result.setIntegerStatistics(new IntegerStatistics(getTimestampValue(timeZone, min), getTimestampValue(timeZone, max))); + result.setIntegerStatistics(new IntegerStatistics(getTimestampValue(min), getTimestampValue(max))); } else if (type instanceof DecimalType) { result.setDecimalStatistics(new DecimalStatistics(getDecimalValue(session, type, min), getDecimalValue(session, type, max))); @@ -438,10 +435,10 @@ public final class Statistics return block.isNull(0) ? Optional.empty() : Optional.of(LocalDate.ofEpochDay(((SqlDate) type.getObjectValue(session, block, 0)).getDays())); } - private static OptionalLong getTimestampValue(DateTimeZone timeZone, Block block) + private static OptionalLong getTimestampValue(Block block) { // TODO https://github.com/prestodb/presto/issues/7122 - return block.isNull(0) ? OptionalLong.empty() : OptionalLong.of(MILLISECONDS.toSeconds(timeZone.convertUTCToLocal(block.getLong(0, 0)))); + return block.isNull(0) ? OptionalLong.empty() : OptionalLong.of(MILLISECONDS.toSeconds(block.getLong(0, 0))); } private static Optional getDecimalValue(ConnectorSession session, Type type, Block block) diff --git a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/TempFileWriter.java b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/TempFileWriter.java index 97ad113e6..7776421c2 100644 --- a/presto-hive/src/main/java/io/prestosql/plugin/hive/util/TempFileWriter.java +++ b/presto-hive/src/main/java/io/prestosql/plugin/hive/util/TempFileWriter.java @@ -34,7 +34,6 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static io.airlift.units.DataSize.Unit.BYTE; import static io.airlift.units.DataSize.Unit.MEGABYTE; import static io.prestosql.orc.metadata.CompressionKind.LZ4; -import static org.joda.time.DateTimeZone.UTC; public class TempFileWriter implements Closeable @@ -90,7 +89,6 @@ public class TempFileWriter .withDictionaryMaxMemory(new DataSize(1, MEGABYTE)), false, ImmutableMap.of(), - UTC, false, OrcWriteValidationMode.BOTH, new OrcWriterStats(), Optional.empty(), Optional.empty()); diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHive.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHive.java index 6fe6aaf38..3a8853498 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHive.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHive.java @@ -111,13 +111,13 @@ import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.TableType; import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.IOException; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -129,7 +129,6 @@ import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.OptionalLong; import java.util.Set; -import java.util.TimeZone; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; @@ -235,7 +234,6 @@ import static io.prestosql.spi.type.HyperLogLogType.HYPER_LOG_LOG; import static io.prestosql.spi.type.IntegerType.INTEGER; import static io.prestosql.spi.type.RealType.REAL; import static io.prestosql.spi.type.SmallintType.SMALLINT; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.TypeSignature.parseTypeSignature; @@ -576,8 +574,6 @@ public abstract class AbstractTestHive protected List tablePartitionFormatPartitions; protected List tableUnpartitionedPartitions; - protected DateTimeZone timeZone; - protected HdfsEnvironment hdfsEnvironment; protected LocationService locationService; @@ -619,7 +615,7 @@ public abstract class AbstractTestHive } } - protected void setupHive(String databaseName, String timeZoneId) + protected void setupHive(String databaseName) { database = databaseName; tablePartitionFormat = new SchemaTableName(database, "presto_test_partition_format"); @@ -702,13 +698,13 @@ public abstract class AbstractTestHive dummyColumn, Domain.create(ValueSet.ofRanges(Range.equal(INTEGER, 4L)), false)))))), ImmutableList.of()); tableUnpartitionedProperties = new ConnectorTableProperties(); - timeZone = DateTimeZone.forTimeZone(TimeZone.getTimeZone(timeZoneId)); } protected final void setup(String host, int port, String databaseName, String timeZone) { - HiveConfig hiveConfig = getHiveConfig(); - hiveConfig.setTimeZone(timeZone); + HiveConfig hiveConfig = getHiveConfig() + .setParquetTimeZone(timeZone) + .setRcfileTimeZone(timeZone); String proxy = System.getProperty("hive.metastore.thrift.client.socks-proxy"); if (proxy != null) { hiveConfig.setMetastoreSocksProxy(HostAndPort.fromString(proxy)); @@ -727,7 +723,7 @@ public abstract class AbstractTestHive protected final void setup(String databaseName, HiveConfig hiveConfig, HiveMetastore hiveMetastore) { - setupHive(databaseName, hiveConfig.getTimeZone()); + setupHive(databaseName); metastoreClient = hiveMetastore; HivePartitionManager partitionManager = new HivePartitionManager(TYPE_MANAGER, hiveConfig); @@ -739,9 +735,7 @@ public abstract class AbstractTestHive metastoreClient, hdfsEnvironment, partitionManager, - timeZone, 10, - true, false, false, false, @@ -768,7 +762,7 @@ public abstract class AbstractTestHive partitionManager, new NamenodeStats(), hdfsEnvironment, - new CachingDirectoryLister(new HiveConfig()), + new CachingDirectoryLister(hiveConfig), directExecutor(), new HiveCoercionPolicy(TYPE_MANAGER), new CounterStat(), @@ -4252,7 +4246,7 @@ public abstract class AbstractTestHive assertNull(row.getField(index)); } else { - SqlTimestamp expected = sqlTimestampOf(2011, 5, 6, 7, 8, 9, 123, timeZone, UTC_KEY, SESSION); + SqlTimestamp expected = sqlTimestampOf(2011, 5, 6, 7, 8, 9, 123); assertEquals(row.getField(index), expected); } } @@ -4336,6 +4330,18 @@ public abstract class AbstractTestHive } } + // ARRAY + index = columnIndex.get("t_array_timestamp"); + if (index != null) { + if ((rowNumber % 43) == 0) { + assertNull(row.getField(index)); + } + else { + SqlTimestamp expected = sqlTimestampOf(LocalDateTime.of(2011, 5, 6, 7, 8, 9, 123_000_000)); + 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 226453d75..a099705a5 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.testing.MaterializedRow; 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.io.IOException; 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; @@ -96,6 +96,7 @@ import static io.prestosql.plugin.hive.HiveTestUtils.SESSION; import static io.prestosql.plugin.hive.HiveTestUtils.TYPE_MANAGER; import static io.prestosql.plugin.hive.HiveTestUtils.isDistinctFrom; import static io.prestosql.plugin.hive.HiveTestUtils.mapType; +import static io.prestosql.plugin.hive.HiveType.HIVE_TIMESTAMP; import static io.prestosql.plugin.hive.HiveUtil.isStructuralType; import static io.prestosql.plugin.hive.util.SerDeUtils.serializeObject; import static io.prestosql.spi.type.BigintType.BIGINT; @@ -148,17 +149,20 @@ import static org.testng.Assert.assertTrue; @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( + private static final String TIMESTAMP_STRING = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").withZoneUTC().print( TIMESTAMP); + private static final Timestamp HIVE_TIMESTAMP = Timestamp.ofEpochMilli(TIMESTAMP); private static final String VARCHAR_MAX_LENGTH_STRING; @@ -297,8 +301,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, @@ -359,11 +363,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), @@ -419,11 +423,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), @@ -561,7 +565,7 @@ public abstract class AbstractTestHiveFileFormats return columns; } - public static FileSplit createTestFile( + public static FileSplit createTestFilePresto( String filePath, HiveStorageFormat storageFormat, HiveCompressionCodec compressionCodec, @@ -618,7 +622,7 @@ public abstract class AbstractTestHiveFileFormats 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, @@ -837,7 +841,7 @@ public abstract class AbstractTestHiveFileFormats assertEquals(actualValue, expectedValue); } else if (testColumn.getObjectInspector().getTypeName().equals("timestamp")) { - SqlTimestamp expectedTimestamp = sqlTimestampOf((Long) expectedValue, SESSION); + SqlTimestamp expectedTimestamp = sqlTimestampOf((Long) expectedValue); assertEquals(actualValue, expectedTimestamp, "Wrong value for column " + testColumn.getName()); } else if (testColumn.getObjectInspector().getTypeName().startsWith("char")) { diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveLocal.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveLocal.java index 140523ed5..114e235e4 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveLocal.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/AbstractTestHiveLocal.java @@ -69,7 +69,8 @@ public abstract class AbstractTestHiveLocal .build()); HiveConfig hiveConfig = new HiveConfig() - .setTimeZone("America/Los_Angeles"); + .setParquetTimeZone("America/Los_Angeles") + .setRcfileTimeZone("America/Los_Angeles"); setup(testDbName, hiveConfig, metastore); } diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveQueryRunner.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveQueryRunner.java index a13cabd09..fcae4779d 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveQueryRunner.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/HiveQueryRunner.java @@ -184,7 +184,8 @@ public final class HiveQueryRunner Map hiveProperties = ImmutableMap.builder() .putAll(extraHiveProperties) - .put("hive.time-zone", TIME_ZONE.getID()) + .put("hive.rcfile.time-zone", TIME_ZONE.getID()) + .put("hive.parquet.time-zone", TIME_ZONE.getID()) .put("hive.security", security) .put("hive.max-partitions-per-scan", "1000") .put("hive.assume-canonical-partition-keys", "true") 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 0cc6911e1..de06147dd 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 @@ -52,12 +52,15 @@ import io.prestosql.spi.util.BloomFilter; import io.prestosql.testing.NoOpIndexClient; import io.prestosql.testing.TestingConnectorSession; import io.prestosql.type.InternalTypeManager; +import org.apache.hadoop.hive.common.type.Timestamp; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.invoke.MethodHandle; import java.math.BigDecimal; import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -94,7 +97,7 @@ public final class HiveTestUtils FileFormatDataSourceStats stats = new FileFormatDataSourceStats(); HdfsEnvironment testHdfsEnvironment = createTestHdfsEnvironment(hiveConfig); return ImmutableSet.builder() - .add(new RcFilePageSourceFactory(TYPE_MANAGER, testHdfsEnvironment, stats)) + .add(new RcFilePageSourceFactory(TYPE_MANAGER, testHdfsEnvironment, stats, hiveConfig)) .add(new OrcPageSourceFactory(TYPE_MANAGER, hiveConfig, testHdfsEnvironment, stats, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), @@ -104,10 +107,15 @@ public final class HiveTestUtils Duration.ofMillis(new HiveConfig().getOrcBloomFiltersCacheTtl().toMillis()), new HiveConfig().getOrcRowDataCacheMaximumWeight(), Duration.ofMillis(new HiveConfig().getOrcRowDataCacheTtl().toMillis()), new HiveConfig().isOrcCacheStatsMetricCollectionEnabled()))) - .add(new ParquetPageSourceFactory(TYPE_MANAGER, testHdfsEnvironment, stats)) + .add(new ParquetPageSourceFactory(TYPE_MANAGER, testHdfsEnvironment, stats, hiveConfig)) .build(); } + public static HiveRecordCursorProvider createGenericHiveRecordCursorProvider(HdfsEnvironment hdfsEnvironment) + { + return new GenericHiveRecordCursorProvider(hdfsEnvironment); + } + public static Set getDefaultHiveSelectiveFactories(HiveConfig hiveConfig) { FileFormatDataSourceStats stats = new FileFormatDataSourceStats(); @@ -256,4 +264,9 @@ public final class HiveTestUtils return dynamicFilterSupplier; } + + 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/TestColumnTypeCacheable.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestColumnTypeCacheable.java index 930ad48d8..5d124faf8 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestColumnTypeCacheable.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestColumnTypeCacheable.java @@ -550,8 +550,8 @@ public class TestColumnTypeCacheable ConnectorSession session = new TestingConnectorSession(new HiveSessionProperties(new HiveConfig().setDynamicFilterPartitionFilteringEnabled(false), new OrcFileWriterConfig(), new ParquetFileWriterConfig()).getSessionProperties()); ColumnMetadata ptdMetadata = new ColumnMetadata("pt_d", TIMESTAMP); Set> cachePredicates = ImmutableSet.of( - TupleDomain.withColumnDomains(ImmutableMap.of(ptdMetadata, Domain.singleValue(TIMESTAMP, HiveUtil.parseHiveTimestamp("1995-10-09 00:00:00", new HiveConfig().getDateTimeZone())))), - TupleDomain.withColumnDomains(ImmutableMap.of(ptdMetadata, Domain.singleValue(TIMESTAMP, HiveUtil.parseHiveTimestamp("1995-11-14 00:00:00", new HiveConfig().getDateTimeZone()))))); + TupleDomain.withColumnDomains(ImmutableMap.of(ptdMetadata, Domain.singleValue(TIMESTAMP, HiveUtil.parseHiveTimestamp("1995-10-09 00:00:00")))), + TupleDomain.withColumnDomains(ImmutableMap.of(ptdMetadata, Domain.singleValue(TIMESTAMP, HiveUtil.parseHiveTimestamp("1995-11-14 00:00:00"))))); HiveSplitSource hiveSplitSource = HiveSplitSource.allAtOnce( session, "database", 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 d4343b98e..65e6a77e9 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 @@ -22,9 +22,11 @@ import io.prestosql.spi.Page; import io.prestosql.spi.block.Block; import io.prestosql.spi.block.BlockBuilder; import io.prestosql.spi.type.StandardTypes; +import io.prestosql.spi.type.TimestampType; import io.prestosql.spi.type.Type; +import org.apache.hadoop.hive.common.type.Date; import org.apache.hadoop.hive.common.type.HiveVarchar; -import org.apache.hadoop.hive.serde2.io.DateWritable; +import org.apache.hadoop.hive.serde2.io.DateWritableV2; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaHiveVarcharObjectInspector; @@ -32,20 +34,19 @@ import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils; import org.testng.annotations.Test; -import java.sql.Date; -import java.sql.Timestamp; -import java.time.Instant; import java.util.List; import java.util.Map; import static com.google.common.collect.ImmutableList.toImmutableList; import static io.prestosql.plugin.hive.HiveBucketing.BucketingVersion.BUCKETING_V1; import static io.prestosql.plugin.hive.HiveBucketing.BucketingVersion.BUCKETING_V2; +import static io.prestosql.plugin.hive.HiveBucketing.getBucketHashCode; import static io.prestosql.spi.type.TypeUtils.writeNativeValue; import static java.lang.Double.longBitsToDouble; import static java.lang.Float.intBitsToFloat; import static java.util.Arrays.asList; import static java.util.Map.Entry; +import static org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory.timestampTypeInfo; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.testng.Assert.assertEquals; @@ -121,14 +122,19 @@ public class TestHiveBucketing assertBucketEquals("date", Date.valueOf("2015-11-19"), 16758, 8542395); assertBucketEquals("date", Date.valueOf("1950-11-19"), -6983, -431619185); - assertBucketEquals("timestamp", null, 0, 0); - assertBucketEquals("timestamp", Timestamp.valueOf("1970-01-01 00:00:00.000"), BUCKETING_V1, 7200); - assertBucketEquals("timestamp", Timestamp.valueOf("1969-12-31 23:59:59.999"), BUCKETING_V1, -74736673); - assertBucketEquals("timestamp", Timestamp.valueOf("1950-11-19 12:34:56.789"), BUCKETING_V1, -670699780); - assertBucketEquals("timestamp", Timestamp.valueOf("2015-11-19 07:06:05.432"), BUCKETING_V1, 1278000719); - assertThatThrownBy(() -> assertBucketEquals("timestamp", Timestamp.valueOf("1970-01-01 00:00:00.000"), BUCKETING_V2, 0xDEAD_C0D3)) - .isInstanceOf(RuntimeException.class) - .hasMessage("Computation of Hive bucket hashCode is not supported for Hive primitive category: TIMESTAMP"); + for (BucketingVersion version : BucketingVersion.values()) { + List typeInfos = ImmutableList.of(timestampTypeInfo); + + assertThatThrownBy(() -> getBucketHashCode(version, typeInfos, new Object[]{0})) + .hasMessage("Computation of Hive bucket hashCode is not supported for Hive primitive category: TIMESTAMP"); + TimestampType timestampType = TimestampType.TIMESTAMP; + BlockBuilder builder = timestampType.createBlockBuilder(null, 1); + timestampType.writeLong(builder, 0); + Page page = new Page(builder.build()); + + assertThatThrownBy(() -> getBucketHashCode(version, typeInfos, page, 0)) + .hasMessage("Computation of Hive bucket hashCode is not supported for Hive primitive category: TIMESTAMP"); + } assertBucketEquals("array", null, 0, 0); assertBucketEquals("array", ImmutableList.of(), 0, 0); @@ -224,8 +230,8 @@ public class TestHiveBucketing nativeContainerValues[i] = toNativeContainerValue(type, hiveValue); } ImmutableList blockList = blockListBuilder.build(); - int result1 = HiveBucketing.getBucketHashCode(bucketingVersion, hiveTypeInfos, new Page(blockList.toArray(new Block[blockList.size()])), 2); - int result2 = HiveBucketing.getBucketHashCode(bucketingVersion, hiveTypeInfos, nativeContainerValues); + int result1 = getBucketHashCode(bucketingVersion, hiveTypeInfos, new Page(blockList.toArray(new Block[blockList.size()])), 2); + int result2 = getBucketHashCode(bucketingVersion, hiveTypeInfos, nativeContainerValues); assertEquals(result1, result2, "overloads of getBucketHashCode produced different result"); return result1; } @@ -316,17 +322,11 @@ public class TestHiveBucketing case StandardTypes.CHAR: return Slices.utf8Slice(hiveValue.toString()); case StandardTypes.DATE: - long daysSinceEpochInLocalZone = ((Date) hiveValue).toLocalDate().toEpochDay(); - assertEquals(daysSinceEpochInLocalZone, DateWritable.dateToDays((Date) hiveValue)); + long daysSinceEpochInLocalZone = ((Date) hiveValue).toEpochDay(); + assertEquals(daysSinceEpochInLocalZone, DateWritableV2.dateToDays((Date) hiveValue)); return daysSinceEpochInLocalZone; - case StandardTypes.TIMESTAMP: - Instant instant = ((Timestamp) hiveValue).toInstant(); - long epochSecond = instant.getEpochSecond(); - int nano = instant.getNano(); - assertEquals(nano % 1_000_000, 0); - return epochSecond * 1000 + nano / 1_000_000; default: - throw new UnsupportedOperationException("unknown type"); + throw new IllegalArgumentException("Unsupported bucketing type: " + type); } } diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveConfig.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveConfig.java index 49bfbecd6..6f71d1751 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveConfig.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveConfig.java @@ -38,7 +38,6 @@ public class TestHiveConfig public void testDefaults() { ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(HiveConfig.class) - .setTimeZone(TimeZone.getDefault().getID()) .setMaxSplitSize(new DataSize(64, Unit.MEGABYTE)) .setMaxPartitionsPerScan(100_000) .setMaxOutstandingSplits(1_000) @@ -82,6 +81,8 @@ public class TestHiveConfig .setMaxOpenSortFiles(50) .setWriteValidationThreads(16) .setTextMaxLineLength(new DataSize(100, Unit.MEGABYTE)) + .setOrcLegacyTimeZone(TimeZone.getDefault().getID()) + .setParquetTimeZone(TimeZone.getDefault().getID()) .setUseParquetColumnNames(false) .setFailOnCorruptedParquetStatistics(true) .setParquetMaxReadBlockSize(new DataSize(16, Unit.MEGABYTE)) @@ -100,6 +101,7 @@ public class TestHiveConfig .setOrcBloomFiltersCacheEnabled(false).setOrcBloomFiltersCacheTtl(new Duration(4, TimeUnit.HOURS)).setOrcBloomFiltersCacheLimit(250_000) .setOrcRowDataCacheEnabled(false).setOrcRowDataCacheTtl(new Duration(4, TimeUnit.HOURS)).setOrcRowDataCacheMaximumWeight(new DataSize(20, GIGABYTE)) .setOrcLazyReadSmallRanges(true) + .setRcfileTimeZone(TimeZone.getDefault().getID()) .setRcfileWriterValidate(false) .setOrcWriteLegacyVersion(false) .setOrcWriterValidationPercentage(0.0) @@ -153,7 +155,6 @@ public class TestHiveConfig public void testExplicitPropertyMappings() { Map properties = new ImmutableMap.Builder() - .put("hive.time-zone", nonDefaultTimeZone().getID()) .put("hive.max-split-size", "256MB") .put("hive.max-partitions-per-scan", "123") .put("hive.max-outstanding-splits", "10") @@ -199,6 +200,8 @@ public class TestHiveConfig .put("hive.max-concurrent-file-renames", "100") .put("hive.assume-canonical-partition-keys", "true") .put("hive.text.max-line-length", "13MB") + .put("hive.orc.time-zone", nonDefaultTimeZone().getID()) + .put("hive.parquet.time-zone", nonDefaultTimeZone().getID()) .put("hive.parquet.use-column-names", "true") .put("hive.parquet.fail-on-corrupted-statistics", "false") .put("hive.parquet.max-read-block-size", "66kB") @@ -226,6 +229,7 @@ public class TestHiveConfig .put("hive.orc.row-data.block.cache.ttl", "1h") .put("hive.orc.row-data.block.cache.max.weight", "1MB") .put("hive.orc.lazy-read-small-ranges", "false") + .put("hive.rcfile.time-zone", nonDefaultTimeZone().getID()) .put("hive.rcfile.writer.validate", "true") .put("hive.orc.writer.use-legacy-version-number", "true") .put("hive.orc.writer.validation-percentage", "0.16") @@ -275,7 +279,6 @@ public class TestHiveConfig .build(); HiveConfig expected = new HiveConfig() - .setTimeZone(nonDefaultTimeZone().toTimeZone().getID()) .setMaxSplitSize(new DataSize(256, Unit.MEGABYTE)) .setMaxPartitionsPerScan(123) .setMaxOutstandingSplits(10) @@ -318,11 +321,14 @@ public class TestHiveConfig .setDomainSocketPath("/foo") .setS3FileSystemType(S3FileSystemType.EMRFS) .setTextMaxLineLength(new DataSize(13, Unit.MEGABYTE)) + .setOrcLegacyTimeZone(nonDefaultTimeZone().getID()) + .setParquetTimeZone(nonDefaultTimeZone().getID()) .setUseParquetColumnNames(true) .setFailOnCorruptedParquetStatistics(false) .setParquetMaxReadBlockSize(new DataSize(66, Unit.KILOBYTE)) .setUseOrcColumnNames(true) .setAssumeCanonicalPartitionKeys(true) + .setRcfileTimeZone(nonDefaultTimeZone().getID()) .setOrcBloomFiltersEnabled(true) .setOrcDefaultBloomFilterFpp(0.96) .setOrcMaxMergeDistance(new DataSize(22, Unit.KILOBYTE)) @@ -336,6 +342,7 @@ public class TestHiveConfig .setOrcBloomFiltersCacheEnabled(true).setOrcBloomFiltersCacheTtl(new Duration(1, TimeUnit.HOURS)).setOrcBloomFiltersCacheLimit(100) .setOrcRowDataCacheEnabled(true).setOrcRowDataCacheTtl(new Duration(1, TimeUnit.HOURS)).setOrcRowDataCacheMaximumWeight(new DataSize(1, MEGABYTE)) .setOrcLazyReadSmallRanges(false) + .setRcfileTimeZone(nonDefaultTimeZone().getID()) .setRcfileWriterValidate(true) .setOrcWriteLegacyVersion(true) .setOrcWriterValidationPercentage(0.16) diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveFileFormats.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveFileFormats.java index 5dc9bcb04..82491f583 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveFileFormats.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveFileFormats.java @@ -44,7 +44,6 @@ import org.apache.hadoop.hive.serde2.objectinspector.StructField; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.typeinfo.VarcharTypeInfo; import org.apache.hadoop.mapred.FileSplit; -import org.joda.time.DateTimeZone; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -73,6 +72,9 @@ import static io.prestosql.plugin.hive.HiveStorageFormat.RCBINARY; import static io.prestosql.plugin.hive.HiveStorageFormat.RCTEXT; import static io.prestosql.plugin.hive.HiveStorageFormat.SEQUENCEFILE; import static io.prestosql.plugin.hive.HiveStorageFormat.TEXTFILE; +import static io.prestosql.plugin.hive.HiveTestUtils.HDFS_ENVIRONMENT; +import static io.prestosql.plugin.hive.HiveTestUtils.TYPE_MANAGER; +import static io.prestosql.plugin.hive.HiveTestUtils.createGenericHiveRecordCursorProvider; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.FILE_INPUT_FORMAT; @@ -91,8 +93,6 @@ public class TestHiveFileFormats private static TestingConnectorSession parquetPageSourceSession = new TestingConnectorSession(new HiveSessionProperties(createParquetHiveConfig(false), new OrcFileWriterConfig(), new ParquetFileWriterConfig()).getSessionProperties()); private static TestingConnectorSession parquetPageSourceSessionUseName = new TestingConnectorSession(new HiveSessionProperties(createParquetHiveConfig(true), new OrcFileWriterConfig(), new ParquetFileWriterConfig()).getSessionProperties()); - private static final DateTimeZone HIVE_STORAGE_TIME_ZONE = DateTimeZone.forID("America/Bahia_Banderas"); - @DataProvider(name = "rowCount") public static Object[][] rowCountProvider() { @@ -119,7 +119,7 @@ public class TestHiveFileFormats assertThatFileFormat(TEXTFILE) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") @@ -133,7 +133,7 @@ public class TestHiveFileFormats assertThatFileFormat(SEQUENCEFILE) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") @@ -150,7 +150,7 @@ public class TestHiveFileFormats assertThatFileFormat(CSV) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test @@ -162,7 +162,7 @@ public class TestHiveFileFormats new TestColumn("t_null_string", javaStringObjectInspector, null, Slices.utf8Slice("")), // null was converted to empty string! new TestColumn("t_string", javaStringObjectInspector, "test", Slices.utf8Slice("test")))) .withRowsCount(2) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") @@ -180,9 +180,7 @@ public class TestHiveFileFormats .filter(column -> !column.getName().equals("t_map_float")) .filter(column -> !column.getName().equals("t_map_double")) // null map keys are not supported - .filter(column -> !column.getName().equals("t_map_null_key")) - .filter(column -> !column.getName().equals("t_map_null_key_complex_key_value")) - .filter(column -> !column.getName().equals("t_map_null_key_complex_value")) + .filter(TestHiveFileFormats::withoutNullMapKeyTests) // decimal(38) is broken or not supported .filter(column -> !column.getName().equals("t_decimal_precision_38")) .filter(column -> !column.getName().equals("t_map_decimal_precision_38")) @@ -192,7 +190,7 @@ public class TestHiveFileFormats assertThatFileFormat(JSON) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") @@ -208,7 +206,7 @@ public class TestHiveFileFormats assertThatFileFormat(RCTEXT) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") @@ -218,7 +216,7 @@ public class TestHiveFileFormats assertThatFileFormat(RCTEXT) .withColumns(TEST_COLUMNS) .withRowsCount(rowCount) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); } @Test(dataProvider = "rowCount") @@ -233,25 +231,9 @@ public class TestHiveFileFormats assertThatFileFormat(RCTEXT) .withColumns(testColumns) .withRowsCount(rowCount) - .withFileWriterFactory(new RcFileFileWriterFactory(HiveTestUtils.HDFS_ENVIRONMENT, HiveTestUtils.TYPE_MANAGER, new NodeVersion("test"), HIVE_STORAGE_TIME_ZONE, STATS)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); - } - - @Test(dataProvider = "rowCount") - public void testRCBinary(int rowCount) - throws Exception - { - // RCBinary does not support complex type as key of a map and interprets empty VARCHAR as nulls - List testColumns = TEST_COLUMNS.stream() - .filter(testColumn -> { - String name = testColumn.getName(); - return !name.equals("t_map_null_key_complex_key_value") && !name.equals("t_empty_varchar"); - }).collect(toList()); - assertThatFileFormat(RCBINARY) - .withColumns(testColumns) - .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .withFileWriterFactory(new RcFileFileWriterFactory(HDFS_ENVIRONMENT, TYPE_MANAGER, new NodeVersion("test"), HIVE_STORAGE_TIME_ZONE, STATS)) + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)) + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); } @Test(dataProvider = "rowCount") @@ -259,14 +241,16 @@ public class TestHiveFileFormats throws Exception { // RCBinary does not support complex type as key of a map and interprets empty VARCHAR as nulls + // Hive binary writers are broken for timestamps List testColumns = TEST_COLUMNS.stream() .filter(testColumn -> !testColumn.getName().equals("t_empty_varchar")) + .filter(TestHiveFileFormats::withoutTimestamps) .collect(toList()); assertThatFileFormat(RCBINARY) .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); } @Test(dataProvider = "rowCount") @@ -280,22 +264,33 @@ public class TestHiveFileFormats .filter(TestHiveFileFormats::withoutNullMapKeyTests) .collect(toList()); + // Hive cannot read timestamps from old files + List testColumnsNoTimestamps = testColumns.stream() + .filter(TestHiveFileFormats::withoutTimestamps) + .collect(toList()); + assertThatFileFormat(RCBINARY) .withColumns(testColumns) .withRowsCount(rowCount) - .withFileWriterFactory(new RcFileFileWriterFactory(HiveTestUtils.HDFS_ENVIRONMENT, HiveTestUtils.TYPE_MANAGER, new NodeVersion("test"), HIVE_STORAGE_TIME_ZONE, STATS)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .withFileWriterFactory(new RcFileFileWriterFactory(HDFS_ENVIRONMENT, TYPE_MANAGER, new NodeVersion("test"), HIVE_STORAGE_TIME_ZONE, STATS)) + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())) + .withColumns(testColumnsNoTimestamps) + .isReadableByRecordCursor(createGenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test(dataProvider = "rowCount") public void testOrc(int rowCount) throws Exception { + // Hive binary writers are broken for timestamps + List testColumns = TEST_COLUMNS.stream() + .filter(TestHiveFileFormats::withoutTimestamps) + .collect(toImmutableList()); + assertThatFileFormat(ORC) - .withColumns(TEST_COLUMNS) + .withColumns(testColumns) .withRowsCount(rowCount) - .isReadableByPageSource(new OrcPageSourceFactory(HiveTestUtils.TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HiveTestUtils.HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( + .isReadableByPageSource(new OrcPageSourceFactory(TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcStripeFooterCacheTtl().toMillis()), @@ -319,16 +314,16 @@ public class TestHiveFileFormats // A Presto page can not contain a map with null keys, so a page based writer can not write null keys List testColumns = TEST_COLUMNS.stream() - .filter(testColumn -> !testColumn.getName().equals("t_map_null_key") && !testColumn.getName().equals("t_map_null_key_complex_value") && !testColumn.getName().equals("t_map_null_key_complex_key_value")) + .filter(TestHiveFileFormats::withoutNullMapKeyTests) .collect(toList()); assertThatFileFormat(ORC) .withColumns(testColumns) .withRowsCount(rowCount) .withSession(session) - .withFileWriterFactory(new OrcFileWriterFactory(HiveTestUtils.HDFS_ENVIRONMENT, HiveTestUtils.TYPE_MANAGER, new NodeVersion("test"), HIVE_STORAGE_TIME_ZONE, false, STATS, new OrcWriterOptions())) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)) - .isReadableByPageSource(new OrcPageSourceFactory(HiveTestUtils.TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HiveTestUtils.HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( + .withFileWriterFactory(new OrcFileWriterFactory(HDFS_ENVIRONMENT, TYPE_MANAGER, new NodeVersion("test"), false, STATS, new OrcWriterOptions())) + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)) + .isReadableByPageSource(new OrcPageSourceFactory(TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcStripeFooterCacheTtl().toMillis()), @@ -345,12 +340,17 @@ public class TestHiveFileFormats { TestingConnectorSession session = new TestingConnectorSession(new HiveSessionProperties(new HiveConfig(), new OrcFileWriterConfig(), new ParquetFileWriterConfig()).getSessionProperties()); + // Hive binary writers are broken for timestamps + List testColumns = TEST_COLUMNS.stream() + .filter(TestHiveFileFormats::withoutTimestamps) + .collect(toImmutableList()); + assertThatFileFormat(ORC) - .withWriteColumns(TEST_COLUMNS) + .withWriteColumns(testColumns) .withRowsCount(rowCount) - .withReadColumns(Lists.reverse(TEST_COLUMNS)) + .withReadColumns(Lists.reverse(testColumns)) .withSession(session) - .isReadableByPageSource(new OrcPageSourceFactory(HiveTestUtils.TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(true), HiveTestUtils.HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( + .isReadableByPageSource(new OrcPageSourceFactory(TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(true), HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcStripeFooterCacheTtl().toMillis()), @@ -385,7 +385,7 @@ public class TestHiveFileFormats assertThatFileFormat(AVRO) .withColumns(getTestColumnsSupportedByAvro()) .withRowsCount(rowCount) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } private static List getTestColumnsSupportedByAvro() @@ -407,7 +407,7 @@ public class TestHiveFileFormats .withColumns(testColumns) .withSession(parquetPageSourceSession) .withRowsCount(rowCount) - .isReadableByPageSource(new ParquetPageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new ParquetPageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); } @Test(dataProvider = "rowCount") @@ -430,7 +430,7 @@ public class TestHiveFileFormats .withReadColumns(readColumns) .withSession(parquetPageSourceSession) .withRowsCount(rowCount) - .isReadableByPageSource(new ParquetPageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new ParquetPageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); // test name-based access readColumns = Lists.reverse(writeColumns); @@ -438,7 +438,7 @@ public class TestHiveFileFormats .withWriteColumns(writeColumns) .withReadColumns(readColumns) .withSession(parquetPageSourceSessionUseName) - .isReadableByPageSource(new ParquetPageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new ParquetPageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); } private static List getTestColumnsSupportedByParquet() @@ -466,19 +466,19 @@ public class TestHiveFileFormats assertThatFileFormat(RCTEXT) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())) + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); assertThatFileFormat(RCBINARY) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())) + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); assertThatFileFormat(ORC) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByPageSource(new OrcPageSourceFactory(HiveTestUtils.TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HiveTestUtils.HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( + .isReadableByPageSource(new OrcPageSourceFactory(TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcStripeFooterCacheTtl().toMillis()), @@ -492,22 +492,22 @@ public class TestHiveFileFormats .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) .withSession(parquetPageSourceSession) - .isReadableByPageSource(new ParquetPageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS)); + .isReadableByPageSource(new ParquetPageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig())); assertThatFileFormat(AVRO) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); assertThatFileFormat(SEQUENCEFILE) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); assertThatFileFormat(TEXTFILE) .withWriteColumns(ImmutableList.of(writeColumn)) .withReadColumns(ImmutableList.of(readColumn)) - .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT)); + .isReadableByRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT)); } @Test @@ -524,17 +524,17 @@ public class TestHiveFileFormats assertThatFileFormat(RCTEXT) .withColumns(columns) - .isFailingForPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS), expectedErrorCode, expectedMessage) - .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); + .isFailingForPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig()), expectedErrorCode, expectedMessage) + .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); assertThatFileFormat(RCBINARY) .withColumns(columns) - .isFailingForPageSource(new RcFilePageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS), expectedErrorCode, expectedMessage) - .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); + .isFailingForPageSource(new RcFilePageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig()), expectedErrorCode, expectedMessage) + .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); assertThatFileFormat(ORC) .withColumns(columns) - .isFailingForPageSource(new OrcPageSourceFactory(HiveTestUtils.TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HiveTestUtils.HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( + .isFailingForPageSource(new OrcPageSourceFactory(TYPE_MANAGER, new HiveConfig().setUseOrcColumnNames(false), HDFS_ENVIRONMENT, STATS, OrcCacheStore.builder().newCacheStore( new HiveConfig().getOrcFileTailCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcFileTailCacheTtl().toMillis()), new HiveConfig().getOrcStripeFooterCacheLimit(), Duration.ofMillis(new HiveConfig().getOrcStripeFooterCacheTtl().toMillis()), @@ -547,15 +547,15 @@ public class TestHiveFileFormats assertThatFileFormat(PARQUET) .withColumns(columns) .withSession(parquetPageSourceSession) - .isFailingForPageSource(new ParquetPageSourceFactory(HiveTestUtils.TYPE_MANAGER, HiveTestUtils.HDFS_ENVIRONMENT, STATS), expectedErrorCode, expectedMessage); + .isFailingForPageSource(new ParquetPageSourceFactory(TYPE_MANAGER, HDFS_ENVIRONMENT, STATS, new HiveConfig()), expectedErrorCode, expectedMessage); assertThatFileFormat(SEQUENCEFILE) .withColumns(columns) - .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); + .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); assertThatFileFormat(TEXTFILE) .withColumns(columns) - .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HiveTestUtils.HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); + .isFailingForRecordCursor(new GenericHiveRecordCursorProvider(HDFS_ENVIRONMENT), expectedErrorCode, expectedMessage); } private void testCursorProvider(HiveRecordCursorProvider cursorProvider, @@ -592,8 +592,7 @@ public class TestHiveFileFormats TupleDomain.all(), getColumnHandles(testColumns), partitionKeys, - DateTimeZone.getDefault(), - HiveTestUtils.TYPE_MANAGER, + TYPE_MANAGER, ImmutableMap.of(), Optional.empty(), false, @@ -646,8 +645,7 @@ public class TestHiveFileFormats TupleDomain.all(), columnHandles, partitionKeys, - DateTimeZone.getDefault(), - HiveTestUtils.TYPE_MANAGER, + TYPE_MANAGER, ImmutableMap.of(), Optional.empty(), false, @@ -835,10 +833,10 @@ public class TestHiveFileFormats try { FileSplit split; if (fileWriterFactory != null) { - split = createTestFile(file.getAbsolutePath(), storageFormat, compressionCodec, writeColumns, session, rowsCount, fileWriterFactory); + split = createTestFilePresto(file.getAbsolutePath(), storageFormat, compressionCodec, writeColumns, session, rowsCount, fileWriterFactory); } else { - split = createTestFile(file.getAbsolutePath(), storageFormat, compressionCodec, writeColumns, rowsCount); + split = createTestFileHive(file.getAbsolutePath(), storageFormat, compressionCodec, writeColumns, rowsCount); } if (pageSourceFactory.isPresent()) { testPageSourceFactory(pageSourceFactory.get(), split, storageFormat, readColumns, session, rowsCount); @@ -870,4 +868,12 @@ public class TestHiveFileFormats } } } + + private static boolean withoutTimestamps(TestColumn testColumn) + { + String name = testColumn.getName(); + return !name.equals("t_timestamp") && + !name.equals("t_map_timestamp") && + !name.equals("t_array_timestamp"); + } } diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveUtil.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveUtil.java index 09703e77e..a0b1f8cc7 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveUtil.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveUtil.java @@ -100,7 +100,7 @@ public class TestHiveUtil @Test public void testParseHiveTimestamp() { - DateTime time = new DateTime(2011, 5, 6, 7, 8, 9, 123, nonDefaultTimeZone()); + DateTime time = new DateTime(2011, 5, 6, 7, 8, 9, 123, DateTimeZone.UTC); assertEquals(parse(time, "yyyy-MM-dd HH:mm:ss"), unixTime(time, 0)); assertEquals(parse(time, "yyyy-MM-dd HH:mm:ss.S"), unixTime(time, 1)); assertEquals(parse(time, "yyyy-MM-dd HH:mm:ss.SSS"), unixTime(time, 3)); @@ -232,7 +232,7 @@ public class TestHiveUtil private static long parse(DateTime time, String pattern) { - return parseHiveTimestamp(DateTimeFormat.forPattern(pattern).print(time), nonDefaultTimeZone()); + return parseHiveTimestamp(DateTimeFormat.forPattern(pattern).print(time)); } private static long unixTime(DateTime time, int factionalDigits) diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveWriterFactory.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveWriterFactory.java index a34235834..1fd1bc863 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveWriterFactory.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestHiveWriterFactory.java @@ -60,6 +60,7 @@ import static io.prestosql.plugin.hive.HiveTestUtils.getDefaultHiveFileWriterFac import static io.prestosql.plugin.hive.HiveTestUtils.getDefaultOrcFileWriterFactory; import static java.util.concurrent.Executors.newCachedThreadPool; import static org.apache.hadoop.hive.ql.exec.Utilities.getBucketIdFromFile; +import static org.joda.time.DateTimeZone.UTC; import static org.testng.Assert.assertEquals; public class TestHiveWriterFactory @@ -140,6 +141,7 @@ public class TestHiveWriterFactory hiveConfig.getWriterSortBufferSize(), hiveConfig.getMaxOpenSortFiles(), false, + UTC, session, new TestingNodeManager("fake-environment"), new HiveEventClient(), diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestOrcPageSourceMemoryTracking.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestOrcPageSourceMemoryTracking.java index 5659c90ae..fcbe52101 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/TestOrcPageSourceMemoryTracking.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/TestOrcPageSourceMemoryTracking.java @@ -74,7 +74,6 @@ import org.apache.hadoop.mapred.FileSplit; import org.apache.hadoop.mapred.JobConf; import org.apache.orc.NullMemoryManager; import org.apache.orc.impl.WriterImpl; -import org.joda.time.DateTimeZone; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -507,7 +506,6 @@ public class TestOrcPageSourceMemoryTracking TupleDomain.all(), columns, partitionKeys, - DateTimeZone.UTC, TYPE_MANAGER, ImmutableMap.of(), Optional.empty(), diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/benchmark/FileFormat.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/benchmark/FileFormat.java index b8b5c33ba..baaa5760b 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/benchmark/FileFormat.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/benchmark/FileFormat.java @@ -55,7 +55,6 @@ import io.prestosql.spi.type.Type; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.mapred.JobConf; -import org.joda.time.DateTimeZone; import java.io.File; import java.io.FileOutputStream; @@ -77,6 +76,7 @@ import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.FILE_ import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.META_TABLE_COLUMNS; import static org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.META_TABLE_COLUMN_TYPES; import static org.apache.hadoop.hive.serde.serdeConstants.SERIALIZATION_LIB; +import static org.joda.time.DateTimeZone.UTC; public enum FileFormat { @@ -84,7 +84,7 @@ public enum FileFormat @Override public ConnectorPageSource createFileFormatReader(ConnectorSession session, HdfsEnvironment hdfsEnvironment, File targetFile, List columnNames, List columnTypes) { - HivePageSourceFactory pageSourceFactory = new RcFilePageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats()); + HivePageSourceFactory pageSourceFactory = new RcFilePageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats(), new HiveConfig().setRcfileTimeZone("UTC")); return createPageSource(pageSourceFactory, session, targetFile, columnNames, columnTypes, HiveStorageFormat.RCBINARY); } @@ -100,7 +100,7 @@ public enum FileFormat return new PrestoRcFileFormatWriter( targetFile, columnTypes, - new BinaryRcFileEncoding(), + new BinaryRcFileEncoding(UTC), compressionCodec); } }, @@ -108,7 +108,7 @@ public enum FileFormat @Override public ConnectorPageSource createFileFormatReader(ConnectorSession session, HdfsEnvironment hdfsEnvironment, File targetFile, List columnNames, List columnTypes) { - HivePageSourceFactory pageSourceFactory = new RcFilePageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats()); + HivePageSourceFactory pageSourceFactory = new RcFilePageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats(), new HiveConfig().setRcfileTimeZone("UTC")); return createPageSource(pageSourceFactory, session, targetFile, columnNames, columnTypes, HiveStorageFormat.RCTEXT); } @@ -124,7 +124,7 @@ public enum FileFormat return new PrestoRcFileFormatWriter( targetFile, columnTypes, - new TextRcFileEncoding(DateTimeZone.forID(session.getTimeZoneKey().getId())), + new TextRcFileEncoding(), compressionCodec); } }, @@ -158,7 +158,6 @@ public enum FileFormat targetFile, columnNames, columnTypes, - DateTimeZone.forID(session.getTimeZoneKey().getId()), compressionCodec); } }, @@ -167,7 +166,7 @@ public enum FileFormat @Override public ConnectorPageSource createFileFormatReader(ConnectorSession session, HdfsEnvironment hdfsEnvironment, File targetFile, List columnNames, List columnTypes) { - HivePageSourceFactory pageSourceFactory = new ParquetPageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats()); + HivePageSourceFactory pageSourceFactory = new ParquetPageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats(), new HiveConfig()); return createPageSource(pageSourceFactory, session, targetFile, columnNames, columnTypes, HiveStorageFormat.PARQUET); } @@ -247,7 +246,7 @@ public enum FileFormat @Override public ConnectorPageSource createFileFormatReader(ConnectorSession session, HdfsEnvironment hdfsEnvironment, File targetFile, List columnNames, List columnTypes) { - HivePageSourceFactory pageSourceFactory = new ParquetPageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats()); + HivePageSourceFactory pageSourceFactory = new ParquetPageSourceFactory(TYPE_MANAGER, hdfsEnvironment, new FileFormatDataSourceStats(), new HiveConfig()); return createPageSource(pageSourceFactory, session, targetFile, columnNames, columnTypes, HiveStorageFormat.PARQUET); } @@ -316,7 +315,6 @@ public enum FileFormat createSchema(format, columnNames, columnTypes), columnHandles, TupleDomain.all(), - DateTimeZone.forID(session.getTimeZoneKey().getId()), TYPE_MANAGER, false, ImmutableMap.of()) @@ -352,7 +350,6 @@ public enum FileFormat createSchema(format, columnNames, columnTypes), columnHandles, TupleDomain.all(), - DateTimeZone.forID(session.getTimeZoneKey().getId()), Optional.empty(), Optional.empty(), Optional.empty(), @@ -386,6 +383,7 @@ public enum FileFormat format.getEstimatedWriterSystemMemoryUsage(), config, TYPE_MANAGER, + UTC, session); } @@ -458,7 +456,7 @@ public enum FileFormat { private final OrcWriter writer; - public PrestoOrcFormatWriter(File targetFile, List columnNames, List types, DateTimeZone hiveStorageTimeZone, HiveCompressionCodec compressionCodec) + public PrestoOrcFormatWriter(File targetFile, List columnNames, List types, HiveCompressionCodec compressionCodec) throws IOException { writer = new OrcWriter( @@ -469,7 +467,6 @@ public enum FileFormat new OrcWriterOptions(), false, ImmutableMap.of(), - hiveStorageTimeZone, false, BOTH, new OrcWriterStats(), Optional.empty(), Optional.empty()); diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/orc/TestOrcAcidPageSource.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/orc/TestOrcAcidPageSource.java index 538dd7db1..aca0f5255 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/orc/TestOrcAcidPageSource.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/orc/TestOrcAcidPageSource.java @@ -38,7 +38,6 @@ import io.prestosql.type.InternalTypeManager; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.mapred.JobConf; -import org.joda.time.DateTimeZone; import org.testng.annotations.Test; import java.io.File; @@ -176,7 +175,6 @@ public class TestOrcAcidPageSource createSchema(), columnHandles, tupleDomain, - DateTimeZone.UTC, Optional.empty(), deleteDeltaLocations, Optional.empty(), diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/AbstractTestParquetReader.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/AbstractTestParquetReader.java index bc41109df..bb4fed2d0 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/AbstractTestParquetReader.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/AbstractTestParquetReader.java @@ -28,7 +28,9 @@ import io.prestosql.spi.type.SqlDecimal; import io.prestosql.spi.type.SqlTimestamp; import io.prestosql.spi.type.SqlVarbinary; import io.prestosql.spi.type.Type; +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.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaHiveDecimalObjectInspector; import org.apache.hadoop.hive.serde2.typeinfo.DecimalTypeInfo; @@ -39,8 +41,6 @@ import org.testng.annotations.Test; import java.math.BigDecimal; import java.math.BigInteger; -import java.sql.Date; -import java.sql.Timestamp; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; @@ -64,7 +64,6 @@ import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.cycle; import static com.google.common.collect.Iterables.limit; import static com.google.common.collect.Iterables.transform; -import static io.prestosql.plugin.hive.parquet.ParquetTester.HIVE_STORAGE_TIME_ZONE; import static io.prestosql.plugin.hive.parquet.ParquetTester.insertNullEvery; import static io.prestosql.spi.type.BigintType.BIGINT; import static io.prestosql.spi.type.BooleanType.BOOLEAN; @@ -80,7 +79,6 @@ import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.spi.type.VarcharType.createUnboundedVarcharType; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingConnectorSession.SESSION; import static io.prestosql.tests.StructuralTestUtil.mapType; import static java.lang.Math.toIntExact; import static java.lang.String.format; @@ -122,7 +120,7 @@ public abstract class AbstractTestParquetReader @BeforeClass public void setUp() { - assertEquals(DateTimeZone.getDefault(), HIVE_STORAGE_TIME_ZONE); + assertEquals(DateTimeZone.getDefault(), DateTimeZone.forID("America/Bahia_Banderas")); // Parquet has excessive logging at INFO level parquetLogger = Logger.getLogger("org.apache.parquet.hadoop"); @@ -1774,7 +1772,7 @@ public abstract class AbstractTestParquetReader if (input == null) { return null; } - Timestamp timestamp = new Timestamp(0); + Timestamp timestamp = new Timestamp(); long seconds = (input / 1000); int nanos = ((input % 1000) * 1_000_000); @@ -1789,7 +1787,7 @@ public abstract class AbstractTestParquetReader nanos -= 1_000_000_000; seconds += 1; } - timestamp.setTime(seconds * 1000); + timestamp.setTimeInMillis(seconds * 1000); timestamp.setNanos(nanos); return timestamp; } @@ -1799,7 +1797,7 @@ public abstract class AbstractTestParquetReader if (input == null) { return null; } - return sqlTimestampOf(input, SESSION); + return sqlTimestampOf(input); } private static Date intToDate(Integer input) @@ -1807,7 +1805,7 @@ public abstract class AbstractTestParquetReader if (input == null) { return null; } - return Date.valueOf(LocalDate.ofEpochDay(input)); + return Date.valueOf(LocalDate.ofEpochDay(input).toString()); } private static SqlDate intToSqlDate(Integer input) diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/ParquetTester.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/ParquetTester.java index 907301023..c475d824b 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/ParquetTester.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/ParquetTester.java @@ -64,7 +64,6 @@ import org.apache.hadoop.mapred.JobConf; import org.apache.parquet.column.ParquetProperties.WriterVersion; import org.apache.parquet.hadoop.metadata.CompressionCodecName; import org.apache.parquet.schema.MessageType; -import org.joda.time.DateTimeZone; import java.io.Closeable; import java.io.File; @@ -90,7 +89,6 @@ import static io.prestosql.plugin.hive.HiveUtil.isArrayType; import static io.prestosql.plugin.hive.HiveUtil.isMapType; import static io.prestosql.plugin.hive.HiveUtil.isRowType; import static io.prestosql.plugin.hive.HiveUtil.isStructuralType; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.Varchars.isVarcharType; import static java.util.Arrays.stream; @@ -113,7 +111,6 @@ import static org.testng.Assert.assertTrue; public class ParquetTester { - public static final DateTimeZone HIVE_STORAGE_TIME_ZONE = DateTimeZone.forID("America/Bahia_Banderas"); private static final boolean OPTIMIZED = true; private static final HiveConfig HIVE_CLIENT_CONFIG = createHiveConfig(false); private static final HdfsEnvironment HDFS_ENVIRONMENT = HiveTestUtils.createTestHdfsEnvironment(HIVE_CLIENT_CONFIG); @@ -474,7 +471,7 @@ public class ParquetTester return new SqlDate(((Long) fieldFromCursor).intValue()); } if (TimestampType.TIMESTAMP.equals(type)) { - return new SqlTimestamp((long) fieldFromCursor, UTC_KEY); + return new SqlTimestamp((long) fieldFromCursor); } return fieldFromCursor; } diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/TestParquetPageSourceFactory.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/TestParquetPageSourceFactory.java index e59bf5b4a..20fd16af6 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/TestParquetPageSourceFactory.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/TestParquetPageSourceFactory.java @@ -51,7 +51,7 @@ public class TestParquetPageSourceFactory { HiveHdfsConfiguration hiveHdfsConfiguration = new HiveHdfsConfiguration(new HdfsConfigurationInitializer(new HiveConfig(), ImmutableSet.of()), ImmutableSet.of()); HdfsEnvironment hdfsEnvironment = new HdfsEnvironment(hiveHdfsConfiguration, new HiveConfig(), new NoHdfsAuthentication()); - parquetPageSourceFactory = new ParquetPageSourceFactory(new TestingTypeManager(), hdfsEnvironment, new FileFormatDataSourceStats()); + parquetPageSourceFactory = new ParquetPageSourceFactory(new TestingTypeManager(), hdfsEnvironment, new FileFormatDataSourceStats(), new HiveConfig()); } @AfterClass(alwaysRun = true) @@ -68,7 +68,7 @@ public class TestParquetPageSourceFactory schema.setProperty(SERIALIZATION_LIB, ""); schema.setProperty(FILE_INPUT_FORMAT, ""); schema.setProperty(FILE_OUTPUT_FORMAT, ""); - Optional optionalPageSource = parquetPageSourceFactory.createPageSource(new Configuration(), null, null, 0L, 0L, 0L, schema, null, null, null, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), null, false, -1L); + Optional optionalPageSource = parquetPageSourceFactory.createPageSource(new Configuration(), null, null, 0L, 0L, 0L, schema, null, null, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), null, false, -1L); assertFalse(optionalPageSource.isPresent()); } @@ -80,7 +80,7 @@ public class TestParquetPageSourceFactory schema.setProperty(SERIALIZATION_LIB, PARQUET.getSerDe()); schema.setProperty(FILE_INPUT_FORMAT, HoodieParquetRealtimeInputFormat.class.getName()); schema.setProperty(FILE_OUTPUT_FORMAT, ""); - Optional optionalPageSource = parquetPageSourceFactory.createPageSource(new Configuration(), null, null, 0L, 0L, 0L, schema, null, null, null, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), null, false, -1L); + Optional optionalPageSource = parquetPageSourceFactory.createPageSource(new Configuration(), null, null, 0L, 0L, 0L, schema, null, null, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), null, false, -1L); assertTrue(shouldUseRecordReaderFromInputFormat(new Configuration(), schema)); assertFalse(optionalPageSource.isPresent()); } diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/write/TestDataWritableWriter.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/write/TestDataWritableWriter.java index 6e5ad143c..1dfab8639 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/write/TestDataWritableWriter.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/parquet/write/TestDataWritableWriter.java @@ -14,11 +14,12 @@ package io.prestosql.plugin.hive.parquet.write; import io.airlift.log.Logger; +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.ql.io.parquet.serde.ParquetHiveSerDe; import org.apache.hadoop.hive.ql.io.parquet.timestamp.NanoTimeUtils; import org.apache.hadoop.hive.ql.io.parquet.write.DataWritableWriter; -import org.apache.hadoop.hive.serde2.io.DateWritable; import org.apache.hadoop.hive.serde2.io.ParquetHiveRecord; import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.MapObjectInspector; @@ -46,8 +47,6 @@ import org.apache.parquet.schema.GroupType; import org.apache.parquet.schema.OriginalType; import org.apache.parquet.schema.Type; -import java.sql.Date; -import java.sql.Timestamp; import java.util.List; import java.util.Map; @@ -377,7 +376,7 @@ public class TestDataWritableWriter break; case DATE: Date vDate = ((DateObjectInspector) inspector).getPrimitiveJavaObject(value); - recordConsumer.addInteger(DateWritable.dateToDays(vDate)); + recordConsumer.addInteger(vDate.toEpochDay()); break; default: throw new IllegalArgumentException("Unsupported primitive data type: " + inspector.getPrimitiveCategory()); diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/statistics/TestMetastoreHiveStatisticsProvider.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/statistics/TestMetastoreHiveStatisticsProvider.java index 019ffeb8c..e102b2cfb 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/statistics/TestMetastoreHiveStatisticsProvider.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/statistics/TestMetastoreHiveStatisticsProvider.java @@ -42,7 +42,6 @@ import io.prestosql.spi.statistics.TableStatistics; import io.prestosql.spi.type.DecimalType; import io.prestosql.spi.type.Type; import io.prestosql.testing.TestingConnectorSession; -import org.joda.time.DateTimeZone; import org.testng.annotations.Test; import java.math.BigDecimal; @@ -474,7 +473,7 @@ public class TestMetastoreHiveStatisticsProvider private static void assertConvertPartitionValueToDouble(Type type, String value, double expected) { - Object prestoValue = parsePartitionValue(format("p=%s", value), value, type, DateTimeZone.getDefault()).getValue(); + Object prestoValue = parsePartitionValue(format("p=%s", value), value, type).getValue(); assertEquals(convertPartitionValueToDouble(type, prestoValue), expected); } @@ -777,7 +776,7 @@ public class TestMetastoreHiveStatisticsProvider private static HivePartition partition(String name) { - return parsePartition(TABLE, name, ImmutableList.of(PARTITION_COLUMN_1, PARTITION_COLUMN_2), ImmutableList.of(VARCHAR, BIGINT), DateTimeZone.getDefault()); + return parsePartition(TABLE, name, ImmutableList.of(PARTITION_COLUMN_1, PARTITION_COLUMN_2), ImmutableList.of(VARCHAR, BIGINT)); } private static PartitionStatistics rowsCount(long rowsCount) diff --git a/presto-hive/src/test/java/io/prestosql/plugin/hive/util/TestSerDeUtils.java b/presto-hive/src/test/java/io/prestosql/plugin/hive/util/TestSerDeUtils.java index e445a15d1..a2edf81b2 100644 --- a/presto-hive/src/test/java/io/prestosql/plugin/hive/util/TestSerDeUtils.java +++ b/presto-hive/src/test/java/io/prestosql/plugin/hive/util/TestSerDeUtils.java @@ -28,6 +28,8 @@ import io.prestosql.spi.block.BlockEncodingSerde; import io.prestosql.spi.type.ArrayType; import io.prestosql.spi.type.RowType; import io.prestosql.tests.StructuralTestUtil; +import org.apache.hadoop.hive.common.type.Date; +import org.apache.hadoop.hive.common.type.Timestamp; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category; import org.apache.hadoop.io.BytesWritable; @@ -35,7 +37,7 @@ import org.joda.time.DateTime; import org.testng.annotations.Test; import java.lang.reflect.Type; -import java.sql.Timestamp; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -58,6 +60,7 @@ import static io.prestosql.tests.StructuralTestUtil.mapBlockOf; import static io.prestosql.tests.StructuralTestUtil.rowBlockOf; import static java.lang.Double.doubleToLongBits; import static java.lang.Float.floatToRawIntBits; +import static java.lang.Math.toIntExact; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.ObjectInspectorOptions; import static org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory.getReflectionObjectInspector; @@ -155,10 +158,16 @@ public class TestSerDeUtils Block actualString = toBinaryBlock(createUnboundedVarcharType(), "abdd", getInspector(String.class)); assertBlockEquals(actualString, expectedString); + // date + int date = toIntExact(LocalDate.of(2008, 10, 28).toEpochDay()); + Block expectedDate = VARBINARY.createBlockBuilder(null, 1).writeInt(date).closeEntry().build(); + Block actualDate = toBinaryBlock(BIGINT, Date.ofEpochDay(date), getInspector(Date.class)); + assertBlockEquals(actualDate, expectedDate); + // timestamp DateTime dateTime = new DateTime(2008, 10, 28, 16, 7, 15, 0); Block expectedTimestamp = VARBINARY.createBlockBuilder(null, 1).writeLong(dateTime.getMillis()).closeEntry().build(); - Block actualTimestamp = toBinaryBlock(BIGINT, new Timestamp(dateTime.getMillis()), getInspector(Timestamp.class)); + Block actualTimestamp = toBinaryBlock(BIGINT, Timestamp.ofEpochMilli(dateTime.getMillis()), getInspector(Timestamp.class)); assertBlockEquals(actualTimestamp, expectedTimestamp); // binary diff --git a/presto-kafka/src/test/resources/read_test/all_datatypes_json.json b/presto-kafka/src/test/resources/read_test/all_datatypes_json.json new file mode 100644 index 000000000..cddaa14e3 --- /dev/null +++ b/presto-kafka/src/test/resources/read_test/all_datatypes_json.json @@ -0,0 +1,188 @@ +{ + "tableName": "all_datatypes_json", + "schemaName": "product_tests", + "topicName": "all_datatypes_json", + "message": { + "dataFormat": "json", + "fields": [ + { + "name": "c_varchar", + "type": "VARCHAR", + "mapping": "j_varchar" + }, + { + "name": "c_bigint", + "type": "BIGINT", + "mapping": "j_bigint" + }, + { + "name": "c_integer", + "type": "INTEGER", + "mapping": "j_integer" + }, + { + "name": "c_smallint", + "type": "SMALLINT", + "mapping": "j_smallint" + }, + { + "name": "c_tinyint", + "type": "TINYINT", + "mapping": "j_tinyint" + }, + { + "name": "c_double", + "type": "DOUBLE", + "mapping": "j_double" + }, + { + "name": "c_boolean", + "type": "BOOLEAN", + "mapping": "j_boolean" + }, + { + "name": "c_timestamp_milliseconds_since_epoch", + "type": "TIMESTAMP", + "mapping": "j_timestamp_milliseconds_since_epoch", + "dataFormat": "milliseconds-since-epoch" + }, + { + "name": "c_timestamp_seconds_since_epoch", + "type": "TIMESTAMP", + "mapping": "j_timestamp_seconds_since_epoch", + "dataFormat": "seconds-since-epoch" + }, + { + "name": "c_timestamp_iso8601", + "type": "TIMESTAMP", + "mapping": "j_timestamp_iso8601", + "dataFormat": "iso8601" + }, + { + "name": "c_timestamp_rfc2822", + "type": "TIMESTAMP", + "mapping": "j_timestamp_rfc2822", + "dataFormat": "rfc2822" + }, + { + "name": "c_timestamp_custom", + "type": "TIMESTAMP", + "mapping": "j_timestamp_custom", + "dataFormat": "custom-date-time", + "formatHint": "MM/yyyy/dd H:m:s" + }, + { + "name": "c_date_iso8601", + "type": "DATE", + "mapping": "j_date_iso8601", + "dataFormat": "iso8601" + }, + { + "name": "c_date_rfc2822", + "type": "DATE", + "mapping": "j_date_rfc2822", + "dataFormat": "rfc2822" + }, + { + "name": "c_date_custom", + "type": "DATE", + "mapping": "j_date_custom", + "dataFormat": "custom-date-time", + "formatHint": "yyyy/dd/MM" + }, + { + "name": "c_time_milliseconds_since_epoch", + "type": "TIME", + "mapping": "j_time_milliseconds_since_epoch", + "dataFormat": "milliseconds-since-epoch" + }, + { + "name": "c_time_seconds_since_epoch", + "type": "TIME", + "mapping": "j_time_seconds_since_epoch", + "dataFormat": "seconds-since-epoch" + }, + { + "name": "c_time_iso8601", + "type": "TIME", + "mapping": "j_time_iso8601", + "dataFormat": "iso8601" + }, + { + "name": "c_time_rfc2822", + "type": "TIME", + "mapping": "j_time_rfc2822", + "dataFormat": "rfc2822" + }, + { + "name": "c_time_custom", + "type": "TIME", + "mapping": "j_time_custom", + "dataFormat": "custom-date-time", + "formatHint": "mm:HH:ss" + }, + { + "name": "c_timestamptz_milliseconds_since_epoch", + "type": "TIMESTAMP WITH TIME ZONE", + "mapping": "j_timestamptz_milliseconds_since_epoch", + "dataFormat": "milliseconds-since-epoch" + }, + { + "name": "c_timestamptz_seconds_since_epoch", + "type": "TIMESTAMP WITH TIME ZONE", + "mapping": "j_timestamptz_seconds_since_epoch", + "dataFormat": "seconds-since-epoch" + }, + { + "name": "c_timestamptz_iso8601", + "type": "TIMESTAMP WITH TIME ZONE", + "mapping": "j_timestamptz_iso8601", + "dataFormat": "iso8601" + }, + { + "name": "c_timestamptz_rfc2822", + "type": "TIMESTAMP WITH TIME ZONE", + "mapping": "j_timestamptz_rfc2822", + "dataFormat": "rfc2822" + }, + { + "name": "c_timestamptz_custom", + "type": "TIMESTAMP WITH TIME ZONE", + "mapping": "j_timestamptz_custom", + "dataFormat": "custom-date-time", + "formatHint": "MM/yyyy/dd H:m:s" + }, + { + "name": "c_timetz_milliseconds_since_epoch", + "type": "TIME WITH TIME ZONE", + "mapping": "j_timetz_milliseconds_since_epoch", + "dataFormat": "milliseconds-since-epoch" + }, + { + "name": "c_timetz_seconds_since_epoch", + "type": "TIME WITH TIME ZONE", + "mapping": "j_timetz_seconds_since_epoch", + "dataFormat": "seconds-since-epoch" + }, + { + "name": "c_timetz_iso8601", + "type": "TIME WITH TIME ZONE", + "mapping": "j_timetz_iso8601", + "dataFormat": "iso8601" + }, + { + "name": "c_timetz_rfc2822", + "type": "TIME WITH TIME ZONE", + "mapping": "j_timetz_rfc2822", + "dataFormat": "rfc2822" + }, + { + "name": "c_timetz_custom", + "type": "TIME WITH TIME ZONE", + "mapping": "j_timetz_custom", + "dataFormat": "custom-date-time", + "formatHint": "mm:HH:ss" + } + ] + } +} diff --git a/presto-main/src/main/java/io/prestosql/FullConnectorSession.java b/presto-main/src/main/java/io/prestosql/FullConnectorSession.java index ed39151a6..3839eb155 100644 --- a/presto-main/src/main/java/io/prestosql/FullConnectorSession.java +++ b/presto-main/src/main/java/io/prestosql/FullConnectorSession.java @@ -39,7 +39,6 @@ public class FullConnectorSession private final CatalogName catalogName; private final String catalog; private final SessionPropertyManager sessionPropertyManager; - private final boolean isLegacyTimestamp; public FullConnectorSession(Session session, ConnectorIdentity identity) { @@ -49,7 +48,6 @@ public class FullConnectorSession this.catalogName = null; this.catalog = null; this.sessionPropertyManager = null; - this.isLegacyTimestamp = SystemSessionProperties.isLegacyTimestamp(session); } public FullConnectorSession( @@ -66,7 +64,6 @@ public class FullConnectorSession this.catalogName = requireNonNull(catalogName, "catalogName is null"); this.catalog = requireNonNull(catalog, "catalog is null"); this.sessionPropertyManager = requireNonNull(sessionPropertyManager, "sessionPropertyManager is null"); - this.isLegacyTimestamp = SystemSessionProperties.isLegacyTimestamp(session); } public Session getSession() @@ -116,12 +113,6 @@ public class FullConnectorSession return session.getTraceToken(); } - @Override - public boolean isLegacyTimestamp() - { - return isLegacyTimestamp; - } - @Override public T getProperty(String propertyName, Class type) { diff --git a/presto-main/src/main/java/io/prestosql/SystemSessionProperties.java b/presto-main/src/main/java/io/prestosql/SystemSessionProperties.java index 9b0383f28..fcfc3e0a6 100644 --- a/presto-main/src/main/java/io/prestosql/SystemSessionProperties.java +++ b/presto-main/src/main/java/io/prestosql/SystemSessionProperties.java @@ -105,7 +105,6 @@ public final class SystemSessionProperties public static final String ITERATIVE_OPTIMIZER_TIMEOUT = "iterative_optimizer_timeout"; public static final String ENABLE_FORCED_EXCHANGE_BELOW_GROUP_ID = "enable_forced_exchange_below_group_id"; public static final String EXCHANGE_COMPRESSION = "exchange_compression"; - public static final String LEGACY_TIMESTAMP = "legacy_timestamp"; public static final String ENABLE_INTERMEDIATE_AGGREGATIONS = "enable_intermediate_aggregations"; public static final String PUSH_AGGREGATION_THROUGH_JOIN = "push_aggregation_through_join"; public static final String PUSH_PARTIAL_AGGREGATION_THROUGH_JOIN = "push_partial_aggregation_through_join"; @@ -519,11 +518,6 @@ public final class SystemSessionProperties "Enable compression in exchanges", featuresConfig.isExchangeCompressionEnabled(), false), - booleanProperty( - LEGACY_TIMESTAMP, - "Use legacy TIME & TIMESTAMP semantics (warning: this will be removed)", - featuresConfig.isLegacyTimestamp(), - true), booleanProperty( ENABLE_INTERMEDIATE_AGGREGATIONS, "Enable the use of intermediate aggregations", @@ -1066,11 +1060,6 @@ public final class SystemSessionProperties return session.getSystemProperty(ITERATIVE_OPTIMIZER, Boolean.class); } - public static boolean isLegacyTimestamp(Session session) - { - return session.getSystemProperty(LEGACY_TIMESTAMP, Boolean.class); - } - public static Duration getOptimizerTimeout(Session session) { return session.getSystemProperty(ITERATIVE_OPTIMIZER_TIMEOUT, Duration.class); diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/ArrayToJsonCast.java b/presto-main/src/main/java/io/prestosql/operator/scalar/ArrayToJsonCast.java index 099973b42..9889ac22b 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/ArrayToJsonCast.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/ArrayToJsonCast.java @@ -22,7 +22,6 @@ import io.prestosql.metadata.BoundVariables; import io.prestosql.metadata.FunctionAndTypeManager; import io.prestosql.metadata.SqlOperator; import io.prestosql.spi.block.Block; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.function.BuiltInScalarFunctionImplementation; import io.prestosql.spi.function.OperatorType; import io.prestosql.spi.type.StandardTypes; @@ -50,7 +49,7 @@ public class ArrayToJsonCast extends SqlOperator { public static final ArrayToJsonCast ARRAY_TO_JSON = new ArrayToJsonCast(); - private static final MethodHandle METHOD_HANDLE = methodHandle(ArrayToJsonCast.class, "toJson", JsonGeneratorWriter.class, ConnectorSession.class, Block.class); + private static final MethodHandle METHOD_HANDLE = methodHandle(ArrayToJsonCast.class, "toJson", JsonGeneratorWriter.class, Block.class); private ArrayToJsonCast() { @@ -79,14 +78,14 @@ public class ArrayToJsonCast methodHandle); } - public static Slice toJson(JsonGeneratorWriter writer, ConnectorSession session, Block block) + public static Slice toJson(JsonGeneratorWriter writer, Block block) { try { SliceOutput output = new DynamicSliceOutput(40); try (JsonGenerator jsonGenerator = createJsonGenerator(JSON_FACTORY, output)) { jsonGenerator.writeStartArray(); for (int i = 0; i < block.getPositionCount(); i++) { - writer.writeJsonValue(jsonGenerator, block, i, session); + writer.writeJsonValue(jsonGenerator, block, i); } jsonGenerator.writeEndArray(); } diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/DateTimeFunctions.java b/presto-main/src/main/java/io/prestosql/operator/scalar/DateTimeFunctions.java index c16bf3985..4a2d51174 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/DateTimeFunctions.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/DateTimeFunctions.java @@ -107,14 +107,6 @@ public final class DateTimeFunctions // We do all calculation in UTC, as session.getStartTime() is in UTC // and we need to have UTC millis for packDateTimeWithZone long millis = UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); - - if (!session.isLegacyTimestamp()) { - // However, those UTC millis are pointing to the correct UTC timestamp - // Our TIME WITH TIME ZONE representation does use UTC 1970-01-01 representation - // So we have to hack here in order to get valid representation - // of TIME WITH TIME ZONE - millis -= valueToSessionTimeZoneOffsetDiff(session.getStartTime(), getDateTimeZone(session.getTimeZoneKey())); - } return packDateTimeWithZone(millis, session.getTimeZoneKey()); } @@ -123,9 +115,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIME) public static long localTime(ConnectorSession session) { - if (session.isLegacyTimestamp()) { - return UTC_CHRONOLOGY.millisOfDay().get(session.getStartTime()); - } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.millisOfDay().get(session.getStartTime()); } @@ -151,9 +140,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIMESTAMP) public static long localTimestamp(ConnectorSession session) { - if (session.isLegacyTimestamp()) { - return session.getStartTime(); - } ISOChronology localChronology = getChronology(session.getTimeZoneKey()); return localChronology.getZone().convertUTCToLocal(session.getStartTime()); } @@ -208,16 +194,9 @@ public final class DateTimeFunctions // the maximum year represented by 64bits timestamp is ~584944387 it may require up to 35 characters. public static Slice toISO8601FromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - DateTimeFormatter formatter = ISODateTimeFormat.dateTime() - .withChronology(getChronology(session.getTimeZoneKey())); - return utf8Slice(formatter.print(timestamp)); - } - else { - DateTimeFormatter formatter = ISODateTimeFormat.dateHourMinuteSecondMillis() - .withChronology(UTC_CHRONOLOGY); - return utf8Slice(formatter.print(timestamp)); - } + DateTimeFormatter formatter = ISODateTimeFormat.dateHourMinuteSecondMillis() + .withChronology(UTC_CHRONOLOGY); + return utf8Slice(formatter.print(timestamp)); } @ScalarFunction("to_iso8601") @@ -317,12 +296,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIME) public static long truncateTime(ConnectorSession session, @SqlType("varchar(x)") Slice unit, @SqlType(StandardTypes.TIME) long time) { - if (session.isLegacyTimestamp()) { - return getTimeField(getChronology(session.getTimeZoneKey()), unit).roundFloor(time); - } - else { - return getTimeField(UTC_CHRONOLOGY, unit).roundFloor(time); - } + return getTimeField(UTC_CHRONOLOGY, unit).roundFloor(time); } @Description("truncate to the specified precision") @@ -341,12 +315,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIMESTAMP) public static long truncateTimestamp(ConnectorSession session, @SqlType("varchar(x)") Slice unit, @SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getTimestampField(getChronology(session.getTimeZoneKey()), unit).roundFloor(timestamp); - } - else { - return getTimestampField(UTC_CHRONOLOGY, unit).roundFloor(timestamp); - } + return getTimestampField(UTC_CHRONOLOGY, unit).roundFloor(timestamp); } @Description("truncate to the specified precision") @@ -375,11 +344,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIME) public static long addFieldValueTime(ConnectorSession session, @SqlType("varchar(x)") Slice unit, @SqlType(StandardTypes.BIGINT) long value, @SqlType(StandardTypes.TIME) long time) { - if (session.isLegacyTimestamp()) { - ISOChronology chronology = getChronology(session.getTimeZoneKey()); - return modulo24Hour(chronology, getTimeField(chronology, unit).add(time, toIntExact(value))); - } - return modulo24Hour(getTimeField(UTC_CHRONOLOGY, unit).add(time, toIntExact(value))); } @@ -407,10 +371,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) long value, @SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getTimestampField(getChronology(session.getTimeZoneKey()), unit).add(timestamp, toIntExact(value)); - } - return getTimestampField(UTC_CHRONOLOGY, unit).add(timestamp, toIntExact(value)); } @@ -442,12 +402,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) public static long diffTime(ConnectorSession session, @SqlType("varchar(x)") Slice unit, @SqlType(StandardTypes.TIME) long time1, @SqlType(StandardTypes.TIME) long time2) { - if (session.isLegacyTimestamp()) { - // Session zone could have policy change on/around 1970-01-01, so we cannot use UTC - ISOChronology chronology = getChronology(session.getTimeZoneKey()); - return getTimeField(chronology, unit).getDifferenceAsLong(time2, time1); - } - return getTimeField(UTC_CHRONOLOGY, unit).getDifferenceAsLong(time2, time1); } @@ -473,10 +427,6 @@ public final class DateTimeFunctions @SqlType(StandardTypes.TIMESTAMP) long timestamp1, @SqlType(StandardTypes.TIMESTAMP) long timestamp2) { - if (session.isLegacyTimestamp()) { - return getTimestampField(getChronology(session.getTimeZoneKey()), unit).getDifferenceAsLong(timestamp2, timestamp1); - } - return getTimestampField(UTC_CHRONOLOGY, unit).getDifferenceAsLong(timestamp2, timestamp1); } @@ -587,16 +537,11 @@ public final class DateTimeFunctions @SqlType(StandardTypes.VARCHAR) public static Slice formatDatetime(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp, @SqlType("varchar(x)") Slice formatString) { - if (session.isLegacyTimestamp()) { - return formatDatetime(getChronology(session.getTimeZoneKey()), session.getLocale(), timestamp, formatString); - } - else { - if (datetimeFormatSpecifiesZone(formatString)) { - // Timezone is unknown for TIMESTAMP w/o TZ so it cannot be printed out. - throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "format_datetime for TIMESTAMP type, cannot use 'Z' nor 'z' in format, as this type does not contain TZ information"); - } - return formatDatetime(UTC_CHRONOLOGY, session.getLocale(), timestamp, formatString); + if (datetimeFormatSpecifiesZone(formatString)) { + // Timezone is unknown for TIMESTAMP w/o TZ so it cannot be printed out. + throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "format_datetime for TIMESTAMP type, cannot use 'Z' nor 'z' in format, as this type does not contain TZ information"); } + return formatDatetime(UTC_CHRONOLOGY, session.getLocale(), timestamp, formatString); } /** @@ -657,12 +602,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.VARCHAR) public static Slice dateFormat(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp, @SqlType("varchar(x)") Slice formatString) { - if (session.isLegacyTimestamp()) { - return dateFormat(getChronology(session.getTimeZoneKey()), session.getLocale(), timestamp, formatString); - } - else { - return dateFormat(UTC_CHRONOLOGY, session.getLocale(), timestamp, formatString); - } + return dateFormat(UTC_CHRONOLOGY, session.getLocale(), timestamp, formatString); } @ScalarFunction("date_format") @@ -691,7 +631,7 @@ public final class DateTimeFunctions public static long dateParse(ConnectorSession session, @SqlType("varchar(x)") Slice dateTime, @SqlType("varchar(y)") Slice formatString) { DateTimeFormatter formatter = DATETIME_FORMATTER_CACHE.get(formatString) - .withChronology(session.isLegacyTimestamp() ? getChronology(session.getTimeZoneKey()) : UTC_CHRONOLOGY) + .withZoneUTC() .withLocale(session.getLocale()); try { @@ -803,12 +743,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) public static long minuteFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).minuteOfHour().get(timestamp); - } - else { - return MINUTE_OF_HOUR.get(timestamp); - } + return MINUTE_OF_HOUR.get(timestamp); } @Description("minute of the hour of the given timestamp") @@ -824,12 +759,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) public static long minuteFromTime(ConnectorSession session, @SqlType(StandardTypes.TIME) long time) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).minuteOfHour().get(time); - } - else { - return MINUTE_OF_HOUR.get(time); - } + return MINUTE_OF_HOUR.get(time); } @Description("minute of the hour of the given time") @@ -853,12 +783,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) public static long hourFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).hourOfDay().get(timestamp); - } - else { - return HOUR_OF_DAY.get(timestamp); - } + return HOUR_OF_DAY.get(timestamp); } @Description("hour of the day of the given timestamp") @@ -874,12 +799,7 @@ public final class DateTimeFunctions @SqlType(StandardTypes.BIGINT) public static long hourFromTime(ConnectorSession session, @SqlType(StandardTypes.TIME) long time) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).hourOfDay().get(time); - } - else { - return HOUR_OF_DAY.get(time); - } + return HOUR_OF_DAY.get(time); } @Description("hour of the day of the given time") @@ -901,14 +821,9 @@ public final class DateTimeFunctions @Description("day of the week of the given timestamp") @ScalarFunction(value = "day_of_week", alias = "dow") @SqlType(StandardTypes.BIGINT) - public static long dayOfWeekFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long dayOfWeekFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).dayOfWeek().get(timestamp); - } - else { - return DAY_OF_WEEK.get(timestamp); - } + return DAY_OF_WEEK.get(timestamp); } @Description("day of the week of the given timestamp") @@ -930,14 +845,9 @@ public final class DateTimeFunctions @Description("day of the month of the given timestamp") @ScalarFunction(value = "day", alias = "day_of_month") @SqlType(StandardTypes.BIGINT) - public static long dayFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long dayFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).dayOfMonth().get(timestamp); - } - else { - return DAY_OF_MONTH.get(timestamp); - } + return DAY_OF_MONTH.get(timestamp); } @Description("day of the month of the given timestamp") @@ -967,14 +877,9 @@ public final class DateTimeFunctions @Description("day of the year of the given timestamp") @ScalarFunction(value = "day_of_year", alias = "doy") @SqlType(StandardTypes.BIGINT) - public static long dayOfYearFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long dayOfYearFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).dayOfYear().get(timestamp); - } - else { - return DAY_OF_YEAR.get(timestamp); - } + return DAY_OF_YEAR.get(timestamp); } @Description("day of the year of the given timestamp") @@ -996,14 +901,9 @@ public final class DateTimeFunctions @Description("week of the year of the given timestamp") @ScalarFunction(value = "week", alias = "week_of_year") @SqlType(StandardTypes.BIGINT) - public static long weekFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long weekFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).weekOfWeekyear().get(timestamp); - } - else { - return WEEK_OF_YEAR.get(timestamp); - } + return WEEK_OF_YEAR.get(timestamp); } @Description("week of the year of the given timestamp") @@ -1025,14 +925,9 @@ public final class DateTimeFunctions @Description("year of the ISO week of the given timestamp") @ScalarFunction(value = "year_of_week", alias = "yow") @SqlType(StandardTypes.BIGINT) - public static long yearOfWeekFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long yearOfWeekFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).weekyear().get(timestamp); - } - else { - return YEAR_OF_WEEK.get(timestamp); - } + return YEAR_OF_WEEK.get(timestamp); } @Description("year of the ISO week of the given timestamp") @@ -1054,14 +949,9 @@ public final class DateTimeFunctions @Description("month of the year of the given timestamp") @ScalarFunction("month") @SqlType(StandardTypes.BIGINT) - public static long monthFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long monthFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).monthOfYear().get(timestamp); - } - else { - return MONTH_OF_YEAR.get(timestamp); - } + return MONTH_OF_YEAR.get(timestamp); } @Description("month of the year of the given timestamp") @@ -1091,14 +981,9 @@ public final class DateTimeFunctions @Description("quarter of the year of the given timestamp") @ScalarFunction("quarter") @SqlType(StandardTypes.BIGINT) - public static long quarterFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long quarterFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return QUARTER_OF_YEAR.getField(getChronology(session.getTimeZoneKey())).get(timestamp); - } - else { - return QUARTER_OF_YEAR.getField(UTC_CHRONOLOGY).get(timestamp); - } + return QUARTER_OF_YEAR.getField(UTC_CHRONOLOGY).get(timestamp); } @Description("quarter of the year of the given timestamp") @@ -1120,14 +1005,9 @@ public final class DateTimeFunctions @Description("year of the given timestamp") @ScalarFunction("year") @SqlType(StandardTypes.BIGINT) - public static long yearFromTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long timestamp) + public static long yearFromTimestamp(@SqlType(StandardTypes.TIMESTAMP) long timestamp) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).year().get(timestamp); - } - else { - return YEAR.get(timestamp); - } + return YEAR.get(timestamp); } @Description("year of the given timestamp") diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/FormatFunction.java b/presto-main/src/main/java/io/prestosql/operator/scalar/FormatFunction.java index 80860cf4b..794e4d94f 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/FormatFunction.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/FormatFunction.java @@ -197,7 +197,7 @@ public final class FormatFunction return (session, block) -> toZonedDateTime(type.getLong(block, position)); } if (type.equals(TIMESTAMP)) { - return (session, block) -> toLocalDateTime(session, type.getLong(block, position)); + return (session, block) -> toLocalDateTime(type.getLong(block, position)); } if (type.equals(TIME)) { return (session, block) -> toLocalTime(session, type.getLong(block, position)); @@ -266,23 +266,14 @@ public final class FormatFunction return ZonedDateTime.ofInstant(instant, zoneId); } - private static LocalDateTime toLocalDateTime(ConnectorSession session, long value) + private static LocalDateTime toLocalDateTime(long value) { Instant instant = Instant.ofEpochMilli(value); - if (session.isLegacyTimestamp()) { - ZoneId zoneId = ZoneId.of(session.getTimeZoneKey().getId()); - return LocalDateTime.ofInstant(instant, zoneId); - } return LocalDateTime.ofInstant(instant, ZoneOffset.UTC); } private static LocalTime toLocalTime(ConnectorSession session, long value) { - if (session.isLegacyTimestamp()) { - Instant instant = Instant.ofEpochMilli(value); - ZoneId zoneId = ZoneId.of(session.getTimeZoneKey().getId()); - return ZonedDateTime.ofInstant(instant, zoneId).toLocalTime(); - } return LocalTime.ofNanoOfDay(MILLISECONDS.toNanos(value)); } diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/JsonOperators.java b/presto-main/src/main/java/io/prestosql/operator/scalar/JsonOperators.java index ab59f1ffb..f780dbff7 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/JsonOperators.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/JsonOperators.java @@ -337,7 +337,7 @@ public final class JsonOperators try { SliceOutput output = new DynamicSliceOutput(25); try (JsonGenerator jsonGenerator = createJsonGenerator(JSON_FACTORY, output)) { - jsonGenerator.writeString(printTimestampWithoutTimeZone(session.getTimeZoneKey(), value)); + jsonGenerator.writeString(printTimestampWithoutTimeZone(value)); } return output.slice(); } diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/MapToJsonCast.java b/presto-main/src/main/java/io/prestosql/operator/scalar/MapToJsonCast.java index 062e24fc7..92db5b862 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/MapToJsonCast.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/MapToJsonCast.java @@ -23,7 +23,6 @@ import io.prestosql.metadata.FunctionAndTypeManager; import io.prestosql.metadata.SqlOperator; import io.prestosql.spi.annotation.UsedByGeneratedCode; import io.prestosql.spi.block.Block; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.function.BuiltInScalarFunctionImplementation; import io.prestosql.spi.function.OperatorType; import io.prestosql.spi.type.StandardTypes; @@ -54,7 +53,7 @@ public class MapToJsonCast extends SqlOperator { public static final MapToJsonCast MAP_TO_JSON = new MapToJsonCast(); - private static final MethodHandle METHOD_HANDLE = methodHandle(MapToJsonCast.class, "toJson", ObjectKeyProvider.class, JsonGeneratorWriter.class, ConnectorSession.class, Block.class); + private static final MethodHandle METHOD_HANDLE = methodHandle(MapToJsonCast.class, "toJson", ObjectKeyProvider.class, JsonGeneratorWriter.class, Block.class); private MapToJsonCast() { @@ -87,7 +86,7 @@ public class MapToJsonCast } @UsedByGeneratedCode - public static Slice toJson(ObjectKeyProvider provider, JsonGeneratorWriter writer, ConnectorSession session, Block block) + public static Slice toJson(ObjectKeyProvider provider, JsonGeneratorWriter writer, Block block) { try { Map orderedKeyToValuePosition = new TreeMap<>(); @@ -101,7 +100,7 @@ public class MapToJsonCast jsonGenerator.writeStartObject(); for (Map.Entry entry : orderedKeyToValuePosition.entrySet()) { jsonGenerator.writeFieldName(entry.getKey()); - writer.writeJsonValue(jsonGenerator, block, entry.getValue(), session); + writer.writeJsonValue(jsonGenerator, block, entry.getValue()); } jsonGenerator.writeEndObject(); } diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/RowToJsonCast.java b/presto-main/src/main/java/io/prestosql/operator/scalar/RowToJsonCast.java index 5d9c55c1e..99abdc119 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/RowToJsonCast.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/RowToJsonCast.java @@ -23,7 +23,6 @@ import io.prestosql.metadata.FunctionAndTypeManager; import io.prestosql.metadata.SqlOperator; import io.prestosql.spi.annotation.UsedByGeneratedCode; import io.prestosql.spi.block.Block; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.function.BuiltInScalarFunctionImplementation; import io.prestosql.spi.function.OperatorType; import io.prestosql.spi.type.StandardTypes; @@ -53,7 +52,7 @@ public class RowToJsonCast extends SqlOperator { public static final RowToJsonCast ROW_TO_JSON = new RowToJsonCast(); - private static final MethodHandle METHOD_HANDLE = methodHandle(RowToJsonCast.class, "toJson", List.class, ConnectorSession.class, Block.class); + private static final MethodHandle METHOD_HANDLE = methodHandle(RowToJsonCast.class, "toJson", List.class, Block.class); private RowToJsonCast() { @@ -85,14 +84,14 @@ public class RowToJsonCast } @UsedByGeneratedCode - public static Slice toJson(List fieldWriters, ConnectorSession session, Block block) + public static Slice toJson(List fieldWriters, Block block) { try { SliceOutput output = new DynamicSliceOutput(40); try (JsonGenerator jsonGenerator = createJsonGenerator(JSON_FACTORY, output)) { jsonGenerator.writeStartArray(); for (int i = 0; i < block.getPositionCount(); i++) { - fieldWriters.get(i).writeJsonValue(jsonGenerator, block, i, session); + fieldWriters.get(i).writeJsonValue(jsonGenerator, block, i); } jsonGenerator.writeEndArray(); } diff --git a/presto-main/src/main/java/io/prestosql/operator/scalar/SequenceFunction.java b/presto-main/src/main/java/io/prestosql/operator/scalar/SequenceFunction.java index 03bfdbb2b..5273a039c 100644 --- a/presto-main/src/main/java/io/prestosql/operator/scalar/SequenceFunction.java +++ b/presto-main/src/main/java/io/prestosql/operator/scalar/SequenceFunction.java @@ -137,7 +137,7 @@ public final class SequenceFunction int value = 0; for (int i = 0; i < length; ++i) { - BIGINT.writeLong(blockBuilder, DateTimeOperators.timestampPlusIntervalYearToMonth(session, start, value)); + BIGINT.writeLong(blockBuilder, DateTimeOperators.timestampPlusIntervalYearToMonth(start, value)); value += step; } diff --git a/presto-main/src/main/java/io/prestosql/sql/analyzer/ExpressionAnalyzer.java b/presto-main/src/main/java/io/prestosql/sql/analyzer/ExpressionAnalyzer.java index 47da3b6de..108e23ab0 100644 --- a/presto-main/src/main/java/io/prestosql/sql/analyzer/ExpressionAnalyzer.java +++ b/presto-main/src/main/java/io/prestosql/sql/analyzer/ExpressionAnalyzer.java @@ -881,12 +881,7 @@ public class ExpressionAnalyzer protected Type visitTimestampLiteral(TimestampLiteral node, StackableAstVisitorContext context) { try { - if (SystemSessionProperties.isLegacyTimestamp(session)) { - parseTimestampLiteral(session.getTimeZoneKey(), node.getValue()); - } - else { - parseTimestampLiteral(node.getValue()); - } + parseTimestampLiteral(node.getValue()); } catch (Exception e) { throw new SemanticException(INVALID_LITERAL, node, "'%s' is not a valid timestamp literal", node.getValue()); diff --git a/presto-main/src/main/java/io/prestosql/sql/analyzer/FeaturesConfig.java b/presto-main/src/main/java/io/prestosql/sql/analyzer/FeaturesConfig.java index 80bcbe711..94a308851 100644 --- a/presto-main/src/main/java/io/prestosql/sql/analyzer/FeaturesConfig.java +++ b/presto-main/src/main/java/io/prestosql/sql/analyzer/FeaturesConfig.java @@ -57,7 +57,9 @@ import static java.util.concurrent.TimeUnit.MINUTES; "analyzer.experimental-syntax-enabled", "optimizer.processing-optimization", "deprecated.legacy-order-by", - "deprecated.legacy-join-using"}) + "deprecated.legacy-join-using", + "deprecated.legacy-timestamp", +}) public class FeaturesConfig { @VisibleForTesting @@ -92,7 +94,6 @@ public class FeaturesConfig private boolean pushLimitThroughSemiJoin = true; private boolean pushLimitThroughOuterJoin = true; private boolean exchangeCompressionEnabled; - private boolean legacyTimestamp = true; private boolean legacyMapSubscript; private boolean optimizeMixedDistinctAggregations; private boolean unwrapCasts = true; @@ -255,18 +256,6 @@ public class FeaturesConfig return this; } - @Config("deprecated.legacy-timestamp") - public FeaturesConfig setLegacyTimestamp(boolean value) - { - this.legacyTimestamp = value; - return this; - } - - public boolean isLegacyTimestamp() - { - return legacyTimestamp; - } - @Config("deprecated.legacy-map-subscript") public FeaturesConfig setLegacyMapSubscript(boolean value) { diff --git a/presto-main/src/main/java/io/prestosql/sql/planner/LiteralInterpreter.java b/presto-main/src/main/java/io/prestosql/sql/planner/LiteralInterpreter.java index 8a0d5feb7..31beed50a 100644 --- a/presto-main/src/main/java/io/prestosql/sql/planner/LiteralInterpreter.java +++ b/presto-main/src/main/java/io/prestosql/sql/planner/LiteralInterpreter.java @@ -256,24 +256,14 @@ public final class LiteralInterpreter @Override protected Long visitTimeLiteral(TimeLiteral node, ConnectorSession session) { - if (session.isLegacyTimestamp()) { - return parseTimeLiteral(session.getTimeZoneKey(), node.getValue()); - } - else { - return parseTimeLiteral(node.getValue()); - } + return parseTimeLiteral(node.getValue()); } @Override protected Long visitTimestampLiteral(TimestampLiteral node, ConnectorSession session) { try { - if (session.isLegacyTimestamp()) { - return parseTimestampLiteral(session.getTimeZoneKey(), node.getValue()); - } - else { - return parseTimestampLiteral(node.getValue()); - } + return parseTimestampLiteral(node.getValue()); } catch (RuntimeException e) { throw new SemanticException(INVALID_LITERAL, node, "'%s' is not a valid timestamp literal", node.getValue()); diff --git a/presto-main/src/main/java/io/prestosql/sql/relational/SqlToRowExpressionTranslator.java b/presto-main/src/main/java/io/prestosql/sql/relational/SqlToRowExpressionTranslator.java index 39e33d911..f00c18c5a 100644 --- a/presto-main/src/main/java/io/prestosql/sql/relational/SqlToRowExpressionTranslator.java +++ b/presto-main/src/main/java/io/prestosql/sql/relational/SqlToRowExpressionTranslator.java @@ -17,7 +17,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import io.prestosql.Session; -import io.prestosql.SystemSessionProperties; import io.prestosql.metadata.FunctionAndTypeManager; import io.prestosql.operator.scalar.TryFunction; import io.prestosql.spi.function.FunctionKind; @@ -33,7 +32,6 @@ import io.prestosql.spi.type.DecimalParseResult; import io.prestosql.spi.type.Decimals; import io.prestosql.spi.type.RowType; import io.prestosql.spi.type.RowType.Field; -import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import io.prestosql.spi.type.TypeSignature; import io.prestosql.spi.type.UnknownType; @@ -174,8 +172,6 @@ public final class SqlToRowExpressionTranslator types, layout, functionAndTypeManager, - session.getTimeZoneKey(), - SystemSessionProperties.isLegacyTimestamp(session), transactionId); RowExpression result = visitor.process(expression, null); @@ -196,8 +192,6 @@ public final class SqlToRowExpressionTranslator private final Map, Type> types; private final Map layout; private final FunctionAndTypeManager functionAndTypeManager; - private final TimeZoneKey timeZoneKey; - private final boolean isLegacyTimestamp; private final Optional transactionId; private final FunctionResolution functionResolution; @@ -206,16 +200,12 @@ public final class SqlToRowExpressionTranslator Map, Type> types, Map layout, FunctionAndTypeManager functionAndTypeManager, - TimeZoneKey timeZoneKey, - boolean isLegacyTimestamp, Optional transactionId) { this.functionKind = functionKind; this.types = ImmutableMap.copyOf(requireNonNull(types, "types is null")); this.functionAndTypeManager = functionAndTypeManager; this.layout = layout; - this.timeZoneKey = timeZoneKey; - this.isLegacyTimestamp = isLegacyTimestamp; this.transactionId = transactionId; this.functionResolution = new FunctionResolution(functionAndTypeManager); } @@ -345,13 +335,7 @@ public final class SqlToRowExpressionTranslator value = parseTimeWithTimeZone(node.getValue()); } else { - if (isLegacyTimestamp) { - // parse in time zone of client - value = parseTimeWithoutTimeZone(timeZoneKey, node.getValue()); - } - else { - value = parseTimeWithoutTimeZone(node.getValue()); - } + value = parseTimeWithoutTimeZone(node.getValue()); } return constant(value, getType(node)); } @@ -359,13 +343,7 @@ public final class SqlToRowExpressionTranslator @Override protected RowExpression visitTimestampLiteral(TimestampLiteral node, Void context) { - long value; - if (isLegacyTimestamp) { - value = parseTimestampLiteral(timeZoneKey, node.getValue()); - } - else { - value = parseTimestampLiteral(node.getValue()); - } + long value = parseTimestampLiteral(node.getValue()); return constant(value, getType(node)); } diff --git a/presto-main/src/main/java/io/prestosql/testing/DateTimeTestingUtils.java b/presto-main/src/main/java/io/prestosql/testing/DateTimeTestingUtils.java index 5843c3d1e..c99a10bed 100644 --- a/presto-main/src/main/java/io/prestosql/testing/DateTimeTestingUtils.java +++ b/presto-main/src/main/java/io/prestosql/testing/DateTimeTestingUtils.java @@ -13,22 +13,14 @@ */ package io.prestosql.testing; -import io.prestosql.Session; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.type.SqlTime; import io.prestosql.spi.type.SqlTimestamp; -import io.prestosql.spi.type.TimeZoneKey; import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.ZoneId; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; import static java.lang.Math.toIntExact; -import static java.time.ZoneOffset.UTC; import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -44,37 +36,8 @@ public final class DateTimeTestingUtils int hourOfDay, int minuteOfHour, int secondOfMinute, - int millisOfSecond, - Session session) + int millisOfSecond) { - return sqlTimestampOf( - year, - monthOfYear, - dayOfMonth, - hourOfDay, - minuteOfHour, - secondOfMinute, - millisOfSecond, - getDateTimeZone(session.getTimeZoneKey()), - session.getTimeZoneKey(), - session.toConnectorSession()); - } - - public static SqlTimestamp sqlTimestampOf( - int year, - int monthOfYear, - int dayOfMonth, - int hourOfDay, - int minuteOfHour, - int secondOfMinute, - int millisOfSecond, - DateTimeZone baseZone, - TimeZoneKey timestampZone, - ConnectorSession session) - { - if (session.isLegacyTimestamp()) { - return new SqlTimestamp(new DateTime(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, baseZone).getMillis(), timestampZone); - } return sqlTimestampOf(LocalDateTime.of(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisToNanos(millisOfSecond))); } @@ -86,48 +49,28 @@ public final class DateTimeTestingUtils return new SqlTimestamp(DAYS.toMillis(dateTime.toLocalDate().toEpochDay()) + NANOSECONDS.toMillis(dateTime.toLocalTime().toNanoOfDay())); } - public static SqlTimestamp sqlTimestampOf(DateTime dateTime, Session session) + private static SqlTimestamp sqlTimestampOf(DateTime dateTime) { - return sqlTimestampOf(dateTime, session.toConnectorSession()); + return sqlTimestampOf(dateTime.getMillis()); } - private static SqlTimestamp sqlTimestampOf(DateTime dateTime, ConnectorSession session) + public static SqlTimestamp sqlTimestampOf(long millis) { - return sqlTimestampOf(dateTime.getMillis(), session); - } - - public static SqlTimestamp sqlTimestampOf(long millis, ConnectorSession session) - { - if (session.isLegacyTimestamp()) { - return new SqlTimestamp(millis, session.getTimeZoneKey()); - } - else { - return new SqlTimestamp(millis); - } + return new SqlTimestamp(millis); } public static SqlTime sqlTimeOf( int hourOfDay, int minuteOfHour, int secondOfMinute, - int millisOfSecond, - Session session) + int millisOfSecond) { LocalTime time = LocalTime.of(hourOfDay, minuteOfHour, secondOfMinute, millisToNanos(millisOfSecond)); - return sqlTimeOf(time, session); + return sqlTimeOf(time); } - public static SqlTime sqlTimeOf(LocalTime time, Session session) + public static SqlTime sqlTimeOf(LocalTime time) { - if (session.toConnectorSession().isLegacyTimestamp()) { - long millisUtc = LocalDate.ofEpochDay(0) - .atTime(time) - .atZone(UTC) - .withZoneSameLocal(ZoneId.of(session.getTimeZoneKey().getId())) - .toInstant() - .toEpochMilli(); - return new SqlTime(millisUtc, session.getTimeZoneKey()); - } return new SqlTime(NANOSECONDS.toMillis(time.toNanoOfDay())); } diff --git a/presto-main/src/main/java/io/prestosql/testing/MaterializedResult.java b/presto-main/src/main/java/io/prestosql/testing/MaterializedResult.java index a5b0bdd15..662fa26c6 100644 --- a/presto-main/src/main/java/io/prestosql/testing/MaterializedResult.java +++ b/presto-main/src/main/java/io/prestosql/testing/MaterializedResult.java @@ -302,7 +302,7 @@ public class MaterializedResult type.writeLong(blockBuilder, packDateTimeWithZone(millisUtc, timeZoneKey)); } else if (TIMESTAMP.equals(type)) { - long millisUtc = ((SqlTimestamp) value).getMillisUtc(); + long millisUtc = ((SqlTimestamp) value).getMillis(); type.writeLong(blockBuilder, millisUtc); } else if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) { diff --git a/presto-main/src/main/java/io/prestosql/testing/TestingConnectorSession.java b/presto-main/src/main/java/io/prestosql/testing/TestingConnectorSession.java index a3643debf..097f46d63 100644 --- a/presto-main/src/main/java/io/prestosql/testing/TestingConnectorSession.java +++ b/presto-main/src/main/java/io/prestosql/testing/TestingConnectorSession.java @@ -22,7 +22,6 @@ import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.security.ConnectorIdentity; import io.prestosql.spi.session.PropertyMetadata; import io.prestosql.spi.type.TimeZoneKey; -import io.prestosql.sql.analyzer.FeaturesConfig; import java.util.List; import java.util.Locale; @@ -50,7 +49,6 @@ public class TestingConnectorSession private final long startTime; private final Map> properties; private final Map propertyValues; - private final boolean isLegacyTimestamp; public TestingConnectorSession(List> properties) { @@ -59,7 +57,7 @@ public class TestingConnectorSession public TestingConnectorSession(List> properties, Map propertyValues) { - this("user", Optional.of("test"), Optional.empty(), UTC_KEY, ENGLISH, System.currentTimeMillis(), properties, propertyValues, new FeaturesConfig().isLegacyTimestamp()); + this("user", Optional.of("test"), Optional.empty(), UTC_KEY, ENGLISH, System.currentTimeMillis(), properties, propertyValues); } public TestingConnectorSession( @@ -70,8 +68,7 @@ public class TestingConnectorSession Locale locale, long startTime, List> propertyMetadatas, - Map propertyValues, - boolean isLegacyTimestamp) + Map propertyValues) { this.queryId = queryIdGenerator.createNextQueryId().toString(); this.identity = new ConnectorIdentity(requireNonNull(user, "user is null"), Optional.empty(), Optional.empty()); @@ -82,7 +79,6 @@ public class TestingConnectorSession this.startTime = startTime; this.properties = Maps.uniqueIndex(propertyMetadatas, PropertyMetadata::getName); this.propertyValues = ImmutableMap.copyOf(propertyValues); - this.isLegacyTimestamp = isLegacyTimestamp; } @Override @@ -127,12 +123,6 @@ public class TestingConnectorSession return traceToken; } - @Override - public boolean isLegacyTimestamp() - { - return isLegacyTimestamp; - } - @Override public T getProperty(String name, Class type) { diff --git a/presto-main/src/main/java/io/prestosql/type/DateOperators.java b/presto-main/src/main/java/io/prestosql/type/DateOperators.java index e4ff68b0e..a44104a47 100644 --- a/presto-main/src/main/java/io/prestosql/type/DateOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/DateOperators.java @@ -114,17 +114,7 @@ public final class DateOperators @SqlType(StandardTypes.TIMESTAMP) public static long castToTimestamp(ConnectorSession session, @SqlType(StandardTypes.DATE) long value) { - if (session.isLegacyTimestamp()) { - long utcMillis = TimeUnit.DAYS.toMillis(value); - - // date is encoded as milliseconds at midnight in UTC - // convert to midnight in the session timezone - ISOChronology chronology = getChronology(session.getTimeZoneKey()); - return utcMillis - chronology.getZone().getOffset(utcMillis); - } - else { - return TimeUnit.DAYS.toMillis(value); - } + return TimeUnit.DAYS.toMillis(value); } @ScalarOperator(CAST) diff --git a/presto-main/src/main/java/io/prestosql/type/DateTimeOperators.java b/presto-main/src/main/java/io/prestosql/type/DateTimeOperators.java index d8ef6d2ba..3856c9736 100644 --- a/presto-main/src/main/java/io/prestosql/type/DateTimeOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/DateTimeOperators.java @@ -162,26 +162,16 @@ public final class DateTimeOperators @ScalarOperator(ADD) @SqlType(StandardTypes.TIMESTAMP) - public static long timestampPlusIntervalYearToMonth(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right) + public static long timestampPlusIntervalYearToMonth(@SqlType(StandardTypes.TIMESTAMP) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).monthOfYear().add(left, right); - } - else { - return MONTH_OF_YEAR_UTC.add(left, right); - } + return MONTH_OF_YEAR_UTC.add(left, right); } @ScalarOperator(ADD) @SqlType(StandardTypes.TIMESTAMP) - public static long intervalYearToMonthPlusTimestamp(ConnectorSession session, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, @SqlType(StandardTypes.TIMESTAMP) long right) + public static long intervalYearToMonthPlusTimestamp(@SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, @SqlType(StandardTypes.TIMESTAMP) long right) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).monthOfYear().add(right, left); - } - else { - return MONTH_OF_YEAR_UTC.add(right, left); - } + return MONTH_OF_YEAR_UTC.add(right, left); } @ScalarOperator(ADD) @@ -260,14 +250,9 @@ public final class DateTimeOperators @ScalarOperator(SUBTRACT) @SqlType(StandardTypes.TIMESTAMP) - public static long timestampMinusIntervalYearToMonth(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right) + public static long timestampMinusIntervalYearToMonth(@SqlType(StandardTypes.TIMESTAMP) long left, @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right) { - if (session.isLegacyTimestamp()) { - return getChronology(session.getTimeZoneKey()).monthOfYear().add(left, -right); - } - else { - return MONTH_OF_YEAR_UTC.add(left, -right); - } + return MONTH_OF_YEAR_UTC.add(left, -right); } @ScalarOperator(SUBTRACT) diff --git a/presto-main/src/main/java/io/prestosql/type/TimeOperators.java b/presto-main/src/main/java/io/prestosql/type/TimeOperators.java index 240b05c95..ef6b55a9d 100644 --- a/presto-main/src/main/java/io/prestosql/type/TimeOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/TimeOperators.java @@ -118,19 +118,14 @@ public final class TimeOperators @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) public static long castToTimeWithTimeZone(ConnectorSession session, @SqlType(StandardTypes.TIME) long value) { - if (session.isLegacyTimestamp()) { - return packDateTimeWithZone(value, session.getTimeZoneKey()); - } - else { - ISOChronology localChronology = getChronology(session.getTimeZoneKey()); + ISOChronology localChronology = getChronology(session.getTimeZoneKey()); - // This cast does treat TIME as wall time in session TZ. This means that in order to get - // its UTC representation we need to shift the value by the offset of TZ. - // We use value offset in this place to be sure that we will have same hour represented - // in TIME WITH TIME ZONE. Calculating real TZ offset will happen when really required. - // This is done due to inadequate TIME WITH TIME ZONE representation. - return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(value, false), session.getTimeZoneKey()); - } + // This cast does treat TIME as wall time in session TZ. This means that in order to get + // its UTC representation we need to shift the value by the offset of TZ. + // We use value offset in this place to be sure that we will have same hour represented + // in TIME WITH TIME ZONE. Calculating real TZ offset will happen when really required. + // This is done due to inadequate TIME WITH TIME ZONE representation. + return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(value, false), session.getTimeZoneKey()); } @ScalarOperator(CAST) @@ -152,12 +147,7 @@ public final class TimeOperators @SqlType("varchar(x)") public static Slice castToSlice(ConnectorSession session, @SqlType(StandardTypes.TIME) long value) { - if (session.isLegacyTimestamp()) { - return utf8Slice(printTimeWithoutTimeZone(session.getTimeZoneKey(), value)); - } - else { - return utf8Slice(printTimeWithoutTimeZone(value)); - } + return utf8Slice(printTimeWithoutTimeZone(value)); } @ScalarOperator(CAST) @@ -166,12 +156,7 @@ public final class TimeOperators public static long castFromSlice(ConnectorSession session, @SqlType("varchar(x)") Slice value) { try { - if (session.isLegacyTimestamp()) { - return parseTimeWithoutTimeZone(session.getTimeZoneKey(), value.toStringUtf8()); - } - else { - return parseTimeWithoutTimeZone(value.toStringUtf8()); - } + return parseTimeWithoutTimeZone(value.toStringUtf8()); } catch (IllegalArgumentException e) { throw new PrestoException(INVALID_CAST_ARGUMENT, "Value cannot be cast to time: " + value.toStringUtf8(), e); diff --git a/presto-main/src/main/java/io/prestosql/type/TimeWithTimeZoneOperators.java b/presto-main/src/main/java/io/prestosql/type/TimeWithTimeZoneOperators.java index e30917374..efb4a68a9 100644 --- a/presto-main/src/main/java/io/prestosql/type/TimeWithTimeZoneOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/TimeWithTimeZoneOperators.java @@ -16,7 +16,6 @@ package io.prestosql.type; import io.airlift.slice.Slice; import io.airlift.slice.XxHash64; import io.prestosql.spi.block.Block; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.function.BlockIndex; import io.prestosql.spi.function.BlockPosition; import io.prestosql.spi.function.IsNull; @@ -121,29 +120,24 @@ public final class TimeWithTimeZoneOperators @ScalarOperator(CAST) @SqlType(StandardTypes.TIME) - public static long castToTime(ConnectorSession session, @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long value) + public static long castToTime(@SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long value) { // This is exactly the same operation as for TIME WITH TIME ZONE -> TIMESTAMP, as the representations // of those types are aligned in range that is covered by TIME WITH TIME ZONE. - return castToTimestamp(session, value); + return castToTimestamp(value); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIMESTAMP) - public static long castToTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long value) + public static long castToTimestamp(@SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long value) { - if (session.isLegacyTimestamp()) { - return unpackMillisUtc(value); - } - else { - // This is hack that we need to use as the timezone interpretation depends on date (not only on time) - // TODO remove REFERENCE_TIMESTAMP_UTC when removing support for political time zones in TIME WIT TIME ZONE - long currentMillisOfDay = ChronoField.MILLI_OF_DAY.getFrom(Instant.ofEpochMilli(REFERENCE_TIMESTAMP_UTC).atZone(ZoneOffset.UTC)); - long timeMillisUtcInCurrentDay = REFERENCE_TIMESTAMP_UTC - currentMillisOfDay + unpackMillisUtc(value); + // This is hack that we need to use as the timezone interpretation depends on date (not only on time) + // TODO remove REFERENCE_TIMESTAMP_UTC when removing support for political time zones in TIME WIT TIME ZONE + long currentMillisOfDay = ChronoField.MILLI_OF_DAY.getFrom(Instant.ofEpochMilli(REFERENCE_TIMESTAMP_UTC).atZone(ZoneOffset.UTC)); + long timeMillisUtcInCurrentDay = REFERENCE_TIMESTAMP_UTC - currentMillisOfDay + unpackMillisUtc(value); - ISOChronology chronology = getChronology(unpackZoneKey(value)); - return unpackMillisUtc(value) + chronology.getZone().getOffset(timeMillisUtcInCurrentDay); - } + ISOChronology chronology = getChronology(unpackZoneKey(value)); + return unpackMillisUtc(value) + chronology.getZone().getOffset(timeMillisUtcInCurrentDay); } @ScalarOperator(CAST) diff --git a/presto-main/src/main/java/io/prestosql/type/TimestampOperators.java b/presto-main/src/main/java/io/prestosql/type/TimestampOperators.java index f4fdc3e25..ce42e7697 100644 --- a/presto-main/src/main/java/io/prestosql/type/TimestampOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/TimestampOperators.java @@ -122,102 +122,59 @@ public final class TimestampOperators @ScalarFunction("date") @ScalarOperator(CAST) @SqlType(StandardTypes.DATE) - public static long castToDate(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) + public static long castToDate(@SqlType(StandardTypes.TIMESTAMP) long value) { - ISOChronology chronology; - if (session.isLegacyTimestamp()) { - // round down the current timestamp to days - chronology = getChronology(session.getTimeZoneKey()); - long date = chronology.dayOfYear().roundFloor(value); - // date is currently midnight in timezone of the session - // convert to UTC - long millis = date + chronology.getZone().getOffset(date); - return TimeUnit.MILLISECONDS.toDays(millis); - } - else { - return TimeUnit.MILLISECONDS.toDays(value); - } + return TimeUnit.MILLISECONDS.toDays(value); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIME) - public static long castToTime(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) + public static long castToTime(@SqlType(StandardTypes.TIMESTAMP) long value) { - if (session.isLegacyTimestamp()) { - return modulo24Hour(getChronology(session.getTimeZoneKey()), value); - } - else { - return modulo24Hour(value); - } + return modulo24Hour(value); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) public static long castToTimeWithTimeZone(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) { - if (session.isLegacyTimestamp()) { - int timeMillis = modulo24Hour(getChronology(session.getTimeZoneKey()), value); - return packDateTimeWithZone(timeMillis, session.getTimeZoneKey()); - } - else { - ISOChronology localChronology = getChronology(session.getTimeZoneKey()); + ISOChronology localChronology = getChronology(session.getTimeZoneKey()); - // This cast does treat TIMESTAMP as wall time in session TZ. This means that in order to get - // its UTC representation we need to shift the value by the offset of TZ. - return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(modulo24Hour(value), false), session.getTimeZoneKey()); - } + // This cast does treat TIMESTAMP as wall time in session TZ. This means that in order to get + // its UTC representation we need to shift the value by the offset of TZ. + return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(modulo24Hour(value), false), session.getTimeZoneKey()); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) public static long castToTimestampWithTimeZone(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) { - if (session.isLegacyTimestamp()) { - return packDateTimeWithZone(value, session.getTimeZoneKey()); - } - else { - ISOChronology localChronology = getChronology(session.getTimeZoneKey()); + ISOChronology localChronology = getChronology(session.getTimeZoneKey()); - // This cast does treat TIMESTAMP as wall time in session TZ. This means that in order to get - // its UTC representation we need to shift the value by the offset of TZ. - return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(value, false), session.getTimeZoneKey()); - } + // This cast does treat TIMESTAMP as wall time in session TZ. This means that in order to get + // its UTC representation we need to shift the value by the offset of TZ. + return packDateTimeWithZone(localChronology.getZone().convertLocalToUTC(value, false), session.getTimeZoneKey()); } @ScalarOperator(CAST) @LiteralParameters("x") @SqlType("varchar(x)") - public static Slice castToSlice(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP) long value) + public static Slice castToSlice(@SqlType(StandardTypes.TIMESTAMP) long value) { - if (session.isLegacyTimestamp()) { - return utf8Slice(printTimestampWithoutTimeZone(session.getTimeZoneKey(), value)); - } - else { - return utf8Slice(printTimestampWithoutTimeZone(value)); - } + return utf8Slice(printTimestampWithoutTimeZone(value)); } @ScalarOperator(CAST) @LiteralParameters("x") @SqlType(StandardTypes.TIMESTAMP) - public static long castFromSlice(ConnectorSession session, @SqlType("varchar(x)") Slice value) + public static long castFromSlice(@SqlType("varchar(x)") Slice value) { // This accepts value with or without time zone - if (session.isLegacyTimestamp()) { - try { - return parseTimestampWithoutTimeZone(session.getTimeZoneKey(), trim(value).toStringUtf8()); - } - catch (IllegalArgumentException e) { - throw new PrestoException(INVALID_CAST_ARGUMENT, "Value cannot be cast to timestamp: " + value.toStringUtf8(), e); - } + try { + return parseTimestampWithoutTimeZone(trim(value).toStringUtf8()); } - else { - try { - return parseTimestampWithoutTimeZone(trim(value).toStringUtf8()); - } - catch (IllegalArgumentException e) { - throw new PrestoException(INVALID_CAST_ARGUMENT, "Value cannot be cast to timestamp: " + value.toStringUtf8(), e); - } + catch (IllegalArgumentException e) { + throw new PrestoException(INVALID_CAST_ARGUMENT, "Value cannot be cast to timestamp: " + value.toStringUtf8(), e); } } diff --git a/presto-main/src/main/java/io/prestosql/type/TimestampWithTimeZoneOperators.java b/presto-main/src/main/java/io/prestosql/type/TimestampWithTimeZoneOperators.java index 2c8cd7a20..a166aebda 100644 --- a/presto-main/src/main/java/io/prestosql/type/TimestampWithTimeZoneOperators.java +++ b/presto-main/src/main/java/io/prestosql/type/TimestampWithTimeZoneOperators.java @@ -141,48 +141,32 @@ public final class TimestampWithTimeZoneOperators @ScalarOperator(CAST) @SqlType(StandardTypes.TIME) - public static long castToTime(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) + public static long castToTime(@SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) { - if (session.isLegacyTimestamp()) { - return modulo24Hour(unpackChronology(value), unpackMillisUtc(value)); - } - else { - return modulo24Hour(castToTimestamp(session, value)); - } + return modulo24Hour(castToTimestamp(value)); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) - public static long castToTimeWithTimeZone(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) + public static long castToTimeWithTimeZone(@SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) { - if (session.isLegacyTimestamp()) { - int millis = modulo24Hour(unpackChronology(value), unpackMillisUtc(value)); - return packDateTimeWithZone(millis, unpackZoneKey(value)); - } - else { - long millis = modulo24Hour(castToTimestamp(session, value)); - ISOChronology localChronology = unpackChronology(value); + long millis = modulo24Hour(castToTimestamp(value)); + ISOChronology localChronology = unpackChronology(value); - // This cast does treat TIME as wall time in given TZ. This means that in order to get - // its UTC representation we need to shift the value by the offset of TZ. - // We use value offset in this place to be sure that we will have same hour represented - // in TIME WITH TIME ZONE. Calculating real TZ offset will happen when really required. - // This is done due to inadequate TIME WITH TIME ZONE representation. - return packDateTimeWithZone(millis - localChronology.getZone().getOffset(millis), unpackZoneKey(value)); - } + // This cast does treat TIME as wall time in given TZ. This means that in order to get + // its UTC representation we need to shift the value by the offset of TZ. + // We use value offset in this place to be sure that we will have same hour represented + // in TIME WITH TIME ZONE. Calculating real TZ offset will happen when really required. + // This is done due to inadequate TIME WITH TIME ZONE representation. + return packDateTimeWithZone(millis - localChronology.getZone().getOffset(millis), unpackZoneKey(value)); } @ScalarOperator(CAST) @SqlType(StandardTypes.TIMESTAMP) - public static long castToTimestamp(ConnectorSession session, @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) + public static long castToTimestamp(@SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long value) { - if (session.isLegacyTimestamp()) { - return unpackMillisUtc(value); - } - else { - ISOChronology chronology = getChronology(unpackZoneKey(value)); - return chronology.getZone().convertUTCToLocal(unpackMillisUtc(value)); - } + ISOChronology chronology = getChronology(unpackZoneKey(value)); + return chronology.getZone().convertUTCToLocal(unpackMillisUtc(value)); } @ScalarOperator(CAST) diff --git a/presto-main/src/main/java/io/prestosql/util/JsonUtil.java b/presto-main/src/main/java/io/prestosql/util/JsonUtil.java index 99c9a027a..a33dd3203 100644 --- a/presto-main/src/main/java/io/prestosql/util/JsonUtil.java +++ b/presto-main/src/main/java/io/prestosql/util/JsonUtil.java @@ -27,7 +27,6 @@ import io.prestosql.spi.PrestoException; import io.prestosql.spi.block.Block; import io.prestosql.spi.block.BlockBuilder; import io.prestosql.spi.block.SingleRowBlockWriter; -import io.prestosql.spi.connector.ConnectorSession; import io.prestosql.spi.type.ArrayType; import io.prestosql.spi.type.DecimalType; import io.prestosql.spi.type.Decimals; @@ -248,7 +247,7 @@ public final class JsonUtil public interface JsonGeneratorWriter { // write a Json value into the JsonGenerator, provided by block and position - void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException; static JsonGeneratorWriter createJsonGeneratorWriter(Type type) @@ -311,7 +310,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { jsonGenerator.writeNull(); @@ -322,7 +321,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -346,7 +345,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -363,7 +362,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -380,7 +379,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -404,7 +403,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -428,7 +427,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -454,7 +453,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -471,7 +470,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -488,7 +487,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -496,7 +495,7 @@ public final class JsonUtil } else { long value = TIMESTAMP.getLong(block, position); - jsonGenerator.writeString(printTimestampWithoutTimeZone(session.getTimeZoneKey(), value)); + jsonGenerator.writeString(printTimestampWithoutTimeZone(value)); } } } @@ -505,7 +504,7 @@ public final class JsonUtil implements JsonGeneratorWriter { @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -531,7 +530,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -541,7 +540,7 @@ public final class JsonUtil Block arrayBlock = type.getObject(block, position); jsonGenerator.writeStartArray(); for (int i = 0; i < arrayBlock.getPositionCount(); i++) { - elementWriter.writeJsonValue(jsonGenerator, arrayBlock, i, session); + elementWriter.writeJsonValue(jsonGenerator, arrayBlock, i); } jsonGenerator.writeEndArray(); } @@ -563,7 +562,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -580,7 +579,7 @@ public final class JsonUtil jsonGenerator.writeStartObject(); for (Map.Entry entry : orderedKeyToValuePosition.entrySet()) { jsonGenerator.writeFieldName(entry.getKey()); - valueWriter.writeJsonValue(jsonGenerator, mapBlock, entry.getValue(), session); + valueWriter.writeJsonValue(jsonGenerator, mapBlock, entry.getValue()); } jsonGenerator.writeEndObject(); } @@ -600,7 +599,7 @@ public final class JsonUtil } @Override - public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position, ConnectorSession session) + public void writeJsonValue(JsonGenerator jsonGenerator, Block block, int position) throws IOException { if (block.isNull(position)) { @@ -610,7 +609,7 @@ public final class JsonUtil Block rowBlock = type.getObject(block, position); jsonGenerator.writeStartArray(); for (int i = 0; i < rowBlock.getPositionCount(); i++) { - fieldWriters.get(i).writeJsonValue(jsonGenerator, rowBlock, i, session); + fieldWriters.get(i).writeJsonValue(jsonGenerator, rowBlock, i); } jsonGenerator.writeEndArray(); } diff --git a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctions.java b/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctions.java index eefee05f7..028c80d66 100644 --- a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctions.java +++ b/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctions.java @@ -16,20 +16,66 @@ package io.prestosql.operator.scalar; import io.prestosql.Session; import io.prestosql.spi.type.TimeType; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.TimestampType; +import io.prestosql.testing.TestingSession; import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalTime; +import java.time.OffsetTime; +import java.time.ZoneOffset; + import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static io.prestosql.spi.type.VarcharType.createVarcharType; +import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; +import static io.prestosql.testing.TestingSession.testSessionBuilder; public class TestDateTimeFunctions - extends TestDateTimeFunctionsBase + extends AbstractTestFunctions { + protected static final TimeZoneKey TIME_ZONE_KEY = TestingSession.DEFAULT_TIME_ZONE_KEY; + protected static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); + protected static final DateTimeZone UTC_TIME_ZONE = getDateTimeZone(UTC_KEY); + protected static final DateTimeZone DATE_TIME_ZONE_NUMERICAL = getDateTimeZone(getTimeZoneKey("-11:00")); + protected static final TimeZoneKey KATHMANDU_ZONE_KEY = getTimeZoneKey("Asia/Kathmandu"); + protected static final DateTimeZone KATHMANDU_ZONE = getDateTimeZone(KATHMANDU_ZONE_KEY); + protected static final ZoneOffset WEIRD_ZONE = ZoneOffset.ofHoursMinutes(7, 9); + protected static final DateTimeZone WEIRD_DATE_TIME_ZONE = DateTimeZone.forID(WEIRD_ZONE.getId()); + + protected static final DateTime DATE = new DateTime(2001, 8, 22, 0, 0, 0, 0, DateTimeZone.UTC); + protected static final String DATE_LITERAL = "DATE '2001-08-22'"; + protected static final String DATE_ISO8601_STRING = "2001-08-22"; + + protected static final LocalTime TIME = LocalTime.of(3, 4, 5, 321_000_000); + protected static final String TIME_LITERAL = "TIME '03:04:05.321'"; + protected static final OffsetTime WEIRD_TIME = OffsetTime.of(3, 4, 5, 321_000_000, WEIRD_ZONE); + protected static final String WEIRD_TIME_LITERAL = "TIME '03:04:05.321 +07:09'"; + + protected static final DateTime TIMESTAMP = new DateTime(2001, 8, 22, 3, 4, 5, 321, UTC_TIME_ZONE); // This is TIMESTAMP w/o TZ + protected static final DateTime TIMESTAMP_WITH_NUMERICAL_ZONE = new DateTime(2001, 8, 22, 3, 4, 5, 321, DATE_TIME_ZONE_NUMERICAL); + protected static final String TIMESTAMP_LITERAL = "TIMESTAMP '2001-08-22 03:04:05.321'"; + protected static final String TIMESTAMP_ISO8601_STRING = "2001-08-22T03:04:05.321-11:00"; + protected static final String TIMESTAMP_ISO8601_STRING_NO_TIME_ZONE = "2001-08-22T03:04:05.321"; + protected static final DateTime WEIRD_TIMESTAMP = new DateTime(2001, 8, 22, 3, 4, 5, 321, WEIRD_DATE_TIME_ZONE); + protected static final String WEIRD_TIMESTAMP_LITERAL = "TIMESTAMP '2001-08-22 03:04:05.321 +07:09'"; + protected static final String WEIRD_TIMESTAMP_ISO8601_STRING = "2001-08-22T03:04:05.321+07:09"; + + protected static final String INTERVAL_LITERAL = "INTERVAL '90061.234' SECOND"; + protected static final Duration DAY_TO_SECOND_INTERVAL = Duration.ofMillis(90061234); + public TestDateTimeFunctions() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(TIME_ZONE_KEY) + .setStartTime(Instant.ofEpochMilli(new DateTime(2017, 4, 1, 12, 34, 56, 789, UTC_TIME_ZONE).getMillis()).getEpochSecond()) + .build()); } @Test @@ -67,7 +113,7 @@ public class TestDateTimeFunctions .setStartTime(new DateTime(2017, 3, 1, 15, 45, 0, 0, KATHMANDU_ZONE).getMillis()) .build(); try (FunctionAssertions localAssertion = new FunctionAssertions(localSession)) { - localAssertion.assertFunctionString("CURRENT_TIME", TIME_WITH_TIME_ZONE, "15:45:00.000 Asia/Kathmandu"); + localAssertion.assertFunctionString("CURRENT_TIME", TIME_WITH_TIME_ZONE, "15:30:00.000 Asia/Kathmandu"); } } diff --git a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsBase.java b/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsBase.java deleted file mode 100644 index 130a606f7..000000000 --- a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsBase.java +++ /dev/null @@ -1,1220 +0,0 @@ -/* - * 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 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 io.prestosql.operator.scalar; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.prestosql.Session; -import io.prestosql.spi.StandardErrorCode; -import io.prestosql.spi.type.BigintType; -import io.prestosql.spi.type.DateType; -import io.prestosql.spi.type.SqlDate; -import io.prestosql.spi.type.SqlTime; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeType; -import io.prestosql.spi.type.TimeZoneKey; -import io.prestosql.spi.type.TimestampType; -import io.prestosql.spi.type.Type; -import io.prestosql.testing.TestingConnectorSession; -import io.prestosql.testing.TestingSession; -import io.prestosql.type.SqlIntervalDayTime; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Hours; -import org.joda.time.Minutes; -import org.joda.time.ReadableInstant; -import org.joda.time.Seconds; -import org.joda.time.chrono.ISOChronology; -import org.testng.annotations.Test; - -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.OffsetTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.util.Locale; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import static io.prestosql.SystemSessionProperties.isLegacyTimestamp; -import static io.prestosql.operator.scalar.DateTimeFunctions.currentDate; -import static io.prestosql.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; -import static io.prestosql.spi.type.BigintType.BIGINT; -import static io.prestosql.spi.type.DoubleType.DOUBLE; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.type.VarcharType.createVarcharType; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; -import static java.lang.Math.toIntExact; -import static java.lang.String.format; -import static java.time.temporal.ChronoField.MILLI_OF_SECOND; -import static java.util.Locale.US; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.HOURS; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.joda.time.DateTimeUtils.getInstantChronology; -import static org.joda.time.Days.daysBetween; -import static org.joda.time.DurationFieldType.millis; -import static org.joda.time.Months.monthsBetween; -import static org.joda.time.Weeks.weeksBetween; -import static org.joda.time.Years.yearsBetween; -import static org.testng.Assert.assertEquals; - -public abstract class TestDateTimeFunctionsBase - extends AbstractTestFunctions -{ - protected static final TimeZoneKey TIME_ZONE_KEY = TestingSession.DEFAULT_TIME_ZONE_KEY; - protected static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - protected static final DateTimeZone UTC_TIME_ZONE = getDateTimeZone(UTC_KEY); - protected static final DateTimeZone DATE_TIME_ZONE_NUMERICAL = getDateTimeZone(getTimeZoneKey("-11:00")); - protected static final TimeZoneKey KATHMANDU_ZONE_KEY = getTimeZoneKey("Asia/Kathmandu"); - protected static final DateTimeZone KATHMANDU_ZONE = getDateTimeZone(KATHMANDU_ZONE_KEY); - protected static final ZoneOffset WEIRD_ZONE = ZoneOffset.ofHoursMinutes(7, 9); - protected static final DateTimeZone WEIRD_DATE_TIME_ZONE = DateTimeZone.forID(WEIRD_ZONE.getId()); - - protected static final DateTime DATE = new DateTime(2001, 8, 22, 0, 0, 0, 0, DateTimeZone.UTC); - protected static final String DATE_LITERAL = "DATE '2001-08-22'"; - protected static final String DATE_ISO8601_STRING = "2001-08-22"; - - protected static final LocalTime TIME = LocalTime.of(3, 4, 5, 321_000_000); - protected static final String TIME_LITERAL = "TIME '03:04:05.321'"; - protected static final OffsetTime WEIRD_TIME = OffsetTime.of(3, 4, 5, 321_000_000, WEIRD_ZONE); - protected static final String WEIRD_TIME_LITERAL = "TIME '03:04:05.321 +07:09'"; - - protected static final DateTime NEW_TIMESTAMP = new DateTime(2001, 8, 22, 3, 4, 5, 321, UTC_TIME_ZONE); // This is TIMESTAMP w/o TZ - protected static final DateTime LEGACY_TIMESTAMP = new DateTime(2001, 8, 22, 3, 4, 5, 321, DATE_TIME_ZONE); - protected static final DateTime TIMESTAMP_WITH_NUMERICAL_ZONE = new DateTime(2001, 8, 22, 3, 4, 5, 321, DATE_TIME_ZONE_NUMERICAL); - protected static final String TIMESTAMP_LITERAL = "TIMESTAMP '2001-08-22 03:04:05.321'"; - protected static final String TIMESTAMP_ISO8601_STRING = "2001-08-22T03:04:05.321-11:00"; - protected static final String TIMESTAMP_ISO8601_STRING_NO_TIME_ZONE = "2001-08-22T03:04:05.321"; - protected static final DateTime WEIRD_TIMESTAMP = new DateTime(2001, 8, 22, 3, 4, 5, 321, WEIRD_DATE_TIME_ZONE); - protected static final String WEIRD_TIMESTAMP_LITERAL = "TIMESTAMP '2001-08-22 03:04:05.321 +07:09'"; - protected static final String WEIRD_TIMESTAMP_ISO8601_STRING = "2001-08-22T03:04:05.321+07:09"; - - protected static final String INTERVAL_LITERAL = "INTERVAL '90061.234' SECOND"; - protected static final Duration DAY_TO_SECOND_INTERVAL = Duration.ofMillis(90061234); - - @SuppressWarnings("MemberName") - private final DateTime TIMESTAMP; - - protected TestDateTimeFunctionsBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(TIME_ZONE_KEY) - .setStartTime(new DateTime(2017, 4, 1, 12, 34, 56, 789, UTC_TIME_ZONE).getMillis()) - .build()); - TIMESTAMP = legacyTimestamp ? LEGACY_TIMESTAMP : NEW_TIMESTAMP; - } - - @Test - public void testCurrentDate() - { - // current date is the time at midnight in the session time zone - assertFunction("CURRENT_DATE", DateType.DATE, new SqlDate(toIntExact(epochDaysInZone(TIME_ZONE_KEY, session.getStartTime())))); - } - - @Test - public void testCurrentDateTimezone() - { - TimeZoneKey kievTimeZoneKey = getTimeZoneKey("Europe/Kiev"); - TimeZoneKey bahiaBanderasTimeZoneKey = getTimeZoneKey("America/Bahia_Banderas"); // The zone has 'gap' on 1970-01-01 - TimeZoneKey montrealTimeZoneKey = getTimeZoneKey("America/Montreal"); - long timeIncrement = TimeUnit.MINUTES.toMillis(53); - // We expect UTC millis later on so we have to use UTC chronology - for (long instant = ISOChronology.getInstanceUTC().getDateTimeMillis(2000, 6, 15, 0, 0, 0, 0); - instant < ISOChronology.getInstanceUTC().getDateTimeMillis(2016, 6, 15, 0, 0, 0, 0); - instant += timeIncrement) { - assertCurrentDateAtInstant(kievTimeZoneKey, instant); - assertCurrentDateAtInstant(bahiaBanderasTimeZoneKey, instant); - assertCurrentDateAtInstant(montrealTimeZoneKey, instant); - assertCurrentDateAtInstant(TIME_ZONE_KEY, instant); - } - } - - private void assertCurrentDateAtInstant(TimeZoneKey timeZoneKey, long instant) - { - long expectedDays = epochDaysInZone(timeZoneKey, instant); - long dateTimeCalculation = currentDate(new TestingConnectorSession("test", Optional.empty(), Optional.empty(), timeZoneKey, US, instant, ImmutableList.of(), ImmutableMap.of(), isLegacyTimestamp(session))); - assertEquals(dateTimeCalculation, expectedDays); - } - - private static long epochDaysInZone(TimeZoneKey timeZoneKey, long instant) - { - return LocalDate.from(Instant.ofEpochMilli(instant).atZone(ZoneId.of(timeZoneKey.getId()))).toEpochDay(); - } - - @Test - public void testFromUnixTime() - { - DateTime dateTime = new DateTime(2001, 1, 22, 3, 4, 5, 0, DATE_TIME_ZONE); - double seconds = dateTime.getMillis() / 1000.0; - assertFunction("from_unixtime(" + seconds + ")", TimestampType.TIMESTAMP, sqlTimestampOf(dateTime, session)); - - dateTime = new DateTime(2001, 1, 22, 3, 4, 5, 888, DATE_TIME_ZONE); - seconds = dateTime.getMillis() / 1000.0; - assertFunction("from_unixtime(" + seconds + ")", TimestampType.TIMESTAMP, sqlTimestampOf(dateTime, session)); - } - - @Test - public void testFromUnixTimeWithOffset() - { - DateTime dateTime = new DateTime(2001, 1, 22, 3, 4, 5, 0, DATE_TIME_ZONE); - double seconds = dateTime.getMillis() / 1000.0; - - int timeZoneHoursOffset = 1; - int timezoneMinutesOffset = 10; - - DateTime expected = new DateTime(dateTime, getDateTimeZone(getTimeZoneKeyForOffset((timeZoneHoursOffset * 60L) + timezoneMinutesOffset))); - assertFunction("from_unixtime(" + seconds + ", " + timeZoneHoursOffset + ", " + timezoneMinutesOffset + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - // test invalid minute offsets - assertInvalidFunction("from_unixtime(0, 1, 10000)", INVALID_FUNCTION_ARGUMENT); - assertInvalidFunction("from_unixtime(0, 10000, 0)", INVALID_FUNCTION_ARGUMENT); - assertInvalidFunction("from_unixtime(0, -100, 100)", INVALID_FUNCTION_ARGUMENT); - } - - @Test - public void testFromUnixTimeWithTimeZone() - { - String zoneId = "Asia/Shanghai"; - DateTime expected = new DateTime(1970, 1, 1, 10, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - zoneId = "Asia/Tokyo"; - expected = new DateTime(1970, 1, 1, 11, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - zoneId = "Europe/Moscow"; - expected = new DateTime(1970, 1, 1, 5, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - zoneId = "America/New_York"; - expected = new DateTime(1969, 12, 31, 21, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - zoneId = "America/Chicago"; - expected = new DateTime(1969, 12, 31, 20, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - - zoneId = "America/Los_Angeles"; - expected = new DateTime(1969, 12, 31, 18, 0, 0, DateTimeZone.forID(zoneId)); - assertFunction(format("from_unixtime(7200, '%s')", zoneId), TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(expected)); - } - - @Test - public void testToUnixTime() - { - assertFunction("to_unixtime(" + TIMESTAMP_LITERAL + ")", DOUBLE, TIMESTAMP.getMillis() / 1000.0); - assertFunction("to_unixtime(" + WEIRD_TIMESTAMP_LITERAL + ")", DOUBLE, WEIRD_TIMESTAMP.getMillis() / 1000.0); - } - - @Test - public void testDate() - { - assertFunction("date('" + DATE_ISO8601_STRING + "')", DateType.DATE, toDate(DATE)); - assertFunction("date(" + WEIRD_TIMESTAMP_LITERAL + ")", DateType.DATE, toDate(DATE)); - assertFunction("date(" + TIMESTAMP_LITERAL + ")", DateType.DATE, toDate(DATE)); - } - - @Test - public void testFromISO8601() - { - assertFunction("from_iso8601_timestamp('" + TIMESTAMP_ISO8601_STRING + "')", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(TIMESTAMP_WITH_NUMERICAL_ZONE)); - assertFunction("from_iso8601_timestamp('" + WEIRD_TIMESTAMP_ISO8601_STRING + "')", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP)); - assertFunction("from_iso8601_date('" + DATE_ISO8601_STRING + "')", DateType.DATE, toDate(DATE)); - } - - @Test - public void testToIso8601() - { - assertFunction("to_iso8601(" + WEIRD_TIMESTAMP_LITERAL + ")", createVarcharType(35), WEIRD_TIMESTAMP_ISO8601_STRING); - assertFunction("to_iso8601(" + DATE_LITERAL + ")", createVarcharType(16), DATE_ISO8601_STRING); - } - - @Test - public void testTimeZone() - { - assertFunction("hour(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getHourOfDay()); - assertFunction("minute(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMinuteOfHour()); - assertFunction("hour(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getHourOfDay()); - assertFunction("minute(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMinuteOfHour()); - assertFunction("current_timezone()", VARCHAR, TIME_ZONE_KEY.getId()); - } - - @Test - public void testPartFunctions() - { - assertFunction("millisecond(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMillisOfSecond()); - assertFunction("second(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getSecondOfMinute()); - assertFunction("minute(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMinuteOfHour()); - assertFunction("hour(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getHourOfDay()); - assertFunction("day_of_week(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.dayOfWeek().get()); - assertFunction("dow(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.dayOfWeek().get()); - assertFunction("day(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfMonth()); - assertFunction("day_of_month(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfMonth()); - assertFunction("day_of_year(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.dayOfYear().get()); - assertFunction("doy(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.dayOfYear().get()); - assertFunction("week(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.weekOfWeekyear().get()); - assertFunction("week_of_year(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.weekOfWeekyear().get()); - assertFunction("month(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMonthOfYear()); - assertFunction("quarter(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMonthOfYear() / 4 + 1); - assertFunction("year(" + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getYear()); - assertFunction("timezone_minute(" + TIMESTAMP_LITERAL + ")", BIGINT, 0L); - assertFunction("timezone_hour(" + TIMESTAMP_LITERAL + ")", BIGINT, -11L); - - assertFunction("timezone_hour(localtimestamp)", BIGINT, 14L); - assertFunction("timezone_hour(current_timestamp)", BIGINT, 14L); - - assertFunction("millisecond(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMillisOfSecond()); - assertFunction("second(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getSecondOfMinute()); - assertFunction("minute(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMinuteOfHour()); - assertFunction("hour(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getHourOfDay()); - assertFunction("day_of_week(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.dayOfWeek().get()); - assertFunction("dow(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.dayOfWeek().get()); - assertFunction("day(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfMonth()); - assertFunction("day_of_month(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfMonth()); - assertFunction("day_of_year(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.dayOfYear().get()); - assertFunction("doy(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.dayOfYear().get()); - assertFunction("week(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.weekOfWeekyear().get()); - assertFunction("week_of_year(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.weekOfWeekyear().get()); - assertFunction("month(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMonthOfYear()); - assertFunction("quarter(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMonthOfYear() / 4 + 1); - assertFunction("year(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getYear()); - assertFunction("timezone_minute(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, 9L); - assertFunction("timezone_hour(" + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, 7L); - - assertFunction("millisecond(" + TIME_LITERAL + ")", BIGINT, TIME.getLong(MILLI_OF_SECOND)); - assertFunction("second(" + TIME_LITERAL + ")", BIGINT, (long) TIME.getSecond()); - assertFunction("minute(" + TIME_LITERAL + ")", BIGINT, (long) TIME.getMinute()); - assertFunction("hour(" + TIME_LITERAL + ")", BIGINT, (long) TIME.getHour()); - - assertFunction("millisecond(" + WEIRD_TIME_LITERAL + ")", BIGINT, WEIRD_TIME.getLong(MILLI_OF_SECOND)); - assertFunction("second(" + WEIRD_TIME_LITERAL + ")", BIGINT, (long) WEIRD_TIME.getSecond()); - assertFunction("minute(" + WEIRD_TIME_LITERAL + ")", BIGINT, (long) WEIRD_TIME.getMinute()); - assertFunction("hour(" + WEIRD_TIME_LITERAL + ")", BIGINT, (long) WEIRD_TIME.getHour()); - - assertFunction("millisecond(" + INTERVAL_LITERAL + ")", BIGINT, (long) DAY_TO_SECOND_INTERVAL.getNano() / 1_000_000); - assertFunction("second(" + INTERVAL_LITERAL + ")", BIGINT, DAY_TO_SECOND_INTERVAL.getSeconds() % 60); - assertFunction("minute(" + INTERVAL_LITERAL + ")", BIGINT, DAY_TO_SECOND_INTERVAL.getSeconds() / 60 % 60); - assertFunction("hour(" + INTERVAL_LITERAL + ")", BIGINT, DAY_TO_SECOND_INTERVAL.getSeconds() / 3600 % 24); - } - - @Test - public void testYearOfWeek() - { - assertFunction("year_of_week(DATE '2001-08-22')", BIGINT, 2001L); - assertFunction("yow(DATE '2001-08-22')", BIGINT, 2001L); - assertFunction("year_of_week(DATE '2005-01-02')", BIGINT, 2004L); - assertFunction("year_of_week(DATE '2008-12-28')", BIGINT, 2008L); - assertFunction("year_of_week(DATE '2008-12-29')", BIGINT, 2009L); - assertFunction("year_of_week(DATE '2009-12-31')", BIGINT, 2009L); - assertFunction("year_of_week(DATE '2010-01-03')", BIGINT, 2009L); - assertFunction("year_of_week(TIMESTAMP '2001-08-22 03:04:05.321 +07:09')", BIGINT, 2001L); - assertFunction("year_of_week(TIMESTAMP '2010-01-03 03:04:05.321')", BIGINT, 2009L); - } - - @Test - public void testExtractFromTimestamp() - { - assertFunction("extract(second FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getSecondOfMinute()); - assertFunction("extract(minute FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMinuteOfHour()); - assertFunction("extract(hour FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getHourOfDay()); - assertFunction("extract(day_of_week FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfWeek()); - assertFunction("extract(dow FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfWeek()); - assertFunction("extract(day FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfMonth()); - assertFunction("extract(day_of_month FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfMonth()); - assertFunction("extract(day_of_year FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfYear()); - assertFunction("extract(year_of_week FROM " + TIMESTAMP_LITERAL + ")", BIGINT, 2001L); - assertFunction("extract(doy FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getDayOfYear()); - assertFunction("extract(week FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getWeekOfWeekyear()); - assertFunction("extract(month FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMonthOfYear()); - assertFunction("extract(quarter FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getMonthOfYear() / 4 + 1); - assertFunction("extract(year FROM " + TIMESTAMP_LITERAL + ")", BIGINT, (long) TIMESTAMP.getYear()); - - assertFunction("extract(second FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getSecondOfMinute()); - assertFunction("extract(minute FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMinuteOfHour()); - assertFunction("extract(hour FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getHourOfDay()); - assertFunction("extract(day_of_week FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfWeek()); - assertFunction("extract(dow FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfWeek()); - assertFunction("extract(day FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfMonth()); - assertFunction("extract(day_of_month FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfMonth()); - assertFunction("extract(day_of_year FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfYear()); - assertFunction("extract(doy FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getDayOfYear()); - assertFunction("extract(week FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getWeekOfWeekyear()); - assertFunction("extract(month FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMonthOfYear()); - assertFunction("extract(quarter FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getMonthOfYear() / 4 + 1); - assertFunction("extract(year FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, (long) WEIRD_TIMESTAMP.getYear()); - assertFunction("extract(timezone_minute FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, 9L); - assertFunction("extract(timezone_hour FROM " + WEIRD_TIMESTAMP_LITERAL + ")", BIGINT, 7L); - } - - @Test - public void testExtractFromTime() - { - assertFunction("extract(second FROM " + TIME_LITERAL + ")", BIGINT, 5L); - assertFunction("extract(minute FROM " + TIME_LITERAL + ")", BIGINT, 4L); - assertFunction("extract(hour FROM " + TIME_LITERAL + ")", BIGINT, 3L); - - assertFunction("extract(second FROM " + WEIRD_TIME_LITERAL + ")", BIGINT, 5L); - assertFunction("extract(minute FROM " + WEIRD_TIME_LITERAL + ")", BIGINT, 4L); - assertFunction("extract(hour FROM " + WEIRD_TIME_LITERAL + ")", BIGINT, 3L); - } - - @Test - public void testExtractFromDate() - { - assertFunction("extract(day_of_week FROM " + DATE_LITERAL + ")", BIGINT, 3L); - assertFunction("extract(dow FROM " + DATE_LITERAL + ")", BIGINT, 3L); - assertFunction("extract(day FROM " + DATE_LITERAL + ")", BIGINT, 22L); - assertFunction("extract(day_of_month FROM " + DATE_LITERAL + ")", BIGINT, 22L); - assertFunction("extract(day_of_year FROM " + DATE_LITERAL + ")", BIGINT, 234L); - assertFunction("extract(doy FROM " + DATE_LITERAL + ")", BIGINT, 234L); - assertFunction("extract(year_of_week FROM " + DATE_LITERAL + ")", BIGINT, 2001L); - assertFunction("extract(yow FROM " + DATE_LITERAL + ")", BIGINT, 2001L); - assertFunction("extract(week FROM " + DATE_LITERAL + ")", BIGINT, 34L); - assertFunction("extract(month FROM " + DATE_LITERAL + ")", BIGINT, 8L); - assertFunction("extract(quarter FROM " + DATE_LITERAL + ")", BIGINT, 3L); - assertFunction("extract(year FROM " + DATE_LITERAL + ")", BIGINT, 2001L); - - assertFunction("extract(quarter FROM DATE '2001-01-01')", BIGINT, 1L); - assertFunction("extract(quarter FROM DATE '2001-03-31')", BIGINT, 1L); - assertFunction("extract(quarter FROM DATE '2001-04-01')", BIGINT, 2L); - assertFunction("extract(quarter FROM DATE '2001-06-30')", BIGINT, 2L); - assertFunction("extract(quarter FROM DATE '2001-07-01')", BIGINT, 3L); - assertFunction("extract(quarter FROM DATE '2001-09-30')", BIGINT, 3L); - assertFunction("extract(quarter FROM DATE '2001-10-01')", BIGINT, 4L); - assertFunction("extract(quarter FROM DATE '2001-12-31')", BIGINT, 4L); - - assertFunction("extract(quarter FROM TIMESTAMP '2001-01-01 00:00:00.000')", BIGINT, 1L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-03-31 23:59:59.999')", BIGINT, 1L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-04-01 00:00:00.000')", BIGINT, 2L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-06-30 23:59:59.999')", BIGINT, 2L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-07-01 00:00:00.000')", BIGINT, 3L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-09-30 23:59:59.999')", BIGINT, 3L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-10-01 00:00:00.000')", BIGINT, 4L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-12-31 23:59:59.999')", BIGINT, 4L); - - assertFunction("extract(quarter FROM TIMESTAMP '2001-01-01 00:00:00.000 +06:00')", BIGINT, 1L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-03-31 23:59:59.999 +06:00')", BIGINT, 1L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-04-01 00:00:00.000 +06:00')", BIGINT, 2L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-06-30 23:59:59.999 +06:00')", BIGINT, 2L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-07-01 00:00:00.000 +06:00')", BIGINT, 3L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-09-30 23:59:59.999 +06:00')", BIGINT, 3L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-10-01 00:00:00.000 +06:00')", BIGINT, 4L); - assertFunction("extract(quarter FROM TIMESTAMP '2001-12-31 23:59:59.999 +06:00')", BIGINT, 4L); - } - - @Test - public void testExtractFromInterval() - { - assertFunction("extract(second FROM INTERVAL '5' SECOND)", BIGINT, 5L); - assertFunction("extract(second FROM INTERVAL '65' SECOND)", BIGINT, 5L); - - assertFunction("extract(minute FROM INTERVAL '4' MINUTE)", BIGINT, 4L); - assertFunction("extract(minute FROM INTERVAL '64' MINUTE)", BIGINT, 4L); - assertFunction("extract(minute FROM INTERVAL '247' SECOND)", BIGINT, 4L); - - assertFunction("extract(hour FROM INTERVAL '3' HOUR)", BIGINT, 3L); - assertFunction("extract(hour FROM INTERVAL '27' HOUR)", BIGINT, 3L); - assertFunction("extract(hour FROM INTERVAL '187' MINUTE)", BIGINT, 3L); - - assertFunction("extract(day FROM INTERVAL '2' DAY)", BIGINT, 2L); - assertFunction("extract(day FROM INTERVAL '55' HOUR)", BIGINT, 2L); - - assertFunction("extract(month FROM INTERVAL '3' MONTH)", BIGINT, 3L); - assertFunction("extract(month FROM INTERVAL '15' MONTH)", BIGINT, 3L); - - assertFunction("extract(year FROM INTERVAL '2' YEAR)", BIGINT, 2L); - assertFunction("extract(year FROM INTERVAL '29' MONTH)", BIGINT, 2L); - } - - @Test - public void testTruncateTimestamp() - { - DateTime result = TIMESTAMP; - result = result.withMillisOfSecond(0); - assertFunction("date_trunc('second', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withSecondOfMinute(0); - assertFunction("date_trunc('minute', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withMinuteOfHour(0); - assertFunction("date_trunc('hour', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withHourOfDay(0); - assertFunction("date_trunc('day', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withDayOfMonth(20); - assertFunction("date_trunc('week', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withDayOfMonth(1); - assertFunction("date_trunc('month', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withMonthOfYear(7); - assertFunction("date_trunc('quarter', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = result.withMonthOfYear(1); - assertFunction("date_trunc('year', " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(result, session)); - - result = WEIRD_TIMESTAMP; - result = result.withMillisOfSecond(0); - assertFunction("date_trunc('second', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withSecondOfMinute(0); - assertFunction("date_trunc('minute', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withMinuteOfHour(0); - assertFunction("date_trunc('hour', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withHourOfDay(0); - assertFunction("date_trunc('day', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withDayOfMonth(20); - assertFunction("date_trunc('week', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withDayOfMonth(1); - assertFunction("date_trunc('month', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withMonthOfYear(7); - assertFunction("date_trunc('quarter', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - - result = result.withMonthOfYear(1); - assertFunction("date_trunc('year', " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(result)); - } - - @Test - public void testTruncateTime() - { - LocalTime result = TIME; - result = result.withNano(0); - assertFunction("date_trunc('second', " + TIME_LITERAL + ")", TimeType.TIME, toTime(result)); - - result = result.withSecond(0); - assertFunction("date_trunc('minute', " + TIME_LITERAL + ")", TimeType.TIME, toTime(result)); - - result = result.withMinute(0); - assertFunction("date_trunc('hour', " + TIME_LITERAL + ")", TimeType.TIME, toTime(result)); - } - - @Test - public void testTruncateTimeWithTimeZone() - { - OffsetTime result = WEIRD_TIME; - result = result.withNano(0); - assertFunction("date_trunc('second', " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(result)); - - result = result.withSecond(0); - assertFunction("date_trunc('minute', " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(result)); - - result = result.withMinute(0); - assertFunction("date_trunc('hour', " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(result)); - } - - @Test - public void testTruncateDate() - { - DateTime result = DATE; - assertFunction("date_trunc('day', " + DATE_LITERAL + ")", DateType.DATE, toDate(result)); - - result = result.withDayOfMonth(20); - assertFunction("date_trunc('week', " + DATE_LITERAL + ")", DateType.DATE, toDate(result)); - - result = result.withDayOfMonth(1); - assertFunction("date_trunc('month', " + DATE_LITERAL + ")", DateType.DATE, toDate(result)); - - result = result.withMonthOfYear(7); - assertFunction("date_trunc('quarter', " + DATE_LITERAL + ")", DateType.DATE, toDate(result)); - - result = result.withMonthOfYear(1); - assertFunction("date_trunc('year', " + DATE_LITERAL + ")", DateType.DATE, toDate(result)); - } - - @Test - public void testAddFieldToTimestamp() - { - assertFunction("date_add('millisecond', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusMillis(3), session)); - assertFunction("date_add('second', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusSeconds(3), session)); - assertFunction("date_add('minute', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusMinutes(3), session)); - assertFunction("date_add('hour', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusHours(3), session)); - assertFunction("date_add('hour', 23, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusHours(23), session)); - assertFunction("date_add('hour', -4, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.minusHours(4), session)); - assertFunction("date_add('hour', -23, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.minusHours(23), session)); - assertFunction("date_add('day', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusDays(3), session)); - assertFunction("date_add('week', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusWeeks(3), session)); - assertFunction("date_add('month', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusMonths(3), session)); - assertFunction("date_add('quarter', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusMonths(3 * 3), session)); - assertFunction("date_add('year', 3, " + TIMESTAMP_LITERAL + ")", TimestampType.TIMESTAMP, sqlTimestampOf(TIMESTAMP.plusYears(3), session)); - - assertFunction("date_add('millisecond', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusMillis(3))); - assertFunction("date_add('second', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusSeconds(3))); - assertFunction("date_add('minute', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusMinutes(3))); - assertFunction("date_add('hour', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusHours(3))); - assertFunction("date_add('day', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusDays(3))); - assertFunction("date_add('week', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusWeeks(3))); - assertFunction("date_add('month', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusMonths(3))); - assertFunction("date_add('quarter', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusMonths(3 * 3))); - assertFunction("date_add('year', 3, " + WEIRD_TIMESTAMP_LITERAL + ")", TIMESTAMP_WITH_TIME_ZONE, toTimestampWithTimeZone(WEIRD_TIMESTAMP.plusYears(3))); - } - - @Test - public void testAddFieldToDate() - { - assertFunction("date_add('day', 0, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE)); - assertFunction("date_add('day', 3, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE.plusDays(3))); - assertFunction("date_add('week', 3, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE.plusWeeks(3))); - assertFunction("date_add('month', 3, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE.plusMonths(3))); - assertFunction("date_add('quarter', 3, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE.plusMonths(3 * 3))); - assertFunction("date_add('year', 3, " + DATE_LITERAL + ")", DateType.DATE, toDate(DATE.plusYears(3))); - } - - @Test - public void testAddFieldToTime() - { - assertFunction("date_add('millisecond', 0, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME)); - assertFunction("date_add('millisecond', 3, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.plusNanos(3_000_000))); - assertFunction("date_add('second', 3, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.plusSeconds(3))); - assertFunction("date_add('minute', 3, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.plusMinutes(3))); - assertFunction("date_add('hour', 3, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.plusHours(3))); - assertFunction("date_add('hour', 23, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.plusHours(23))); - assertFunction("date_add('hour', -4, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.minusHours(4))); - assertFunction("date_add('hour', -23, " + TIME_LITERAL + ")", TimeType.TIME, toTime(TIME.minusHours(23))); - } - - @Test - public void testAddFieldToTimeWithTimeZone() - { - assertFunction("date_add('millisecond', 3, " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(WEIRD_TIME.plusNanos(3_000_000))); - assertFunction("date_add('second', 3, " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(WEIRD_TIME.plusSeconds(3))); - assertFunction("date_add('minute', 3, " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(WEIRD_TIME.plusMinutes(3))); - assertFunction("date_add('hour', 3, " + WEIRD_TIME_LITERAL + ")", TIME_WITH_TIME_ZONE, toTimeWithTimeZone(WEIRD_TIME.plusHours(3))); - } - - @Test - public void testDateDiffTimestamp() - { - DateTime baseDateTime = new DateTime(1960, 5, 3, 7, 2, 9, 678, isLegacyTimestamp(session) ? DATE_TIME_ZONE : UTC_TIME_ZONE); - String baseDateTimeLiteral = "TIMESTAMP '1960-05-03 07:02:09.678'"; - - assertFunction("date_diff('millisecond', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, millisBetween(baseDateTime, TIMESTAMP)); - assertFunction("date_diff('second', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) secondsBetween(baseDateTime, TIMESTAMP).getSeconds()); - assertFunction("date_diff('minute', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) minutesBetween(baseDateTime, TIMESTAMP).getMinutes()); - assertFunction("date_diff('hour', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) hoursBetween(baseDateTime, TIMESTAMP).getHours()); - assertFunction("date_diff('day', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) daysBetween(baseDateTime, TIMESTAMP).getDays()); - assertFunction("date_diff('week', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) weeksBetween(baseDateTime, TIMESTAMP).getWeeks()); - assertFunction("date_diff('month', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) monthsBetween(baseDateTime, TIMESTAMP).getMonths()); - assertFunction("date_diff('quarter', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) monthsBetween(baseDateTime, TIMESTAMP).getMonths() / 3); - assertFunction("date_diff('year', " + baseDateTimeLiteral + ", " + TIMESTAMP_LITERAL + ")", BIGINT, (long) yearsBetween(baseDateTime, TIMESTAMP).getYears()); - - DateTime weirdBaseDateTime = new DateTime(1960, 5, 3, 7, 2, 9, 678, WEIRD_DATE_TIME_ZONE); - String weirdBaseDateTimeLiteral = "TIMESTAMP '1960-05-03 07:02:09.678 +07:09'"; - - assertFunction("date_diff('millisecond', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - millisBetween(weirdBaseDateTime, WEIRD_TIMESTAMP)); - assertFunction("date_diff('second', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) secondsBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getSeconds()); - assertFunction("date_diff('minute', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) minutesBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getMinutes()); - assertFunction("date_diff('hour', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) hoursBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getHours()); - assertFunction("date_diff('day', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) daysBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getDays()); - assertFunction("date_diff('week', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) weeksBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getWeeks()); - assertFunction("date_diff('month', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) monthsBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getMonths()); - assertFunction("date_diff('quarter', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) monthsBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getMonths() / 3); - assertFunction("date_diff('year', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIMESTAMP_LITERAL + ")", - BIGINT, - (long) yearsBetween(weirdBaseDateTime, WEIRD_TIMESTAMP).getYears()); - } - - @Test - public void testDateDiffDate() - { - DateTime baseDateTime = new DateTime(1960, 5, 3, 0, 0, 0, 0, DateTimeZone.UTC); - String baseDateTimeLiteral = "DATE '1960-05-03'"; - - assertFunction("date_diff('day', " + baseDateTimeLiteral + ", " + DATE_LITERAL + ")", BIGINT, (long) daysBetween(baseDateTime, DATE).getDays()); - assertFunction("date_diff('week', " + baseDateTimeLiteral + ", " + DATE_LITERAL + ")", BIGINT, (long) weeksBetween(baseDateTime, DATE).getWeeks()); - assertFunction("date_diff('month', " + baseDateTimeLiteral + ", " + DATE_LITERAL + ")", BIGINT, (long) monthsBetween(baseDateTime, DATE).getMonths()); - assertFunction("date_diff('quarter', " + baseDateTimeLiteral + ", " + DATE_LITERAL + ")", BIGINT, (long) monthsBetween(baseDateTime, DATE).getMonths() / 3); - assertFunction("date_diff('year', " + baseDateTimeLiteral + ", " + DATE_LITERAL + ")", BIGINT, (long) yearsBetween(baseDateTime, DATE).getYears()); - } - - @Test - public void testDateDiffTime() - { - LocalTime baseDateTime = LocalTime.of(7, 2, 9, 678_000_000); - String baseDateTimeLiteral = "TIME '07:02:09.678'"; - - assertFunction("date_diff('millisecond', " + baseDateTimeLiteral + ", " + TIME_LITERAL + ")", BIGINT, millisBetween(baseDateTime, TIME)); - assertFunction("date_diff('second', " + baseDateTimeLiteral + ", " + TIME_LITERAL + ")", BIGINT, secondsBetween(baseDateTime, TIME)); - assertFunction("date_diff('minute', " + baseDateTimeLiteral + ", " + TIME_LITERAL + ")", BIGINT, minutesBetween(baseDateTime, TIME)); - assertFunction("date_diff('hour', " + baseDateTimeLiteral + ", " + TIME_LITERAL + ")", BIGINT, hoursBetween(baseDateTime, TIME)); - } - - @Test - public void testDateDiffTimeWithTimeZone() - { - OffsetTime weirdBaseDateTime = OffsetTime.of(7, 2, 9, 678_000_000, WEIRD_ZONE); - String weirdBaseDateTimeLiteral = "TIME '07:02:09.678 +07:09'"; - - assertFunction("date_diff('millisecond', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIME_LITERAL + ")", BIGINT, millisBetween(weirdBaseDateTime, WEIRD_TIME)); - assertFunction("date_diff('second', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIME_LITERAL + ")", BIGINT, secondsBetween(weirdBaseDateTime, WEIRD_TIME)); - assertFunction("date_diff('minute', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIME_LITERAL + ")", BIGINT, minutesBetween(weirdBaseDateTime, WEIRD_TIME)); - assertFunction("date_diff('hour', " + weirdBaseDateTimeLiteral + ", " + WEIRD_TIME_LITERAL + ")", BIGINT, hoursBetween(weirdBaseDateTime, WEIRD_TIME)); - } - - @Test - public void testParseDatetime() - { - assertFunction("parse_datetime('1960/01/22 03:04', 'YYYY/MM/DD HH:mm')", - TIMESTAMP_WITH_TIME_ZONE, - toTimestampWithTimeZone(new DateTime(1960, 1, 22, 3, 4, 0, 0, DATE_TIME_ZONE))); - assertFunction("parse_datetime('1960/01/22 03:04 Asia/Oral', 'YYYY/MM/DD HH:mm ZZZZZ')", - TIMESTAMP_WITH_TIME_ZONE, - toTimestampWithTimeZone(new DateTime(1960, 1, 22, 3, 4, 0, 0, DateTimeZone.forID("Asia/Oral")))); - assertFunction("parse_datetime('1960/01/22 03:04 +0500', 'YYYY/MM/DD HH:mm Z')", - TIMESTAMP_WITH_TIME_ZONE, - toTimestampWithTimeZone(new DateTime(1960, 1, 22, 3, 4, 0, 0, DateTimeZone.forOffsetHours(5)))); - } - - @Test - public void testFormatDatetime() - { - assertFunction("format_datetime(" + TIMESTAMP_LITERAL + ", 'YYYY/MM/dd HH:mm')", VARCHAR, "2001/08/22 03:04"); - assertFunction("format_datetime(" + WEIRD_TIMESTAMP_LITERAL + ", 'YYYY/MM/dd HH:mm')", VARCHAR, "2001/08/22 03:04"); - assertFunction("format_datetime(" + WEIRD_TIMESTAMP_LITERAL + ", 'YYYY/MM/dd HH:mm ZZZZ')", VARCHAR, "2001/08/22 03:04 +07:09"); - } - - @Test - public void testDateFormat() - { - String dateTimeLiteral = "TIMESTAMP '2001-01-09 13:04:05.321'"; - - assertFunction("date_format(" + dateTimeLiteral + ", '%a')", VARCHAR, "Tue"); - assertFunction("date_format(" + dateTimeLiteral + ", '%b')", VARCHAR, "Jan"); - assertFunction("date_format(" + dateTimeLiteral + ", '%c')", VARCHAR, "1"); - assertFunction("date_format(" + dateTimeLiteral + ", '%d')", VARCHAR, "09"); - assertFunction("date_format(" + dateTimeLiteral + ", '%e')", VARCHAR, "9"); - assertFunction("date_format(" + dateTimeLiteral + ", '%f')", VARCHAR, "321000"); - assertFunction("date_format(" + dateTimeLiteral + ", '%H')", VARCHAR, "13"); - assertFunction("date_format(" + dateTimeLiteral + ", '%h')", VARCHAR, "01"); - assertFunction("date_format(" + dateTimeLiteral + ", '%I')", VARCHAR, "01"); - assertFunction("date_format(" + dateTimeLiteral + ", '%i')", VARCHAR, "04"); - assertFunction("date_format(" + dateTimeLiteral + ", '%j')", VARCHAR, "009"); - assertFunction("date_format(" + dateTimeLiteral + ", '%k')", VARCHAR, "13"); - assertFunction("date_format(" + dateTimeLiteral + ", '%l')", VARCHAR, "1"); - assertFunction("date_format(" + dateTimeLiteral + ", '%M')", VARCHAR, "January"); - assertFunction("date_format(" + dateTimeLiteral + ", '%m')", VARCHAR, "01"); - assertFunction("date_format(" + dateTimeLiteral + ", '%p')", VARCHAR, "PM"); - assertFunction("date_format(" + dateTimeLiteral + ", '%r')", VARCHAR, "01:04:05 PM"); - assertFunction("date_format(" + dateTimeLiteral + ", '%S')", VARCHAR, "05"); - assertFunction("date_format(" + dateTimeLiteral + ", '%s')", VARCHAR, "05"); - assertFunction("date_format(" + dateTimeLiteral + ", '%T')", VARCHAR, "13:04:05"); - assertFunction("date_format(" + dateTimeLiteral + ", '%v')", VARCHAR, "02"); - assertFunction("date_format(" + dateTimeLiteral + ", '%W')", VARCHAR, "Tuesday"); - assertFunction("date_format(" + dateTimeLiteral + ", '%Y')", VARCHAR, "2001"); - assertFunction("date_format(" + dateTimeLiteral + ", '%y')", VARCHAR, "01"); - assertFunction("date_format(" + dateTimeLiteral + ", '%%')", VARCHAR, "%"); - assertFunction("date_format(" + dateTimeLiteral + ", 'foo')", VARCHAR, "foo"); - assertFunction("date_format(" + dateTimeLiteral + ", '%g')", VARCHAR, "g"); - assertFunction("date_format(" + dateTimeLiteral + ", '%4')", VARCHAR, "4"); - assertFunction("date_format(" + dateTimeLiteral + ", '%x %v')", VARCHAR, "2001 02"); - assertFunction("date_format(" + dateTimeLiteral + ", '%Y年%m月%d日')", VARCHAR, "2001年01月09日"); - - String weirdDateTimeLiteral = "TIMESTAMP '2001-01-09 13:04:05.321 +07:09'"; - - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%a')", VARCHAR, "Tue"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%b')", VARCHAR, "Jan"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%c')", VARCHAR, "1"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%d')", VARCHAR, "09"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%e')", VARCHAR, "9"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%f')", VARCHAR, "321000"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%H')", VARCHAR, "13"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%h')", VARCHAR, "01"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%I')", VARCHAR, "01"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%i')", VARCHAR, "04"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%j')", VARCHAR, "009"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%k')", VARCHAR, "13"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%l')", VARCHAR, "1"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%M')", VARCHAR, "January"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%m')", VARCHAR, "01"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%p')", VARCHAR, "PM"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%r')", VARCHAR, "01:04:05 PM"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%S')", VARCHAR, "05"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%s')", VARCHAR, "05"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%T')", VARCHAR, "13:04:05"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%v')", VARCHAR, "02"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%W')", VARCHAR, "Tuesday"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%Y')", VARCHAR, "2001"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%y')", VARCHAR, "01"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%%')", VARCHAR, "%"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", 'foo')", VARCHAR, "foo"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%g')", VARCHAR, "g"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%4')", VARCHAR, "4"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%x %v')", VARCHAR, "2001 02"); - assertFunction("date_format(" + weirdDateTimeLiteral + ", '%Y年%m月%d日')", VARCHAR, "2001年01月09日"); - - assertFunction("date_format(TIMESTAMP '2001-01-09 13:04:05.32', '%f')", VARCHAR, "320000"); - assertFunction("date_format(TIMESTAMP '2001-01-09 00:04:05.32', '%k')", VARCHAR, "0"); - - assertInvalidFunction("date_format(DATE '2001-01-09', '%D')", "%D not supported in date format string"); - assertInvalidFunction("date_format(DATE '2001-01-09', '%U')", "%U not supported in date format string"); - assertInvalidFunction("date_format(DATE '2001-01-09', '%u')", "%u not supported in date format string"); - assertInvalidFunction("date_format(DATE '2001-01-09', '%V')", "%V not supported in date format string"); - assertInvalidFunction("date_format(DATE '2001-01-09', '%w')", "%w not supported in date format string"); - assertInvalidFunction("date_format(DATE '2001-01-09', '%X')", "%X not supported in date format string"); - } - - @Test - public void testDateParse() - { - assertFunction("date_parse('2013', '%Y')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 1, 1, 0, 0, 0, 0, session)); - assertFunction("date_parse('2013-05', '%Y-%m')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 1, 0, 0, 0, 0, session)); - assertFunction("date_parse('2013-05-17', '%Y-%m-%d')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 0, 0, 0, 0, session)); - assertFunction("date_parse('2013-05-17 12:35:10', '%Y-%m-%d %h:%i:%s')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 0, 35, 10, 0, session)); - assertFunction("date_parse('2013-05-17 12:35:10 PM', '%Y-%m-%d %h:%i:%s %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 12, 35, 10, 0, session)); - assertFunction("date_parse('2013-05-17 12:35:10 AM', '%Y-%m-%d %h:%i:%s %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 0, 35, 10, 0, session)); - - assertFunction("date_parse('2013-05-17 00:35:10', '%Y-%m-%d %H:%i:%s')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 0, 35, 10, 0, session)); - assertFunction("date_parse('2013-05-17 23:35:10', '%Y-%m-%d %H:%i:%s')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 23, 35, 10, 0, session)); - assertFunction("date_parse('abc 2013-05-17 fff 23:35:10 xyz', 'abc %Y-%m-%d fff %H:%i:%s xyz')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 23, 35, 10, 0, session)); - - assertFunction("date_parse('2013 14', '%Y %y')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2014, 1, 1, 0, 0, 0, 0, session)); - - assertFunction("date_parse('1998 53', '%x %v')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1998, 12, 28, 0, 0, 0, 0, session)); - - assertFunction("date_parse('1.1', '%s.%f')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 100, session)); - assertFunction("date_parse('1.01', '%s.%f')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 10, session)); - assertFunction("date_parse('1.2006', '%s.%f')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 200, session)); - assertFunction("date_parse('59.123456789', '%s.%f')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 59, 123, session)); - - assertFunction("date_parse('0', '%k')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 0, 0, session)); - - assertFunction("date_parse('28-JAN-16 11.45.46.421000 PM','%d-%b-%y %l.%i.%s.%f %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2016, 1, 28, 23, 45, 46, 421, session)); - assertFunction("date_parse('11-DEC-70 11.12.13.456000 AM','%d-%b-%y %l.%i.%s.%f %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(1970, 12, 11, 11, 12, 13, 456, session)); - assertFunction("date_parse('31-MAY-69 04.59.59.999000 AM','%d-%b-%y %l.%i.%s.%f %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2069, 5, 31, 4, 59, 59, 999, session)); - - assertInvalidFunction("date_parse('', '%D')", "%D not supported in date format string"); - assertInvalidFunction("date_parse('', '%U')", "%U not supported in date format string"); - assertInvalidFunction("date_parse('', '%u')", "%u not supported in date format string"); - assertInvalidFunction("date_parse('', '%V')", "%V not supported in date format string"); - assertInvalidFunction("date_parse('', '%w')", "%w not supported in date format string"); - assertInvalidFunction("date_parse('', '%X')", "%X not supported in date format string"); - - assertInvalidFunction("date_parse('3.0123456789', '%s.%f')", "Invalid format: \"3.0123456789\" is malformed at \"9\""); - assertInvalidFunction("date_parse('1970-01-01', '')", "Both printing and parsing not supported"); - } - - @Test - public void testLocale() - { - Locale locale = Locale.KOREAN; - Session localeSession = Session.builder(this.session) - .setTimeZoneKey(TIME_ZONE_KEY) - .setLocale(locale) - .build(); - - try (FunctionAssertions localeAssertions = new FunctionAssertions(localeSession)) { - String dateTimeLiteral = "TIMESTAMP '2001-01-09 13:04:05.321'"; - - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%a')", VARCHAR, "화"); - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%W')", VARCHAR, "화요일"); - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%p')", VARCHAR, "오후"); - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%r')", VARCHAR, "01:04:05 오후"); - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%b')", VARCHAR, "1월"); - localeAssertions.assertFunction("date_format(" + dateTimeLiteral + ", '%M')", VARCHAR, "1월"); - - localeAssertions.assertFunction("format_datetime(" + dateTimeLiteral + ", 'EEE')", VARCHAR, "화"); - localeAssertions.assertFunction("format_datetime(" + dateTimeLiteral + ", 'EEEE')", VARCHAR, "화요일"); - localeAssertions.assertFunction("format_datetime(" + dateTimeLiteral + ", 'a')", VARCHAR, "오후"); - localeAssertions.assertFunction("format_datetime(" + dateTimeLiteral + ", 'MMM')", VARCHAR, "1월"); - localeAssertions.assertFunction("format_datetime(" + dateTimeLiteral + ", 'MMMM')", VARCHAR, "1월"); - - localeAssertions.assertFunction("date_parse('2013-05-17 12:35:10 오후', '%Y-%m-%d %h:%i:%s %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 12, 35, 10, 0, localeSession)); - localeAssertions.assertFunction("date_parse('2013-05-17 12:35:10 오전', '%Y-%m-%d %h:%i:%s %p')", - TimestampType.TIMESTAMP, - sqlTimestampOf(2013, 5, 17, 0, 35, 10, 0, localeSession)); - - localeAssertions.assertFunction("parse_datetime('2013-05-17 12:35:10 오후', 'yyyy-MM-dd hh:mm:ss a')", - TIMESTAMP_WITH_TIME_ZONE, - toTimestampWithTimeZone(new DateTime(2013, 5, 17, 12, 35, 10, 0, DATE_TIME_ZONE))); - localeAssertions.assertFunction("parse_datetime('2013-05-17 12:35:10 오전', 'yyyy-MM-dd hh:mm:ss aaa')", - TIMESTAMP_WITH_TIME_ZONE, - toTimestampWithTimeZone(new DateTime(2013, 5, 17, 0, 35, 10, 0, DATE_TIME_ZONE))); - } - } - - @Test - public void testDateTimeOutputString() - { - // SqlDate - assertFunctionString("date '2012-12-31'", DateType.DATE, "2012-12-31"); - assertFunctionString("date '0000-12-31'", DateType.DATE, "0000-12-31"); - assertFunctionString("date '0000-09-23'", DateType.DATE, "0000-09-23"); - assertFunctionString("date '0001-10-25'", DateType.DATE, "0001-10-25"); - assertFunctionString("date '1560-04-29'", DateType.DATE, "1560-04-29"); - - // SqlTime - assertFunctionString("time '00:00:00'", TimeType.TIME, "00:00:00.000"); - assertFunctionString("time '01:02:03'", TimeType.TIME, "01:02:03.000"); - assertFunctionString("time '23:23:23.233'", TimeType.TIME, "23:23:23.233"); - assertFunctionString("time '23:59:59.999'", TimeType.TIME, "23:59:59.999"); - - // SqlTimeWithTimeZone - assertFunctionString("time '00:00:00 UTC'", TIME_WITH_TIME_ZONE, "00:00:00.000 UTC"); - assertFunctionString("time '01:02:03 Asia/Shanghai'", TIME_WITH_TIME_ZONE, "01:02:03.000 Asia/Shanghai"); - assertFunctionString("time '23:23:23.233 America/Los_Angeles'", TIME_WITH_TIME_ZONE, "23:23:23.233 America/Los_Angeles"); - assertFunctionString(WEIRD_TIME_LITERAL, TIME_WITH_TIME_ZONE, "03:04:05.321 +07:09"); - assertFunctionString("time '23:59:59.999 Asia/Kathmandu'", TIME_WITH_TIME_ZONE, "23:59:59.999 Asia/Kathmandu"); - - // SqlTimestamp - assertFunctionString("timestamp '0000-01-02 01:02:03'", TimestampType.TIMESTAMP, "0000-01-02 01:02:03.000"); - assertFunctionString("timestamp '2012-12-31 00:00:00'", TimestampType.TIMESTAMP, "2012-12-31 00:00:00.000"); - assertFunctionString("timestamp '1234-05-06 23:23:23.233'", TimestampType.TIMESTAMP, "1234-05-06 23:23:23.233"); - assertFunctionString("timestamp '2333-02-23 23:59:59.999'", TimestampType.TIMESTAMP, "2333-02-23 23:59:59.999"); - - // SqlTimestampWithTimeZone - assertFunctionString("timestamp '2012-12-31 00:00:00 UTC'", TIMESTAMP_WITH_TIME_ZONE, "2012-12-31 00:00:00.000 UTC"); - assertFunctionString("timestamp '0000-01-02 01:02:03 Asia/Shanghai'", TIMESTAMP_WITH_TIME_ZONE, "0000-01-02 01:02:03.000 Asia/Shanghai"); - assertFunctionString("timestamp '1234-05-06 23:23:23.233 America/Los_Angeles'", TIMESTAMP_WITH_TIME_ZONE, "1234-05-06 23:23:23.233 America/Los_Angeles"); - assertFunctionString("timestamp '2333-02-23 23:59:59.999 Asia/Tokyo'", TIMESTAMP_WITH_TIME_ZONE, "2333-02-23 23:59:59.999 Asia/Tokyo"); - } - - @Test - public void testTimeWithTimeZoneAtTimeZone() - { - // this test does use hidden at_timezone function as it is equivalent of using SQL syntax AT TIME ZONE - // but our test framework doesn't support that syntax directly. - - Session oldKathmanduTimeZoneOffsetSession = - Session.builder(this.session) - .setTimeZoneKey(TIME_ZONE_KEY) - .setStartTime(new DateTime(1980, 1, 1, 10, 0, 0, DATE_TIME_ZONE).getMillis()) - .build(); - - TimeZoneKey europeWarsawTimeZoneKey = getTimeZoneKey("Europe/Warsaw"); - DateTimeZone europeWarsawTimeZone = getDateTimeZone(europeWarsawTimeZoneKey); - Session europeWarsawSessionWinter = - Session.builder(this.session) - .setTimeZoneKey(europeWarsawTimeZoneKey) - .setStartTime(new DateTime(2017, 1, 1, 10, 0, 0, europeWarsawTimeZone).getMillis()) - .build(); - try (FunctionAssertions europeWarsawAssertionsWinter = new FunctionAssertions(europeWarsawSessionWinter); - FunctionAssertions oldKathmanduTimeZoneOffsetAssertions = new FunctionAssertions(oldKathmanduTimeZoneOffsetSession)) { - long millisTenOClockWarsawWinter = new DateTime(1970, 1, 1, 9, 0, 0, 0, UTC_TIME_ZONE).getMillis(); - - // Simple shift to UTC - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', 'UTC')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, UTC_KEY)); - - // Simple shift to fixed TZ - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', '+00:45')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, getTimeZoneKey("+00:45"))); - - // Simple shift to geographical TZ - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', 'America/New_York')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, getTimeZoneKey("America/New_York"))); - - // No shift but different time zone - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', 'Europe/Berlin')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, getTimeZoneKey("Europe/Berlin"))); - - // Noop on UTC - assertFunction("at_timezone(TIME '10:00 UTC', 'UTC')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 10, 0, 0, 0, UTC_TIME_ZONE).getMillis(), TimeZoneKey.UTC_KEY)); - - // Noop on other TZ - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', 'Europe/Warsaw')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, europeWarsawTimeZoneKey)); - - // Noop on other TZ on different session TZ - assertFunction("at_timezone(TIME '10:00 Europe/Warsaw', 'Europe/Warsaw')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(millisTenOClockWarsawWinter, europeWarsawTimeZoneKey)); - - // Shift through days back - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '2:00 Europe/Warsaw', 'America/New_York')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 20, 0, 0, 0, getDateTimeZone(getTimeZoneKey("America/New_York"))).getMillis(), getTimeZoneKey("America/New_York"))); - - // Shift through days forward - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '22:00 America/New_York', 'Europe/Warsaw')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 4, 0, 0, 0, europeWarsawTimeZone).getMillis(), europeWarsawTimeZoneKey)); - - // Shift backward on min value - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '00:00 +14:00', '+13:00')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 23, 0, 0, 0, getDateTimeZone(getTimeZoneKey("+13:00"))).getMillis(), getTimeZoneKey("+13:00"))); - - // Shift backward on min value - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '00:00 +14:00', '-14:00')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 20, 0, 0, 0, getDateTimeZone(getTimeZoneKey("-14:00"))).getMillis(), getTimeZoneKey("-14:00"))); - - // Shift backward on max value - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '23:59:59.999 +14:00', '+13:00')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 22, 59, 59, 999, getDateTimeZone(getTimeZoneKey("+13:00"))).getMillis(), getTimeZoneKey("+13:00"))); - - // Shift forward on max value - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '23:59:59.999 +14:00', '-14:00')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 19, 59, 59, 999, getDateTimeZone(getTimeZoneKey("-14:00"))).getMillis(), getTimeZoneKey("-14:00"))); - - // Asia/Kathmandu used +5:30 TZ until 1986 and than switched to +5:45 - // This test checks if we do use offset of time zone valid currently and not the historical one - assertFunction("at_timezone(TIME '10:00 Asia/Kathmandu', 'UTC')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 4, 15, 0, 0, UTC_TIME_ZONE).getMillis(), TimeZoneKey.UTC_KEY)); - - // Noop when time zone doesn't change - TimeZoneKey kabul = TimeZoneKey.getTimeZoneKey("Asia/Kabul"); - assertFunction("at_timezone(TIME '10:00 Asia/Kabul', 'Asia/Kabul')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 10, 0, 0, 0, getDateTimeZone(kabul)).getMillis(), kabul)); - - // This test checks if the TZ offset isn't calculated on other fixed point in time by checking if - // session started in 1980 would get historical Asia/Kathmandu offset. - oldKathmanduTimeZoneOffsetAssertions.assertFunction("at_timezone(TIME '10:00 Asia/Kathmandu', 'UTC')", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 4, 30, 0, 0, UTC_TIME_ZONE).getMillis(), TimeZoneKey.UTC_KEY)); - - // Check simple interval shift - europeWarsawAssertionsWinter.assertFunction("at_timezone(TIME '10:00 +01:00', INTERVAL '2' HOUR)", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 11, 0, 0, 0, getDateTimeZone(getTimeZoneKey("+02:00"))).getMillis(), getTimeZoneKey("+02:00"))); - - // Check to high interval shift - europeWarsawAssertionsWinter.assertInvalidFunction("at_timezone(TIME '10:00 +01:00', INTERVAL '60' HOUR)", - StandardErrorCode.INVALID_FUNCTION_ARGUMENT, - "Invalid offset minutes 3600"); - } - } - - @Test - public void testParseDuration() - { - assertFunction("parse_duration('1234 ns')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 0)); - assertFunction("parse_duration('1234 us')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 1)); - assertFunction("parse_duration('1234 ms')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1, 234)); - assertFunction("parse_duration('1234 s')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 20, 34, 0)); - assertFunction("parse_duration('1234 m')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 20, 34, 0, 0)); - assertFunction("parse_duration('1234 h')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(51, 10, 0, 0, 0)); - assertFunction("parse_duration('1234 d')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(1234, 0, 0, 0, 0)); - assertFunction("parse_duration('1234.567 ns')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 0)); - assertFunction("parse_duration('1234.567 ms')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1, 235)); - assertFunction("parse_duration('1234.567 s')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1234, 567)); - assertFunction("parse_duration('1234.567 m')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 20, 34, 34, 20)); - assertFunction("parse_duration('1234.567 h')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(51, 10, 34, 1, 200)); - assertFunction("parse_duration('1234.567 d')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(1234, 13, 36, 28, 800)); - - // without space - assertFunction("parse_duration('1234ns')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 0)); - assertFunction("parse_duration('1234us')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 1)); - assertFunction("parse_duration('1234ms')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1, 234)); - assertFunction("parse_duration('1234s')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 20, 34, 0)); - assertFunction("parse_duration('1234m')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 20, 34, 0, 0)); - assertFunction("parse_duration('1234h')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(51, 10, 0, 0, 0)); - assertFunction("parse_duration('1234d')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(1234, 0, 0, 0, 0)); - assertFunction("parse_duration('1234.567ns')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 0, 0)); - assertFunction("parse_duration('1234.567ms')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1, 235)); - assertFunction("parse_duration('1234.567s')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 0, 0, 1234, 567)); - assertFunction("parse_duration('1234.567m')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(0, 20, 34, 34, 20)); - assertFunction("parse_duration('1234.567h')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(51, 10, 34, 1, 200)); - assertFunction("parse_duration('1234.567d')", INTERVAL_DAY_TIME, new SqlIntervalDayTime(1234, 13, 36, 28, 800)); - - // invalid function calls - assertInvalidFunction("parse_duration('')", "duration is empty"); - assertInvalidFunction("parse_duration('1f')", "Unknown time unit: f"); - assertInvalidFunction("parse_duration('abc')", "duration is not a valid data duration string: abc"); - } - - @Test - public void testIntervalDayToSecondToMilliseconds() - { - assertFunction("to_milliseconds(parse_duration('1ns'))", BigintType.BIGINT, 0L); - assertFunction("to_milliseconds(parse_duration('1ms'))", BigintType.BIGINT, 1L); - assertFunction("to_milliseconds(parse_duration('1s'))", BigintType.BIGINT, SECONDS.toMillis(1)); - assertFunction("to_milliseconds(parse_duration('1h'))", BigintType.BIGINT, HOURS.toMillis(1)); - assertFunction("to_milliseconds(parse_duration('1d'))", BigintType.BIGINT, DAYS.toMillis(1)); - } - - private void assertFunctionString(String projection, Type expectedType, String expected) - { - functionAssertions.assertFunctionString(projection, expectedType, expected); - } - - private static SqlDate toDate(DateTime dateDate) - { - long millis = dateDate.getMillis(); - return new SqlDate(toIntExact(MILLISECONDS.toDays(millis))); - } - - private static long millisBetween(ReadableInstant start, ReadableInstant end) - { - requireNonNull(start, "start is null"); - requireNonNull(end, "end is null"); - return millis().getField(getInstantChronology(start)).getDifferenceAsLong(end.getMillis(), start.getMillis()); - } - - private static Seconds secondsBetween(ReadableInstant start, ReadableInstant end) - { - return Seconds.secondsBetween(start, end); - } - - private static Minutes minutesBetween(ReadableInstant start, ReadableInstant end) - { - return Minutes.minutesBetween(start, end); - } - - private static Hours hoursBetween(ReadableInstant start, ReadableInstant end) - { - return Hours.hoursBetween(start, end); - } - - private static long millisBetween(LocalTime start, LocalTime end) - { - return NANOSECONDS.toMillis(end.toNanoOfDay() - start.toNanoOfDay()); - } - - private static long secondsBetween(LocalTime start, LocalTime end) - { - return NANOSECONDS.toSeconds(end.toNanoOfDay() - start.toNanoOfDay()); - } - - private static long minutesBetween(LocalTime start, LocalTime end) - { - return NANOSECONDS.toMinutes(end.toNanoOfDay() - start.toNanoOfDay()); - } - - private static long hoursBetween(LocalTime start, LocalTime end) - { - return NANOSECONDS.toHours(end.toNanoOfDay() - start.toNanoOfDay()); - } - - private static long millisBetween(OffsetTime start, OffsetTime end) - { - return millisUtc(end) - millisUtc(start); - } - - private static long secondsBetween(OffsetTime start, OffsetTime end) - { - return MILLISECONDS.toSeconds(millisBetween(start, end)); - } - - private static long minutesBetween(OffsetTime start, OffsetTime end) - { - return MILLISECONDS.toMinutes(millisBetween(start, end)); - } - - private static long hoursBetween(OffsetTime start, OffsetTime end) - { - return MILLISECONDS.toHours(millisBetween(start, end)); - } - - private SqlTime toTime(LocalTime time) - { - return sqlTimeOf(time, session); - } - - private static SqlTimeWithTimeZone toTimeWithTimeZone(OffsetTime offsetTime) - { - return new SqlTimeWithTimeZone( - millisUtc(offsetTime), - TimeZoneKey.getTimeZoneKey(offsetTime.getOffset().getId())); - } - - private static long millisUtc(OffsetTime offsetTime) - { - return offsetTime.atDate(LocalDate.ofEpochDay(0)).toInstant().toEpochMilli(); - } - - private static SqlTimestampWithTimeZone toTimestampWithTimeZone(DateTime dateTime) - { - return new SqlTimestampWithTimeZone(dateTime.getMillis(), dateTime.getZone().toTimeZone()); - } -} diff --git a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsLegacy.java b/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsLegacy.java deleted file mode 100644 index 2b6176286..000000000 --- a/presto-main/src/test/java/io/prestosql/operator/scalar/TestDateTimeFunctionsLegacy.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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 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 io.prestosql.operator.scalar; - -import io.prestosql.Session; -import io.prestosql.spi.type.TimeType; -import io.prestosql.spi.type.TimestampType; -import org.joda.time.DateTime; -import org.testng.annotations.Test; - -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.type.VarcharType.createVarcharType; - -public class TestDateTimeFunctionsLegacy - extends TestDateTimeFunctionsBase -{ - public TestDateTimeFunctionsLegacy() - { - super(true); - } - - @Test - public void testToIso8601ForTimestampWithoutTimeZone() - { - assertFunction("to_iso8601(" + TIMESTAMP_LITERAL + ")", createVarcharType(35), TIMESTAMP_ISO8601_STRING); - } - - @Test - public void testFormatDateCanImplicitlyAddTimeZoneToTimestampLiteral() - { - assertFunction("format_datetime(" + TIMESTAMP_LITERAL + ", 'YYYY/MM/dd HH:mm ZZZZ')", VARCHAR, "2001/08/22 03:04 " + DATE_TIME_ZONE.getID()); - } - - @Test - public void testLocalTime() - { - Session localSession = Session.builder(session) - .setStartTime(new DateTime(2017, 3, 1, 14, 30, 0, 0, DATE_TIME_ZONE).getMillis()) - .build(); - try (FunctionAssertions localAssertion = new FunctionAssertions(localSession)) { - localAssertion.assertFunctionString("LOCALTIME", TimeType.TIME, "13:30:00.000"); - } - } - - @Test - public void testCurrentTime() - { - Session localSession = Session.builder(session) - // we use Asia/Kathmandu here to test the difference in semantic change of current_time - // between legacy and non-legacy timestamp - .setTimeZoneKey(KATHMANDU_ZONE_KEY) - .setStartTime(new DateTime(2017, 3, 1, 15, 45, 0, 0, KATHMANDU_ZONE).getMillis()) - .build(); - try (FunctionAssertions localAssertion = new FunctionAssertions(localSession)) { - localAssertion.assertFunctionString("CURRENT_TIME", TIME_WITH_TIME_ZONE, "15:30:00.000 Asia/Kathmandu"); - } - } - - @Test - public void testLocalTimestamp() - { - Session localSession = Session.builder(session) - .setStartTime(new DateTime(2017, 3, 1, 14, 30, 0, 0, DATE_TIME_ZONE).getMillis()) - .build(); - try (FunctionAssertions localAssertion = new FunctionAssertions(localSession)) { - localAssertion.assertFunctionString("LOCALTIMESTAMP", TimestampType.TIMESTAMP, "2017-03-01 14:30:00.000"); - } - } - - @Test - public void testCurrentTimestamp() - { - Session localSession = Session.builder(session) - .setStartTime(new DateTime(2017, 3, 1, 14, 30, 0, 0, DATE_TIME_ZONE).getMillis()) - .build(); - try (FunctionAssertions localAssertion = new FunctionAssertions(localSession)) { - localAssertion.assertFunctionString("CURRENT_TIMESTAMP", TIMESTAMP_WITH_TIME_ZONE, "2017-03-01 14:30:00.000 " + DATE_TIME_ZONE.getID()); - localAssertion.assertFunctionString("NOW()", TIMESTAMP_WITH_TIME_ZONE, "2017-03-01 14:30:00.000 " + DATE_TIME_ZONE.getID()); - } - } -} diff --git a/presto-main/src/test/java/io/prestosql/sql/TestExpressionInterpreter.java b/presto-main/src/test/java/io/prestosql/sql/TestExpressionInterpreter.java index 6cdc16dfd..64656ccbf 100644 --- a/presto-main/src/test/java/io/prestosql/sql/TestExpressionInterpreter.java +++ b/presto-main/src/test/java/io/prestosql/sql/TestExpressionInterpreter.java @@ -41,7 +41,6 @@ import io.prestosql.sql.tree.QualifiedName; import io.prestosql.sql.tree.StringLiteral; import org.intellij.lang.annotations.Language; import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.joda.time.LocalDate; import org.joda.time.LocalTime; import org.testng.annotations.Test; @@ -66,7 +65,6 @@ import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.spi.type.VarcharType.createVarcharType; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; import static io.prestosql.sql.ExpressionFormatter.formatExpression; import static io.prestosql.sql.ExpressionUtils.rewriteIdentifiersToSymbolReferences; import static io.prestosql.sql.ParsingUtil.createParsingOptions; @@ -76,6 +74,7 @@ import static io.prestosql.sql.planner.SymbolUtils.toSymbolReference; import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; import static java.lang.String.format; import static java.util.Locale.ENGLISH; +import static org.joda.time.DateTimeZone.UTC; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; import static org.testng.Assert.assertTrue; @@ -379,7 +378,7 @@ public class TestExpressionInterpreter @Test public void testExtract() { - DateTime dateTime = new DateTime(2001, 8, 22, 3, 4, 5, 321, getDateTimeZone(TEST_SESSION.getTimeZoneKey())); + DateTime dateTime = new DateTime(2001, 8, 22, 3, 4, 5, 321, UTC); double seconds = dateTime.getMillis() / 1000.0; assertOptimizedEquals("extract (YEAR from from_unixtime(" + seconds + "))", "2001"); @@ -399,10 +398,10 @@ public class TestExpressionInterpreter assertOptimizedEquals("extract (QUARTER from bound_timestamp)", "3"); assertOptimizedEquals("extract (MONTH from bound_timestamp)", "8"); assertOptimizedEquals("extract (WEEK from bound_timestamp)", "34"); - assertOptimizedEquals("extract (DOW from bound_timestamp)", "2"); - assertOptimizedEquals("extract (DOY from bound_timestamp)", "233"); - assertOptimizedEquals("extract (DAY from bound_timestamp)", "21"); - assertOptimizedEquals("extract (HOUR from bound_timestamp)", "16"); + assertOptimizedEquals("extract (DOW from bound_timestamp)", "3"); + assertOptimizedEquals("extract (DOY from bound_timestamp)", "234"); + assertOptimizedEquals("extract (DAY from bound_timestamp)", "22"); + assertOptimizedEquals("extract (HOUR from bound_timestamp)", "3"); assertOptimizedEquals("extract (MINUTE from bound_timestamp)", "4"); assertOptimizedEquals("extract (SECOND from bound_timestamp)", "5"); // todo reenable when cast as timestamp with time zone is implemented @@ -510,9 +509,9 @@ public class TestExpressionInterpreter public void testCurrentTimestamp() { double current = TEST_SESSION.getStartTime() / 1000.0; - assertOptimizedEquals("current_timestamp = from_unixtime(" + current + ")", "true"); + assertOptimizedEquals("current_timestamp = from_unixtime(" + current + ")", "false"); double future = current + TimeUnit.MINUTES.toSeconds(1); - assertOptimizedEquals("current_timestamp > from_unixtime(" + future + ")", "false"); + assertOptimizedEquals("current_timestamp > from_unixtime(" + future + ")", "true"); } @Test @@ -1470,15 +1469,15 @@ public class TestExpressionInterpreter case "bound_double": return 12.34; case "bound_date": - return new LocalDate(2001, 8, 22).toDateMidnight(DateTimeZone.UTC).getMillis(); + return new LocalDate(2001, 8, 22).toDateMidnight(UTC).getMillis(); case "bound_time": - return new LocalTime(3, 4, 5, 321).toDateTime(new DateTime(0, DateTimeZone.UTC)).getMillis(); + return new LocalTime(3, 4, 5, 321).toDateTime(new DateTime(0, UTC)).getMillis(); case "bound_timestamp": - return new DateTime(2001, 8, 22, 3, 4, 5, 321, DateTimeZone.UTC).getMillis(); + return new DateTime(2001, 8, 22, 3, 4, 5, 321, UTC).getMillis(); case "bound_pattern": return utf8Slice("%el%"); case "bound_timestamp_with_timezone": - return new SqlTimestampWithTimeZone(new DateTime(1970, 1, 1, 1, 0, 0, 999, DateTimeZone.UTC).getMillis(), getTimeZoneKey("Z")); + return new SqlTimestampWithTimeZone(new DateTime(1970, 1, 1, 1, 0, 0, 999, UTC).getMillis(), getTimeZoneKey("Z")); case "bound_varbinary": return Slices.wrappedBuffer((byte) 0xab); case "bound_decimal_short": diff --git a/presto-main/src/test/java/io/prestosql/sql/analyzer/TestFeaturesConfig.java b/presto-main/src/test/java/io/prestosql/sql/analyzer/TestFeaturesConfig.java index 2cc60af88..bf6d9bccf 100644 --- a/presto-main/src/test/java/io/prestosql/sql/analyzer/TestFeaturesConfig.java +++ b/presto-main/src/test/java/io/prestosql/sql/analyzer/TestFeaturesConfig.java @@ -97,7 +97,6 @@ public class TestFeaturesConfig .setDefaultFilterFactorEnabled(false) .setEnableForcedExchangeBelowGroupId(true) .setExchangeCompressionEnabled(false) - .setLegacyTimestamp(true) .setEnableIntermediateAggregations(false) .setPushAggregationThroughJoin(true) .setParseDecimalLiteralsAsDouble(false) @@ -201,7 +200,6 @@ public class TestFeaturesConfig .put("experimental.memory-revoking-threshold", "0.2") .put("experimental.memory-revoking-target", "0.8") .put("exchange.compression-enabled", "true") - .put("deprecated.legacy-timestamp", "false") .put("optimizer.enable-intermediate-aggregations", "true") .put("parse-decimal-literals-as-double", "true") .put("optimizer.force-single-node-output", "false") @@ -299,7 +297,6 @@ public class TestFeaturesConfig .setMemoryRevokingThreshold(0.2) .setMemoryRevokingTarget(0.8) .setExchangeCompressionEnabled(true) - .setLegacyTimestamp(false) .setEnableIntermediateAggregations(true) .setParseDecimalLiteralsAsDouble(true) .setForceSingleNodeOutput(false) diff --git a/presto-main/src/test/java/io/prestosql/sql/gen/TestExpressionCompiler.java b/presto-main/src/test/java/io/prestosql/sql/gen/TestExpressionCompiler.java index ea2cb0a87..fedfdbb9b 100644 --- a/presto-main/src/test/java/io/prestosql/sql/gen/TestExpressionCompiler.java +++ b/presto-main/src/test/java/io/prestosql/sql/gen/TestExpressionCompiler.java @@ -88,7 +88,8 @@ import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.spi.type.VarcharType.createUnboundedVarcharType; import static io.prestosql.spi.type.VarcharType.createVarcharType; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; +import static io.prestosql.sql.tree.Extract.Field.TIMEZONE_HOUR; +import static io.prestosql.sql.tree.Extract.Field.TIMEZONE_MINUTE; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.type.JsonType.JSON; import static io.prestosql.util.StructuralTestUtil.mapType; @@ -97,7 +98,6 @@ import static java.lang.Runtime.getRuntime; import static java.lang.String.format; import static java.util.Collections.singletonList; import static java.util.concurrent.Executors.newFixedThreadPool; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.stream.Collectors.joining; import static java.util.stream.IntStream.range; import static org.joda.time.DateTimeZone.UTC; @@ -872,7 +872,7 @@ public class TestExpressionCompiler assertExecute("try_cast('foo' as varchar)", VARCHAR, "foo"); assertExecute("try_cast('foo' as bigint)", BIGINT, null); assertExecute("try_cast('foo' as integer)", INTEGER, null); - assertExecute("try_cast('2001-08-22' as timestamp)", TIMESTAMP, sqlTimestampOf(2001, 8, 22, 0, 0, 0, 0, TEST_SESSION)); + assertExecute("try_cast('2001-08-22' as timestamp)", TIMESTAMP, sqlTimestampOf(2001, 8, 22, 0, 0, 0, 0)); assertExecute("try_cast(bound_string as bigint)", BIGINT, null); assertExecute("try_cast(cast(null as varchar) as bigint)", BIGINT, null); assertExecute("try_cast(bound_long / 13 as bigint)", BIGINT, 94L); @@ -1495,19 +1495,19 @@ public class TestExpressionCompiler { for (DateTime left : dateTimeValues) { for (Field field : Field.values()) { + if (field == TIMEZONE_MINUTE || field == TIMEZONE_HOUR) { + continue; + } Long expected = null; Long millis = null; if (left != null) { millis = left.getMillis(); expected = callExtractFunction(TEST_SESSION.toConnectorSession(), millis, field); } - DateTimeZone zone = getDateTimeZone(TEST_SESSION.getTimeZoneKey()); - long zoneOffsetMinutes = millis != null ? MILLISECONDS.toMinutes(zone.getOffset(millis)) : 0; String expressionPattern = format( - "extract(%s from from_unixtime(%%s / 1000.0E0, %s, %s))", + "extract(%s from from_unixtime(cast(%s as double) / 1000))", field, - zoneOffsetMinutes / 60, - zoneOffsetMinutes % 60); + millis); assertExecute(generateExpression(expressionPattern, millis), BIGINT, expected); } } @@ -1520,25 +1520,25 @@ public class TestExpressionCompiler { switch (field) { case YEAR: - return DateTimeFunctions.yearFromTimestamp(session, value); + return DateTimeFunctions.yearFromTimestamp(value); case QUARTER: - return DateTimeFunctions.quarterFromTimestamp(session, value); + return DateTimeFunctions.quarterFromTimestamp(value); case MONTH: - return DateTimeFunctions.monthFromTimestamp(session, value); + return DateTimeFunctions.monthFromTimestamp(value); case WEEK: - return DateTimeFunctions.weekFromTimestamp(session, value); + return DateTimeFunctions.weekFromTimestamp(value); case DAY: case DAY_OF_MONTH: - return DateTimeFunctions.dayFromTimestamp(session, value); + return DateTimeFunctions.dayFromTimestamp(value); case DAY_OF_WEEK: case DOW: - return DateTimeFunctions.dayOfWeekFromTimestamp(session, value); + return DateTimeFunctions.dayOfWeekFromTimestamp(value); case YEAR_OF_WEEK: case YOW: - return DateTimeFunctions.yearOfWeekFromTimestamp(session, value); + return DateTimeFunctions.yearOfWeekFromTimestamp(value); case DAY_OF_YEAR: case DOY: - return DateTimeFunctions.dayOfYearFromTimestamp(session, value); + return DateTimeFunctions.dayOfYearFromTimestamp(value); case HOUR: return DateTimeFunctions.hourFromTimestamp(session, value); case MINUTE: diff --git a/presto-main/src/test/java/io/prestosql/type/TestArrayOperators.java b/presto-main/src/test/java/io/prestosql/type/TestArrayOperators.java index c4cc67c19..10a11b4c8 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestArrayOperators.java +++ b/presto-main/src/test/java/io/prestosql/type/TestArrayOperators.java @@ -46,7 +46,6 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; import static io.hetu.core.transport.block.BlockSerdeUtil.writeBlock; -import static io.prestosql.SessionTestUtils.TEST_SESSION; import static io.prestosql.operator.aggregation.TypedSet.MAX_FUNCTION_MEMORY; import static io.prestosql.spi.StandardErrorCode.EXCEEDED_FUNCTION_MEMORY_LIMIT; import static io.prestosql.spi.StandardErrorCode.INVALID_CAST_ARGUMENT; @@ -208,7 +207,7 @@ public class TestArrayOperators assertFunction( "CAST(ARRAY[TIMESTAMP '1970-01-01 00:00:01', null] AS JSON)", JSON, - format("[\"%s\",null]", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + format("[\"%s\",null]", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction( "CAST(ARRAY[DATE '2001-08-22', DATE '2001-08-23', null] AS JSON)", JSON, @@ -372,8 +371,8 @@ public class TestArrayOperators "ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01']", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0))); assertFunction("ARRAY [sqrt(-1)]", new ArrayType(DOUBLE), ImmutableList.of(NaN)); assertFunction("ARRAY [pow(infinity(), 2)]", new ArrayType(DOUBLE), ImmutableList.of(POSITIVE_INFINITY)); assertFunction("ARRAY [pow(-infinity(), 1)]", new ArrayType(DOUBLE), ImmutableList.of(NEGATIVE_INFINITY)); @@ -408,8 +407,8 @@ public class TestArrayOperators assertFunction("ARRAY [TRUE] || ARRAY [FALSE]", new ArrayType(BOOLEAN), ImmutableList.of(true, false)); assertFunction("concat(ARRAY [1] , ARRAY[2,3])", new ArrayType(INTEGER), ImmutableList.of(1, 2, 3)); assertFunction("ARRAY [TIMESTAMP '1970-01-01 00:00:01'] || ARRAY[TIMESTAMP '1973-07-08 22:00:01']", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0))); assertFunction("ARRAY [ARRAY[ARRAY[1]]] || ARRAY [ARRAY[ARRAY[2]]]", new ArrayType(new ArrayType(new ArrayType(INTEGER))), asList(singletonList(Ints.asList(1)), singletonList(Ints.asList(2)))); @@ -470,11 +469,11 @@ public class TestArrayOperators assertFunction("'puppies' || ARRAY ['kittens']", new ArrayType(createVarcharType(7)), Lists.newArrayList("puppies", "kittens")); assertFunction("ARRAY ['kittens'] || 'puppies'", new ArrayType(createVarcharType(7)), Lists.newArrayList("kittens", "puppies")); assertFunction("ARRAY [TIMESTAMP '1970-01-01 00:00:01'] || TIMESTAMP '1973-07-08 22:00:01'", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0))); assertFunction("TIMESTAMP '1973-07-08 22:00:01' || ARRAY [TIMESTAMP '1970-01-01 00:00:01']", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0), + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction("ARRAY [2, 8] || ARRAY[ARRAY[3, 6], ARRAY[4]]", new ArrayType(new ArrayType(INTEGER)), ImmutableList.of(ImmutableList.of(2, 8), ImmutableList.of(3, 6), ImmutableList.of(4))); assertFunction("ARRAY [ARRAY [1], ARRAY [2, 8]] || ARRAY [3, 6]", new ArrayType(new ArrayType(INTEGER)), ImmutableList.of(ImmutableList.of(1), ImmutableList.of(2, 8), ImmutableList.of(3, 6))); assertFunction( @@ -554,16 +553,16 @@ public class TestArrayOperators assertFunction("ARRAY_JOIN(ARRAY [sqrt(-1), infinity()], ',')", VARCHAR, "NaN,Infinity"); assertFunction("ARRAY_JOIN(ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'], '|')", VARCHAR, format( "%s|%s", - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0))); assertFunction( "ARRAY_JOIN(ARRAY [null, TIMESTAMP '1970-01-01 00:00:01'], '|')", VARCHAR, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION).toString()); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0).toString()); assertFunction( "ARRAY_JOIN(ARRAY [null, TIMESTAMP '1970-01-01 00:00:01'], '|', 'XYZ')", VARCHAR, - "XYZ|" + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION).toString()); + "XYZ|" + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0).toString()); assertFunction("ARRAY_JOIN(ARRAY [1.0, 2.1, 3.3], 'x')", VARCHAR, "1.0x2.1x3.3"); assertFunction("ARRAY_JOIN(ARRAY [1.0, 2.100, 3.3], 'x')", VARCHAR, "1.000x2.100x3.300"); assertFunction("ARRAY_JOIN(ARRAY [1.0, 2.100, NULL], 'x', 'N/A')", VARCHAR, "1.000x2.100xN/A"); @@ -718,7 +717,7 @@ public class TestArrayOperators assertFunction( "ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'][1]", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION)); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0)); assertFunction("ARRAY [infinity()][1]", DOUBLE, POSITIVE_INFINITY); assertFunction("ARRAY [-infinity()][1]", DOUBLE, NEGATIVE_INFINITY); assertFunction("ARRAY [sqrt(-1)][1]", DOUBLE, NaN); @@ -770,11 +769,11 @@ public class TestArrayOperators assertFunction( "ELEMENT_AT(ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'], 1)", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION)); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0)); assertFunction( "ELEMENT_AT(ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'], -2)", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION)); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0)); assertFunction("ELEMENT_AT(ARRAY [infinity()], 1)", DOUBLE, POSITIVE_INFINITY); assertFunction("ELEMENT_AT(ARRAY [infinity()], -1)", DOUBLE, POSITIVE_INFINITY); assertFunction("ELEMENT_AT(ARRAY [-infinity()], 1)", DOUBLE, NEGATIVE_INFINITY); @@ -815,9 +814,9 @@ public class TestArrayOperators "ARRAY_SORT(ARRAY [TIMESTAMP '1973-07-08 22:00:01', TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1989-02-06 12:00:00'])", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1989, 2, 6, 12, 0, 0, 0, TEST_SESSION))); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0), + sqlTimestampOf(1989, 2, 6, 12, 0, 0, 0))); assertFunction("ARRAY_SORT(ARRAY [ARRAY [1], ARRAY [2]])", new ArrayType(new ArrayType(INTEGER)), ImmutableList.of(ImmutableList.of(1), ImmutableList.of(2))); @@ -898,9 +897,9 @@ public class TestArrayOperators asList( null, null, - sqlTimestampOf(1989, 2, 6, 12, 0, 0, 0, TEST_SESSION), - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1989, 2, 6, 12, 0, 0, 0), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0), + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction( "ARRAY_SORT(ARRAY[ARRAY[2, 3, 1], null, ARRAY[4, null, 2, 1, 4], ARRAY[1, 2], null], (x, y) -> CASE " + "WHEN x IS NULL THEN -1 " + @@ -979,8 +978,8 @@ public class TestArrayOperators "ARRAY_DISTINCT(ARRAY [TIMESTAMP '1973-07-08 22:00:01', TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'])", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION), - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0), + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction("ARRAY_DISTINCT(ARRAY ['2', '3', '2'])", new ArrayType(createVarcharType(1)), ImmutableList.of("2", "3")); assertFunction("ARRAY_DISTINCT(ARRAY ['BB', 'CCC', 'BB'])", new ArrayType(createVarcharType(3)), ImmutableList.of("BB", "CCC")); assertFunction( @@ -1653,46 +1652,46 @@ public class TestArrayOperators "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2016-04-16 01:07:00', interval '3' minute)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 3, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 6, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 3, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 6, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:10:10', timestamp '2016-04-16 01:03:00', interval '-3' minute)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 10, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 7, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 4, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 10, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 7, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 4, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2016-04-16 01:01:00', interval '20' second)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 0, 30, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 0, 50, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 0, 30, 0), + sqlTimestampOf(2016, 4, 16, 1, 0, 50, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:01:10', timestamp '2016-04-16 01:00:20', interval '-20' second)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 1, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 0, 50, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 1, 0, 30, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 1, 10, 0), + sqlTimestampOf(2016, 4, 16, 1, 0, 50, 0), + sqlTimestampOf(2016, 4, 16, 1, 0, 30, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2016-04-18 01:01:00', interval '19' hour)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 16, 20, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 17, 15, 0, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 4, 16, 20, 0, 10, 0), + sqlTimestampOf(2016, 4, 17, 15, 0, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2016-04-14 01:00:20', interval '-19' hour)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 15, 6, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 4, 14, 11, 0, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 4, 15, 6, 0, 10, 0), + sqlTimestampOf(2016, 4, 14, 11, 0, 10, 0))); // failure modes assertInvalidFunction( @@ -1760,31 +1759,31 @@ public class TestArrayOperators "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2016-09-16 01:10:00', interval '2' month)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 6, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 8, 16, 1, 0, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 6, 16, 1, 0, 10, 0), + sqlTimestampOf(2016, 8, 16, 1, 0, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-09-16 01:10:10', timestamp '2016-04-16 01:00:00', interval '-2' month)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 9, 16, 1, 10, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 7, 16, 1, 10, 10, 0, TEST_SESSION), - sqlTimestampOf(2016, 5, 16, 1, 10, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 9, 16, 1, 10, 10, 0), + sqlTimestampOf(2016, 7, 16, 1, 10, 10, 0), + sqlTimestampOf(2016, 5, 16, 1, 10, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:00:10', timestamp '2021-04-16 01:01:00', interval '2' year)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2018, 4, 16, 1, 0, 10, 0, TEST_SESSION), - sqlTimestampOf(2020, 4, 16, 1, 0, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2018, 4, 16, 1, 0, 10, 0), + sqlTimestampOf(2020, 4, 16, 1, 0, 10, 0))); assertFunction( "SEQUENCE(timestamp '2016-04-16 01:01:10', timestamp '2011-04-16 01:00:00', interval '-2' year)", new ArrayType(TIMESTAMP), ImmutableList.of( - sqlTimestampOf(2016, 4, 16, 1, 1, 10, 0, TEST_SESSION), - sqlTimestampOf(2014, 4, 16, 1, 1, 10, 0, TEST_SESSION), - sqlTimestampOf(2012, 4, 16, 1, 1, 10, 0, TEST_SESSION))); + sqlTimestampOf(2016, 4, 16, 1, 1, 10, 0), + sqlTimestampOf(2014, 4, 16, 1, 1, 10, 0), + sqlTimestampOf(2012, 4, 16, 1, 1, 10, 0))); // failure modes assertInvalidFunction( diff --git a/presto-main/src/test/java/io/prestosql/type/TestDate.java b/presto-main/src/test/java/io/prestosql/type/TestDate.java index e34729b61..d8e451ce5 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestDate.java +++ b/presto-main/src/test/java/io/prestosql/type/TestDate.java @@ -13,11 +13,167 @@ */ package io.prestosql.type; +import io.prestosql.operator.scalar.AbstractTestFunctions; +import io.prestosql.spi.type.SqlDate; +import io.prestosql.spi.type.SqlTimestampWithTimeZone; +import io.prestosql.spi.type.TimeZoneKey; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.testng.annotations.Test; + +import java.util.concurrent.TimeUnit; + +import static io.prestosql.spi.function.OperatorType.INDETERMINATE; +import static io.prestosql.spi.type.BooleanType.BOOLEAN; +import static io.prestosql.spi.type.DateType.DATE; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; +import static io.prestosql.spi.type.TimestampType.TIMESTAMP; +import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; +import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; +import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; +import static io.prestosql.testing.TestingSession.testSessionBuilder; +import static org.joda.time.DateTimeZone.UTC; + public class TestDate - extends TestDateBase + extends AbstractTestFunctions { - public TestDate() + private static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); + private static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); + + protected TestDate() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(TIME_ZONE_KEY) + .build()); + } + + @Test + public void testLiteral() + { + long millis = new DateTime(2001, 1, 22, 0, 0, UTC).getMillis(); + assertFunction("DATE '2001-1-22'", DATE, new SqlDate((int) TimeUnit.MILLISECONDS.toDays(millis))); + } + + @Test + public void testEqual() + { + assertFunction("DATE '2001-1-22' = DATE '2001-1-22'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' = DATE '2001-1-22'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' = DATE '2001-1-23'", BOOLEAN, false); + assertFunction("DATE '2001-1-22' = DATE '2001-1-11'", BOOLEAN, false); + } + + @Test + public void testNotEqual() + { + assertFunction("DATE '2001-1-22' <> DATE '2001-1-23'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' <> DATE '2001-1-11'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' <> DATE '2001-1-22'", BOOLEAN, false); + } + + @Test + public void testLessThan() + { + assertFunction("DATE '2001-1-22' < DATE '2001-1-23'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' < DATE '2001-1-22'", BOOLEAN, false); + assertFunction("DATE '2001-1-22' < DATE '2001-1-20'", BOOLEAN, false); + } + + @Test + public void testLessThanOrEqual() + { + assertFunction("DATE '2001-1-22' <= DATE '2001-1-22'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' <= DATE '2001-1-23'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' <= DATE '2001-1-20'", BOOLEAN, false); + } + + @Test + public void testGreaterThan() + { + assertFunction("DATE '2001-1-22' > DATE '2001-1-11'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' > DATE '2001-1-22'", BOOLEAN, false); + assertFunction("DATE '2001-1-22' > DATE '2001-1-23'", BOOLEAN, false); + } + + @Test + public void testGreaterThanOrEqual() + { + assertFunction("DATE '2001-1-22' >= DATE '2001-1-22'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' >= DATE '2001-1-11'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' >= DATE '2001-1-23'", BOOLEAN, false); + } + + @Test + public void testBetween() + { + assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-23'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-22'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' between DATE '2001-1-22' and DATE '2001-1-23'", BOOLEAN, true); + assertFunction("DATE '2001-1-22' between DATE '2001-1-22' and DATE '2001-1-22'", BOOLEAN, true); + + assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-12'", BOOLEAN, false); + assertFunction("DATE '2001-1-22' between DATE '2001-1-23' and DATE '2001-1-24'", BOOLEAN, false); + assertFunction("DATE '2001-1-22' between DATE '2001-1-23' and DATE '2001-1-11'", BOOLEAN, false); + } + + @Test + public void testCastToTimestamp() + { + assertFunction("cast(DATE '2001-1-22' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0)); + } + + @Test + public void testCastToTimestampWithTimeZone() + { + assertFunction("cast(DATE '2001-1-22' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + } + + @Test + public void testCastToSlice() + { + assertFunction("cast(DATE '2001-1-22' as varchar)", VARCHAR, "2001-01-22"); + } + + @Test + public void testCastFromSlice() + { + assertFunction("cast('2001-1-22' as date) = Date '2001-1-22'", BOOLEAN, true); + assertFunction("cast('\n\t 2001-1-22' as date) = Date '2001-1-22'", BOOLEAN, true); + assertFunction("cast('2001-1-22 \t\n' as date) = Date '2001-1-22'", BOOLEAN, true); + assertFunction("cast('\n\t 2001-1-22 \t\n' as date) = Date '2001-1-22'", BOOLEAN, true); + } + + @Test + public void testGreatest() + { + int days = (int) TimeUnit.MILLISECONDS.toDays(new DateTime(2013, 3, 30, 0, 0, UTC).getMillis()); + assertFunction("greatest(DATE '2013-03-30', DATE '2012-05-23')", DATE, new SqlDate(days)); + assertFunction("greatest(DATE '2013-03-30', DATE '2012-05-23', DATE '2012-06-01')", DATE, new SqlDate(days)); + } + + @Test + public void testLeast() + { + int days = (int) TimeUnit.MILLISECONDS.toDays(new DateTime(2012, 5, 23, 0, 0, UTC).getMillis()); + assertFunction("least(DATE '2013-03-30', DATE '2012-05-23')", DATE, new SqlDate(days)); + assertFunction("least(DATE '2013-03-30', DATE '2012-05-23', DATE '2012-06-01')", DATE, new SqlDate(days)); + } + + @Test + public void testIndeterminate() + { + assertOperator(INDETERMINATE, "cast(null as DATE)", BOOLEAN, true); + assertOperator(INDETERMINATE, "DATE '2013-10-27'", BOOLEAN, false); } } diff --git a/presto-main/src/test/java/io/prestosql/type/TestDateBase.java b/presto-main/src/test/java/io/prestosql/type/TestDateBase.java deleted file mode 100644 index 1a260e6dd..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestDateBase.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.operator.scalar.AbstractTestFunctions; -import io.prestosql.spi.type.SqlDate; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeZoneKey; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import java.util.concurrent.TimeUnit; - -import static io.prestosql.spi.function.OperatorType.INDETERMINATE; -import static io.prestosql.spi.type.BooleanType.BOOLEAN; -import static io.prestosql.spi.type.DateType.DATE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static org.joda.time.DateTimeZone.UTC; - -public abstract class TestDateBase - extends AbstractTestFunctions -{ - private static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); - private static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - - protected TestDateBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(TIME_ZONE_KEY) - .build()); - } - - @Test - public void testLiteral() - { - long millis = new DateTime(2001, 1, 22, 0, 0, UTC).getMillis(); - assertFunction("DATE '2001-1-22'", DATE, new SqlDate((int) TimeUnit.MILLISECONDS.toDays(millis))); - } - - @Test - public void testEqual() - { - assertFunction("DATE '2001-1-22' = DATE '2001-1-22'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' = DATE '2001-1-22'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' = DATE '2001-1-23'", BOOLEAN, false); - assertFunction("DATE '2001-1-22' = DATE '2001-1-11'", BOOLEAN, false); - } - - @Test - public void testNotEqual() - { - assertFunction("DATE '2001-1-22' <> DATE '2001-1-23'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' <> DATE '2001-1-11'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' <> DATE '2001-1-22'", BOOLEAN, false); - } - - @Test - public void testLessThan() - { - assertFunction("DATE '2001-1-22' < DATE '2001-1-23'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' < DATE '2001-1-22'", BOOLEAN, false); - assertFunction("DATE '2001-1-22' < DATE '2001-1-20'", BOOLEAN, false); - } - - @Test - public void testLessThanOrEqual() - { - assertFunction("DATE '2001-1-22' <= DATE '2001-1-22'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' <= DATE '2001-1-23'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' <= DATE '2001-1-20'", BOOLEAN, false); - } - - @Test - public void testGreaterThan() - { - assertFunction("DATE '2001-1-22' > DATE '2001-1-11'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' > DATE '2001-1-22'", BOOLEAN, false); - assertFunction("DATE '2001-1-22' > DATE '2001-1-23'", BOOLEAN, false); - } - - @Test - public void testGreaterThanOrEqual() - { - assertFunction("DATE '2001-1-22' >= DATE '2001-1-22'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' >= DATE '2001-1-11'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' >= DATE '2001-1-23'", BOOLEAN, false); - } - - @Test - public void testBetween() - { - assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-23'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-22'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' between DATE '2001-1-22' and DATE '2001-1-23'", BOOLEAN, true); - assertFunction("DATE '2001-1-22' between DATE '2001-1-22' and DATE '2001-1-22'", BOOLEAN, true); - - assertFunction("DATE '2001-1-22' between DATE '2001-1-11' and DATE '2001-1-12'", BOOLEAN, false); - assertFunction("DATE '2001-1-22' between DATE '2001-1-23' and DATE '2001-1-24'", BOOLEAN, false); - assertFunction("DATE '2001-1-22' between DATE '2001-1-23' and DATE '2001-1-11'", BOOLEAN, false); - } - - @Test - public void testCastToTimestamp() - { - assertFunction("cast(DATE '2001-1-22' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0, session)); - } - - @Test - public void testCastToTimestampWithTimeZone() - { - assertFunction("cast(DATE '2001-1-22' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - } - - @Test - public void testCastToSlice() - { - assertFunction("cast(DATE '2001-1-22' as varchar)", VARCHAR, "2001-01-22"); - } - - @Test - public void testCastFromSlice() - { - assertFunction("cast('2001-1-22' as date) = Date '2001-1-22'", BOOLEAN, true); - assertFunction("cast('\n\t 2001-1-22' as date) = Date '2001-1-22'", BOOLEAN, true); - assertFunction("cast('2001-1-22 \t\n' as date) = Date '2001-1-22'", BOOLEAN, true); - assertFunction("cast('\n\t 2001-1-22 \t\n' as date) = Date '2001-1-22'", BOOLEAN, true); - } - - @Test - public void testGreatest() - { - int days = (int) TimeUnit.MILLISECONDS.toDays(new DateTime(2013, 3, 30, 0, 0, UTC).getMillis()); - assertFunction("greatest(DATE '2013-03-30', DATE '2012-05-23')", DATE, new SqlDate(days)); - assertFunction("greatest(DATE '2013-03-30', DATE '2012-05-23', DATE '2012-06-01')", DATE, new SqlDate(days)); - } - - @Test - public void testLeast() - { - int days = (int) TimeUnit.MILLISECONDS.toDays(new DateTime(2012, 5, 23, 0, 0, UTC).getMillis()); - assertFunction("least(DATE '2013-03-30', DATE '2012-05-23')", DATE, new SqlDate(days)); - assertFunction("least(DATE '2013-03-30', DATE '2012-05-23', DATE '2012-06-01')", DATE, new SqlDate(days)); - } - - @Test - public void testIndeterminate() - { - assertOperator(INDETERMINATE, "cast(null as DATE)", BOOLEAN, true); - assertOperator(INDETERMINATE, "DATE '2013-10-27'", BOOLEAN, false); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestDateLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestDateLegacy.java deleted file mode 100644 index 92b0e33ae..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestDateLegacy.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -public class TestDateLegacy - extends TestDateBase -{ - public TestDateLegacy() - { - super(true); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperators.java b/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperators.java index df3d6b671..4a2406dc9 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperators.java +++ b/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperators.java @@ -15,31 +15,50 @@ package io.prestosql.type; import io.prestosql.Session; +import io.prestosql.operator.scalar.AbstractTestFunctions; import io.prestosql.operator.scalar.FunctionAssertions; +import io.prestosql.spi.type.SqlDate; import io.prestosql.spi.type.SqlTime; import io.prestosql.spi.type.SqlTimeWithTimeZone; +import io.prestosql.spi.type.SqlTimestampWithTimeZone; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.testng.annotations.Test; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import static com.google.common.base.Verify.verify; +import static io.prestosql.spi.StandardErrorCode.INVALID_CAST_ARGUMENT; +import static io.prestosql.spi.type.BooleanType.BOOLEAN; +import static io.prestosql.spi.type.DateType.DATE; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; +import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; +import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.testing.TestingSession.testSessionBuilder; +import static org.joda.time.DateTimeZone.UTC; public class TestDateTimeOperators - extends TestDateTimeOperatorsBase + extends AbstractTestFunctions { + private static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); + private static final DateTimeZone WEIRD_TIME_ZONE = DateTimeZone.forOffsetHoursMinutes(5, 9); + private static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(5 * 60 + 9); + public TestDateTimeOperators() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(TIME_ZONE_KEY) + .build()); } @Test @@ -50,28 +69,28 @@ public class TestDateTimeOperators assertFunction( "TIMESTAMP '2013-03-31 00:05' + INTERVAL '1' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-03-31 00:05' + INTERVAL '2' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 2, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 2, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-03-31 00:05' + INTERVAL '3' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 3, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 3, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-03-31 04:05' - INTERVAL '3' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-03-31 03:05' - INTERVAL '2' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-03-31 01:05' - INTERVAL '1' hour", TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 0, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 3, 31, 0, 5, 0, 0)); } @Test @@ -80,42 +99,42 @@ public class TestDateTimeOperators assertFunction( "TIMESTAMP '2013-10-27 00:05' + INTERVAL '1' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 1, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 1, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 00:05' + INTERVAL '2' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 00:05' + INTERVAL '3' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 3, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 3, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 00:05' + INTERVAL '4' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 4, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 4, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 03:05' - INTERVAL '4' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 26, 23, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 26, 23, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 02:05' - INTERVAL '2' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 01:05' - INTERVAL '1' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 03:05' - INTERVAL '1' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0)); assertFunction( "TIMESTAMP '2013-10-27 03:05' - INTERVAL '2' hour", TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 1, 5, 0, 0, DATE_TIME_ZONE, TIME_ZONE_KEY, session.toConnectorSession())); + sqlTimestampOf(2013, 10, 27, 1, 5, 0, 0)); } @Test @@ -123,48 +142,48 @@ public class TestDateTimeOperators { // PST -> PDT date testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 3, 12, 10, 0, 0, 0, UTC), "TIME '02:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 3, 12, 10, 0, 0, 0, UTC), "TIME '03:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); // PDT -> PST date testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 10, 4, 10, 0, 0, 0, UTC), "TIME '02:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 10, 4, 10, 0, 0, 0, UTC), "TIME '03:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); // PDT date testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 6, 6, 10, 0, 0, 0, UTC), "TIME '02:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 6, 6, 10, 0, 0, 0, UTC), "TIME '03:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); // PST date testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 11, 1, 10, 0, 0, 0, UTC), "TIME '02:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), + new DateTime(2017, 11, 1, 10, 0, 0, 0, UTC), "TIME '03:30:00.000 America/Los_Angeles'", TIME_WITH_TIME_ZONE, new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); @@ -190,12 +209,11 @@ public class TestDateTimeOperators testTimeRepresentationOnDate(new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), "TIME '03:30:00.000'", TIME, new SqlTime(12600000)); } - private void testTimeRepresentationOnDate(DateTime date, String timeLiteral, Type expectedType, Object expected) + private static void testTimeRepresentationOnDate(DateTime date, String timeLiteral, Type expectedType, Object expected) { Session localSession = testSessionBuilder() .setTimeZoneKey(getTimeZoneKey("America/Los_Angeles")) .setStartTime(date.getMillis()) - .setSystemProperty("legacy_timestamp", "false") .build(); try (FunctionAssertions localAssertions = new FunctionAssertions(localSession)) { @@ -211,4 +229,188 @@ public class TestDateTimeOperators verify(m.find()); return m.group(1); } + + @Test + public void testDatePlusInterval() + { + assertFunction("DATE '2001-1-22' + INTERVAL '3' day", DATE, toDate(new DateTime(2001, 1, 25, 0, 0, 0, 0, UTC))); + assertFunction("INTERVAL '3' day + DATE '2001-1-22'", DATE, toDate(new DateTime(2001, 1, 25, 0, 0, 0, 0, UTC))); + assertFunction("DATE '2001-1-22' + INTERVAL '3' month", DATE, toDate(new DateTime(2001, 4, 22, 0, 0, 0, 0, UTC))); + assertFunction("INTERVAL '3' month + DATE '2001-1-22'", DATE, toDate(new DateTime(2001, 4, 22, 0, 0, 0, 0, UTC))); + assertFunction("DATE '2001-1-22' + INTERVAL '3' year", DATE, toDate(new DateTime(2004, 1, 22, 0, 0, 0, 0, UTC))); + assertFunction("INTERVAL '3' year + DATE '2001-1-22'", DATE, toDate(new DateTime(2004, 1, 22, 0, 0, 0, 0, UTC))); + + assertInvalidFunction("DATE '2001-1-22' + INTERVAL '3' hour", "Cannot add hour, minutes or seconds to a date"); + assertInvalidFunction("INTERVAL '3' hour + DATE '2001-1-22'", "Cannot add hour, minutes or seconds to a date"); + } + + @Test + public void testTimePlusInterval() + { + assertFunction("TIME '03:04:05.321' + INTERVAL '3' hour", TIME, sqlTimeOf(6, 4, 5, 321)); + assertFunction("INTERVAL '3' hour + TIME '03:04:05.321'", TIME, sqlTimeOf(6, 4, 5, 321)); + assertFunction("TIME '03:04:05.321' + INTERVAL '3' day", TIME, sqlTimeOf(3, 4, 5, 321)); + assertFunction("INTERVAL '3' day + TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321)); + + assertFunction("TIME '03:04:05.321' + INTERVAL '27' hour", TIME, sqlTimeOf(6, 4, 5, 321)); + assertFunction("INTERVAL '27' hour + TIME '03:04:05.321'", TIME, sqlTimeOf(6, 4, 5, 321)); + + assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' hour", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' hour + TIME '03:04:05.321 +05:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' day", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' day + TIME '03:04:05.321 +05:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + + assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '27' hour", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '27' hour + TIME '03:04:05.321 +05:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testTimestampPlusInterval() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' hour", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 6, 4, 5, 321)); + assertFunction("INTERVAL '3' hour + TIMESTAMP '2001-1-22 03:04:05.321'", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 6, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' day", + TIMESTAMP, + sqlTimestampOf(2001, 1, 25, 3, 4, 5, 321)); + assertFunction("INTERVAL '3' day + TIMESTAMP '2001-1-22 03:04:05.321'", + TIMESTAMP, + sqlTimestampOf(2001, 1, 25, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' month", + TIMESTAMP, + sqlTimestampOf(2001, 4, 22, 3, 4, 5, 321)); + assertFunction("INTERVAL '3' month + TIMESTAMP '2001-1-22 03:04:05.321'", + TIMESTAMP, + sqlTimestampOf(2001, 4, 22, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' year", + TIMESTAMP, + sqlTimestampOf(2004, 1, 22, 3, 4, 5, 321)); + assertFunction("INTERVAL '3' year + TIMESTAMP '2001-1-22 03:04:05.321'", + TIMESTAMP, + sqlTimestampOf(2004, 1, 22, 3, 4, 5, 321)); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' hour", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' hour + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' day", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 25, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' day + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 25, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' month", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 4, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' month + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 4, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' year", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2004, 1, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("INTERVAL '3' year + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2004, 1, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testDateMinusInterval() + { + assertFunction("DATE '2001-1-22' - INTERVAL '3' day", DATE, toDate(new DateTime(2001, 1, 19, 0, 0, 0, 0, UTC))); + + assertInvalidFunction("DATE '2001-1-22' - INTERVAL '3' hour", "Cannot subtract hour, minutes or seconds from a date"); + } + + @Test + public void testTimeMinusInterval() + { + assertFunction("TIME '03:04:05.321' - INTERVAL '3' hour", TIME, sqlTimeOf(0, 4, 5, 321)); + assertFunction("TIME '03:04:05.321' - INTERVAL '3' day", TIME, sqlTimeOf(3, 4, 5, 321)); + + assertFunction("TIME '03:04:05.321' - INTERVAL '6' hour", TIME, sqlTimeOf(21, 4, 5, 321)); + + assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' hour", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 0, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' day", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '6' hour", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 21, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testTimestampMinusInterval() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' - INTERVAL '3' day", + TIMESTAMP, + sqlTimestampOf(2001, 1, 19, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' - INTERVAL '3' day", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 19, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' - INTERVAL '3' month", + TIMESTAMP, + sqlTimestampOf(2000, 10, 22, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' - INTERVAL '3' month", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2000, 10, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testDateToTimestampCoercing() + { + assertFunction("date_format(DATE '2013-10-27', '%Y-%m-%d %H:%i:%s')", VARCHAR, "2013-10-27 00:00:00"); + + assertFunction("DATE '2013-10-27' = TIMESTAMP '2013-10-27 00:00:00'", BOOLEAN, true); + assertFunction("DATE '2013-10-27' < TIMESTAMP '2013-10-27 00:00:01'", BOOLEAN, true); + assertFunction("DATE '2013-10-27' > TIMESTAMP '2013-10-26 23:59:59'", BOOLEAN, true); + } + + @Test + public void testDateToTimestampWithZoneCoercing() + { + assertFunction("DATE '2013-10-27' = TIMESTAMP '2013-10-27 00:00:00 Europe/Berlin'", BOOLEAN, true); + assertFunction("DATE '2013-10-27' < TIMESTAMP '2013-10-27 00:00:01 Europe/Berlin'", BOOLEAN, true); + assertFunction("DATE '2013-10-27' > TIMESTAMP '2013-10-26 23:59:59 Europe/Berlin'", BOOLEAN, true); + } + + @Test + public void testIsDistinctFrom() + { + assertFunction("CAST(NULL AS DATE) IS DISTINCT FROM CAST(NULL AS DATE)", BOOLEAN, false); + assertFunction("DATE '2013-10-27' IS DISTINCT FROM TIMESTAMP '2013-10-27 00:00:00'", BOOLEAN, false); + assertFunction("DATE '2013-10-27' IS DISTINCT FROM TIMESTAMP '2013-10-28 00:00:00'", BOOLEAN, true); + assertFunction("NULL IS DISTINCT FROM DATE '2013-10-27'", BOOLEAN, true); + assertFunction("DATE '2013-10-27' IS DISTINCT FROM NULL", BOOLEAN, true); + } + + @Test + public void testDateCastFromVarchar() + { + assertFunction("DATE '2013-02-02'", DATE, toDate(new DateTime(2013, 2, 2, 0, 0, 0, 0, UTC))); + assertInvalidFunction("DATE '392251590-07-12'", INVALID_CAST_ARGUMENT, "Value cannot be cast to date: 392251590-07-12"); + } + + private static SqlDate toDate(DateTime dateTime) + { + return new SqlDate((int) TimeUnit.MILLISECONDS.toDays(dateTime.getMillis())); + } } diff --git a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsBase.java b/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsBase.java deleted file mode 100644 index 741d44ff0..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsBase.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.operator.scalar.AbstractTestFunctions; -import io.prestosql.spi.type.SqlDate; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeZoneKey; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import java.util.concurrent.TimeUnit; - -import static io.prestosql.spi.type.BooleanType.BOOLEAN; -import static io.prestosql.spi.type.DateType.DATE; -import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static org.joda.time.DateTimeZone.UTC; - -public abstract class TestDateTimeOperatorsBase - extends AbstractTestFunctions -{ - protected static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); - protected static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - protected static final DateTimeZone WEIRD_TIME_ZONE = DateTimeZone.forOffsetHoursMinutes(5, 9); - protected static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(5 * 60 + 9); - - protected TestDateTimeOperatorsBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(TIME_ZONE_KEY) - .build()); - } - - @Test - public void testDatePlusInterval() - { - assertFunction("DATE '2001-1-22' + INTERVAL '3' day", DATE, toDate(new DateTime(2001, 1, 25, 0, 0, 0, 0, UTC))); - assertFunction("INTERVAL '3' day + DATE '2001-1-22'", DATE, toDate(new DateTime(2001, 1, 25, 0, 0, 0, 0, UTC))); - assertFunction("DATE '2001-1-22' + INTERVAL '3' month", DATE, toDate(new DateTime(2001, 4, 22, 0, 0, 0, 0, UTC))); - assertFunction("INTERVAL '3' month + DATE '2001-1-22'", DATE, toDate(new DateTime(2001, 4, 22, 0, 0, 0, 0, UTC))); - assertFunction("DATE '2001-1-22' + INTERVAL '3' year", DATE, toDate(new DateTime(2004, 1, 22, 0, 0, 0, 0, UTC))); - assertFunction("INTERVAL '3' year + DATE '2001-1-22'", DATE, toDate(new DateTime(2004, 1, 22, 0, 0, 0, 0, UTC))); - - assertInvalidFunction("DATE '2001-1-22' + INTERVAL '3' hour", "Cannot add hour, minutes or seconds to a date"); - assertInvalidFunction("INTERVAL '3' hour + DATE '2001-1-22'", "Cannot add hour, minutes or seconds to a date"); - } - - @Test - public void testTimePlusInterval() - { - assertFunction("TIME '03:04:05.321' + INTERVAL '3' hour", TIME, sqlTimeOf(6, 4, 5, 321, session)); - assertFunction("INTERVAL '3' hour + TIME '03:04:05.321'", TIME, sqlTimeOf(6, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' + INTERVAL '3' day", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' day + TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' + INTERVAL '3' month", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' month + TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' + INTERVAL '3' year", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' year + TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321, session)); - - assertFunction("TIME '03:04:05.321' + INTERVAL '27' hour", TIME, sqlTimeOf(6, 4, 5, 321, session)); - assertFunction("INTERVAL '27' hour + TIME '03:04:05.321'", TIME, sqlTimeOf(6, 4, 5, 321, session)); - - assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' hour", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' hour + TIME '03:04:05.321 +05:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' day", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' day + TIME '03:04:05.321 +05:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' month", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' month + TIME '03:04:05.321 +05:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '3' year", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' year + TIME '03:04:05.321 +05:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - - assertFunction("TIME '03:04:05.321 +05:09' + INTERVAL '27' hour", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '27' hour + TIME '03:04:05.321 +05:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testTimestampPlusInterval() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' hour", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 6, 4, 5, 321, session)); - assertFunction("INTERVAL '3' hour + TIMESTAMP '2001-1-22 03:04:05.321'", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 6, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' day", - TIMESTAMP, - sqlTimestampOf(2001, 1, 25, 3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' day + TIMESTAMP '2001-1-22 03:04:05.321'", - TIMESTAMP, - sqlTimestampOf(2001, 1, 25, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' month", - TIMESTAMP, - sqlTimestampOf(2001, 4, 22, 3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' month + TIMESTAMP '2001-1-22 03:04:05.321'", - TIMESTAMP, - sqlTimestampOf(2001, 4, 22, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' + INTERVAL '3' year", - TIMESTAMP, - sqlTimestampOf(2004, 1, 22, 3, 4, 5, 321, session)); - assertFunction("INTERVAL '3' year + TIMESTAMP '2001-1-22 03:04:05.321'", - TIMESTAMP, - sqlTimestampOf(2004, 1, 22, 3, 4, 5, 321, session)); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' hour", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' hour + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 6, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' day", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 25, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' day + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 25, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' month", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 4, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' month + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 4, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' + INTERVAL '3' year", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2004, 1, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("INTERVAL '3' year + TIMESTAMP '2001-1-22 03:04:05.321 +05:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2004, 1, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testDateMinusInterval() - { - assertFunction("DATE '2001-1-22' - INTERVAL '3' day", DATE, toDate(new DateTime(2001, 1, 19, 0, 0, 0, 0, UTC))); - - assertInvalidFunction("DATE '2001-1-22' - INTERVAL '3' hour", "Cannot subtract hour, minutes or seconds from a date"); - } - - @Test - public void testTimeMinusInterval() - { - assertFunction("TIME '03:04:05.321' - INTERVAL '3' hour", TIME, sqlTimeOf(0, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' - INTERVAL '3' day", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' - INTERVAL '3' month", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("TIME '03:04:05.321' - INTERVAL '3' year", TIME, sqlTimeOf(3, 4, 5, 321, session)); - - assertFunction("TIME '03:04:05.321' - INTERVAL '6' hour", TIME, sqlTimeOf(21, 4, 5, 321, session)); - - assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' hour", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 0, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' day", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' month", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '3' year", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05.321 +05:09' - INTERVAL '6' hour", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 21, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testTimestampMinusInterval() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' - INTERVAL '3' day", - TIMESTAMP, - sqlTimestampOf(2001, 1, 19, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' - INTERVAL '3' day", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 19, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' - INTERVAL '3' month", - TIMESTAMP, - sqlTimestampOf(2000, 10, 22, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +05:09' - INTERVAL '3' month", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2000, 10, 22, 3, 4, 5, 321, WEIRD_TIME_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testDateToTimestampCoercing() - { - assertFunction("date_format(DATE '2013-10-27', '%Y-%m-%d %H:%i:%s')", VARCHAR, "2013-10-27 00:00:00"); - - assertFunction("DATE '2013-10-27' = TIMESTAMP '2013-10-27 00:00:00'", BOOLEAN, true); - assertFunction("DATE '2013-10-27' < TIMESTAMP '2013-10-27 00:00:01'", BOOLEAN, true); - assertFunction("DATE '2013-10-27' > TIMESTAMP '2013-10-26 23:59:59'", BOOLEAN, true); - } - - @Test - public void testDateToTimestampWithZoneCoercing() - { - assertFunction("DATE '2013-10-27' = TIMESTAMP '2013-10-27 00:00:00 Europe/Berlin'", BOOLEAN, true); - assertFunction("DATE '2013-10-27' < TIMESTAMP '2013-10-27 00:00:01 Europe/Berlin'", BOOLEAN, true); - assertFunction("DATE '2013-10-27' > TIMESTAMP '2013-10-26 23:59:59 Europe/Berlin'", BOOLEAN, true); - } - - @Test - public void testIsDistinctFrom() - { - assertFunction("CAST(NULL AS DATE) IS DISTINCT FROM CAST(NULL AS DATE)", BOOLEAN, false); - assertFunction("DATE '2013-10-27' IS DISTINCT FROM TIMESTAMP '2013-10-27 00:00:00'", BOOLEAN, false); - assertFunction("DATE '2013-10-27' IS DISTINCT FROM TIMESTAMP '2013-10-28 00:00:00'", BOOLEAN, true); - assertFunction("NULL IS DISTINCT FROM DATE '2013-10-27'", BOOLEAN, true); - assertFunction("DATE '2013-10-27' IS DISTINCT FROM NULL", BOOLEAN, true); - } - - private static SqlDate toDate(DateTime dateTime) - { - return new SqlDate((int) TimeUnit.MILLISECONDS.toDays(dateTime.getMillis())); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsLegacy.java deleted file mode 100644 index fcfdd582e..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestDateTimeOperatorsLegacy.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.Session; -import io.prestosql.operator.scalar.FunctionAssertions; -import io.prestosql.spi.type.SqlTime; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.Type; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Verify.verify; -import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static java.util.concurrent.TimeUnit.HOURS; - -public class TestDateTimeOperatorsLegacy - extends TestDateTimeOperatorsBase -{ - public TestDateTimeOperatorsLegacy() - { - super(true); - } - - @Test - public void testTimeZoneGap() - { - // Time zone gap should be applied - - assertFunction( - "TIMESTAMP '2013-03-31 00:05' + INTERVAL '1' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 1, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-03-31 00:05' + INTERVAL '2' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 3, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-03-31 00:05' + INTERVAL '3' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 4, 5, 0, 0, session)); - - assertFunction( - "TIMESTAMP '2013-03-31 04:05' - INTERVAL '3' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 0, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-03-31 03:05' - INTERVAL '2' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 0, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-03-31 01:05' - INTERVAL '1' hour", - TIMESTAMP, - sqlTimestampOf(2013, 3, 31, 0, 5, 0, 0, session)); - } - - @Test - public void testDaylightTimeSaving() - { - // See testDaylightTimeSavingSwitchCrossingIsNotApplied for new semantics - assertFunction( - "TIMESTAMP '2013-10-27 00:05' + INTERVAL '1' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 1, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-10-27 00:05' + INTERVAL '2' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0, session)); - // we need to manipulate millis directly here because 2 am has two representations in out time zone, and we need the second one - assertFunction( - "TIMESTAMP '2013-10-27 00:05' + INTERVAL '3' hour", - TIMESTAMP, - sqlTimestampOf(new DateTime(2013, 10, 27, 0, 5, 0, 0, DATE_TIME_ZONE).plus(HOURS.toMillis(3)), session)); - assertFunction( - "TIMESTAMP '2013-10-27 00:05' + INTERVAL '4' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 3, 5, 0, 0, session)); - - assertFunction( - "TIMESTAMP '2013-10-27 03:05' - INTERVAL '4' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-10-27 02:05' - INTERVAL '2' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0, session)); - assertFunction( - "TIMESTAMP '2013-10-27 01:05' - INTERVAL '1' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 0, 5, 0, 0, session)); - - assertFunction( - "TIMESTAMP '2013-10-27 03:05' - INTERVAL '1' hour", - TIMESTAMP, - sqlTimestampOf(new DateTime(2013, 10, 27, 0, 5, 0, 0, DATE_TIME_ZONE).plus(HOURS.toMillis(3)), session)); - assertFunction( - "TIMESTAMP '2013-10-27 03:05' - INTERVAL '2' hour", - TIMESTAMP, - sqlTimestampOf(2013, 10, 27, 2, 5, 0, 0, session)); - } - - @Test - public void testTimeWithTimeZoneRepresentation() - { - // PST -> PDT date - testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PDT -> PST date - testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PDT date - testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PST date - testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000 America/Los_Angeles'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(41400000, getTimeZoneKey("America/Los_Angeles"))); - } - - @Test - public void testTimeRepresentation() - { - // PST -> PDT date - testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000'", - TIME, - new SqlTime(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 3, 12, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000'", - TIME, - new SqlTime(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PDT -> PST date - testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000'", - TIME, - new SqlTime(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 10, 4, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000'", - TIME, - new SqlTime(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PDT date - testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000'", - TIME, - new SqlTime(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 6, 6, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000'", - TIME, - new SqlTime(41400000, getTimeZoneKey("America/Los_Angeles"))); - - // PST date - testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '02:30:00.000'", - TIME, - new SqlTime(37800000, getTimeZoneKey("America/Los_Angeles"))); - testTimeRepresentationOnDate( - new DateTime(2017, 11, 1, 10, 0, 0, 0, DateTimeZone.UTC), - "TIME '03:30:00.000'", - TIME, - new SqlTime(41400000, getTimeZoneKey("America/Los_Angeles"))); - } - - private void testTimeRepresentationOnDate(DateTime date, String timeLiteral, Type expectedType, Object expected) - { - Session localSession = testSessionBuilder() - .setTimeZoneKey(getTimeZoneKey("America/Los_Angeles")) - .setStartTime(date.getMillis()) - .setSystemProperty("legacy_timestamp", "true") - .build(); - - try (FunctionAssertions localAssertions = new FunctionAssertions(localSession)) { - localAssertions.assertFunction(timeLiteral, expectedType, expected); - localAssertions.assertFunctionString(timeLiteral, expectedType, valueFromLiteral(timeLiteral)); - } - } - - private String valueFromLiteral(String literal) - { - Pattern p = Pattern.compile("'(.*)'"); - Matcher m = p.matcher(literal); - verify(m.find()); - return m.group(1); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestJsonOperators.java b/presto-main/src/test/java/io/prestosql/type/TestJsonOperators.java index cc1674229..70a81c2e3 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestJsonOperators.java +++ b/presto-main/src/test/java/io/prestosql/type/TestJsonOperators.java @@ -392,7 +392,7 @@ public class TestJsonOperators public void testCastFromTimestamp() { assertFunction("cast(cast (null as timestamp) as JSON)", JSON, null); - assertFunction("CAST(TIMESTAMP '1970-01-01 00:00:01' AS JSON)", JSON, format("\"%s\"", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + assertFunction("CAST(TIMESTAMP '1970-01-01 00:00:01' AS JSON)", JSON, format("\"%s\"", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); } @Test diff --git a/presto-main/src/test/java/io/prestosql/type/TestMapOperators.java b/presto-main/src/test/java/io/prestosql/type/TestMapOperators.java index aa913358b..311c6ca16 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestMapOperators.java +++ b/presto-main/src/test/java/io/prestosql/type/TestMapOperators.java @@ -38,7 +38,6 @@ import java.util.Map; import static com.google.common.base.Preconditions.checkArgument; import static io.airlift.slice.Slices.utf8Slice; -import static io.prestosql.SessionTestUtils.TEST_SESSION; import static io.prestosql.spi.function.OperatorType.HASH_CODE; import static io.prestosql.spi.function.OperatorType.INDETERMINATE; import static io.prestosql.spi.type.BigintType.BIGINT; @@ -104,16 +103,16 @@ public class TestMapOperators mapType(createVarcharType(3), TIMESTAMP), ImmutableMap.of( "1", - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), "100", - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION))); + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0))); assertFunction( "MAP(ARRAY[TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'], ARRAY[1.0E0, 100.0E0])", mapType(TIMESTAMP, DOUBLE), ImmutableMap.of( - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION), + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0), 1.0, - sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0, TEST_SESSION), + sqlTimestampOf(1973, 7, 8, 22, 0, 1, 0), 100.0)); assertInvalidFunction("MAP(ARRAY [1], ARRAY [2, 4])", "Key and value arrays must be the same length"); @@ -246,7 +245,7 @@ public class TestMapOperators assertFunction( "CAST(MAP(ARRAY[1, 2], ARRAY[TIMESTAMP '1970-01-01 00:00:01', null]) AS JSON)", JSON, - format("{\"1\":\"%s\",\"2\":null}", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION).toString())); + format("{\"1\":\"%s\",\"2\":null}", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0).toString())); assertFunction( "CAST(MAP(ARRAY[2, 5, 3], ARRAY[DATE '2001-08-22', DATE '2001-08-23', null]) AS JSON)", JSON, @@ -518,7 +517,7 @@ public class TestMapOperators assertFunction( "element_at(MAP(ARRAY ['1', '100'], ARRAY [TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '2005-09-10 13:00:00']), '1')", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION)); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0)); assertFunction("element_at(MAP(ARRAY [from_unixtime(1), from_unixtime(100)], ARRAY [1.0E0, 100.0E0]), from_unixtime(1))", DOUBLE, 1.0); } @@ -543,7 +542,7 @@ public class TestMapOperators assertFunction( "MAP(ARRAY['1', '100'], ARRAY[TIMESTAMP '1970-01-01 00:00:01', TIMESTAMP '1973-07-08 22:00:01'])['1']", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION)); + sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0)); assertFunction("MAP(ARRAY[from_unixtime(1), from_unixtime(100)], ARRAY[1.0E0, 100.0E0])[from_unixtime(1)]", DOUBLE, 1.0); assertInvalidFunction("MAP(ARRAY [BIGINT '1'], ARRAY [BIGINT '2'])[3]", "Key not present in map: 3"); assertInvalidFunction("MAP(ARRAY ['hi'], ARRAY [2])['missing']", "Key not present in map: missing"); @@ -563,7 +562,7 @@ public class TestMapOperators assertFunction( "MAP_KEYS(MAP(ARRAY[TIMESTAMP '1970-01-01 00:00:01'], ARRAY[1.0E0]))", new ArrayType(TIMESTAMP), - ImmutableList.of(sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + ImmutableList.of(sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction("MAP_KEYS(MAP(ARRAY[CAST('puppies' as varbinary)], ARRAY['kittens']))", new ArrayType(VARBINARY), ImmutableList.of(new SqlVarbinary("puppies".getBytes(UTF_8)))); assertFunction("MAP_KEYS(MAP(ARRAY[1,2], ARRAY[ARRAY[1, 2], ARRAY[3]]))", new ArrayType(INTEGER), ImmutableList.of(1, 2)); assertFunction("MAP_KEYS(MAP(ARRAY[1,4], ARRAY[MAP(ARRAY[2], ARRAY[3]), MAP(ARRAY[5], ARRAY[6])]))", new ArrayType(INTEGER), ImmutableList.of(1, 4)); diff --git a/presto-main/src/test/java/io/prestosql/type/TestRowOperators.java b/presto-main/src/test/java/io/prestosql/type/TestRowOperators.java index 3cd252bef..7f527d03f 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestRowOperators.java +++ b/presto-main/src/test/java/io/prestosql/type/TestRowOperators.java @@ -38,7 +38,6 @@ import java.util.List; import java.util.Set; import static com.google.common.base.Preconditions.checkArgument; -import static io.prestosql.SessionTestUtils.TEST_SESSION; import static io.prestosql.spi.function.OperatorType.HASH_CODE; import static io.prestosql.spi.function.OperatorType.INDETERMINATE; import static io.prestosql.spi.type.BigintType.BIGINT; @@ -119,7 +118,7 @@ public class TestRowOperators assertFunction( "CAST(ROW(TIMESTAMP '1970-01-01 00:00:01', cast(null as TIMESTAMP)) AS JSON)", JSON, - format("[\"%s\",null]", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0, TEST_SESSION))); + format("[\"%s\",null]", sqlTimestampOf(1970, 1, 1, 0, 0, 1, 0))); assertFunction( "cast(ROW(ARRAY[1, 2], ARRAY[3, null], ARRAY[], ARRAY[null, null], CAST(null AS ARRAY)) AS JSON)", diff --git a/presto-main/src/test/java/io/prestosql/type/TestTime.java b/presto-main/src/test/java/io/prestosql/type/TestTime.java deleted file mode 100644 index 9cadbddd5..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTime.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -public class TestTime - extends TestTimeBase -{ - public TestTime() - { - super(false); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimeBase.java b/presto-main/src/test/java/io/prestosql/type/TestTimeBase.java index 2355d5c9c..faa3c582f 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestTimeBase.java +++ b/presto-main/src/test/java/io/prestosql/type/TestTimeBase.java @@ -39,16 +39,15 @@ import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.testing.TestingSession.testSessionBuilder; import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; -public abstract class TestTimeBase +public class TestTimeBase extends AbstractTestFunctions { protected static final TimeZoneKey TIME_ZONE_KEY = TestingSession.DEFAULT_TIME_ZONE_KEY; protected static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - public TestTimeBase(boolean legacyTimestamp) + public TestTimeBase() { super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) .setTimeZoneKey(TIME_ZONE_KEY) .build()); } @@ -56,9 +55,9 @@ public abstract class TestTimeBase @Test public void testLiteral() { - assertFunction("TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321, session)); - assertFunction("TIME '03:04:05'", TIME, sqlTimeOf(3, 4, 5, 0, session)); - assertFunction("TIME '03:04'", TIME, sqlTimeOf(3, 4, 0, 0, session)); + assertFunction("TIME '03:04:05.321'", TIME, sqlTimeOf(3, 4, 5, 321)); + assertFunction("TIME '03:04:05'", TIME, sqlTimeOf(3, 4, 5, 0)); + assertFunction("TIME '03:04'", TIME, sqlTimeOf(3, 4, 0, 0)); assertInvalidFunction("TIME 'text'", SemanticErrorCode.INVALID_LITERAL, "line 1:1: 'text' is not a valid time literal"); } @@ -178,7 +177,7 @@ public abstract class TestTimeBase { assertFunction("cast(TIME '03:04:05.321' as timestamp)", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 3, 4, 5, 321, session)); + sqlTimestampOf(1970, 1, 1, 3, 4, 5, 321)); } @Test diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimeLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestTimeLegacy.java deleted file mode 100644 index 5d30cddcb..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimeLegacy.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -public class TestTimeLegacy - extends TestTimeBase -{ - public TestTimeLegacy() - { - super(true); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZone.java b/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZone.java index aadb387b0..dcdb55709 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZone.java +++ b/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZone.java @@ -13,36 +13,229 @@ */ package io.prestosql.type; +import io.prestosql.operator.scalar.AbstractTestFunctions; +import io.prestosql.spi.type.SqlTimeWithTimeZone; +import io.prestosql.spi.type.SqlTimestampWithTimeZone; +import io.prestosql.spi.type.TimeZoneKey; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; +import static io.prestosql.spi.function.OperatorType.INDETERMINATE; +import static io.prestosql.spi.type.BooleanType.BOOLEAN; import static io.prestosql.spi.type.TimeType.TIME; +import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; +import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; +import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; +import static io.prestosql.testing.TestingSession.testSessionBuilder; +import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; public class TestTimeWithTimeZone - extends TestTimeWithTimeZoneBase + extends AbstractTestFunctions { + private static final DateTimeZone WEIRD_ZONE = DateTimeZone.forOffsetHoursMinutes(7, 9); + private static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(7 * 60 + 9); + public TestTimeWithTimeZone() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(getTimeZoneKey("+06:09")) + .build()); + } + + @Test + public void testLiteral() + { + assertFunction("TIME '03:04:05.321 +07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '03:04:05 +07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '03:04 +07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + + assertFunction("TIME '3:4:5.321+07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '3:4:5+07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIME '3:4+07:09'", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testSubtract() + { + functionAssertions.assertFunctionString("TIME '14:15:16.432 +07:09' - TIME '03:04:05.321 +08:09'", + INTERVAL_DAY_TIME, + "0 12:11:11.111"); + + functionAssertions.assertFunctionString("TIME '03:04:05.321 +08:09' - TIME '14:15:16.432 +07:09'", + INTERVAL_DAY_TIME, + "-0 12:11:11.111"); + } + + @Test + public void testEqual() + { + assertFunction("TIME '03:04:05.321 +07:09' = TIME '03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.321'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' = TIME '03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.333'", BOOLEAN, false); + } + + @Test + public void testNotEqual() + { + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.333'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.321'", BOOLEAN, false); + } + + @Test + public void testLessThan() + { + assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.333'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.321'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05'", BOOLEAN, false); + } + + @Test + public void testLessThanOrEqual() + { + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.333'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.321'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05'", BOOLEAN, false); + } + + @Test + public void testGreaterThan() + { + assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.111 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.111 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.111'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.321'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.333'", BOOLEAN, false); + } + + @Test + public void testGreaterThanOrEqual() + { + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.111 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.111 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.111'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.321'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.333'", BOOLEAN, false); + } + + @Test + public void testBetween() + { + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.111 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111' and TIME '02:04:05.333'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.321 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321' and TIME '02:04:05.333'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.111 +07:09' and TIME '03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111 +06:09' and TIME '02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111' and TIME '02:04:05.321'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.321 +07:09' and TIME '03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321 +06:09' and TIME '02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321' and TIME '02:04:05.321'", BOOLEAN, true); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.322 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.322 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.322' and TIME '02:04:05.333'", BOOLEAN, false); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.311 +07:09' and TIME '03:04:05.312 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.311 +06:09' and TIME '02:04:05.312 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.311' and TIME '02:04:05.312'", BOOLEAN, false); + + assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.333 +07:09' and TIME '03:04:05.111 +07:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.333 +06:09' and TIME '02:04:05.111 +06:09'", BOOLEAN, false); + assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.333' and TIME '02:04:05.111'", BOOLEAN, false); } @Test - @Override public void testCastToTime() { assertFunction("cast(TIME '03:04:05.321 +07:09' as time)", TIME, - sqlTimeOf(3, 4, 5, 321, session)); + sqlTimeOf(3, 4, 5, 321)); } @Test - @Override public void testCastToTimestamp() { assertFunction("cast(TIME '03:04:05.321 +07:09' as timestamp)", TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 3, 4, 5, 321, session)); + sqlTimestampOf(1970, 1, 1, 3, 4, 5, 321)); + } + + @Test + public void testCastToTimestampWithTimeZone() + { + assertFunction("cast(TIME '03:04:05.321 +07:09' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testCastToSlice() + { + assertFunction("cast(TIME '03:04:05.321 +07:09' as varchar)", VARCHAR, "03:04:05.321 +07:09"); + assertFunction("cast(TIME '03:04:05 +07:09' as varchar)", VARCHAR, "03:04:05.000 +07:09"); + assertFunction("cast(TIME '03:04 +07:09' as varchar)", VARCHAR, "03:04:00.000 +07:09"); + } + + @Test + public void testIndeterminate() + { + assertOperator(INDETERMINATE, "cast(null as TIME WITH TIME ZONE)", BOOLEAN, true); + assertOperator(INDETERMINATE, "TIME '03:04:05 +07:09'", BOOLEAN, false); } } diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneBase.java b/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneBase.java deleted file mode 100644 index 9febb18b4..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneBase.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.operator.scalar.AbstractTestFunctions; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeZoneKey; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import static io.prestosql.spi.function.OperatorType.INDETERMINATE; -import static io.prestosql.spi.type.BooleanType.BOOLEAN; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; - -public abstract class TestTimeWithTimeZoneBase - extends AbstractTestFunctions -{ - private static final DateTimeZone WEIRD_ZONE = DateTimeZone.forOffsetHoursMinutes(7, 9); - private static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(7 * 60 + 9); - - protected TestTimeWithTimeZoneBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(getTimeZoneKey("+06:09")) - .build()); - } - - @Test - public void testLiteral() - { - assertFunction("TIME '03:04:05.321 +07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04:05 +07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '03:04 +07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - - assertFunction("TIME '3:4:5.321+07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '3:4:5+07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIME '3:4+07:09'", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testSubtract() - { - functionAssertions.assertFunctionString("TIME '14:15:16.432 +07:09' - TIME '03:04:05.321 +08:09'", - INTERVAL_DAY_TIME, - "0 12:11:11.111"); - - functionAssertions.assertFunctionString("TIME '03:04:05.321 +08:09' - TIME '14:15:16.432 +07:09'", - INTERVAL_DAY_TIME, - "-0 12:11:11.111"); - } - - @Test - public void testEqual() - { - assertFunction("TIME '03:04:05.321 +07:09' = TIME '03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.321'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' = TIME '03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' = TIME '02:04:05.333'", BOOLEAN, false); - } - - @Test - public void testNotEqual() - { - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.333'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' <> TIME '02:04:05.321'", BOOLEAN, false); - } - - @Test - public void testLessThan() - { - assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.333'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05.321'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '03:04:05 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' < TIME '02:04:05'", BOOLEAN, false); - } - - @Test - public void testLessThanOrEqual() - { - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.333'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05.321'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '03:04:05 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' <= TIME '02:04:05'", BOOLEAN, false); - } - - @Test - public void testGreaterThan() - { - assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.111 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.111 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.111'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.321'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' > TIME '02:04:05.333'", BOOLEAN, false); - } - - @Test - public void testGreaterThanOrEqual() - { - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.111 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.111 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.111'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.321'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' >= TIME '02:04:05.333'", BOOLEAN, false); - } - - @Test - public void testBetween() - { - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.111 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111' and TIME '02:04:05.333'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.321 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321' and TIME '02:04:05.333'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.111 +07:09' and TIME '03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111 +06:09' and TIME '02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.111' and TIME '02:04:05.321'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.321 +07:09' and TIME '03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321 +06:09' and TIME '02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.321' and TIME '02:04:05.321'", BOOLEAN, true); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.322 +07:09' and TIME '03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.322 +06:09' and TIME '02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.322' and TIME '02:04:05.333'", BOOLEAN, false); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.311 +07:09' and TIME '03:04:05.312 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.311 +06:09' and TIME '02:04:05.312 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.311' and TIME '02:04:05.312'", BOOLEAN, false); - - assertFunction("TIME '03:04:05.321 +07:09' between TIME '03:04:05.333 +07:09' and TIME '03:04:05.111 +07:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.333 +06:09' and TIME '02:04:05.111 +06:09'", BOOLEAN, false); - assertFunction("TIME '03:04:05.321 +07:09' between TIME '02:04:05.333' and TIME '02:04:05.111'", BOOLEAN, false); - } - - @Test - public abstract void testCastToTime(); - - @Test - public abstract void testCastToTimestamp(); - - @Test - public void testCastToTimestampWithTimeZone() - { - assertFunction("cast(TIME '03:04:05.321 +07:09' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testCastToSlice() - { - assertFunction("cast(TIME '03:04:05.321 +07:09' as varchar)", VARCHAR, "03:04:05.321 +07:09"); - assertFunction("cast(TIME '03:04:05 +07:09' as varchar)", VARCHAR, "03:04:05.000 +07:09"); - assertFunction("cast(TIME '03:04 +07:09' as varchar)", VARCHAR, "03:04:00.000 +07:09"); - } - - @Test - public void testIndeterminate() - { - assertOperator(INDETERMINATE, "cast(null as TIME WITH TIME ZONE)", BOOLEAN, true); - assertOperator(INDETERMINATE, "TIME '03:04:05 +07:09'", BOOLEAN, false); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneLegacy.java deleted file mode 100644 index 47f24c917..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimeWithTimeZoneLegacy.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import org.testng.annotations.Test; - -import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; - -public class TestTimeWithTimeZoneLegacy - extends TestTimeWithTimeZoneBase -{ - public TestTimeWithTimeZoneLegacy() - { - super(true); - } - - @Test - @Override - public void testCastToTime() - { - assertFunction("cast(TIME '03:04:05.321 +07:09' as time)", - TIME, - sqlTimeOf(2 /* not 3 */, 4, 5, 321, session)); - } - - @Test - @Override - public void testCastToTimestamp() - { - assertFunction("cast(TIME '03:04:05.321 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(1970, 1, 1, 2 /* not 3 */, 4, 5, 321, session)); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestamp.java b/presto-main/src/test/java/io/prestosql/type/TestTimestamp.java index d2bf57257..7fd5ea5be 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestamp.java +++ b/presto-main/src/test/java/io/prestosql/type/TestTimestamp.java @@ -13,19 +13,47 @@ */ package io.prestosql.type; +import io.prestosql.operator.scalar.AbstractTestFunctions; +import io.prestosql.spi.type.SqlDate; +import io.prestosql.spi.type.SqlTimeWithTimeZone; +import io.prestosql.spi.type.SqlTimestampWithTimeZone; +import io.prestosql.spi.type.TimeZoneKey; +import io.prestosql.testing.TestingSession; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; import java.time.LocalDateTime; +import java.util.concurrent.TimeUnit; +import static io.prestosql.spi.function.OperatorType.INDETERMINATE; +import static io.prestosql.spi.type.BooleanType.BOOLEAN; +import static io.prestosql.spi.type.DateType.DATE; +import static io.prestosql.spi.type.TimeType.TIME; +import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; +import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; +import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; +import static io.prestosql.sql.analyzer.SemanticErrorCode.INVALID_LITERAL; +import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; +import static io.prestosql.testing.TestingSession.testSessionBuilder; +import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; +import static io.prestosql.type.JsonType.JSON; +import static org.joda.time.DateTimeZone.UTC; public class TestTimestamp - extends TestTimestampBase + extends AbstractTestFunctions { + private static final TimeZoneKey TIME_ZONE_KEY = TestingSession.DEFAULT_TIME_ZONE_KEY; + private static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); + public TestTimestamp() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(TIME_ZONE_KEY) + .build()); } @Test @@ -65,4 +93,234 @@ public class TestTimestamp TIMESTAMP, sqlTimestampOf(LocalDateTime.of(2001, 1, 22, 0, 0, 0))); } + + @Test + public void testSubtract() + { + functionAssertions.assertFunctionString("TIMESTAMP '2017-03-30 14:15:16.432' - TIMESTAMP '2016-03-29 03:04:05.321'", + INTERVAL_DAY_TIME, + "366 11:11:11.111"); + + functionAssertions.assertFunctionString("TIMESTAMP '2016-03-29 03:04:05.321' - TIMESTAMP '2017-03-30 14:15:16.432'", + INTERVAL_DAY_TIME, + "-366 11:11:11.111"); + } + + @Test + public void testLiteral() + { + assertFunction("TIMESTAMP '2013-03-30 01:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0)); + assertFunction("TIMESTAMP '2013-03-30 02:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 2, 5, 0, 0)); + assertFunction("TIMESTAMP '2013-03-30 03:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 3, 5, 0, 0)); + + assertFunction("TIMESTAMP '2001-01-22 03:04:05.321'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-01-22 03:04:05'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 5, 0)); + assertFunction("TIMESTAMP '2001-01-22 03:04'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 0, 0)); + assertFunction("TIMESTAMP '2001-01-22'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0)); + + assertFunction("TIMESTAMP '2001-1-2 3:4:5.321'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '2001-1-2 3:4:5'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 5, 0)); + assertFunction("TIMESTAMP '2001-1-2 3:4'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 0, 0)); + assertFunction("TIMESTAMP '2001-1-2'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 0, 0, 0, 0)); + + assertFunction("TIMESTAMP '123001-01-22 03:04:05.321'", TIMESTAMP, sqlTimestampOf(123001, 1, 22, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '+123001-01-22 03:04:05.321'", TIMESTAMP, sqlTimestampOf(123001, 1, 22, 3, 4, 5, 321)); + assertFunction("TIMESTAMP '-123001-01-22 03:04:05.321'", TIMESTAMP, sqlTimestampOf(-123001, 1, 22, 3, 4, 5, 321)); + + assertInvalidFunction("TIMESTAMP 'text'", INVALID_LITERAL, "line 1:1: 'text' is not a valid timestamp literal"); + } + + @Test + public void testEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' = TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' = TIMESTAMP '2001-1-22'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' = TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' = TIMESTAMP '2001-1-11'", BOOLEAN, false); + } + + @Test + public void testNotEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <> TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' <> TIMESTAMP '2001-1-11'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <> TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' <> TIMESTAMP '2001-1-22'", BOOLEAN, false); + } + + @Test + public void testLessThan() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-23'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-22'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-20'", BOOLEAN, false); + } + + @Test + public void testLessThanOrEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-23'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-22'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-20'", BOOLEAN, false); + } + + @Test + public void testGreaterThan() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-11'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-22'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-23'", BOOLEAN, false); + } + + @Test + public void testGreaterThanOrEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-11'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-22'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-23'", BOOLEAN, false); + } + + @Test + public void testBetween() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.111' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.321' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.111' and TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.321' and TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.322' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.311' and TIMESTAMP '2001-1-22 03:04:05.312'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.333' and TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, false); + } + + @Test + public void testCastToDate() + { + long millis = new DateTime(2001, 1, 22, 0, 0, UTC).getMillis(); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as date)", DATE, new SqlDate((int) TimeUnit.MILLISECONDS.toDays(millis))); + } + + @Test + public void testCastToTime() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time)", TIME, sqlTimeOf(3, 4, 5, 321)); + } + + @Test + public void testCastToTimeWithTimeZone() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time with time zone)", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time with time zone)", + TIME_WITH_TIME_ZONE, + "03:04:05.321 " + DATE_TIME_ZONE.getID()); + } + + @Test + public void testCastToTimestampWithTimeZone() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), TimeZoneKey.getTimeZoneKey(DATE_TIME_ZONE.toTimeZone().getID()))); + functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + "2001-01-22 03:04:05.321 " + DATE_TIME_ZONE.getID()); + } + + @Test + public void testCastToSlice() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as varchar)", VARCHAR, "2001-01-22 03:04:05.321"); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05' as varchar)", VARCHAR, "2001-01-22 03:04:05.000"); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04' as varchar)", VARCHAR, "2001-01-22 03:04:00.000"); + assertFunction("cast(TIMESTAMP '2001-1-22' as varchar)", VARCHAR, "2001-01-22 00:00:00.000"); + } + + @Test + public void testCastToJson() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as json)", JSON, "\"2001-01-22 03:04:05.321\""); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05' as json)", JSON, "\"2001-01-22 03:04:05.000\""); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04' as json)", JSON, "\"2001-01-22 03:04:00.000\""); + assertFunction("cast(TIMESTAMP '2001-1-22' as json)", JSON, "\"2001-01-22 00:00:00.000\""); + + assertFunction("cast(ARRAY[TIMESTAMP '2001-1-22 03:04:05.321'] as json)", JSON, "[\"2001-01-22 03:04:05.321\"]"); + assertFunction("cast(ARRAY[TIMESTAMP '2001-1-22 03:04:05'] as json)", JSON, "[\"2001-01-22 03:04:05.000\"]"); + assertFunction("cast(ARRAY[TIMESTAMP '2001-1-22 03:04'] as json)", JSON, "[\"2001-01-22 03:04:00.000\"]"); + assertFunction("cast(ARRAY[TIMESTAMP '2001-1-22'] as json)", JSON, "[\"2001-01-22 00:00:00.000\"]"); + } + + @Test + public void testCastFromSlice() + { + assertFunction("cast('2001-1-22 03:04:05.321' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + assertFunction("cast('2001-1-22 03:04:05' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 0)); + assertFunction("cast('2001-1-22 03:04' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 0, 0)); + assertFunction("cast('2001-1-22' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0)); + assertFunction("cast('\n\t 2001-1-22 03:04:05.321' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + assertFunction("cast('2001-1-22 03:04:05.321 \t\n' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + assertFunction("cast('\n\t 2001-1-22 03:04:05.321 \t\n' as timestamp)", + TIMESTAMP, + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + } + + @Test + public void testGreatest() + { + assertFunction("greatest(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05')", + TIMESTAMP, + sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0)); + assertFunction("greatest(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05', TIMESTAMP '2012-05-01 01:05')", + TIMESTAMP, + sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0)); + } + + @Test + public void testLeast() + { + assertFunction("least(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05')", + TIMESTAMP, + sqlTimestampOf(2012, 3, 30, 1, 5, 0, 0)); + assertFunction("least(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05', TIMESTAMP '2012-05-01 01:05')", + TIMESTAMP, + sqlTimestampOf(2012, 3, 30, 1, 5, 0, 0)); + } + + @Test + public void testIndeterminate() + { + assertOperator(INDETERMINATE, "cast(null as TIMESTAMP)", BOOLEAN, true); + assertOperator(INDETERMINATE, "TIMESTAMP '2012-03-30 01:05'", BOOLEAN, false); + } } diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestampBase.java b/presto-main/src/test/java/io/prestosql/type/TestTimestampBase.java deleted file mode 100644 index 3b49821ed..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestampBase.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.operator.scalar.AbstractTestFunctions; -import io.prestosql.spi.type.SqlDate; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeZoneKey; -import io.prestosql.sql.analyzer.SemanticErrorCode; -import io.prestosql.testing.TestingSession; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import java.util.concurrent.TimeUnit; - -import static io.prestosql.spi.function.OperatorType.INDETERMINATE; -import static io.prestosql.spi.type.BooleanType.BOOLEAN; -import static io.prestosql.spi.type.DateType.DATE; -import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; -import static org.joda.time.DateTimeZone.UTC; - -public abstract class TestTimestampBase - extends AbstractTestFunctions -{ - protected static final TimeZoneKey TIME_ZONE_KEY = TestingSession.DEFAULT_TIME_ZONE_KEY; - protected static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - protected static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(7 * 60 + 9); - protected static final DateTimeZone WEIRD_ZONE = getDateTimeZone(WEIRD_TIME_ZONE_KEY); - protected static final TimeZoneKey ORAL_TIME_ZONE_KEY = getTimeZoneKey("Asia/Oral"); - protected static final DateTimeZone ORAL_ZONE = getDateTimeZone(ORAL_TIME_ZONE_KEY); - - protected TestTimestampBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(TIME_ZONE_KEY) - .build()); - } - - @Test - public void testSubtract() - { - functionAssertions.assertFunctionString("TIMESTAMP '2017-03-30 14:15:16.432' - TIMESTAMP '2016-03-29 03:04:05.321'", - INTERVAL_DAY_TIME, - "366 11:11:11.111"); - - functionAssertions.assertFunctionString("TIMESTAMP '2016-03-29 03:04:05.321' - TIMESTAMP '2017-03-30 14:15:16.432'", - INTERVAL_DAY_TIME, - "-366 11:11:11.111"); - } - - @Test - public void testLiteral() - { - assertFunction("TIMESTAMP '2013-03-30 01:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0, session)); - assertFunction("TIMESTAMP '2013-03-30 02:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 2, 5, 0, 0, session)); - assertFunction("TIMESTAMP '2013-03-30 03:05'", TIMESTAMP, sqlTimestampOf(2013, 3, 30, 3, 5, 0, 0, session)); - - assertFunction("TIMESTAMP '2001-01-22 03:04:05.321'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-01-22 03:04:05'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 5, 0, session)); - assertFunction("TIMESTAMP '2001-01-22 03:04'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 3, 4, 0, 0, session)); - assertFunction("TIMESTAMP '2001-01-22'", TIMESTAMP, sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0, session)); - - assertFunction("TIMESTAMP '2001-1-2 3:4:5.321'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 5, 321, session)); - assertFunction("TIMESTAMP '2001-1-2 3:4:5'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 5, 0, session)); - assertFunction("TIMESTAMP '2001-1-2 3:4'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 3, 4, 0, 0, session)); - assertFunction("TIMESTAMP '2001-1-2'", TIMESTAMP, sqlTimestampOf(2001, 1, 2, 0, 0, 0, 0, session)); - - assertInvalidFunction("TIMESTAMP 'text'", SemanticErrorCode.INVALID_LITERAL, "line 1:1: 'text' is not a valid timestamp literal"); - } - - @Test - public void testEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' = TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' = TIMESTAMP '2001-1-22'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' = TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' = TIMESTAMP '2001-1-11'", BOOLEAN, false); - } - - @Test - public void testNotEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <> TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' <> TIMESTAMP '2001-1-11'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <> TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' <> TIMESTAMP '2001-1-22'", BOOLEAN, false); - } - - @Test - public void testLessThan() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-23'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' < TIMESTAMP '2001-1-22 03:04:05'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-22'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' < TIMESTAMP '2001-1-20'", BOOLEAN, false); - } - - @Test - public void testLessThanOrEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-23'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-22'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' <= TIMESTAMP '2001-1-22 03:04:05'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' <= TIMESTAMP '2001-1-20'", BOOLEAN, false); - } - - @Test - public void testGreaterThan() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-11'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' > TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-22'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' > TIMESTAMP '2001-1-23'", BOOLEAN, false); - } - - @Test - public void testGreaterThanOrEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-11'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-22'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' >= TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22' >= TIMESTAMP '2001-1-23'", BOOLEAN, false); - } - - @Test - public void testBetween() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.111' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.321' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.111' and TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.321' and TIMESTAMP '2001-1-22 03:04:05.321'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.322' and TIMESTAMP '2001-1-22 03:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.311' and TIMESTAMP '2001-1-22 03:04:05.312'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321' between TIMESTAMP '2001-1-22 03:04:05.333' and TIMESTAMP '2001-1-22 03:04:05.111'", BOOLEAN, false); - } - - @Test - public void testCastToDate() - { - long millis = new DateTime(2001, 1, 22, 0, 0, UTC).getMillis(); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as date)", DATE, new SqlDate((int) TimeUnit.MILLISECONDS.toDays(millis))); - } - - @Test - public void testCastToTime() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time)", TIME, sqlTimeOf(3, 4, 5, 321, session)); - } - - @Test - public void testCastToTimeWithTimeZone() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time with time zone)", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321' as time with time zone)", - TIME_WITH_TIME_ZONE, - "03:04:05.321 " + DATE_TIME_ZONE.getID()); - } - - @Test - public void testCastToTimestampWithTimeZone() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), DATE_TIME_ZONE.toTimeZone())); - functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - "2001-01-22 03:04:05.321 " + DATE_TIME_ZONE.getID()); - } - - @Test - public void testCastToSlice() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321' as varchar)", VARCHAR, "2001-01-22 03:04:05.321"); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05' as varchar)", VARCHAR, "2001-01-22 03:04:05.000"); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04' as varchar)", VARCHAR, "2001-01-22 03:04:00.000"); - assertFunction("cast(TIMESTAMP '2001-1-22' as varchar)", VARCHAR, "2001-01-22 00:00:00.000"); - } - - @Test - public void testCastFromSlice() - { - assertFunction("cast('2001-1-22 03:04:05.321' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); - assertFunction("cast('2001-1-22 03:04:05' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 0, session)); - assertFunction("cast('2001-1-22 03:04' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 0, 0, session)); - assertFunction("cast('2001-1-22' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 0, 0, 0, 0, session)); - assertFunction("cast('\n\t 2001-1-22 03:04:05.321' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); - assertFunction("cast('2001-1-22 03:04:05.321 \t\n' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); - assertFunction("cast('\n\t 2001-1-22 03:04:05.321 \t\n' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); - } - - @Test - public void testGreatest() - { - assertFunction("greatest(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05')", - TIMESTAMP, - sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0, session)); - assertFunction("greatest(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05', TIMESTAMP '2012-05-01 01:05')", - TIMESTAMP, - sqlTimestampOf(2013, 3, 30, 1, 5, 0, 0, session)); - } - - @Test - public void testLeast() - { - assertFunction("least(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05')", - TIMESTAMP, - sqlTimestampOf(2012, 3, 30, 1, 5, 0, 0, session)); - assertFunction("least(TIMESTAMP '2013-03-30 01:05', TIMESTAMP '2012-03-30 01:05', TIMESTAMP '2012-05-01 01:05')", - TIMESTAMP, - sqlTimestampOf(2012, 3, 30, 1, 5, 0, 0, session)); - } - - @Test - public void testIndeterminate() - { - assertOperator(INDETERMINATE, "cast(null as TIMESTAMP)", BOOLEAN, true); - assertOperator(INDETERMINATE, "TIMESTAMP '2012-03-30 01:05'", BOOLEAN, false); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestampLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestTimestampLegacy.java deleted file mode 100644 index dfa0bdfa0..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestampLegacy.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; - -public class TestTimestampLegacy - extends TestTimestampBase -{ - public TestTimestampLegacy() - { - super(true); - } - - @Override - public void testCastFromSlice() - { - super.testCastFromSlice(); - assertFunction( - "cast('2001-1-22 03:04:05.321 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 8, 55, 5, 321, session)); - assertFunction( - "cast('2001-1-22 03:04:05 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 8, 55, 5, 0, session)); - assertFunction( - "cast('2001-1-22 03:04 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 8, 55, 0, 0, session)); - assertFunction( - "cast('2001-1-22 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 5, 51, 0, 0, session)); - - assertFunction( - "cast('2001-1-22 03:04:05.321 Asia/Oral' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 12, 4, 5, 321, session)); - assertFunction( - "cast('2001-1-22 03:04:05 Asia/Oral' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 12, 4, 5, 0, session)); - assertFunction( - "cast('2001-1-22 03:04 Asia/Oral' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 12, 4, 0, 0, session)); - assertFunction( - "cast('2001-1-22 Asia/Oral' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21, 9, 0, 0, 0, session)); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZone.java b/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZone.java index 668dcd6ed..f2ca8cbc2 100644 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZone.java +++ b/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZone.java @@ -13,29 +13,260 @@ */ package io.prestosql.type; +import io.prestosql.operator.scalar.AbstractTestFunctions; +import io.prestosql.spi.type.SqlTimeWithTimeZone; +import io.prestosql.spi.type.SqlTimestampWithTimeZone; +import io.prestosql.spi.type.TimeZoneKey; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; +import static io.prestosql.spi.function.OperatorType.INDETERMINATE; +import static io.prestosql.spi.type.BooleanType.BOOLEAN; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; +import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; +import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; +import static io.prestosql.testing.TestingSession.testSessionBuilder; +import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; public class TestTimestampWithTimeZone - extends TestTimestampWithTimeZoneBase + extends AbstractTestFunctions { + private static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKeyForOffset(6 * 60 + 9); + private static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); + private static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(7 * 60 + 9); + private static final DateTimeZone WEIRD_ZONE = getDateTimeZone(WEIRD_TIME_ZONE_KEY); + private static final TimeZoneKey BERLIN_TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); + private static final DateTimeZone BERLIN_ZONE = getDateTimeZone(BERLIN_TIME_ZONE_KEY); + public TestTimestampWithTimeZone() { - super(false); + super(testSessionBuilder() + .setTimeZoneKey(TIME_ZONE_KEY) + .build()); + } + + @Test + public void testCastToTimeWithTimeZone() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time with time zone)", + TIME_WITH_TIME_ZONE, + new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time with time zone)", + TIME_WITH_TIME_ZONE, + "03:04:05.321 +07:09"); + } + + @Test + public void testLiteral() + { + assertFunction("TIMESTAMP '2001-01-02 03:04:05.321 +07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 03:04:05 +07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 03:04 +07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 +07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + + assertFunction("TIMESTAMP '2001-1-2 3:4:5.321+07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-2 3:4:5+07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-2 3:4+07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-1-2+07:09'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + + assertFunction("TIMESTAMP '2001-01-02 03:04:05.321 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 03:04:05 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 03:04 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '2001-01-02 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + + assertFunction("TIMESTAMP '12001-01-02 03:04:05.321 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(12001, 1, 2, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '+12001-01-02 03:04:05.321 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(12001, 1, 2, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("TIMESTAMP '-12001-01-02 03:04:05.321 Europe/Berlin'", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(-12001, 1, 2, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + } + + @Test + public void testSubtract() + { + functionAssertions.assertFunctionString("TIMESTAMP '2017-03-30 14:15:16.432 +07:09' - TIMESTAMP '2016-03-29 03:04:05.321 +08:09'", + INTERVAL_DAY_TIME, + "366 12:11:11.111"); + + functionAssertions.assertFunctionString("TIMESTAMP '2016-03-29 03:04:05.321 +08:09' - TIMESTAMP '2017-03-30 14:15:16.432 +07:09'", + INTERVAL_DAY_TIME, + "-366 12:11:11.111"); + } + + @Test + public void testEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' = TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' = TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, false); + } + + @Test + public void testNotEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' <> TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' <> TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); + } + + @Test + public void testLessThan() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-20 +07:09'", BOOLEAN, false); + } + + @Test + public void testLessThanOrEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-20 +07:09'", BOOLEAN, false); + } + + @Test + public void testGreaterThan() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, false); + } + + @Test + public void testGreaterThanOrEqual() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, false); + } + + @Test + public void testBetween() + { + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.111 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.321 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.111 +07:09' and TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111 +06:09' and TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111' and TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.321 +07:09' and TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321 +06:09' and TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321' and TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.322 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.322 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.322' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.311 +07:09' and TIMESTAMP '2001-1-22 03:04:05.312 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.311 +06:09' and TIMESTAMP '2001-1-22 02:04:05.312 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.311' and TIMESTAMP '2001-1-22 02:04:05.312'", BOOLEAN, false); + + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.333 +07:09' and TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.333 +06:09' and TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, false); + assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.333' and TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, false); } @Test - @Override public void testCastToTime() { assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time)", TIME, - sqlTimeOf(3, 4, 5, 321, session)); + sqlTimeOf(3, 4, 5, 321)); functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time)", TIME, @@ -43,30 +274,110 @@ public class TestTimestampWithTimeZone } @Test - @Override - public void testCastToTimeWithTimeZone() - { - super.testCastToTimeWithTimeZone(); - - functionAssertions.assertFunctionString("cast(TIMESTAMP '2017-06-06 10:00:00.000 Europe/Warsaw' as time with time zone)", - TIME_WITH_TIME_ZONE, - "10:00:00.000 Europe/Warsaw"); - functionAssertions.assertFunctionString("cast(TIMESTAMP '2017-06-06 10:00:00.000 Asia/Kathmandu' as time with time zone)", - TIME_WITH_TIME_ZONE, - "10:00:00.000 Asia/Kathmandu"); - } - - @Test - @Override public void testCastToTimestamp() { assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as timestamp)", TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); // This TZ had switch in 2014, so if we test for 2014 and used unpacked value we would use wrong shift assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 Pacific/Bougainville' as timestamp)", TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321, session)); + sqlTimestampOf(2001, 1, 22, 3, 4, 5, 321)); + } + + @Test + public void testCastToSlice() + { + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:05.321 +07:09"); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:05.000 +07:09"); + assertFunction("cast(TIMESTAMP '2001-1-22 03:04 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:00.000 +07:09"); + assertFunction("cast(TIMESTAMP '2001-1-22 +07:09' as varchar)", VARCHAR, "2001-01-22 00:00:00.000 +07:09"); + } + + @Test + public void testCastFromSlice() + { + assertFunction("cast('2001-1-22 03:04:05.321' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04:05' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); + + assertFunction("cast('2001-1-22 03:04:05.321 +07:09' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04:05 +07:09' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04 +07:09' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 +07:09' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + + assertFunction("cast('2001-1-22 03:04:05.321 Europe/Berlin' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04:05 Europe/Berlin' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04 Europe/Berlin' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 Europe/Berlin' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + + assertFunction("cast('\n\t 2001-1-22 03:04:05.321 Europe/Berlin' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("cast('2001-1-22 03:04:05.321 Europe/Berlin \t\n' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + assertFunction("cast('\n\t 2001-1-22 03:04:05.321 Europe/Berlin \t\n' as timestamp with time zone)", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); + } + + @Test + public void testGreatest() + { + assertFunction( + "greatest(TIMESTAMP '2002-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09', TIMESTAMP '2000-01-02 01:04:05.321 +02:09')", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2002, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction( + "greatest(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 04:04:05.321 +10:09')", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testLeast() + { + assertFunction( + "least(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09', TIMESTAMP '2002-01-02 01:04:05.321 +02:09')", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + assertFunction( + "least(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09')", + TIMESTAMP_WITH_TIME_ZONE, + new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); + } + + @Test + public void testIndeterminate() + { + assertOperator(INDETERMINATE, "cast(null as TIMESTAMP WITH TIME ZONE)", BOOLEAN, true); + assertOperator(INDETERMINATE, "TIMESTAMP '2001-01-02 01:04:05.321 +02:09'", BOOLEAN, false); } } diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneBase.java b/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneBase.java deleted file mode 100644 index 53a5e3211..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneBase.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import io.prestosql.operator.scalar.AbstractTestFunctions; -import io.prestosql.spi.type.SqlDate; -import io.prestosql.spi.type.SqlTimeWithTimeZone; -import io.prestosql.spi.type.SqlTimestampWithTimeZone; -import io.prestosql.spi.type.TimeZoneKey; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.testng.annotations.Test; - -import java.util.concurrent.TimeUnit; - -import static io.prestosql.spi.function.OperatorType.INDETERMINATE; -import static io.prestosql.spi.type.BooleanType.BOOLEAN; -import static io.prestosql.spi.type.DateType.DATE; -import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; -import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; -import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; -import static io.prestosql.spi.type.VarcharType.VARCHAR; -import static io.prestosql.spi.util.DateTimeZoneIndex.getDateTimeZone; -import static io.prestosql.testing.TestingSession.testSessionBuilder; -import static io.prestosql.type.IntervalDayTimeType.INTERVAL_DAY_TIME; -import static org.joda.time.DateTimeZone.UTC; - -public abstract class TestTimestampWithTimeZoneBase - extends AbstractTestFunctions -{ - private static final TimeZoneKey TIME_ZONE_KEY = getTimeZoneKeyForOffset(6 * 60 + 9); - private static final DateTimeZone DATE_TIME_ZONE = getDateTimeZone(TIME_ZONE_KEY); - private static final TimeZoneKey WEIRD_TIME_ZONE_KEY = getTimeZoneKeyForOffset(7 * 60 + 9); - private static final DateTimeZone WEIRD_ZONE = getDateTimeZone(WEIRD_TIME_ZONE_KEY); - private static final TimeZoneKey BERLIN_TIME_ZONE_KEY = getTimeZoneKey("Europe/Berlin"); - private static final DateTimeZone BERLIN_ZONE = getDateTimeZone(BERLIN_TIME_ZONE_KEY); - - protected TestTimestampWithTimeZoneBase(boolean legacyTimestamp) - { - super(testSessionBuilder() - .setSystemProperty("legacy_timestamp", String.valueOf(legacyTimestamp)) - .setTimeZoneKey(TIME_ZONE_KEY) - .build()); - } - - @Test - public void testLiteral() - { - assertFunction("TIMESTAMP '2001-01-02 03:04:05.321 +07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 03:04:05 +07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 03:04 +07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 +07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - - assertFunction("TIMESTAMP '2001-1-2 3:4:5.321+07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-2 3:4:5+07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-2 3:4+07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-1-2+07:09'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - - assertFunction("TIMESTAMP '2001-01-02 03:04:05.321 Europe/Berlin'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 03:04:05 Europe/Berlin'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 03:04 Europe/Berlin'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("TIMESTAMP '2001-01-02 Europe/Berlin'", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 0, 0, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - } - - @Test - public void testSubtract() - { - functionAssertions.assertFunctionString("TIMESTAMP '2017-03-30 14:15:16.432 +07:09' - TIMESTAMP '2016-03-29 03:04:05.321 +08:09'", - INTERVAL_DAY_TIME, - "366 12:11:11.111"); - - functionAssertions.assertFunctionString("TIMESTAMP '2016-03-29 03:04:05.321 +08:09' - TIMESTAMP '2017-03-30 14:15:16.432 +07:09'", - INTERVAL_DAY_TIME, - "-366 12:11:11.111"); - } - - @Test - public void testEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' = TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' = TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' = TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, false); - } - - @Test - public void testNotEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' <> TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <> TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' <> TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); - } - - @Test - public void testLessThan() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 03:04:05 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' < TIMESTAMP '2001-1-22 02:04:05'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' < TIMESTAMP '2001-1-20 +07:09'", BOOLEAN, false); - } - - @Test - public void testLessThanOrEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 03:04:05 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' <= TIMESTAMP '2001-1-22 02:04:05'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' <= TIMESTAMP '2001-1-20 +07:09'", BOOLEAN, false); - } - - @Test - public void testGreaterThan() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' > TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' > TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, false); - } - - @Test - public void testGreaterThanOrEqual() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-11 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-22 +07:09'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' >= TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 +07:09' >= TIMESTAMP '2001-1-23 +07:09'", BOOLEAN, false); - } - - @Test - public void testBetween() - { - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.111 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.321 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.111 +07:09' and TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111 +06:09' and TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.111' and TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.321 +07:09' and TIMESTAMP '2001-1-22 03:04:05.321 +07:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321 +06:09' and TIMESTAMP '2001-1-22 02:04:05.321 +06:09'", BOOLEAN, true); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.321' and TIMESTAMP '2001-1-22 02:04:05.321'", BOOLEAN, true); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.322 +07:09' and TIMESTAMP '2001-1-22 03:04:05.333 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.322 +06:09' and TIMESTAMP '2001-1-22 02:04:05.333 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.322' and TIMESTAMP '2001-1-22 02:04:05.333'", BOOLEAN, false); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.311 +07:09' and TIMESTAMP '2001-1-22 03:04:05.312 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.311 +06:09' and TIMESTAMP '2001-1-22 02:04:05.312 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.311' and TIMESTAMP '2001-1-22 02:04:05.312'", BOOLEAN, false); - - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 03:04:05.333 +07:09' and TIMESTAMP '2001-1-22 03:04:05.111 +07:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.333 +06:09' and TIMESTAMP '2001-1-22 02:04:05.111 +06:09'", BOOLEAN, false); - assertFunction("TIMESTAMP '2001-1-22 03:04:05.321 +07:09' between TIMESTAMP '2001-1-22 02:04:05.333' and TIMESTAMP '2001-1-22 02:04:05.111'", BOOLEAN, false); - } - - @Test - public void testCastToDate() - { - long millis = new DateTime(2001, 1, 22, 0, 0, UTC).getMillis(); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as date)", DATE, new SqlDate((int) TimeUnit.MILLISECONDS.toDays(millis))); - } - - @Test - public abstract void testCastToTime(); - - @Test - public void testCastToTimeWithTimeZone() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time with time zone)", - TIME_WITH_TIME_ZONE, - new SqlTimeWithTimeZone(new DateTime(1970, 1, 1, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - functionAssertions.assertFunctionString("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time with time zone)", - TIME_WITH_TIME_ZONE, - "03:04:05.321 +07:09"); - } - - @Test - public abstract void testCastToTimestamp(); - - @Test - public void testCastToSlice() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:05.321 +07:09"); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:05.000 +07:09"); - assertFunction("cast(TIMESTAMP '2001-1-22 03:04 +07:09' as varchar)", VARCHAR, "2001-01-22 03:04:00.000 +07:09"); - assertFunction("cast(TIMESTAMP '2001-1-22 +07:09' as varchar)", VARCHAR, "2001-01-22 00:00:00.000 +07:09"); - } - - @Test - public void testCastFromSlice() - { - assertFunction("cast('2001-1-22 03:04:05.321' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04:05' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, DATE_TIME_ZONE).getMillis(), TIME_ZONE_KEY)); - - assertFunction("cast('2001-1-22 03:04:05.321 +07:09' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04:05 +07:09' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04 +07:09' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 +07:09' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - - assertFunction("cast('2001-1-22 03:04:05.321 Europe/Berlin' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04:05 Europe/Berlin' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04 Europe/Berlin' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 Europe/Berlin' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 0, 0, 0, 0, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - - assertFunction("cast('\n\t 2001-1-22 03:04:05.321 Europe/Berlin' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("cast('2001-1-22 03:04:05.321 Europe/Berlin \t\n' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - assertFunction("cast('\n\t 2001-1-22 03:04:05.321 Europe/Berlin \t\n' as timestamp with time zone)", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 22, 3, 4, 5, 321, BERLIN_ZONE).getMillis(), BERLIN_TIME_ZONE_KEY)); - } - - @Test - public void testGreatest() - { - assertFunction( - "greatest(TIMESTAMP '2002-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09', TIMESTAMP '2000-01-02 01:04:05.321 +02:09')", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2002, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction( - "greatest(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 04:04:05.321 +10:09')", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testLeast() - { - assertFunction( - "least(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09', TIMESTAMP '2002-01-02 01:04:05.321 +02:09')", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - assertFunction( - "least(TIMESTAMP '2001-01-02 03:04:05.321 +07:09', TIMESTAMP '2001-01-02 01:04:05.321 +02:09')", - TIMESTAMP_WITH_TIME_ZONE, - new SqlTimestampWithTimeZone(new DateTime(2001, 1, 2, 3, 4, 5, 321, WEIRD_ZONE).getMillis(), WEIRD_TIME_ZONE_KEY)); - } - - @Test - public void testIndeterminate() - { - assertOperator(INDETERMINATE, "cast(null as TIMESTAMP WITH TIME ZONE)", BOOLEAN, true); - assertOperator(INDETERMINATE, "TIMESTAMP '2001-01-02 01:04:05.321 +02:09'", BOOLEAN, false); - } -} diff --git a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneLegacy.java b/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneLegacy.java deleted file mode 100644 index 99e9f8a34..000000000 --- a/presto-main/src/test/java/io/prestosql/type/TestTimestampWithTimeZoneLegacy.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 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 io.prestosql.type; - -import org.testng.annotations.Test; - -import static io.prestosql.spi.type.TimeType.TIME; -import static io.prestosql.spi.type.TimestampType.TIMESTAMP; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimeOf; -import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; - -public class TestTimestampWithTimeZoneLegacy - extends TestTimestampWithTimeZoneBase -{ - public TestTimestampWithTimeZoneLegacy() - { - super(true); - } - - @Test - @Override - public void testCastToTime() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as time)", - TIME, - sqlTimeOf(2 /* not 3 */, 4, 5, 321, session)); - } - - @Test - @Override - public void testCastToTimestamp() - { - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 +07:09' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 22, 2 /* not 3 */, 4, 5, 321, session)); - - // This TZ had switch in 2014 - assertFunction("cast(TIMESTAMP '2001-1-22 03:04:05.321 Pacific/Bougainville' as timestamp)", - TIMESTAMP, - sqlTimestampOf(2001, 1, 21 /* not 22 */, 23 /* not 3 */, 13, 5, 321, session)); - } -} diff --git a/presto-mysql/src/main/java/io/prestosql/plugin/mysql/MySqlClient.java b/presto-mysql/src/main/java/io/prestosql/plugin/mysql/MySqlClient.java index 631e86d89..45bb48bf0 100644 --- a/presto-mysql/src/main/java/io/prestosql/plugin/mysql/MySqlClient.java +++ b/presto-mysql/src/main/java/io/prestosql/plugin/mysql/MySqlClient.java @@ -208,7 +208,7 @@ public class MySqlClient } if (TIMESTAMP.equals(type)) { // TODO use `timestampWriteFunction` - return WriteMapping.longMapping("datetime", timestampWriteFunctionUsingSqlTimestamp(session)); + return WriteMapping.longMapping("datetime", timestampWriteFunctionUsingSqlTimestamp()); } if (VARBINARY.equals(type)) { return WriteMapping.sliceMapping("mediumblob", varbinaryWriteFunction()); diff --git a/presto-orc/src/main/java/io/prestosql/orc/AbstractOrcRecordReader.java b/presto-orc/src/main/java/io/prestosql/orc/AbstractOrcRecordReader.java index 17a1c882b..de826c2c9 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/AbstractOrcRecordReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/AbstractOrcRecordReader.java @@ -145,7 +145,7 @@ abstract class AbstractOrcRecordReader ColumnMetadata orcTypes, Optional decompressor, int rowsInRowGroup, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, HiveWriterVersion hiveWriterVersion, MetadataReader metadataReader, DataSize maxMergeDistance, @@ -174,7 +174,6 @@ abstract class AbstractOrcRecordReader requireNonNull(orcDataSource, "orcDataSource is null"); requireNonNull(orcTypes, "types is null"); requireNonNull(decompressor, "decompressor is null"); - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); requireNonNull(userMetadata, "userMetadata is null"); requireNonNull(systemMemoryUsage, "systemMemoryUsage is null"); requireNonNull(exceptionTransform, "exceptionTransform is null"); @@ -280,7 +279,7 @@ abstract class AbstractOrcRecordReader AggregatedMemoryContext streamReadersSystemMemoryContext = this.systemMemoryUsage.newAggregatedMemoryContext(); stripeReader = new StripeReader( orcDataSource, - hiveStorageTimeZone.toTimeZone().toZoneId(), + legacyFileTimeZone.toTimeZone().toZoneId(), decompressor, orcTypes, ImmutableSet.copyOf(readColumns), @@ -650,8 +649,7 @@ abstract class AbstractOrcRecordReader for (AbstractColumnReader columnReader : columnReaders) { if (columnReader != null) { ZoneId fileTimeZone = stripe.getFileTimeZone(); - ZoneId storageTimeZone = stripe.getStorageTimeZone(); - columnReader.startStripe(fileTimeZone, storageTimeZone, + columnReader.startStripe(fileTimeZone, dictionaryStreamSources, columnEncodings); } } diff --git a/presto-orc/src/main/java/io/prestosql/orc/OrcReader.java b/presto-orc/src/main/java/io/prestosql/orc/OrcReader.java index 270616968..c157b196d 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/OrcReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/OrcReader.java @@ -52,6 +52,7 @@ import static io.prestosql.memory.context.AggregatedMemoryContext.newSimpleAggre import static io.prestosql.orc.metadata.OrcColumnId.ROOT_COLUMN; import static java.lang.Math.toIntExact; import static java.util.Objects.requireNonNull; +import static org.joda.time.DateTimeZone.UTC; public class OrcReader { @@ -158,7 +159,7 @@ public class OrcReader List readColumns, List readTypes, OrcPredicate predicate, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, AggregatedMemoryContext systemMemoryUsage, int initialBatchSize, Function exceptionTransform) @@ -170,7 +171,7 @@ public class OrcReader predicate, 0, orcDataSource.getSize(), - hiveStorageTimeZone, + legacyFileTimeZone, systemMemoryUsage, initialBatchSize, exceptionTransform, @@ -188,7 +189,7 @@ public class OrcReader OrcPredicate predicate, long offset, long length, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, AggregatedMemoryContext systemMemoryUsage, int initialBatchSize, Function exceptionTransform) @@ -208,7 +209,7 @@ public class OrcReader footer.getTypes(), decompressor, footer.getRowsInRowGroup(), - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"), + requireNonNull(legacyFileTimeZone, "hiveStorageTimeZone is null"), hiveWriterVersion, metadataReader, maxMergeDistance, @@ -231,7 +232,7 @@ public class OrcReader List readColumns, List readTypes, OrcPredicate predicate, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, AggregatedMemoryContext systemMemoryUsage, int initialBatchSize, Function exceptionTransform, @@ -245,7 +246,7 @@ public class OrcReader predicate, 0, orcDataSource.getSize(), - hiveStorageTimeZone, + legacyFileTimeZone, systemMemoryUsage, initialBatchSize, exceptionTransform, @@ -319,7 +320,7 @@ public class OrcReader OrcPredicate predicate, long offset, long length, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, AggregatedMemoryContext systemMemoryUsage, int initialBatchSize, Function exceptionTransform, @@ -353,7 +354,7 @@ public class OrcReader footer.getTypes(), decompressor, footer.getRowsInRowGroup(), - requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"), + requireNonNull(legacyFileTimeZone, "legacyFileTimeZone is null"), hiveWriterVersion, metadataReader, maxMergeDistance, @@ -423,8 +424,7 @@ public class OrcReader static void validateFile( OrcWriteValidation writeValidation, OrcDataSource input, - List readTypes, - DateTimeZone hiveStorageTimeZone) + List readTypes) throws OrcCorruptionException { try { @@ -433,7 +433,7 @@ public class OrcReader orcReader.getRootColumn().getNestedColumns(), readTypes, OrcPredicate.TRUE, - hiveStorageTimeZone, + UTC, newSimpleAggregatedMemoryContext(), INITIAL_BATCH_SIZE, exception -> { diff --git a/presto-orc/src/main/java/io/prestosql/orc/OrcRecordReader.java b/presto-orc/src/main/java/io/prestosql/orc/OrcRecordReader.java index 6f85187f0..67e01a520 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/OrcRecordReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/OrcRecordReader.java @@ -84,7 +84,7 @@ public class OrcRecordReader ColumnMetadata orcTypes, Optional decompressor, int rowsInRowGroup, - DateTimeZone hiveStorageTimeZone, + DateTimeZone legacyFileTimeZone, HiveWriterVersion hiveWriterVersion, MetadataReader metadataReader, DataSize maxMergeDistance, @@ -116,7 +116,7 @@ public class OrcRecordReader orcTypes, decompressor, rowsInRowGroup, - hiveStorageTimeZone, + legacyFileTimeZone, hiveWriterVersion, metadataReader, maxMergeDistance, diff --git a/presto-orc/src/main/java/io/prestosql/orc/OrcWriter.java b/presto-orc/src/main/java/io/prestosql/orc/OrcWriter.java index 8d98523ab..d21346319 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/OrcWriter.java +++ b/presto-orc/src/main/java/io/prestosql/orc/OrcWriter.java @@ -41,7 +41,6 @@ import io.prestosql.orc.writer.ColumnWriter; import io.prestosql.orc.writer.SliceDictionaryColumnWriter; import io.prestosql.spi.Page; import io.prestosql.spi.type.Type; -import org.joda.time.DateTimeZone; import org.openjdk.jol.info.ClassLayout; import javax.annotation.Nullable; @@ -104,7 +103,6 @@ public final class OrcWriter private final int maxCompressionBufferSize; private final Map userMetadata; private final CompressedMetadataWriter metadataWriter; - private final DateTimeZone hiveStorageTimeZone; private final List closedStripes = new ArrayList<>(); private final ColumnMetadata orcTypes; @@ -132,7 +130,6 @@ public final class OrcWriter OrcWriterOptions options, boolean writeLegacyVersion, Map userMetadata, - DateTimeZone hiveStorageTimeZone, boolean validate, OrcWriteValidationMode validationMode, OrcWriterStats stats, @@ -146,7 +143,7 @@ public final class OrcWriter this.types = ImmutableList.copyOf(requireNonNull(types, "types is null")); this.compression = requireNonNull(compression, "compression is null"); recordValidation(validation -> validation.setCompression(compression)); - recordValidation(validation -> validation.setTimeZone(hiveStorageTimeZone.toTimeZone().toZoneId())); + recordValidation(validation -> validation.setTimeZone(ZoneId.of("UTC"))); requireNonNull(options, "options is null"); checkArgument(options.getStripeMaxSize().compareTo(options.getStripeMinSize()) >= 0, "stripeMaxSize must be greater than stripeMinSize"); @@ -160,7 +157,6 @@ public final class OrcWriter this.userMetadata = buildUserMetadata(userMetadata); this.metadataWriter = new CompressedMetadataWriter(new OrcMetadataWriter(writeLegacyVersion), compression, maxCompressionBufferSize); - this.hiveStorageTimeZone = requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null"); this.stats = requireNonNull(stats, "stats is null"); requireNonNull(columnNames, "columnNames is null"); @@ -175,7 +171,7 @@ public final class OrcWriter for (int fieldId = 0; fieldId < types.size(); fieldId++) { OrcColumnId fieldColumnIndex = rootType.getFieldTypeIndex(fieldId); Type fieldType = types.get(fieldId); - ColumnWriter columnWriter = createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, maxCompressionBufferSize, hiveStorageTimeZone, options.getMaxStringStatisticsLimit()); + ColumnWriter columnWriter = createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, maxCompressionBufferSize, options.getMaxStringStatisticsLimit()); columnWriters.add(columnWriter); if (columnWriter instanceof SliceDictionaryColumnWriter) { @@ -434,8 +430,7 @@ public final class OrcWriter columnStatistics.put(ROOT_COLUMN, new ColumnStatistics((long) stripeRowCount, 0, null, null, null, null, null, null, null, null)); // add footer - Optional timeZone = Optional.of(hiveStorageTimeZone.toTimeZone().toZoneId()); - StripeFooter stripeFooter = new StripeFooter(allStreams, toColumnMetadata(columnEncodings, orcTypes.size()), timeZone); + StripeFooter stripeFooter = new StripeFooter(allStreams, toColumnMetadata(columnEncodings, orcTypes.size()), ZoneId.of("UTC")); Slice footer = metadataWriter.writeStripeFooter(stripeFooter); outputData.add(createDataOutput(footer)); @@ -539,7 +534,7 @@ public final class OrcWriter throws OrcCorruptionException { checkState(validationBuilder != null, "validation is not enabled"); - validateFile(validationBuilder.build(), input, types, hiveStorageTimeZone); + validateFile(validationBuilder.build(), input, types); } private static ColumnMetadata toColumnMetadata(Map data, int expectedSize) diff --git a/presto-orc/src/main/java/io/prestosql/orc/Stripe.java b/presto-orc/src/main/java/io/prestosql/orc/Stripe.java index e2dfd95d8..ae2d743e3 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/Stripe.java +++ b/presto-orc/src/main/java/io/prestosql/orc/Stripe.java @@ -28,16 +28,14 @@ public class Stripe { private final long rowCount; private final ZoneId fileTimeZone; - private final ZoneId storageTimeZone; private final ColumnMetadata columnEncodings; private final List rowGroups; private final InputStreamSources dictionaryStreamSources; - public Stripe(long rowCount, ZoneId fileTimeZone, ZoneId storageTimeZone, ColumnMetadata columnEncodings, List rowGroups, InputStreamSources dictionaryStreamSources) + public Stripe(long rowCount, ZoneId fileTimeZone, ColumnMetadata columnEncodings, List rowGroups, InputStreamSources dictionaryStreamSources) { this.rowCount = rowCount; this.fileTimeZone = requireNonNull(fileTimeZone, "fileTimeZone is null"); - this.storageTimeZone = requireNonNull(storageTimeZone, "storageTimeZone is null"); this.columnEncodings = requireNonNull(columnEncodings, "columnEncodings is null"); this.rowGroups = ImmutableList.copyOf(requireNonNull(rowGroups, "rowGroups is null")); this.dictionaryStreamSources = requireNonNull(dictionaryStreamSources, "dictionaryStreamSources is null"); @@ -53,11 +51,6 @@ public class Stripe return fileTimeZone; } - public ZoneId getStorageTimeZone() - { - return storageTimeZone; - } - public ColumnMetadata getColumnEncodings() { return columnEncodings; @@ -79,7 +72,6 @@ public class Stripe return toStringHelper(this) .add("rowCount", rowCount) .add("fileTimeZone", fileTimeZone) - .add("storageTimeZone", storageTimeZone) .add("columnEncodings", columnEncodings) .add("rowGroups", rowGroups) .add("dictionaryStreams", dictionaryStreamSources) diff --git a/presto-orc/src/main/java/io/prestosql/orc/StripeReader.java b/presto-orc/src/main/java/io/prestosql/orc/StripeReader.java index f73c9d278..eb14876df 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/StripeReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/StripeReader.java @@ -84,7 +84,7 @@ public class StripeReader private static final Logger log = Logger.get(StripeReader.class); private final OrcDataSource orcDataSource; - private final ZoneId storageTimeZone; + private final ZoneId legacyFileTimeZone; private final Optional decompressor; private final ColumnMetadata types; private final HiveWriterVersion hiveWriterVersion; @@ -97,7 +97,7 @@ public class StripeReader private final OrcCacheProperties orcCacheProperties; public StripeReader(OrcDataSource orcDataSource, - ZoneId storageTimeZone, + ZoneId legacyFileTimeZone, Optional decompressor, ColumnMetadata types, Set readColumns, @@ -110,7 +110,7 @@ public class StripeReader OrcCacheProperties orcCacheProperties) { this.orcDataSource = requireNonNull(orcDataSource, "orcDataSource is null"); - this.storageTimeZone = requireNonNull(storageTimeZone, "storageTimeZone is null"); + this.legacyFileTimeZone = requireNonNull(legacyFileTimeZone, "legacyFileTimeZone is null"); this.decompressor = requireNonNull(decompressor, "decompressor is null"); this.types = requireNonNull(types, "types is null"); this.includedOrcColumnIds = getIncludeColumns(requireNonNull(readColumns, "readColumns is null")); @@ -147,9 +147,9 @@ public class StripeReader } ColumnMetadata columnEncodings = stripeFooter.getColumnEncodings(); if (writeValidation.isPresent()) { - writeValidation.get().validateTimeZone(orcDataSource.getId(), stripeFooter.getTimeZone().orElse(null)); + writeValidation.get().validateTimeZone(orcDataSource.getId(), stripeFooter.getTimeZone()); } - ZoneId fileTimeZone = stripeFooter.getTimeZone().orElse(storageTimeZone); + ZoneId fileTimeZone = stripeFooter.getTimeZone(); // get streams for selected columns Map streams = new HashMap<>(); @@ -204,7 +204,7 @@ public class StripeReader selectedRowGroups, columnEncodings); - return new Stripe(stripe.getNumberOfRows(), fileTimeZone, storageTimeZone, columnEncodings, rowGroups, dictionaryStreamSources); + return new Stripe(stripe.getNumberOfRows(), fileTimeZone, columnEncodings, rowGroups, dictionaryStreamSources); } catch (InvalidCheckpointException e) { // The ORC file contains a corrupt checkpoint stream treat the stripe as a single row group. @@ -275,7 +275,7 @@ public class StripeReader } RowGroup rowGroup = new RowGroup(0, 0, stripe.getNumberOfRows(), minAverageRowBytes, new InputStreamSources(builder.build())); - return new Stripe(stripe.getNumberOfRows(), fileTimeZone, storageTimeZone, columnEncodings, ImmutableList.of(rowGroup), dictionaryStreamSources); + return new Stripe(stripe.getNumberOfRows(), fileTimeZone, columnEncodings, ImmutableList.of(rowGroup), dictionaryStreamSources); } private static boolean isSupportedStreamType(Stream stream, OrcTypeKind orcTypeKind) @@ -425,7 +425,7 @@ public class StripeReader // read the footer Slice tailBuffer = orcDataSource.readFully(offset, tailLength); try (InputStream inputStream = new OrcInputStream(OrcChunkLoader.create(orcDataSource.getId(), tailBuffer, decompressor, systemMemoryUsage))) { - return metadataReader.readStripeFooter(types, inputStream); + return metadataReader.readStripeFooter(types, inputStream, legacyFileTimeZone); } } diff --git a/presto-orc/src/main/java/io/prestosql/orc/metadata/ExceptionWrappingMetadataReader.java b/presto-orc/src/main/java/io/prestosql/orc/metadata/ExceptionWrappingMetadataReader.java index 73508ea2e..e0932f0fa 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/metadata/ExceptionWrappingMetadataReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/metadata/ExceptionWrappingMetadataReader.java @@ -21,6 +21,7 @@ import io.prestosql.spi.PrestoException; import java.io.IOException; import java.io.InputStream; +import java.time.ZoneId; import java.util.List; import static com.google.common.base.Preconditions.checkArgument; @@ -77,11 +78,11 @@ public class ExceptionWrappingMetadataReader } @Override - public StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream) + public StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream, ZoneId legacyFileTimeZone) throws IOException { try { - return delegate.readStripeFooter(types, inputStream); + return delegate.readStripeFooter(types, inputStream, legacyFileTimeZone); } catch (IOException | RuntimeException e) { throw propagate(e, "Invalid stripe footer"); diff --git a/presto-orc/src/main/java/io/prestosql/orc/metadata/MetadataReader.java b/presto-orc/src/main/java/io/prestosql/orc/metadata/MetadataReader.java index e8b1cb92e..3beae6c6e 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/metadata/MetadataReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/metadata/MetadataReader.java @@ -18,6 +18,7 @@ import io.prestosql.orc.metadata.statistics.HashableBloomFilter; import java.io.IOException; import java.io.InputStream; +import java.time.ZoneId; import java.util.List; public interface MetadataReader @@ -31,7 +32,7 @@ public interface MetadataReader Footer readFooter(HiveWriterVersion hiveWriterVersion, InputStream inputStream) throws IOException; - StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream) + StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream, ZoneId legacyFileTimeZone) throws IOException; List readRowIndexes(HiveWriterVersion hiveWriterVersion, InputStream inputStream) diff --git a/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataReader.java b/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataReader.java index d5f7f44b5..10f468330 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataReader.java @@ -43,6 +43,7 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.nio.ByteOrder; +import java.time.ZoneId; import java.util.List; import java.util.Map; import java.util.Optional; @@ -159,7 +160,7 @@ public class OrcMetadataReader } @Override - public StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream) + public StripeFooter readStripeFooter(ColumnMetadata types, InputStream inputStream, ZoneId legacyFileTimeZone) throws IOException { CodedInputStream input = CodedInputStream.newInstance(inputStream); @@ -168,7 +169,8 @@ public class OrcMetadataReader toStream(stripeFooter.getStreamsList()), toColumnEncoding(stripeFooter.getColumnsList()), Optional.ofNullable(emptyToNull(stripeFooter.getWriterTimezone())) - .map(zone -> TimeZone.getTimeZone(zone).toZoneId())); + .map(zone -> TimeZone.getTimeZone(zone).toZoneId()) + .orElse(legacyFileTimeZone)); } private static Stream toStream(OrcProto.Stream stream) diff --git a/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataWriter.java b/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataWriter.java index 4ec6a6bb5..4c9b697dc 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataWriter.java +++ b/presto-orc/src/main/java/io/prestosql/orc/metadata/OrcMetadataWriter.java @@ -32,11 +32,9 @@ import io.prestosql.orc.protobuf.MessageLite; import java.io.IOException; import java.io.OutputStream; -import java.time.ZoneId; import java.util.List; import java.util.Map.Entry; import java.util.Optional; -import java.util.TimeZone; import static java.lang.Math.toIntExact; import static java.util.stream.Collectors.toList; @@ -284,8 +282,6 @@ public class OrcMetadataWriter public int writeStripeFooter(SliceOutput output, StripeFooter footer) throws IOException { - ZoneId zone = footer.getTimeZone().orElseThrow(() -> new IllegalArgumentException("Time zone not set")); - OrcProto.StripeFooter footerProtobuf = OrcProto.StripeFooter.newBuilder() .addAllStreams(footer.getStreams().stream() .map(OrcMetadataWriter::toStream) @@ -293,7 +289,7 @@ public class OrcMetadataWriter .addAllColumns(footer.getColumnEncodings().stream() .map(OrcMetadataWriter::toColumnEncoding) .collect(toList())) - .setWriterTimezone(TimeZone.getTimeZone(zone).getID()) + .setWriterTimezone(footer.getTimeZone().getId()) .build(); return writeProtobufObject(output, footerProtobuf); diff --git a/presto-orc/src/main/java/io/prestosql/orc/metadata/StripeFooter.java b/presto-orc/src/main/java/io/prestosql/orc/metadata/StripeFooter.java index 040b3d9eb..c5ced1a3b 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/metadata/StripeFooter.java +++ b/presto-orc/src/main/java/io/prestosql/orc/metadata/StripeFooter.java @@ -17,7 +17,6 @@ import com.google.common.collect.ImmutableList; import java.time.ZoneId; import java.util.List; -import java.util.Optional; import static java.util.Objects.requireNonNull; @@ -25,9 +24,9 @@ public class StripeFooter { private final List streams; private final ColumnMetadata columnEncodings; - private final Optional timeZone; + private final ZoneId timeZone; - public StripeFooter(List streams, ColumnMetadata columnEncodings, Optional timeZone) + public StripeFooter(List streams, ColumnMetadata columnEncodings, ZoneId timeZone) { this.streams = ImmutableList.copyOf(requireNonNull(streams, "streams is null")); this.columnEncodings = requireNonNull(columnEncodings, "columnEncodings is null"); @@ -44,7 +43,7 @@ public class StripeFooter return streams; } - public Optional getTimeZone() + public ZoneId getTimeZone() { return timeZone; } diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractColumnReader.java index 8d80775e1..81271d615 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractColumnReader.java @@ -22,7 +22,7 @@ import java.time.ZoneId; public interface AbstractColumnReader { - void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException; void startRowGroup(InputStreamSources dataStreamSources) diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractDecimalSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractDecimalSelectiveColumnReader.java index 628fb55ef..c1a03d0a7 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractDecimalSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractDecimalSelectiveColumnReader.java @@ -95,7 +95,7 @@ public abstract class AbstractDecimalSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(DecimalInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractNumericColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractNumericColumnReader.java index c3b4e2cce..3e1a5b34d 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractNumericColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/AbstractNumericColumnReader.java @@ -97,7 +97,7 @@ public abstract class AbstractNumericColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanColumnReader.java index 250557c48..47352866b 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanColumnReader.java @@ -176,7 +176,7 @@ public class BooleanColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(BooleanInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanSelectiveColumnReader.java index f9f57d1f3..15da7509e 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/BooleanSelectiveColumnReader.java @@ -93,7 +93,7 @@ public class BooleanSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(BooleanInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/ByteColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/ByteColumnReader.java index a9246e0bd..bc89afd2e 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/ByteColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/ByteColumnReader.java @@ -177,7 +177,7 @@ public class ByteColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(ByteInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/CachingColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/CachingColumnReader.java index eda7f048b..0a222c99c 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/CachingColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/CachingColumnReader.java @@ -77,12 +77,12 @@ public class CachingColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, - ColumnMetadata encoding) throws IOException + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, + ColumnMetadata encoding) throws IOException { this.offset = 0; this.nextBatchSize = 0; - delegate.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + delegate.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/DataCachingSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/DataCachingSelectiveColumnReader.java index ea8404adb..16003909f 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/DataCachingSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/DataCachingSelectiveColumnReader.java @@ -134,9 +134,9 @@ public class DataCachingSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { - delegate.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + delegate.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/DecimalColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/DecimalColumnReader.java index 6c48b45c4..b4a0b7da8 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/DecimalColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/DecimalColumnReader.java @@ -307,7 +307,7 @@ public class DecimalColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); decimalStreamSource = missingStreamSource(DecimalInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleColumnReader.java index 947fe3432..0004b0953 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleColumnReader.java @@ -179,7 +179,7 @@ public class DoubleColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(DoubleInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleSelectiveColumnReader.java index 82ed94447..35562b129 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/DoubleSelectiveColumnReader.java @@ -95,7 +95,7 @@ public class DoubleSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(DoubleInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/FloatColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/FloatColumnReader.java index e5c6c5e3e..25f6fe7c3 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/FloatColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/FloatColumnReader.java @@ -178,7 +178,7 @@ public class FloatColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(FloatInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/FloatSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/FloatSelectiveColumnReader.java index 0b89c3530..3df32540a 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/FloatSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/FloatSelectiveColumnReader.java @@ -85,7 +85,7 @@ public class FloatSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); dataStreamSource = missingStreamSource(FloatInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/ListColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/ListColumnReader.java index fcfadf892..7b4cc64ae 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/ListColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/ListColumnReader.java @@ -165,7 +165,7 @@ public class ListColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { presentStreamSource = missingStreamSource(BooleanInputStream.class); @@ -179,7 +179,7 @@ public class ListColumnReader rowGroupOpen = false; - elementColumnReader.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + elementColumnReader.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/LongSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/LongSelectiveColumnReader.java index dd7fdbb7f..b96634696 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/LongSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/LongSelectiveColumnReader.java @@ -319,7 +319,7 @@ public class LongSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dataStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dataStreamSources, ColumnMetadata encoding) { presentStreamSource = dataStreamSources.getInputStreamSource(streamDescriptor, PRESENT, BooleanInputStream.class); dataStreamSource = dataStreamSources.getInputStreamSource(streamDescriptor, DATA, LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/MapColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/MapColumnReader.java index b5e20be41..66d763239 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/MapColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/MapColumnReader.java @@ -224,7 +224,7 @@ public class MapColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { presentStreamSource = missingStreamSource(BooleanInputStream.class); @@ -238,8 +238,8 @@ public class MapColumnReader rowGroupOpen = false; - keyColumnReader.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); - valueColumnReader.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + keyColumnReader.startStripe(fileTimeZone, dictionaryStreamSources, encoding); + valueColumnReader.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/ResultCachingSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/ResultCachingSelectiveColumnReader.java index 305a14b23..72e9eca0d 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/ResultCachingSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/ResultCachingSelectiveColumnReader.java @@ -127,9 +127,9 @@ public class ResultCachingSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, - InputStreamSources dictionaryStreamSources, - ColumnMetadata encoding) throws IOException + public void startStripe(ZoneId fileTimeZone, + InputStreamSources dictionaryStreamSources, + ColumnMetadata encoding) throws IOException { this.offset = 0; this.readSize = 0; @@ -144,7 +144,7 @@ public class ResultCachingSelectiveColumnReader cachedBlock = cacheAccumulated(stripeInformation);*/ - delegate.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + delegate.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SelectiveColumnReaders.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SelectiveColumnReaders.java index 08c2d88f4..fbeb794b9 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SelectiveColumnReaders.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SelectiveColumnReaders.java @@ -54,7 +54,7 @@ public final class SelectiveColumnReaders case CHAR: return new SliceSelectiveColumnReader(orcType, column, filter, outputType, systemMemoryContext.newLocalMemoryContext(SelectiveColumnReaders.class.getSimpleName())); case TIMESTAMP: - return new TimestampSelectiveColumnReader(column, filter, hiveStorageTimeZone, outputType.isPresent(), systemMemoryContext.newLocalMemoryContext(SelectiveColumnReaders.class.getSimpleName())); + return new TimestampSelectiveColumnReader(column, filter, outputType.isPresent(), systemMemoryContext.newLocalMemoryContext(SelectiveColumnReaders.class.getSimpleName())); case DECIMAL: if (orcType.getPrecision().get() > MAX_SHORT_PRECISION) { return new LongDecimalSelectiveColumnReader(orcType, column, filter, outputType, systemMemoryContext.newLocalMemoryContext(SelectiveColumnReaders.class.getSimpleName())); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceColumnReader.java index 49352c79f..131693ab9 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceColumnReader.java @@ -85,7 +85,7 @@ public class SliceColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { ColumnEncodingKind columnEncodingKind = encoding.get(column.getColumnId()).getColumnEncodingKind(); @@ -99,7 +99,7 @@ public class SliceColumnReader throw new IllegalArgumentException("Unsupported encoding " + columnEncodingKind); } - currentReader.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + currentReader.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionaryColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionaryColumnReader.java index 2956ca7ec..1780c75b1 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionaryColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionaryColumnReader.java @@ -312,7 +312,7 @@ public class SliceDictionaryColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { dictionaryDataStreamSource = dictionaryStreamSources.getInputStreamSource(column, DICTIONARY_DATA, ByteArrayInputStream.class); dictionaryLengthStreamSource = dictionaryStreamSources.getInputStreamSource(column, LENGTH, LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionarySelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionarySelectiveColumnReader.java index 7257c885b..d6f17b709 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionarySelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDictionarySelectiveColumnReader.java @@ -472,7 +472,7 @@ public class SliceDictionarySelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { stripeDictionaryDataStreamSource = dictionaryStreamSources.getInputStreamSource(streamDescriptor, DICTIONARY_DATA, ByteArrayInputStream.class); stripeDictionaryLengthStreamSource = dictionaryStreamSources.getInputStreamSource(streamDescriptor, LENGTH, LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectColumnReader.java index 1504bfe2e..bec1e2952 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectColumnReader.java @@ -246,7 +246,7 @@ public class SliceDirectColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); lengthStreamSource = missingStreamSource(LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectSelectiveColumnReader.java index 374ef6363..b02980e89 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceDirectSelectiveColumnReader.java @@ -498,7 +498,7 @@ public class SliceDirectSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); lengthStreamSource = missingStreamSource(LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceSelectiveColumnReader.java index 1cce01029..d0b738569 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/SliceSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/SliceSelectiveColumnReader.java @@ -60,7 +60,7 @@ public class SliceSelectiveColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { ColumnEncoding.ColumnEncodingKind columnEncodingKind = encoding.get(streamDescriptor.getColumnId()).getColumnEncodingKind(); @@ -74,7 +74,7 @@ public class SliceSelectiveColumnReader throw new IllegalArgumentException("Unsupported encoding " + columnEncodingKind); } - currentReader.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + currentReader.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } @Override diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/StructColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/StructColumnReader.java index 7f508c053..ad094bd76 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/StructColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/StructColumnReader.java @@ -174,7 +174,7 @@ public class StructColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) throws IOException { presentStreamSource = missingStreamSource(BooleanInputStream.class); @@ -187,7 +187,7 @@ public class StructColumnReader rowGroupOpen = false; for (ColumnReader structField : structFields.values()) { - structField.startStripe(fileTimeZone, storageTimeZone, dictionaryStreamSources, encoding); + structField.startStripe(fileTimeZone, dictionaryStreamSources, encoding); } } diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampColumnReader.java index 847378c40..e06d012f1 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampColumnReader.java @@ -26,7 +26,6 @@ import io.prestosql.orc.stream.LongInputStream; import io.prestosql.spi.block.Block; import io.prestosql.spi.block.LongArrayBlock; import io.prestosql.spi.block.RunLengthEncodedBlock; -import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.TimestampType; import io.prestosql.spi.type.Type; import org.joda.time.DateTimeZone; @@ -40,7 +39,6 @@ import java.time.ZonedDateTime; import java.util.Optional; import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Verify.verify; import static io.airlift.slice.SizeOf.sizeOf; import static io.prestosql.orc.metadata.Stream.StreamKind.DATA; import static io.prestosql.orc.metadata.Stream.StreamKind.PRESENT; @@ -60,9 +58,6 @@ public class TimestampColumnReader private final OrcColumn column; private long baseTimestampInSeconds; - @Nullable - private DateTimeZone storageDateTimeZone; - @Nullable private DateTimeZone fileDateTimeZone; private int readOffset; @@ -176,17 +171,9 @@ public class TimestampColumnReader for (int i = 0; i < nextBatchSize; i++) { values[i] = decodeTimestamp(secondsStream.next(), nanosStream.next(), baseTimestampInSeconds); } - if (storageDateTimeZone != fileDateTimeZone) { - verify(storageDateTimeZone != null && fileDateTimeZone != null); - if (fileDateTimeZone == DateTimeZone.UTC) { - for (int i = 0; i < nextBatchSize; i++) { - values[i] = storageDateTimeZone.convertLocalToUTC(values[i], false); - } - } - else { - for (int i = 0; i < nextBatchSize; i++) { - values[i] = fileDateTimeZone.getMillisKeepLocal(storageDateTimeZone, values[i]); - } + if (fileDateTimeZone != DateTimeZone.UTC) { + for (int i = 0; i < nextBatchSize; i++) { + values[i] = fileDateTimeZone.convertUTCToLocal(values[i]); } } return new LongArrayBlock(nextBatchSize, Optional.empty(), values); @@ -208,20 +195,10 @@ public class TimestampColumnReader values[i] = decodeTimestamp(secondsStream.next(), nanosStream.next(), baseTimestampInSeconds); } } - if (storageDateTimeZone != fileDateTimeZone) { - verify(storageDateTimeZone != null && fileDateTimeZone != null); - if (fileDateTimeZone == DateTimeZone.UTC) { - for (int i = 0; i < nextBatchSize; i++) { - if (!isNull[i]) { - values[i] = storageDateTimeZone.convertLocalToUTC(values[i], false); - } - } - } - else { - for (int i = 0; i < nextBatchSize; i++) { - if (!isNull[i]) { - values[i] = fileDateTimeZone.getMillisKeepLocal(storageDateTimeZone, values[i]); - } + if (fileDateTimeZone != DateTimeZone.UTC) { + for (int i = 0; i < nextBatchSize; i++) { + if (!isNull[i]) { + values[i] = fileDateTimeZone.convertUTCToLocal(values[i]); } } } @@ -239,21 +216,11 @@ public class TimestampColumnReader } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { baseTimestampInSeconds = ZonedDateTime.of(2015, 1, 1, 0, 0, 0, 0, fileTimeZone).toEpochSecond(); - TimeZoneKey fileTimeZoneKey = TimeZoneKey.getTimeZoneKey(fileTimeZone.getId()); - TimeZoneKey storageTimeZoneKey = TimeZoneKey.getTimeZoneKey(storageTimeZone.getId()); - if (fileTimeZoneKey.equals(storageTimeZoneKey)) { - storageDateTimeZone = null; - fileDateTimeZone = null; - } - else { - storageDateTimeZone = DateTimeZone.forID(storageTimeZoneKey.getId()); - fileDateTimeZone = DateTimeZone.forID(fileTimeZoneKey.getId()); - } - + fileDateTimeZone = DateTimeZone.forID(fileTimeZone.getId()); presentStreamSource = missingStreamSource(BooleanInputStream.class); secondsStreamSource = missingStreamSource(LongInputStream.class); nanosStreamSource = missingStreamSource(LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampSelectiveColumnReader.java b/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampSelectiveColumnReader.java index 38c32ff4d..5a872366f 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampSelectiveColumnReader.java +++ b/presto-orc/src/main/java/io/prestosql/orc/reader/TimestampSelectiveColumnReader.java @@ -28,7 +28,6 @@ import io.prestosql.spi.block.LongArrayBlock; import io.prestosql.spi.block.LongArrayBlockBuilder; import io.prestosql.spi.block.RunLengthEncodedBlock; import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.openjdk.jol.info.ClassLayout; import javax.annotation.Nullable; @@ -49,6 +48,7 @@ import static io.prestosql.orc.reader.ApacheHiveTimestampDecoder.decodeTimestamp import static io.prestosql.orc.stream.MissingInputStreamSource.missingStreamSource; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static java.util.Objects.requireNonNull; +import static org.joda.time.DateTimeZone.UTC; public class TimestampSelectiveColumnReader implements SelectiveColumnReader @@ -87,7 +87,6 @@ public class TimestampSelectiveColumnReader public TimestampSelectiveColumnReader( OrcColumn streamDescriptor, Optional filter, - DateTimeZone hiveStorageTimeZone, boolean outputRequired, LocalMemoryContext systemMemoryContext) { @@ -96,11 +95,11 @@ public class TimestampSelectiveColumnReader this.outputRequired = outputRequired; this.systemMemoryContext = requireNonNull(systemMemoryContext, "systemMemoryContext is null"); this.nullsAllowed = this.filter == null || this.filter.testNull(); - this.baseTimestampInSeconds = new DateTime(2015, 1, 1, 0, 0, requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null")).getMillis() / 1000; + this.baseTimestampInSeconds = new DateTime(2015, 1, 1, 0, 0, requireNonNull(UTC, "hiveStorageTimeZone is null")).getMillis() / 1000; } @Override - public void startStripe(ZoneId fileTimeZone, ZoneId storageTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) + public void startStripe(ZoneId fileTimeZone, InputStreamSources dictionaryStreamSources, ColumnMetadata encoding) { presentStreamSource = missingStreamSource(BooleanInputStream.class); secondsStreamSource = missingStreamSource(LongInputStream.class); diff --git a/presto-orc/src/main/java/io/prestosql/orc/writer/ColumnWriters.java b/presto-orc/src/main/java/io/prestosql/orc/writer/ColumnWriters.java index 857ec0dc8..19bff61da 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/writer/ColumnWriters.java +++ b/presto-orc/src/main/java/io/prestosql/orc/writer/ColumnWriters.java @@ -23,7 +23,6 @@ import io.prestosql.orc.metadata.statistics.BinaryStatisticsBuilder; import io.prestosql.orc.metadata.statistics.DateStatisticsBuilder; import io.prestosql.orc.metadata.statistics.IntegerStatisticsBuilder; import io.prestosql.spi.type.Type; -import org.joda.time.DateTimeZone; import static java.util.Objects.requireNonNull; @@ -37,7 +36,6 @@ public final class ColumnWriters Type type, CompressionKind compression, int bufferSize, - DateTimeZone hiveStorageTimeZone, DataSize stringStatisticsLimit) { requireNonNull(type, "type is null"); @@ -67,7 +65,7 @@ public final class ColumnWriters return new DecimalColumnWriter(columnId, type, compression, bufferSize); case TIMESTAMP: - return new TimestampColumnWriter(columnId, type, compression, bufferSize, hiveStorageTimeZone); + return new TimestampColumnWriter(columnId, type, compression, bufferSize); case BINARY: return new SliceDirectColumnWriter(columnId, type, compression, bufferSize, BinaryStatisticsBuilder::new); @@ -80,7 +78,7 @@ public final class ColumnWriters case LIST: { OrcColumnId fieldColumnIndex = orcType.getFieldTypeIndex(0); Type fieldType = type.getTypeParameters().get(0); - ColumnWriter elementWriter = createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, bufferSize, hiveStorageTimeZone, stringStatisticsLimit); + ColumnWriter elementWriter = createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, bufferSize, stringStatisticsLimit); return new ListColumnWriter(columnId, compression, bufferSize, elementWriter); } @@ -91,7 +89,6 @@ public final class ColumnWriters type.getTypeParameters().get(0), compression, bufferSize, - hiveStorageTimeZone, stringStatisticsLimit); ColumnWriter valueWriter = createColumnWriter( orcType.getFieldTypeIndex(1), @@ -99,7 +96,6 @@ public final class ColumnWriters type.getTypeParameters().get(1), compression, bufferSize, - hiveStorageTimeZone, stringStatisticsLimit); return new MapColumnWriter(columnId, compression, bufferSize, keyWriter, valueWriter); } @@ -109,7 +105,7 @@ public final class ColumnWriters for (int fieldId = 0; fieldId < orcType.getFieldCount(); fieldId++) { OrcColumnId fieldColumnIndex = orcType.getFieldTypeIndex(fieldId); Type fieldType = type.getTypeParameters().get(fieldId); - fieldWriters.add(createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, bufferSize, hiveStorageTimeZone, stringStatisticsLimit)); + fieldWriters.add(createColumnWriter(fieldColumnIndex, orcTypes, fieldType, compression, bufferSize, stringStatisticsLimit)); } return new StructColumnWriter(columnId, compression, bufferSize, fieldWriters.build()); } diff --git a/presto-orc/src/main/java/io/prestosql/orc/writer/TimestampColumnWriter.java b/presto-orc/src/main/java/io/prestosql/orc/writer/TimestampColumnWriter.java index 7c5f24c56..401ebe2e9 100644 --- a/presto-orc/src/main/java/io/prestosql/orc/writer/TimestampColumnWriter.java +++ b/presto-orc/src/main/java/io/prestosql/orc/writer/TimestampColumnWriter.java @@ -32,11 +32,10 @@ import io.prestosql.orc.stream.PresentOutputStream; import io.prestosql.orc.stream.StreamDataOutput; import io.prestosql.spi.block.Block; import io.prestosql.spi.type.Type; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.openjdk.jol.info.ClassLayout; import java.io.IOException; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -48,6 +47,7 @@ import static io.prestosql.orc.metadata.ColumnEncoding.ColumnEncodingKind.DIRECT import static io.prestosql.orc.metadata.CompressionKind.NONE; import static io.prestosql.orc.metadata.Stream.StreamKind.DATA; import static io.prestosql.orc.metadata.Stream.StreamKind.SECONDARY; +import static java.time.ZoneOffset.UTC; import static java.util.Objects.requireNonNull; public class TimestampColumnWriter @@ -72,7 +72,7 @@ public class TimestampColumnWriter private boolean closed; - public TimestampColumnWriter(OrcColumnId columnId, Type type, CompressionKind compression, int bufferSize, DateTimeZone hiveStorageTimeZone) + public TimestampColumnWriter(OrcColumnId columnId, Type type, CompressionKind compression, int bufferSize) { this.columnId = requireNonNull(columnId, "columnId is null"); this.type = requireNonNull(type, "type is null"); @@ -81,7 +81,7 @@ public class TimestampColumnWriter this.secondsStream = new LongOutputStreamV2(compression, bufferSize, true, DATA); this.nanosStream = new LongOutputStreamV2(compression, bufferSize, false, SECONDARY); this.presentStream = new PresentOutputStream(compression, bufferSize); - this.baseTimestampInSeconds = new DateTime(2015, 1, 1, 0, 0, requireNonNull(hiveStorageTimeZone, "hiveStorageTimeZone is null")).getMillis() / MILLIS_PER_SECOND; + this.baseTimestampInSeconds = OffsetDateTime.of(2015, 1, 1, 0, 0, 0, 0, UTC).toEpochSecond(); } @Override diff --git a/presto-orc/src/test/java/io/prestosql/orc/AbstractTestOrcReader.java b/presto-orc/src/test/java/io/prestosql/orc/AbstractTestOrcReader.java index 067594f6f..bf3b3abe5 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/AbstractTestOrcReader.java +++ b/presto-orc/src/test/java/io/prestosql/orc/AbstractTestOrcReader.java @@ -25,7 +25,6 @@ import io.prestosql.spi.type.SqlDate; import io.prestosql.spi.type.SqlDecimal; import io.prestosql.spi.type.SqlTimestamp; import io.prestosql.spi.type.SqlVarbinary; -import io.prestosql.spi.type.TimeZoneKey; import org.joda.time.DateTimeZone; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -55,7 +54,6 @@ import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Collections.nCopies; import static java.util.stream.Collectors.toList; @@ -193,7 +191,7 @@ public abstract class AbstractTestOrcReader tester.testRoundTrip( TIMESTAMP, writeValues.stream() - .map(timestamp -> sqlTimestampOf(timestamp, SESSION)) + .map(timestamp -> sqlTimestampOf(timestamp)) .collect(toList())); } @@ -290,16 +288,16 @@ public abstract class AbstractTestOrcReader } @Test - public void testLegacyTimestamp() + public void testTimestamp() throws Exception { @SuppressWarnings("deprecation") List values = ImmutableList.of( - new SqlTimestamp(0, TimeZoneKey.UTC_KEY), - new SqlTimestamp(10, TimeZoneKey.UTC_KEY), - new SqlTimestamp(1123456789L, TimeZoneKey.UTC_KEY), // 1970-01-14T00:04:16.789Z - new SqlTimestamp(1000123456789L, TimeZoneKey.UTC_KEY), // 2001-09-10T12:04:16.789Z - new SqlTimestamp(1575553299564L, TimeZoneKey.UTC_KEY)); // 2019-12-05T13:41:39.564Z + new SqlTimestamp(0), + new SqlTimestamp(10), + new SqlTimestamp(1123456789L), // 1970-01-14T00:04:16.789Z + new SqlTimestamp(1000123456789L), // 2001-09-10T12:04:16.789Z + new SqlTimestamp(1575553299564L)); // 2019-12-05T13:41:39.564Z tester.testRoundTrip(TIMESTAMP, newArrayList(limit(cycle(values), 30_000))); } diff --git a/presto-orc/src/test/java/io/prestosql/orc/BenchmarkColumnReaders.java b/presto-orc/src/test/java/io/prestosql/orc/BenchmarkColumnReaders.java index fe061e204..43263e9e0 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/BenchmarkColumnReaders.java +++ b/presto-orc/src/test/java/io/prestosql/orc/BenchmarkColumnReaders.java @@ -66,7 +66,6 @@ import static io.prestosql.spi.type.DoubleType.DOUBLE; import static io.prestosql.spi.type.IntegerType.INTEGER; import static io.prestosql.spi.type.RealType.REAL; import static io.prestosql.spi.type.SmallintType.SMALLINT; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.VarcharType.VARCHAR; @@ -1040,7 +1039,7 @@ public class BenchmarkColumnReaders { List values = new ArrayList<>(); for (int i = 0; i < ROWS; ++i) { - values.add(new SqlTimestamp((random.nextLong()), UTC_KEY)); + values.add(new SqlTimestamp((random.nextLong()))); } return values.iterator(); } @@ -1063,7 +1062,7 @@ public class BenchmarkColumnReaders List values = new ArrayList<>(); for (int i = 0; i < ROWS; ++i) { if (random.nextBoolean()) { - values.add(new SqlTimestamp(random.nextLong(), UTC_KEY)); + values.add(new SqlTimestamp(random.nextLong())); } else { values.add(null); diff --git a/presto-orc/src/test/java/io/prestosql/orc/OrcTester.java b/presto-orc/src/test/java/io/prestosql/orc/OrcTester.java index afc011981..0c7948967 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/OrcTester.java +++ b/presto-orc/src/test/java/io/prestosql/orc/OrcTester.java @@ -43,8 +43,10 @@ import io.prestosql.spi.type.VarbinaryType; import io.prestosql.spi.type.VarcharType; 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.Timestamp; import org.apache.hadoop.hive.ql.exec.FileSinkOperator.RecordWriter; import org.apache.hadoop.hive.ql.io.orc.OrcFile; import org.apache.hadoop.hive.ql.io.orc.OrcFile.ReaderOptions; @@ -55,11 +57,11 @@ import org.apache.hadoop.hive.ql.io.orc.OrcUtil; import org.apache.hadoop.hive.ql.io.orc.Reader; import org.apache.hadoop.hive.ql.io.orc.RecordReader; 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.HiveCharWritable; 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.SettableStructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.StructField; @@ -84,11 +86,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -import java.sql.Date; -import java.sql.Timestamp; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -139,7 +136,6 @@ import static io.prestosql.spi.type.Varchars.truncateToLength; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.util.Arrays.asList; -import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.stream.Collectors.toList; import static org.apache.hadoop.hive.serde2.ColumnProjectionUtils.READ_ALL_COLUMNS; import static org.apache.hadoop.hive.serde2.ColumnProjectionUtils.READ_COLUMN_IDS_CONF_STR; @@ -617,7 +613,7 @@ public class OrcTester } } else if (type == TIMESTAMP) { - return filter.testLong(((SqlTimestamp) value).getMillisUtc()); + return filter.testLong(((SqlTimestamp) value).getMillis()); } else if (type == VARCHAR) { return filter.testBytes(((String) value).getBytes(), 0, ((String) value).length()); @@ -850,7 +846,6 @@ public class OrcTester new OrcWriterOptions(), false, ImmutableMap.of(), - HIVE_STORAGE_TIME_ZONE, true, BOTH, stats, Optional.empty(), Optional.empty()); @@ -907,7 +902,7 @@ public class OrcTester type.writeLong(blockBuilder, days); } else if (TIMESTAMP.equals(type)) { - long millis = ((SqlTimestamp) value).getMillisUtc(); + long millis = ((SqlTimestamp) value).getMillis(); type.writeLong(blockBuilder, millis); } else { @@ -970,7 +965,8 @@ public class OrcTester Reader reader = OrcFile.createReader( new Path(tempFile.getFile().getAbsolutePath()), - new ReaderOptions(configuration)); + new ReaderOptions(configuration) + .useUTCTimestamp(true)); RecordReader recordReader = reader.rows(); StructObjectInspector rowInspector = (StructObjectInspector) reader.getObjectInspector(); @@ -1000,8 +996,8 @@ public class OrcTester else if (actualValue instanceof BytesWritable) { actualValue = new SqlVarbinary(((BytesWritable) actualValue).copyBytes()); } - else if (actualValue instanceof DateWritable) { - actualValue = new SqlDate(((DateWritable) actualValue).getDays()); + else if (actualValue instanceof DateWritableV2) { + actualValue = new SqlDate(((DateWritableV2) actualValue).getDays()); } else if (actualValue instanceof DoubleWritable) { actualValue = ((DoubleWritable) actualValue).get(); @@ -1031,9 +1027,8 @@ public class OrcTester else if (actualValue instanceof Text) { actualValue = actualValue.toString(); } - else if (actualValue instanceof TimestampWritable) { - TimestampWritable timestamp = (TimestampWritable) actualValue; - actualValue = sqlTimestampOf((timestamp.getSeconds() * 1000) + (timestamp.getNanos() / 1000000L), SESSION); + else if (actualValue instanceof TimestampWritableV2) { + actualValue = sqlTimestampOf(((TimestampWritableV2) actualValue).getTimestamp().toEpochMilli()); } else if (actualValue instanceof OrcStruct) { List fields = new ArrayList<>(); @@ -1217,19 +1212,10 @@ public class OrcTester return ((SqlVarbinary) value).getBytes(); } if (type.equals(DATE)) { - int days = ((SqlDate) value).getDays(); - LocalDate localDate = LocalDate.ofEpochDay(days); - ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); - - long millis = SECONDS.toMillis(zonedDateTime.toEpochSecond()); - Date date = new Date(0); - // millis must be set separately to avoid masking - date.setTime(millis); - return date; + return Date.ofEpochDay(((SqlDate) value).getDays()); } if (type.equals(TIMESTAMP)) { - long millisUtc = ((SqlTimestamp) value).getMillisUtc(); - return new Timestamp(millisUtc); + return Timestamp.ofEpochMilli(((SqlTimestamp) value).getMillis()); } if (type instanceof DecimalType) { return HiveDecimal.create(((SqlDecimal) value).toBigDecimal()); diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestCachingColumnReader.java b/presto-orc/src/test/java/io/prestosql/orc/TestCachingColumnReader.java index c080bea44..55a94ca10 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestCachingColumnReader.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestCachingColumnReader.java @@ -180,11 +180,10 @@ public class TestCachingColumnReader InputStreamSources inputStreamSources = mock(InputStreamSources.class); Stripe stripe = mock(Stripe.class); ZoneId fileTimeZone = stripe.getFileTimeZone(); - ZoneId storageTimeZone = stripe.getStorageTimeZone(); ColumnMetadata columnEncodings = stripe.getColumnEncodings(); - cachingColumnReader.startStripe(fileTimeZone, storageTimeZone, inputStreamSources, columnEncodings); - verify(streamReader, atLeastOnce()).startStripe(eq(fileTimeZone), eq(storageTimeZone), eq(inputStreamSources), + cachingColumnReader.startStripe(fileTimeZone, inputStreamSources, columnEncodings); + verify(streamReader, atLeastOnce()).startStripe(eq(fileTimeZone), eq(inputStreamSources), eq(columnEncodings)); } diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestOrcWriter.java b/presto-orc/src/test/java/io/prestosql/orc/TestOrcWriter.java index 5fad6e95d..3327192b2 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestOrcWriter.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestOrcWriter.java @@ -34,12 +34,12 @@ import org.testng.annotations.Test; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.time.ZoneId; import java.util.Optional; import static io.airlift.testing.Assertions.assertGreaterThanOrEqual; import static io.airlift.units.DataSize.Unit.MEGABYTE; import static io.prestosql.memory.context.AggregatedMemoryContext.newSimpleAggregatedMemoryContext; -import static io.prestosql.orc.OrcTester.HIVE_STORAGE_TIME_ZONE; import static io.prestosql.orc.StripeReader.isIndexStream; import static io.prestosql.orc.TestingOrcPredicate.ORC_ROW_GROUP_SIZE; import static io.prestosql.orc.TestingOrcPredicate.ORC_STRIPE_SIZE; @@ -69,7 +69,6 @@ public class TestOrcWriter .withDictionaryMaxMemory(new DataSize(32, MEGABYTE)), false, ImmutableMap.of(), - HIVE_STORAGE_TIME_ZONE, true, validationMode, new OrcWriterStats(), Optional.empty(), Optional.empty()); @@ -103,7 +102,7 @@ public class TestOrcWriter // read the footer Slice tailBuffer = orcDataSource.readFully(stripe.getOffset() + stripe.getIndexLength() + stripe.getDataLength(), toIntExact(stripe.getFooterLength())); try (InputStream inputStream = new OrcInputStream(OrcChunkLoader.create(orcDataSource.getId(), tailBuffer, Optional.empty(), newSimpleAggregatedMemoryContext()))) { - StripeFooter stripeFooter = new OrcMetadataReader().readStripeFooter(footer.getTypes(), inputStream); + StripeFooter stripeFooter = new OrcMetadataReader().readStripeFooter(footer.getTypes(), inputStream, ZoneId.of("UTC")); int size = 0; boolean dataStreamStarted = false; diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestReadBloomFilter.java b/presto-orc/src/test/java/io/prestosql/orc/TestReadBloomFilter.java index 784ee0ba0..d7405b593 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestReadBloomFilter.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestReadBloomFilter.java @@ -20,7 +20,6 @@ import io.prestosql.spi.predicate.Domain; import io.prestosql.spi.type.SqlDate; import io.prestosql.spi.type.SqlTimestamp; import io.prestosql.spi.type.SqlVarbinary; -import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import org.testng.annotations.Test; @@ -57,8 +56,6 @@ import static org.testng.Assert.assertNull; public class TestReadBloomFilter { - private static final TimeZoneKey TIME_ZONE = TimeZoneKey.getTimeZoneKey(HIVE_STORAGE_TIME_ZONE.getID()); - @Test public void test() throws Exception @@ -70,9 +67,9 @@ public class TestReadBloomFilter testType(DATE, ImmutableList.of(new SqlDate(1), new SqlDate(5_000), new SqlDate(10_000)), 5_000L, 7_777L); testType(TIMESTAMP, - ImmutableList.of(new SqlTimestamp(1, TIME_ZONE), new SqlTimestamp(500_000L, TIME_ZONE), new SqlTimestamp(1_000_000L, TIME_ZONE)), - 500_000L + HIVE_STORAGE_TIME_ZONE.getOffset(500_000L), - 777_777L + HIVE_STORAGE_TIME_ZONE.getOffset(777_777L)); + ImmutableList.of(new SqlTimestamp(1), new SqlTimestamp(500_000L), new SqlTimestamp(1_000_000L)), + 500_000L, + 777_777L); testType(REAL, ImmutableList.of(1.11f, 500_000.56f, 1_000_000.99f), (long) floatToIntBits(500_000.56f), (long) floatToIntBits(777_777.77f)); testType(DOUBLE, ImmutableList.of(1.11, 500_000.55, 1_000_000.99), 500_000.55, 777_777.77); diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestSelectiveOrcReader.java b/presto-orc/src/test/java/io/prestosql/orc/TestSelectiveOrcReader.java index a99a98e78..09d76b3a1 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestSelectiveOrcReader.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestSelectiveOrcReader.java @@ -61,7 +61,6 @@ import static io.prestosql.spi.type.SmallintType.SMALLINT; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.util.Collections.nCopies; import static java.util.stream.Collectors.toList; import static org.testng.Assert.assertEquals; @@ -139,7 +138,7 @@ public class TestSelectiveOrcReader .collect(toList()); List timestamps = longValues.stream() - .map(timestamp -> sqlTimestampOf(timestamp & Integer.MAX_VALUE, SESSION)) + .map(timestamp -> sqlTimestampOf(timestamp)) .collect(toList()); tester.testRoundTrip(BIGINT, longValues, ImmutableList.of(ImmutableMap.of(0, filter))); diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestStructColumnReader.java b/presto-orc/src/test/java/io/prestosql/orc/TestStructColumnReader.java index fc9b0176c..351048443 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestStructColumnReader.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestStructColumnReader.java @@ -58,7 +58,6 @@ import java.util.Optional; import static io.airlift.units.DataSize.Unit.MEGABYTE; import static io.prestosql.memory.context.AggregatedMemoryContext.newSimpleAggregatedMemoryContext; import static io.prestosql.metadata.MetadataManager.createTestMetadataManager; -import static io.prestosql.orc.OrcTester.HIVE_STORAGE_TIME_ZONE; import static io.prestosql.orc.OrcWriteValidation.OrcWriteValidationMode.BOTH; import static io.prestosql.orc.TestingOrcPredicate.ORC_ROW_GROUP_SIZE; import static io.prestosql.orc.TestingOrcPredicate.ORC_STRIPE_SIZE; @@ -243,7 +242,6 @@ public class TestStructColumnReader .withDictionaryMaxMemory(new DataSize(32, MEGABYTE)), false, ImmutableMap.of(), - HIVE_STORAGE_TIME_ZONE, true, BOTH, new OrcWriterStats(), Optional.empty(), Optional.empty()); diff --git a/presto-orc/src/test/java/io/prestosql/orc/TestingOrcPredicate.java b/presto-orc/src/test/java/io/prestosql/orc/TestingOrcPredicate.java index b7d2b12a1..908e049cd 100644 --- a/presto-orc/src/test/java/io/prestosql/orc/TestingOrcPredicate.java +++ b/presto-orc/src/test/java/io/prestosql/orc/TestingOrcPredicate.java @@ -77,7 +77,7 @@ public final class TestingOrcPredicate if (TIMESTAMP.equals(type)) { return new LongOrcPredicate(false, expectedValues.stream() - .map(value -> value == null ? null : ((SqlTimestamp) value).getMillisUtc()) + .map(value -> value == null ? null : ((SqlTimestamp) value).getMillis()) .collect(toList())); } if (DATE.equals(type)) { diff --git a/presto-parquet/src/test/java/io/prestosql/parquet/TestParquetTimestampUtils.java b/presto-parquet/src/test/java/io/prestosql/parquet/TestParquetTimestampUtils.java index d15984c3c..7d22f7839 100644 --- a/presto-parquet/src/test/java/io/prestosql/parquet/TestParquetTimestampUtils.java +++ b/presto-parquet/src/test/java/io/prestosql/parquet/TestParquetTimestampUtils.java @@ -14,14 +14,13 @@ package io.prestosql.parquet; import io.prestosql.spi.PrestoException; -import org.apache.hadoop.hive.ql.io.parquet.timestamp.NanoTimeUtils; +import org.apache.hadoop.hive.common.type.Timestamp; import org.apache.parquet.io.api.Binary; import org.testng.annotations.Test; -import java.sql.Timestamp; - import static io.prestosql.parquet.ParquetTimestampUtils.getTimestampMillis; import static io.prestosql.spi.StandardErrorCode.NOT_SUPPORTED; +import static org.apache.hadoop.hive.ql.io.parquet.timestamp.NanoTimeUtils.getNanoTime; import static org.testng.Assert.assertEquals; public class TestParquetTimestampUtils @@ -50,8 +49,8 @@ public class TestParquetTimestampUtils private static void assertTimestampCorrect(String timestampString) { Timestamp timestamp = Timestamp.valueOf(timestampString); - Binary timestampBytes = NanoTimeUtils.getNanoTime(timestamp, false).toBinary(); + Binary timestampBytes = getNanoTime(timestamp, false).toBinary(); long decodedTimestampMillis = getTimestampMillis(timestampBytes); - assertEquals(decodedTimestampMillis, timestamp.getTime()); + assertEquals(decodedTimestampMillis, timestamp.toEpochMilli()); } } diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/BasePostgreSqlClient.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/BasePostgreSqlClient.java index 8d538cbb1..15df39604 100644 --- a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/BasePostgreSqlClient.java +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/BasePostgreSqlClient.java @@ -256,7 +256,7 @@ public abstract class BasePostgreSqlClient return Optional.of(typedVarcharColumnMapping(jdbcTypeName)); } if (typeHandle.getJdbcType() == Types.TIMESTAMP) { - return Optional.of(timestampColumnMapping(session)); + return Optional.of(timestampColumnMapping()); } if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) { if (!typeHandle.getArrayDimensions().isPresent()) { diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java index 95bbf6b33..c4788097f 100644 --- a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java @@ -56,7 +56,7 @@ public class PostgreSqlClient return WriteMapping.sliceMapping("bytea", varbinaryWriteFunction()); } if (TIMESTAMP.equals(type)) { - return WriteMapping.longMapping("timestamp", timestampWriteFunction(session)); + return WriteMapping.longMapping("timestamp", timestampWriteFunction()); } if (TIMESTAMP_WITH_TIME_ZONE.equals(type)) { return WriteMapping.longMapping("timestamp with time zone", timestampWithTimeZoneWriteFunction()); diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/TypeUtils.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/TypeUtils.java index eae1437c1..8b3d2f361 100644 --- a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/TypeUtils.java +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/TypeUtils.java @@ -35,7 +35,6 @@ import java.math.BigInteger; import java.math.MathContext; import java.sql.Date; import java.sql.Timestamp; -import java.time.ZoneId; import java.time.ZoneOffset; import static io.airlift.slice.Slices.utf8Slice; @@ -191,10 +190,6 @@ public final class TypeUtils if (TIMESTAMP.equals(prestoType)) { Timestamp timestamp = (Timestamp) jdbcObject; - if (session.isLegacyTimestamp()) { - ZoneId sessionZone = ZoneId.of(session.getTimeZoneKey().getId()); - return timestamp.toLocalDateTime().atZone(sessionZone).toInstant().toEpochMilli(); - } return timestamp.toLocalDateTime().atZone(ZoneOffset.UTC).toInstant().toEpochMilli(); } diff --git a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java index 7f6881694..c8614af49 100644 --- a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java +++ b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java @@ -522,7 +522,7 @@ public class TestPostgreSqlTypeMapping } @Test(dataProvider = "testTimestampDataProvider") - public void testTimestamp(boolean legacyTimestamp, boolean insertWithPresto) + public void testTimestamp(boolean insertWithPresto) { // using two non-JVM zones so that we don't need to worry what Postgres system zone is for (ZoneId sessionZone : ImmutableList.of(ZoneOffset.UTC, jvmZone, vilnius, kathmandu, ZoneId.of(TestingSession.DEFAULT_TIME_ZONE_KEY.getId()))) { @@ -535,17 +535,16 @@ public class TestPostgreSqlTypeMapping if (!insertWithPresto) { // when writing, Postgres JDBC driver converts LocalDateTime to string representing date-time in JVM zone // TODO upgrade driver or find a different way to write timestamp values - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, epoch); // epoch also is a gap in JVM zone - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInJvmZone1); - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInJvmZone2); + addTimestampTestIfSupported(tests, epoch); // epoch also is a gap in JVM zone + addTimestampTestIfSupported(tests, timeGapInJvmZone1); + addTimestampTestIfSupported(tests, timeGapInJvmZone2); } - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInVilnius); - addTimestampTestIfSupported(tests, legacyTimestamp, sessionZone, timeGapInKathmandu); + addTimestampTestIfSupported(tests, timeGapInVilnius); + addTimestampTestIfSupported(tests, timeGapInKathmandu); Session session = Session.builder(getQueryRunner().getDefaultSession()) .setTimeZoneKey(TimeZoneKey.getTimeZoneKey(sessionZone.getId())) - .setSystemProperty("legacy_timestamp", Boolean.toString(legacyTimestamp)) .build(); if (insertWithPresto) { @@ -557,13 +556,8 @@ public class TestPostgreSqlTypeMapping } } - private void addTimestampTestIfSupported(DataTypeTest tests, boolean legacyTimestamp, ZoneId sessionZone, LocalDateTime dateTime) + private void addTimestampTestIfSupported(DataTypeTest tests, LocalDateTime dateTime) { - if (legacyTimestamp && isGap(sessionZone, dateTime)) { - // in legacy timestamp semantics we cannot represent this dateTime - return; - } - tests.addRoundTrip(timestampDataType(), dateTime); } @@ -571,10 +565,8 @@ public class TestPostgreSqlTypeMapping public Object[][] testTimestampDataProvider() { return new Object[][] { - {true, true}, - {false, true}, - {true, false}, - {false, false}, + {true}, + {false}, }; } diff --git a/presto-product-tests/src/main/java/io/prestosql/tests/hive/TestHiveTableStatistics.java b/presto-product-tests/src/main/java/io/prestosql/tests/hive/TestHiveTableStatistics.java index 516759282..f08708c10 100644 --- a/presto-product-tests/src/main/java/io/prestosql/tests/hive/TestHiveTableStatistics.java +++ b/presto-product-tests/src/main/java/io/prestosql/tests/hive/TestHiveTableStatistics.java @@ -501,7 +501,7 @@ public class TestHiveTableStatistics row("c_double", null, 2.0, 0.0, null, "234.561", "235.567"), row("c_decimal", null, 2.0, 0.0, null, "345.0", "346.0"), row("c_decimal_w_params", null, 2.0, 0.0, null, "345.671", "345.678"), - row("c_timestamp", null, 2.0, 0.0, null, null, null), // timestamp is shifted by hive.time-zone on read + row("c_timestamp", null, 2.0, 0.0, null, null, null), row("c_date", null, 2.0, 0.0, null, "2015-05-09", "2015-06-10"), row("c_string", 22.0, 2.0, 0.0, null, null, null), row("c_varchar", 20.0, 2.0, 0.0, null, null, null), diff --git a/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/BinaryRcFileEncoding.java b/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/BinaryRcFileEncoding.java index e0b2436af..0acceaf60 100644 --- a/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/BinaryRcFileEncoding.java +++ b/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/BinaryRcFileEncoding.java @@ -16,13 +16,23 @@ package io.prestosql.rcfile.binary; import io.prestosql.rcfile.ColumnEncoding; import io.prestosql.rcfile.RcFileEncoding; import io.prestosql.spi.type.Type; +import org.joda.time.DateTimeZone; import java.util.List; import java.util.stream.Collectors; +import static java.util.Objects.requireNonNull; + public class BinaryRcFileEncoding implements RcFileEncoding { + private final DateTimeZone timeZone; + + public BinaryRcFileEncoding(DateTimeZone timeZone) + { + this.timeZone = requireNonNull(timeZone, "timeZone is null"); + } + @Override public ColumnEncoding booleanEncoding(Type type) { @@ -92,7 +102,7 @@ public class BinaryRcFileEncoding @Override public ColumnEncoding timestampEncoding(Type type) { - return new TimestampEncoding(type); + return new TimestampEncoding(type, timeZone); } @Override diff --git a/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/TimestampEncoding.java b/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/TimestampEncoding.java index 19e7525a2..7136ac5fb 100644 --- a/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/TimestampEncoding.java +++ b/presto-rcfile/src/main/java/io/prestosql/rcfile/binary/TimestampEncoding.java @@ -20,6 +20,7 @@ import io.prestosql.rcfile.EncodeOutput; import io.prestosql.spi.block.Block; import io.prestosql.spi.block.BlockBuilder; import io.prestosql.spi.type.Type; +import org.joda.time.DateTimeZone; import static io.airlift.slice.SizeOf.SIZE_OF_INT; import static io.prestosql.rcfile.RcFileDecoderUtils.decodeVIntSize; @@ -29,15 +30,18 @@ import static io.prestosql.rcfile.RcFileDecoderUtils.writeVInt; import static java.lang.Math.floorDiv; import static java.lang.Math.floorMod; import static java.lang.Math.toIntExact; +import static java.util.Objects.requireNonNull; public class TimestampEncoding implements BinaryColumnEncoding { private final Type type; + private final DateTimeZone timeZone; - public TimestampEncoding(Type type) + public TimestampEncoding(Type type, DateTimeZone timeZone) { - this.type = type; + this.type = requireNonNull(type, "type is null"); + this.timeZone = requireNonNull(timeZone, "timeZone is null"); } @Override @@ -112,7 +116,7 @@ public class TimestampEncoding return (b >> 7) != 0; } - private static long getTimestamp(Slice slice, int offset) + private long getTimestamp(Slice slice, int offset) { // read seconds (low 32 bits) int lowest31BitsOfSecondsAndFlag = Integer.reverseBytes(slice.getInt(offset)); @@ -139,7 +143,8 @@ public class TimestampEncoding } long millis = (seconds * 1000) + (nanos / 1_000_000); - return millis; + + return timeZone.convertUTCToLocal(millis); } @SuppressWarnings("NonReproducibleMathCall") @@ -167,8 +172,9 @@ public class TimestampEncoding return nanos; } - private static void writeTimestamp(SliceOutput output, long millis) + private void writeTimestamp(SliceOutput output, long millis) { + millis = timeZone.convertLocalToUTC(millis, false); long seconds = floorDiv(millis, 1000); int nanos = toIntExact(floorMod(millis, 1000) * 1_000_000); writeTimestamp(seconds, nanos, output); diff --git a/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TextRcFileEncoding.java b/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TextRcFileEncoding.java index c15422463..1b1777f4d 100644 --- a/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TextRcFileEncoding.java +++ b/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TextRcFileEncoding.java @@ -18,7 +18,6 @@ import io.airlift.slice.Slices; import io.prestosql.rcfile.ColumnEncoding; import io.prestosql.rcfile.RcFileEncoding; import io.prestosql.spi.type.Type; -import org.joda.time.DateTimeZone; import java.util.List; import java.util.stream.Collectors; @@ -61,24 +60,22 @@ public class TextRcFileEncoding }; public static final Slice DEFAULT_NULL_SEQUENCE = Slices.utf8Slice("\\N"); - private final DateTimeZone hiveStorageTimeZone; private final Slice nullSequence; private final byte[] separators; private final Byte escapeByte; private final boolean lastColumnTakesRest; - public TextRcFileEncoding(DateTimeZone hiveStorageTimeZone) + public TextRcFileEncoding() { - this(hiveStorageTimeZone, + this( DEFAULT_NULL_SEQUENCE, DEFAULT_SEPARATORS, null, false); } - public TextRcFileEncoding(DateTimeZone hiveStorageTimeZone, Slice nullSequence, byte[] separators, Byte escapeByte, boolean lastColumnTakesRest) + public TextRcFileEncoding(Slice nullSequence, byte[] separators, Byte escapeByte, boolean lastColumnTakesRest) { - this.hiveStorageTimeZone = hiveStorageTimeZone; this.nullSequence = nullSequence; this.separators = separators; this.escapeByte = escapeByte; @@ -155,7 +152,7 @@ public class TextRcFileEncoding @Override public ColumnEncoding timestampEncoding(Type type) { - return new TimestampEncoding(type, nullSequence, hiveStorageTimeZone); + return new TimestampEncoding(type, nullSequence); } @Override diff --git a/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TimestampEncoding.java b/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TimestampEncoding.java index e1d631230..cfa4f8b3d 100644 --- a/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TimestampEncoding.java +++ b/presto-rcfile/src/main/java/io/prestosql/rcfile/text/TimestampEncoding.java @@ -20,7 +20,6 @@ import io.prestosql.rcfile.EncodeOutput; import io.prestosql.spi.block.Block; import io.prestosql.spi.block.BlockBuilder; import io.prestosql.spi.type.Type; -import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatterBuilder; @@ -31,7 +30,6 @@ public class TimestampEncoding implements TextColumnEncoding { private static final DateTimeFormatter HIVE_TIMESTAMP_PARSER; - private final DateTimeFormatter dateTimeFormatter; static { @SuppressWarnings("SpellCheckingInspection") @@ -52,11 +50,10 @@ public class TimestampEncoding private final Slice nullSequence; private final StringBuilder buffer = new StringBuilder(); - public TimestampEncoding(Type type, Slice nullSequence, DateTimeZone hiveStorageTimeZone) + public TimestampEncoding(Type type, Slice nullSequence) { this.type = type; this.nullSequence = nullSequence; - this.dateTimeFormatter = HIVE_TIMESTAMP_PARSER.withZone(hiveStorageTimeZone); } @Override @@ -69,7 +66,7 @@ public class TimestampEncoding else { long millis = type.getLong(block, position); buffer.setLength(0); - dateTimeFormatter.printTo(buffer, millis); + HIVE_TIMESTAMP_PARSER.printTo(buffer, millis); for (int index = 0; index < buffer.length(); index++) { output.writeByte(buffer.charAt(index)); } @@ -83,7 +80,7 @@ public class TimestampEncoding { long millis = type.getLong(block, position); buffer.setLength(0); - dateTimeFormatter.printTo(buffer, millis); + HIVE_TIMESTAMP_PARSER.printTo(buffer, millis); for (int index = 0; index < buffer.length(); index++) { output.writeByte(buffer.charAt(index)); } @@ -116,9 +113,9 @@ public class TimestampEncoding type.writeLong(builder, millis); } - private long parseTimestamp(Slice slice, int offset, int length) + private static long parseTimestamp(Slice slice, int offset, int length) { //noinspection deprecation - return dateTimeFormatter.parseMillis(new String(slice.getBytes(offset, length), 0)); + return HIVE_TIMESTAMP_PARSER.parseMillis(new String(slice.getBytes(offset, length), 0)); } } diff --git a/presto-rcfile/src/test/java/io/prestosql/rcfile/AbstractTestRcFileReader.java b/presto-rcfile/src/test/java/io/prestosql/rcfile/AbstractTestRcFileReader.java index 6a854cedf..56bba0bec 100644 --- a/presto-rcfile/src/test/java/io/prestosql/rcfile/AbstractTestRcFileReader.java +++ b/presto-rcfile/src/test/java/io/prestosql/rcfile/AbstractTestRcFileReader.java @@ -28,6 +28,7 @@ import org.testng.annotations.Test; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static com.google.common.collect.Iterables.cycle; import static com.google.common.collect.Iterables.limit; @@ -44,7 +45,6 @@ import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.VarcharType.VARCHAR; import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; -import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Collections.nCopies; import static java.util.stream.Collectors.toList; @@ -164,9 +164,9 @@ public abstract class AbstractTestRcFileReader { tester.testRoundTrip( TIMESTAMP, - intsBetween(-31_234, 31_234).stream() + intsBetween(123_406_789, 123_456_789).stream() .filter(i -> i % 19 == 0) - .map(timestamp -> sqlTimestampOf(timestamp, SESSION)) + .map(timestamp -> sqlTimestampOf(timestamp)) .collect(toList())); } @@ -253,14 +253,14 @@ public abstract class AbstractTestRcFileReader return values; } - private static ContiguousSet longsBetween(long lowerInclusive, long upperExclusive) + private static Set longsBetween(long lowerExclusive, long upperInclusive) { - return ContiguousSet.create(Range.openClosed(lowerInclusive, upperExclusive), DiscreteDomain.longs()); + return ContiguousSet.create(Range.openClosed(lowerExclusive, upperInclusive), DiscreteDomain.longs()); } - private static ContiguousSet intsBetween(int lowerInclusive, int upperExclusive) + private static Set intsBetween(int lowerExclusive, int upperInclusive) { - return ContiguousSet.create(Range.openClosed(lowerInclusive, upperExclusive), DiscreteDomain.integers()); + return ContiguousSet.create(Range.openClosed(lowerExclusive, upperInclusive), DiscreteDomain.integers()); } private static List decimalSequence(String start, String step, int items, int precision, int scale) diff --git a/presto-rcfile/src/test/java/io/prestosql/rcfile/RcFileTester.java b/presto-rcfile/src/test/java/io/prestosql/rcfile/RcFileTester.java index ea47438d0..f5b3e7577 100644 --- a/presto-rcfile/src/test/java/io/prestosql/rcfile/RcFileTester.java +++ b/presto-rcfile/src/test/java/io/prestosql/rcfile/RcFileTester.java @@ -45,7 +45,9 @@ import io.prestosql.spi.type.TypeSignatureParameter; import io.prestosql.spi.type.VarcharType; 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.ql.exec.FileSinkOperator.RecordWriter; import org.apache.hadoop.hive.ql.io.RCFileInputFormat; import org.apache.hadoop.hive.ql.io.RCFileOutputFormat; @@ -56,10 +58,10 @@ import org.apache.hadoop.hive.serde2.StructObject; import org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable; import org.apache.hadoop.hive.serde2.columnar.ColumnarSerDe; import org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe; -import org.apache.hadoop.hive.serde2.io.DateWritable; +import org.apache.hadoop.hive.serde2.io.DateWritableV2; 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.lazy.LazyArray; import org.apache.hadoop.hive.serde2.lazy.LazyMap; import org.apache.hadoop.hive.serde2.lazy.LazyPrimitive; @@ -98,11 +100,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.math.BigInteger; -import java.sql.Date; -import java.sql.Timestamp; -import java.time.LocalDate; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -147,11 +144,11 @@ import static io.prestosql.spi.type.SmallintType.SMALLINT; import static io.prestosql.spi.type.StandardTypes.ARRAY; import static io.prestosql.spi.type.StandardTypes.MAP; import static io.prestosql.spi.type.StandardTypes.ROW; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TinyintType.TINYINT; import static io.prestosql.spi.type.VarbinaryType.VARBINARY; import static io.prestosql.spi.type.VarcharType.VARCHAR; +import static io.prestosql.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.prestosql.testing.TestingConnectorSession.SESSION; import static java.lang.Math.toIntExact; import static java.nio.file.Files.createTempDirectory; @@ -204,7 +201,7 @@ public class RcFileTester @Override public RcFileEncoding getVectorEncoding() { - return new BinaryRcFileEncoding(); + return new BinaryRcFileEncoding(HIVE_STORAGE_TIME_ZONE); } }, @@ -228,7 +225,7 @@ public class RcFileTester @Override public RcFileEncoding getVectorEncoding() { - return new TextRcFileEncoding(HIVE_STORAGE_TIME_ZONE); + return new TextRcFileEncoding(); } }; @@ -716,7 +713,7 @@ public class RcFileTester type.writeLong(blockBuilder, days); } else if (TIMESTAMP.equals(type)) { - long millis = ((SqlTimestamp) value).getMillisUtc(); + long millis = ((SqlTimestamp) value).getMillis(); type.writeLong(blockBuilder, millis); } else { @@ -801,13 +798,13 @@ public class RcFileTester Object rowData = deserializer.deserialize(value); Object actualValue = rowInspector.getStructFieldData(rowData, field); - actualValue = decodeRecordReaderValue(type, actualValue); + actualValue = decodeRecordReaderValue(format, type, actualValue); assertColumnValueEquals(type, actualValue, expectedValue); } assertFalse(iterator.hasNext()); } - private static Object decodeRecordReaderValue(Type type, Object actualValue) + private static Object decodeRecordReaderValue(Format format, Type type, Object actualValue) { if (actualValue instanceof LazyPrimitive) { actualValue = ((LazyPrimitive) actualValue).getWritableObject(); @@ -821,8 +818,8 @@ public class RcFileTester else if (actualValue instanceof BytesWritable) { actualValue = new SqlVarbinary(((BytesWritable) actualValue).copyBytes()); } - else if (actualValue instanceof DateWritable) { - actualValue = new SqlDate(((DateWritable) actualValue).getDays()); + else if (actualValue instanceof DateWritableV2) { + actualValue = new SqlDate(((DateWritableV2) actualValue).getDays()); } else if (actualValue instanceof DoubleWritable) { actualValue = ((DoubleWritable) actualValue).get(); @@ -849,64 +846,64 @@ public class RcFileTester else if (actualValue instanceof Text) { actualValue = actualValue.toString(); } - else if (actualValue instanceof TimestampWritable) { - TimestampWritable timestamp = (TimestampWritable) actualValue; - if (SESSION.isLegacyTimestamp()) { - actualValue = new SqlTimestamp((timestamp.getSeconds() * 1000) + (timestamp.getNanos() / 1000000L), UTC_KEY); - } - else { - actualValue = new SqlTimestamp((timestamp.getSeconds() * 1000) + (timestamp.getNanos() / 1000000L)); + else if (actualValue instanceof TimestampWritableV2) { + long millis = ((TimestampWritableV2) actualValue).getTimestamp().toEpochMilli(); + if (format == Format.BINARY) { + millis = HIVE_STORAGE_TIME_ZONE.convertUTCToLocal(millis); } + actualValue = sqlTimestampOf(millis); } else if (actualValue instanceof StructObject) { StructObject structObject = (StructObject) actualValue; - actualValue = decodeRecordReaderStruct(type, structObject.getFieldsAsList()); + actualValue = decodeRecordReaderStruct(format, type, structObject.getFieldsAsList()); } else if (actualValue instanceof LazyBinaryArray) { - actualValue = decodeRecordReaderList(type, ((LazyBinaryArray) actualValue).getList()); + actualValue = decodeRecordReaderList(format, type, ((LazyBinaryArray) actualValue).getList()); } else if (actualValue instanceof LazyBinaryMap) { - actualValue = decodeRecordReaderMap(type, ((LazyBinaryMap) actualValue).getMap()); + actualValue = decodeRecordReaderMap(format, type, ((LazyBinaryMap) actualValue).getMap()); } else if (actualValue instanceof LazyArray) { - actualValue = decodeRecordReaderList(type, ((LazyArray) actualValue).getList()); + actualValue = decodeRecordReaderList(format, type, ((LazyArray) actualValue).getList()); } else if (actualValue instanceof LazyMap) { - actualValue = decodeRecordReaderMap(type, ((LazyMap) actualValue).getMap()); + actualValue = decodeRecordReaderMap(format, type, ((LazyMap) actualValue).getMap()); } else if (actualValue instanceof List) { - actualValue = decodeRecordReaderList(type, ((List) actualValue)); + actualValue = decodeRecordReaderList(format, type, ((List) actualValue)); } return actualValue; } - private static List decodeRecordReaderList(Type type, List list) + private static List decodeRecordReaderList(Format format, Type type, List list) { Type elementType = type.getTypeParameters().get(0); return list.stream() - .map(element -> decodeRecordReaderValue(elementType, element)) + .map(element -> decodeRecordReaderValue(format, elementType, element)) .collect(toList()); } - private static Object decodeRecordReaderMap(Type type, Map map) + private static Object decodeRecordReaderMap(Format format, Type type, Map map) { Type keyType = type.getTypeParameters().get(0); Type valueType = type.getTypeParameters().get(1); Map newMap = new HashMap<>(); for (Entry entry : map.entrySet()) { - newMap.put(decodeRecordReaderValue(keyType, entry.getKey()), decodeRecordReaderValue(valueType, entry.getValue())); + newMap.put( + decodeRecordReaderValue(format, keyType, entry.getKey()), + decodeRecordReaderValue(format, valueType, entry.getValue())); } return newMap; } - private static List decodeRecordReaderStruct(Type type, List fields) + private static List decodeRecordReaderStruct(Format format, Type type, List fields) { List fieldTypes = type.getTypeParameters(); List newFields = new ArrayList<>(fields.size()); for (int i = 0; i < fields.size(); i++) { Type fieldType = fieldTypes.get(i); Object field = fields.get(i); - newFields.add(decodeRecordReaderValue(fieldType, field)); + newFields.add(decodeRecordReaderValue(format, fieldType, field)); } return newFields; } @@ -930,7 +927,7 @@ public class RcFileTester while (values.hasNext()) { Object value = values.next(); - value = preprocessWriteValueOld(type, value); + value = preprocessWriteValueOld(format, type, value); objectInspector.setStructFieldData(row, fields.get(0), value); Writable record = serializer.serialize(row, objectInspector); @@ -1000,7 +997,7 @@ public class RcFileTester throw new IllegalArgumentException("unsupported type: " + type); } - private static Object preprocessWriteValueOld(Type type, Object value) + private static Object preprocessWriteValueOld(Format format, Type type, Object value) { if (value == null) { return null; @@ -1034,19 +1031,14 @@ public class RcFileTester return ((SqlVarbinary) value).getBytes(); } if (type.equals(DATE)) { - int days = ((SqlDate) value).getDays(); - LocalDate localDate = LocalDate.ofEpochDay(days); - ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); - - long millis = zonedDateTime.toEpochSecond() * 1000; - Date date = new Date(0); - // mills must be set separately to avoid masking - date.setTime(millis); - return date; + return Date.ofEpochDay(((SqlDate) value).getDays()); } if (type.equals(TIMESTAMP)) { - long millisUtc = (int) ((SqlTimestamp) value).getMillisUtc(); - return new Timestamp(millisUtc); + long millis = ((SqlTimestamp) value).getMillis(); + if (format == Format.BINARY) { + millis = HIVE_STORAGE_TIME_ZONE.convertLocalToUTC(millis, false); + } + return Timestamp.ofEpochMilli(millis); } if (type instanceof DecimalType) { return HiveDecimal.create(((SqlDecimal) value).toBigDecimal()); @@ -1054,7 +1046,7 @@ public class RcFileTester if (type.getTypeSignature().getBase().equals(ARRAY)) { Type elementType = type.getTypeParameters().get(0); return ((List) value).stream() - .map(element -> preprocessWriteValueOld(elementType, element)) + .map(element -> preprocessWriteValueOld(format, elementType, element)) .collect(toList()); } if (type.getTypeSignature().getBase().equals(MAP)) { @@ -1062,7 +1054,9 @@ public class RcFileTester Type valueType = type.getTypeParameters().get(1); Map newMap = new HashMap<>(); for (Entry entry : ((Map) value).entrySet()) { - newMap.put(preprocessWriteValueOld(keyType, entry.getKey()), preprocessWriteValueOld(valueType, entry.getValue())); + newMap.put( + preprocessWriteValueOld(format, keyType, entry.getKey()), + preprocessWriteValueOld(format, valueType, entry.getValue())); } return newMap; } @@ -1071,7 +1065,7 @@ public class RcFileTester List fieldTypes = type.getTypeParameters(); List newStruct = new ArrayList<>(); for (int fieldId = 0; fieldId < fieldValues.size(); fieldId++) { - newStruct.add(preprocessWriteValueOld(fieldTypes.get(fieldId), fieldValues.get(fieldId))); + newStruct.add(preprocessWriteValueOld(format, fieldTypes.get(fieldId), fieldValues.get(fieldId))); } return newStruct; } diff --git a/presto-rcfile/src/test/java/io/prestosql/rcfile/TestRcFileReaderManual.java b/presto-rcfile/src/test/java/io/prestosql/rcfile/TestRcFileReaderManual.java index 4df637350..27fd674e0 100644 --- a/presto-rcfile/src/test/java/io/prestosql/rcfile/TestRcFileReaderManual.java +++ b/presto-rcfile/src/test/java/io/prestosql/rcfile/TestRcFileReaderManual.java @@ -21,6 +21,7 @@ import io.airlift.slice.SliceOutput; import io.airlift.units.DataSize; import io.prestosql.rcfile.binary.BinaryRcFileEncoding; import io.prestosql.spi.block.Block; +import org.joda.time.DateTimeZone; import org.testng.annotations.Test; import java.io.IOException; @@ -237,7 +238,7 @@ public class TestRcFileReaderManual RcFileReader reader = new RcFileReader( new SliceRcFileDataSource(data), - new BinaryRcFileEncoding(), + new BinaryRcFileEncoding(DateTimeZone.UTC), ImmutableMap.of(0, SMALLINT), new BogusRcFileCodecFactory(), offset, diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/AbstractDateTimeJsonValueProvider.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/AbstractDateTimeJsonValueProvider.java index 9b6e79d85..06455202f 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/AbstractDateTimeJsonValueProvider.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/AbstractDateTimeJsonValueProvider.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.JsonNode; import io.prestosql.decoder.DecoderColumnHandle; import io.prestosql.decoder.FieldValueProvider; import io.prestosql.spi.PrestoException; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import java.util.concurrent.TimeUnit; @@ -70,7 +71,7 @@ public abstract class AbstractDateTimeJsonValueProvider return millis; } if (type.equals(TIMESTAMP_WITH_TIME_ZONE) || type.equals(TIME_WITH_TIME_ZONE)) { - return packDateTimeWithZone(millis, 0); + return packDateTimeWithZone(millis, getTimeZone()); } return millis; @@ -80,4 +81,9 @@ public abstract class AbstractDateTimeJsonValueProvider * @return epoch milliseconds in UTC */ protected abstract long getMillis(); + + /** + * @return TimeZoneKey for value + */ + protected abstract TimeZoneKey getTimeZone(); } diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/CustomDateTimeJsonFieldDecoder.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/CustomDateTimeJsonFieldDecoder.java index f246e24ca..a1da7c88a 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/CustomDateTimeJsonFieldDecoder.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/CustomDateTimeJsonFieldDecoder.java @@ -18,7 +18,9 @@ import com.google.common.collect.ImmutableSet; import io.prestosql.decoder.DecoderColumnHandle; import io.prestosql.decoder.FieldValueProvider; import io.prestosql.spi.PrestoException; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; +import org.joda.time.chrono.ISOChronology; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; @@ -32,6 +34,7 @@ import static io.prestosql.spi.StandardErrorCode.GENERIC_USER_ERROR; import static io.prestosql.spi.type.DateType.DATE; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static java.lang.String.format; @@ -61,12 +64,15 @@ public class CustomDateTimeJsonFieldDecoder checkArgument(columnHandle.getFormatHint() != null, "format hint not defined for column '%s'", columnHandle.getName()); try { - formatter = DateTimeFormat.forPattern(columnHandle.getFormatHint()).withLocale(Locale.ENGLISH).withZoneUTC(); + formatter = DateTimeFormat.forPattern(columnHandle.getFormatHint()) + .withLocale(Locale.ENGLISH) + .withChronology(ISOChronology.getInstanceUTC()) + .withOffsetParsed(); } catch (IllegalArgumentException e) { throw new PrestoException( GENERIC_USER_ERROR, - format("invalid joda pattern '%s' passed as format hint for column '%s'", columnHandle.getFormatHint(), columnHandle.getName())); + format("invalid Joda Time pattern '%s' passed as format hint for column '%s'", columnHandle.getFormatHint(), columnHandle.getName())); } } @@ -104,5 +110,23 @@ public class CustomDateTimeJsonFieldDecoder format("could not parse value '%s' as '%s' for column '%s'", value.asText(), columnHandle.getType(), columnHandle.getName())); } } + + @Override + protected TimeZoneKey getTimeZone() + { + if (value.isValueNode()) { + try { + return getTimeZoneKey(formatter.parseDateTime(value.asText()).getZone().getID()); + } + catch (IllegalArgumentException e) { + throw new PrestoException( + DECODER_CONVERSION_NOT_SUPPORTED, + format("could not parse value '%s' as '%s' for column '%s'", value.asText(), columnHandle.getType(), columnHandle.getName())); + } + } + throw new PrestoException( + DECODER_CONVERSION_NOT_SUPPORTED, + format("could not parse non-value node as '%s' for column '%s'", columnHandle.getType(), columnHandle.getName())); + } } } diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/ISO8601JsonFieldDecoder.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/ISO8601JsonFieldDecoder.java index 71acee0f7..53939d758 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/ISO8601JsonFieldDecoder.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/ISO8601JsonFieldDecoder.java @@ -104,8 +104,14 @@ public class ISO8601JsonFieldDecoder try { String textValue = value.asText(); if (columnType == TIMESTAMP) { - TemporalAccessor parseResult = ISO_DATE_TIME.parse(textValue); - return TimeUnit.DAYS.toMillis(parseResult.getLong(EPOCH_DAY)) + parseResult.getLong(MILLI_OF_DAY); + try { + TemporalAccessor parseResult = ISO_OFFSET_DATE_TIME.parse(textValue); + return TimeUnit.DAYS.toMillis(parseResult.getLong(EPOCH_DAY)) + parseResult.getLong(MILLI_OF_DAY); + } + catch (DateTimeParseException e) { + TemporalAccessor parseResult = ISO_DATE_TIME.parse(textValue); + return TimeUnit.DAYS.toMillis(parseResult.getLong(EPOCH_DAY)) + parseResult.getLong(MILLI_OF_DAY); + } } if (columnType == TIMESTAMP_WITH_TIME_ZONE) { TemporalAccessor parseResult = ISO_OFFSET_DATE_TIME.parse(textValue); diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/MillisecondsSinceEpochJsonFieldDecoder.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/MillisecondsSinceEpochJsonFieldDecoder.java index 336d4a2bd..6cf778d30 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/MillisecondsSinceEpochJsonFieldDecoder.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/MillisecondsSinceEpochJsonFieldDecoder.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableSet; import io.prestosql.decoder.DecoderColumnHandle; import io.prestosql.decoder.FieldValueProvider; import io.prestosql.spi.PrestoException; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import java.util.Set; @@ -86,5 +87,11 @@ public class MillisecondsSinceEpochJsonFieldDecoder DECODER_CONVERSION_NOT_SUPPORTED, format("could not parse non-value node as '%s' for column '%s'", columnHandle.getType(), columnHandle.getName())); } + + @Override + protected TimeZoneKey getTimeZone() + { + return TimeZoneKey.UTC_KEY; + } } } diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/RFC2822JsonFieldDecoder.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/RFC2822JsonFieldDecoder.java index 34ca1ef8a..bce3dc5cc 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/RFC2822JsonFieldDecoder.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/RFC2822JsonFieldDecoder.java @@ -18,7 +18,9 @@ import com.google.common.collect.ImmutableSet; import io.prestosql.decoder.DecoderColumnHandle; import io.prestosql.decoder.FieldValueProvider; import io.prestosql.spi.PrestoException; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; +import org.joda.time.chrono.ISOChronology; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; @@ -30,6 +32,7 @@ import static io.prestosql.decoder.json.JsonRowDecoderFactory.throwUnsupportedCo import static io.prestosql.spi.type.DateType.DATE; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKey; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static java.lang.String.format; @@ -48,7 +51,11 @@ public class RFC2822JsonFieldDecoder /** * Todo - configurable time zones and locales. */ - private static final DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss Z yyyy").withLocale(Locale.ENGLISH).withZoneUTC(); + private static final DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss Z yyyy") + .withLocale(Locale.ENGLISH) + .withChronology(ISOChronology.getInstanceUTC()) + .withOffsetParsed(); + private final DecoderColumnHandle columnHandle; public RFC2822JsonFieldDecoder(DecoderColumnHandle columnHandle) @@ -90,5 +97,23 @@ public class RFC2822JsonFieldDecoder DECODER_CONVERSION_NOT_SUPPORTED, format("could not parse non-value node as '%s' for column '%s'", columnHandle.getType(), columnHandle.getName())); } + + @Override + protected TimeZoneKey getTimeZone() + { + if (value.isValueNode()) { + try { + return getTimeZoneKey(FORMATTER.parseDateTime(value.asText()).getZone().getID()); + } + catch (IllegalArgumentException e) { + throw new PrestoException( + DECODER_CONVERSION_NOT_SUPPORTED, + format("could not parse value '%s' as '%s' for column '%s'", value.asText(), columnHandle.getType(), columnHandle.getName())); + } + } + throw new PrestoException( + DECODER_CONVERSION_NOT_SUPPORTED, + format("could not parse non-value node as '%s' for column '%s'", columnHandle.getType(), columnHandle.getName())); + } } } diff --git a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/SecondsSinceEpochJsonFieldDecoder.java b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/SecondsSinceEpochJsonFieldDecoder.java index b2555217e..41395ed52 100644 --- a/presto-record-decoder/src/main/java/io/prestosql/decoder/json/SecondsSinceEpochJsonFieldDecoder.java +++ b/presto-record-decoder/src/main/java/io/prestosql/decoder/json/SecondsSinceEpochJsonFieldDecoder.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableSet; import io.prestosql.decoder.DecoderColumnHandle; import io.prestosql.decoder.FieldValueProvider; import io.prestosql.spi.PrestoException; +import io.prestosql.spi.type.TimeZoneKey; import io.prestosql.spi.type.Type; import java.util.Set; @@ -26,6 +27,7 @@ import static io.prestosql.decoder.DecoderErrorCode.DECODER_CONVERSION_NOT_SUPPO import static io.prestosql.decoder.json.JsonRowDecoderFactory.throwUnsupportedColumnType; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; +import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static java.lang.Long.parseLong; @@ -88,5 +90,11 @@ public class SecondsSinceEpochJsonFieldDecoder format("could not parse value '%s' as '%s' for column '%s'", value.asText(), columnHandle.getType(), columnHandle.getName())); } } + + @Override + protected TimeZoneKey getTimeZone() + { + return UTC_KEY; + } } } diff --git a/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestCustomDateTimeJsonFieldDecoder.java b/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestCustomDateTimeJsonFieldDecoder.java index 4655bf8b0..6bb7f7830 100644 --- a/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestCustomDateTimeJsonFieldDecoder.java +++ b/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestCustomDateTimeJsonFieldDecoder.java @@ -24,6 +24,7 @@ import static io.prestosql.spi.type.DateType.DATE; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static java.util.Collections.emptyMap; @@ -43,7 +44,7 @@ public class TestCustomDateTimeJsonFieldDecoder timestampTester.assertDecodedAs("\"02/2018/19 9:20:11\"", TIMESTAMP, 1519032011000L); timestampWithTimeZoneTester.assertDecodedAs("\"02/2018/19 11:20:11 +02:00\"", TIMESTAMP, 1519032011000L); timestampTester.assertDecodedAs("\"02/2018/19 9:20:11\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1519032011000L, UTC_KEY)); - timestampWithTimeZoneTester.assertDecodedAs("\"02/2018/19 11:20:11 +02:00\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1519032011000L, UTC_KEY)); // TODO: extract TZ from pattern + timestampWithTimeZoneTester.assertDecodedAs("\"02/2018/19 11:20:11 +02:00\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1519032011000L, getTimeZoneKeyForOffset(120))); // TODO: extract TZ from pattern timeTester.assertDecodedAs("\"15:13:18\"", TIME, 47718000); timeJustHourTester.assertDecodedAs("\"15\"", TIME, 54000000); timeJustHourTester.assertDecodedAs("15", TIME, 54000000); @@ -95,6 +96,6 @@ public class TestCustomDateTimeJsonFieldDecoder false); assertThatThrownBy(() -> new JsonRowDecoderFactory(new ObjectMapperProvider().get()).create(emptyMap(), ImmutableSet.of(columnHandle))) .isInstanceOf(PrestoException.class) - .hasMessageMatching("invalid joda pattern 'XXMM/yyyy/dd H:m:sXX' passed as format hint for column 'some_column'"); + .hasMessageMatching("invalid Joda Time pattern 'XXMM/yyyy/dd H:m:sXX' passed as format hint for column 'some_column'"); } } diff --git a/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestRFC2822JsonFieldDecoder.java b/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestRFC2822JsonFieldDecoder.java index cf2c690dc..d4704b34e 100644 --- a/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestRFC2822JsonFieldDecoder.java +++ b/presto-record-decoder/src/test/java/io/prestosql/decoder/json/TestRFC2822JsonFieldDecoder.java @@ -21,6 +21,7 @@ import static io.prestosql.spi.type.DateType.DATE; import static io.prestosql.spi.type.TimeType.TIME; import static io.prestosql.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; +import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeyForOffset; import static io.prestosql.spi.type.TimestampType.TIMESTAMP; import static io.prestosql.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static java.util.Arrays.asList; @@ -38,7 +39,7 @@ public class TestRFC2822JsonFieldDecoder tester.assertDecodedAs("\"Fri Feb 09 13:15:19 Z 2018\"", TIMESTAMP, 1518182119000L); tester.assertDecodedAs("\"Fri Feb 09 13:15:19 Z 2018\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1518182119000L, UTC_KEY)); tester.assertDecodedAs("\"Fri Feb 09 15:15:19 +02:00 2018\"", TIMESTAMP, 1518182119000L); - tester.assertDecodedAs("\"Fri Feb 09 15:15:19 +02:00 2018\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1518182119000L, UTC_KEY)); + tester.assertDecodedAs("\"Fri Feb 09 15:15:19 +02:00 2018\"", TIMESTAMP_WITH_TIME_ZONE, packDateTimeWithZone(1518182119000L, getTimeZoneKeyForOffset(120))); } @Test diff --git a/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorSession.java b/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorSession.java index c7dc4aef8..eac79888c 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorSession.java +++ b/presto-spi/src/main/java/io/prestosql/spi/connector/ConnectorSession.java @@ -41,8 +41,6 @@ public interface ConnectorSession long getStartTime(); - boolean isLegacyTimestamp(); - T getProperty(String name, Class type); //for cbg supporting the hive view we need the catalog diff --git a/presto-spi/src/main/java/io/prestosql/spi/type/SqlTimestamp.java b/presto-spi/src/main/java/io/prestosql/spi/type/SqlTimestamp.java index f2d9de2a9..870ab77f4 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/type/SqlTimestamp.java +++ b/presto-spi/src/main/java/io/prestosql/spi/type/SqlTimestamp.java @@ -19,7 +19,6 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Objects; -import java.util.Optional; import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; @@ -30,55 +29,21 @@ public final class SqlTimestamp public static final DateTimeFormatter JSON_FORMATTER = DateTimeFormatter.ofPattern(JSON_FORMAT); private final long millis; - private final Optional sessionTimeZoneKey; public SqlTimestamp(long millis) { this.millis = millis; - sessionTimeZoneKey = Optional.empty(); - } - - @Deprecated - public SqlTimestamp(long millisUtc, TimeZoneKey sessionTimeZoneKey) - { - this.millis = millisUtc; - this.sessionTimeZoneKey = Optional.of(sessionTimeZoneKey); } public long getMillis() { - checkState(!isLegacyTimestamp(), "getMillis() can be called in new timestamp semantics only"); return millis; } - /** - * @deprecated applicable in legacy timestamp semantics only - */ - @Deprecated - public long getMillisUtc() - { - checkState(isLegacyTimestamp(), "getMillisUtc() can be called in legacy timestamp semantics only"); - return millis; - } - - /** - * @deprecated applicable in legacy timestamp semantics only - */ - @Deprecated - public Optional getSessionTimeZoneKey() - { - return sessionTimeZoneKey; - } - - public boolean isLegacyTimestamp() - { - return sessionTimeZoneKey.isPresent(); - } - @Override public int hashCode() { - return Objects.hash(millis, sessionTimeZoneKey); + return Objects.hash(millis); } @Override @@ -91,26 +56,13 @@ public final class SqlTimestamp return false; } SqlTimestamp other = (SqlTimestamp) obj; - return Objects.equals(this.millis, other.millis) && - Objects.equals(this.sessionTimeZoneKey, other.sessionTimeZoneKey); + return Objects.equals(this.millis, other.millis); } @JsonValue @Override public String toString() { - if (isLegacyTimestamp()) { - return Instant.ofEpochMilli(millis).atZone(ZoneId.of(sessionTimeZoneKey.get().getId())).format(JSON_FORMATTER); - } - else { - return Instant.ofEpochMilli(millis).atZone(ZoneId.of(UTC_KEY.getId())).format(JSON_FORMATTER); - } - } - - private static void checkState(boolean condition, String message) - { - if (!condition) { - throw new IllegalStateException(message); - } + return Instant.ofEpochMilli(millis).atZone(ZoneId.of(UTC_KEY.getId())).format(JSON_FORMATTER); } } diff --git a/presto-spi/src/main/java/io/prestosql/spi/type/TimeType.java b/presto-spi/src/main/java/io/prestosql/spi/type/TimeType.java index 8720b71a1..bd22a556d 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/type/TimeType.java +++ b/presto-spi/src/main/java/io/prestosql/spi/type/TimeType.java @@ -38,13 +38,7 @@ public final class TimeType if (block.isNull(position)) { return null; } - - if (session.isLegacyTimestamp()) { - return new SqlTime(block.getLong(position, 0), session.getTimeZoneKey()); - } - else { - return new SqlTime(block.getLong(position, 0)); - } + return new SqlTime(block.getLong(position, 0)); } @Override diff --git a/presto-spi/src/main/java/io/prestosql/spi/type/TimestampType.java b/presto-spi/src/main/java/io/prestosql/spi/type/TimestampType.java index b01088f42..39eea3b50 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/type/TimestampType.java +++ b/presto-spi/src/main/java/io/prestosql/spi/type/TimestampType.java @@ -19,9 +19,7 @@ import io.prestosql.spi.connector.ConnectorSession; import static io.prestosql.spi.type.TypeSignature.parseTypeSignature; /** - * A timestamp is stored as milliseconds from 1970-01-01T00:00:00 UTC and is to be interpreted as date-time in UTC. - * In legacy timestamp semantics, timestamp is stored as milliseconds from 1970-01-01T00:00:00 UTC and is to be - * interpreted in session time zone. + * A timestamp is encoded as milliseconds from 1970-01-01T00:00:00 UTC and is to be interpreted as local date time without regards to any time zone. */ public final class TimestampType extends AbstractLongType @@ -39,13 +37,7 @@ public final class TimestampType if (block.isNull(position)) { return null; } - - if (session.isLegacyTimestamp()) { - return new SqlTimestamp(block.getLong(position, 0), session.getTimeZoneKey()); - } - else { - return new SqlTimestamp(block.getLong(position, 0)); - } + return new SqlTimestamp(block.getLong(position, 0)); } @Override diff --git a/presto-spi/src/main/java/io/prestosql/spi/util/DateTimeUtils.java b/presto-spi/src/main/java/io/prestosql/spi/util/DateTimeUtils.java index ab0e9d4fc..21da22504 100644 --- a/presto-spi/src/main/java/io/prestosql/spi/util/DateTimeUtils.java +++ b/presto-spi/src/main/java/io/prestosql/spi/util/DateTimeUtils.java @@ -57,7 +57,6 @@ public final class DateTimeUtils return DATE_FORMATTER.print(TimeUnit.DAYS.toMillis(days)); } - private static final DateTimeFormatter LEGACY_TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER; private static final DateTimeFormatter TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER; private static final DateTimeFormatter TIMESTAMP_WITH_TIME_ZONE_FORMATTER; private static final DateTimeFormatter TIMESTAMP_WITH_OR_WITHOUT_TIME_ZONE_FORMATTER; @@ -69,10 +68,6 @@ public final class DateTimeUtils DateTimeFormat.forPattern("yyyy-M-d H:m:s").getParser(), DateTimeFormat.forPattern("yyyy-M-d H:m:s.SSS").getParser()}; DateTimePrinter timestampWithoutTimeZonePrinter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").getPrinter(); - LEGACY_TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER = new DateTimeFormatterBuilder() - .append(timestampWithoutTimeZonePrinter, timestampWithoutTimeZoneParser) - .toFormatter() - .withOffsetParsed(); TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER = new DateTimeFormatterBuilder() .append(timestampWithoutTimeZonePrinter, timestampWithoutTimeZoneParser) @@ -156,13 +151,8 @@ public final class DateTimeUtils @Deprecated public static long parseTimestampLiteral(TimeZoneKey timeZoneKey, String value) { - try { - DateTime dateTime = TIMESTAMP_WITH_TIME_ZONE_FORMATTER.parseDateTime(value); - return packDateTimeWithZone(dateTime); - } - catch (RuntimeException e) { - return LEGACY_TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER.withChronology(getChronology(timeZoneKey)).parseMillis(value); - } + DateTime dateTime = TIMESTAMP_WITH_TIME_ZONE_FORMATTER.parseDateTime(value); + return packDateTimeWithZone(dateTime); } /** @@ -226,15 +216,6 @@ public final class DateTimeUtils return TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER.print(timestamp); } - /** - * @deprecated applicable in legacy timestamp semantics only - */ - @Deprecated - public static String printTimestampWithoutTimeZone(TimeZoneKey timeZoneKey, long timestamp) - { - return LEGACY_TIMESTAMP_WITHOUT_TIME_ZONE_FORMATTER.withChronology(getChronology(timeZoneKey)).print(timestamp); - } - public static boolean timestampHasTimeZone(String value) { try { diff --git a/presto-spi/src/test/java/io/prestosql/spi/block/TestingSession.java b/presto-spi/src/test/java/io/prestosql/spi/block/TestingSession.java index 64373cab2..86cc550e5 100644 --- a/presto-spi/src/test/java/io/prestosql/spi/block/TestingSession.java +++ b/presto-spi/src/test/java/io/prestosql/spi/block/TestingSession.java @@ -71,12 +71,6 @@ public final class TestingSession return Optional.empty(); } - @Override - public boolean isLegacyTimestamp() - { - return true; - } - @Override public T getProperty(String name, Class type) { diff --git a/presto-teradata-functions/src/main/java/io/prestosql/teradata/functions/TeradataDateFunctions.java b/presto-teradata-functions/src/main/java/io/prestosql/teradata/functions/TeradataDateFunctions.java index 3671abca7..76d664de9 100644 --- a/presto-teradata-functions/src/main/java/io/prestosql/teradata/functions/TeradataDateFunctions.java +++ b/presto-teradata-functions/src/main/java/io/prestosql/teradata/functions/TeradataDateFunctions.java @@ -35,7 +35,6 @@ import static io.prestosql.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT; import static io.prestosql.spi.type.DateTimeEncoding.unpackMillisUtc; import static io.prestosql.spi.type.DateTimeEncoding.unpackZoneKey; import static io.prestosql.spi.type.TimeZoneKey.MAX_TIME_ZONE_KEY; -import static io.prestosql.spi.type.TimeZoneKey.UTC_KEY; import static io.prestosql.spi.type.TimeZoneKey.getTimeZoneKeys; import static io.prestosql.teradata.functions.dateformat.DateFormatParser.createDateTimeFormatter; import static java.nio.charset.StandardCharsets.UTF_8; @@ -80,7 +79,7 @@ public final class TeradataDateFunctions public static long toDate(ConnectorSession session, @SqlType(StandardTypes.VARCHAR) Slice dateTime, @SqlType(StandardTypes.VARCHAR) Slice formatString) { try { - long millis = parseMillis(UTC_KEY, session.getLocale(), dateTime, formatString); + long millis = parseMillis(session.getLocale(), dateTime, formatString); return MILLISECONDS.toDays(millis); } catch (Throwable t) { @@ -103,17 +102,13 @@ public final class TeradataDateFunctions private static long parseMillis(ConnectorSession session, Slice dateTime, Slice formatString) { - TimeZoneKey timeZoneKey = UTC_KEY; - if (session.isLegacyTimestamp()) { - timeZoneKey = session.getTimeZoneKey(); - } - return parseMillis(timeZoneKey, session.getLocale(), dateTime, formatString); + return parseMillis(session.getLocale(), dateTime, formatString); } - private static long parseMillis(TimeZoneKey timeZoneKey, Locale locale, Slice dateTime, Slice formatString) + private static long parseMillis(Locale locale, Slice dateTime, Slice formatString) { DateTimeFormatter formatter = DATETIME_FORMATTER_CACHE.get(formatString) - .withChronology(CHRONOLOGIES[timeZoneKey.getKey()]) + .withZoneUTC() .withLocale(locale); try { diff --git a/presto-teradata-functions/src/test/java/io/prestosql/teradata/functions/TestTeradataDateFunctions.java b/presto-teradata-functions/src/test/java/io/prestosql/teradata/functions/TestTeradataDateFunctions.java index 0c9111901..5ba25b214 100644 --- a/presto-teradata-functions/src/test/java/io/prestosql/teradata/functions/TestTeradataDateFunctions.java +++ b/presto-teradata-functions/src/test/java/io/prestosql/teradata/functions/TestTeradataDateFunctions.java @@ -132,7 +132,7 @@ public class TestTeradataDateFunctions assertFunction( projection, TimestampType.TIMESTAMP, - sqlTimestampOf(year, month, day, hour, minutes, seconds, 0, SESSION)); + sqlTimestampOf(year, month, day, hour, minutes, seconds, 0)); } private void assertDate(String projection, int year, int month, int day) diff --git a/presto-tests/src/main/java/io/prestosql/tests/AbstractTestAggregations.java b/presto-tests/src/main/java/io/prestosql/tests/AbstractTestAggregations.java index 98864704c..3ce43e730 100644 --- a/presto-tests/src/main/java/io/prestosql/tests/AbstractTestAggregations.java +++ b/presto-tests/src/main/java/io/prestosql/tests/AbstractTestAggregations.java @@ -700,20 +700,20 @@ public abstract class AbstractTestAggregations assertQuery("SELECT approx_distinct(orderdate, 0.023) FROM orders", "SELECT 2443"); // test timestamp - assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP)) FROM orders", "SELECT 2347"); - assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP), 0.023) FROM orders", "SELECT 2347"); + assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP)) FROM orders", "SELECT 2384"); + assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP), 0.023) FROM orders", "SELECT 2384"); // test timestamp with time zone assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP WITH TIME ZONE)) FROM orders", "SELECT 2347"); assertQuery("SELECT approx_distinct(CAST(orderdate AS TIMESTAMP WITH TIME ZONE), 0.023) FROM orders", "SELECT 2347"); // test time - assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME)) FROM orders", "SELECT 996"); - assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME), 0.023) FROM orders", "SELECT 996"); + assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME)) FROM orders", "SELECT 993"); + assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME), 0.023) FROM orders", "SELECT 993"); // test time with time zone - assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME WITH TIME ZONE)) FROM orders", "SELECT 996"); - assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME WITH TIME ZONE), 0.023) FROM orders", "SELECT 996"); + assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME WITH TIME ZONE)) FROM orders", "SELECT 975"); + assertQuery("SELECT approx_distinct(CAST(from_unixtime(custkey) AS TIME WITH TIME ZONE), 0.023) FROM orders", "SELECT 975"); // test short decimal assertQuery("SELECT approx_distinct(CAST(custkey AS DECIMAL(18, 0))) FROM orders", "SELECT 990"); diff --git a/presto-tests/src/main/java/io/prestosql/tests/TestCachedSqlQueryExecution.java b/presto-tests/src/main/java/io/prestosql/tests/TestCachedSqlQueryExecution.java index 0efdc9c26..89b4b1e4d 100644 --- a/presto-tests/src/main/java/io/prestosql/tests/TestCachedSqlQueryExecution.java +++ b/presto-tests/src/main/java/io/prestosql/tests/TestCachedSqlQueryExecution.java @@ -76,14 +76,12 @@ public class TestCachedSqlQueryExecution .setSchema("tiny") .setIdentity(new Identity("test_current_user", Optional.empty())) .setPath(new SqlPath(Optional.of("testPath"))) - .setSystemProperty("legacy_timestamp", String.valueOf(true)) .setSystemProperty("enable_execution_plan_cache", String.valueOf(true)) .setTimeZoneKey(getTimeZoneKey("+06:09")) .build(); private static final Session DEFAULT_SESSION = testSessionBuilder() .setCatalog("test") .setSchema("default") - .setSystemProperty("legacy_timestamp", String.valueOf(true)) .setSystemProperty("enable_execution_plan_cache", String.valueOf(true)) .setTimeZoneKey(getTimeZoneKey("+06:09")) .build(); @@ -91,7 +89,6 @@ public class TestCachedSqlQueryExecution private static final Session CACHING_DISABLED_SESSION = testSessionBuilder() .setCatalog("tpch") .setSchema("tiny") - .setSystemProperty("legacy_timestamp", String.valueOf(true)) .setTimeZoneKey(getTimeZoneKey("+06:09")) .setSystemProperty("enable_execution_plan_cache", String.valueOf(false)) .build(); @@ -99,7 +96,6 @@ public class TestCachedSqlQueryExecution private static final Session DEFAULT_SESSION_WITH_CHANGED_PROPERTY = testSessionBuilder() .setCatalog("tpch") .setSchema("tiny") - .setSystemProperty("legacy_timestamp", String.valueOf(true)) .setTimeZoneKey(getTimeZoneKey("+06:09")) .setSystemProperty("enable_execution_plan_cache", String.valueOf(true)) .setSystemProperty(SystemSessionProperties.JOIN_DISTRIBUTION_TYPE, FeaturesConfig.JoinDistributionType.AUTOMATIC.toString())