/* * 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 com.facebook.presto.hive; import org.apache.hadoop.hive.metastore.Warehouse; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.serde2.thrift.ThriftDeserializer; import org.apache.hadoop.hive.serde2.thrift.test.IntString; import org.apache.thrift.protocol.TBinaryProtocol; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.testng.annotations.Test; import java.util.AbstractList; import java.util.ArrayList; import java.util.List; import java.util.Properties; import static com.facebook.presto.hive.HiveUtil.getDeserializer; import static com.facebook.presto.hive.HiveUtil.parseHiveTimestamp; import static com.facebook.presto.hive.HiveUtil.toPartitionValues; import static io.airlift.testing.Assertions.assertInstanceOf; import static org.apache.hadoop.hive.serde.serdeConstants.SERIALIZATION_CLASS; import static org.apache.hadoop.hive.serde.serdeConstants.SERIALIZATION_FORMAT; import static org.apache.hadoop.hive.serde.serdeConstants.SERIALIZATION_LIB; import static org.testng.Assert.assertEquals; public class TestHiveUtil { @Test public void testParseHiveTimestamp() { DateTime time = new DateTime(2011, 5, 6, 7, 8, 9, 123, nonDefaultTimeZone()); 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)); assertEquals(parse(time, "yyyy-MM-dd HH:mm:ss.SSSSSSS"), unixTime(time, 6)); assertEquals(parse(time, "yyyy-MM-dd HH:mm:ss.SSSSSSSSS"), unixTime(time, 7)); } @Test public void testGetThriftDeserializer() { Properties schema = new Properties(); schema.setProperty(SERIALIZATION_LIB, ThriftDeserializer.class.getName()); schema.setProperty(SERIALIZATION_CLASS, IntString.class.getName()); schema.setProperty(SERIALIZATION_FORMAT, TBinaryProtocol.class.getName()); assertInstanceOf(getDeserializer(schema), ThriftDeserializer.class); } @Test public void testToPartitionValues() throws MetaException { assertToPartitionValues("ds=2015-12-30/event_type=QueryCompletion"); assertToPartitionValues("ds=2015-12-30"); assertToPartitionValues("a=1/b=2/c=3"); assertToPartitionValues("a=1"); assertToPartitionValues("pk=!@%23$%25%5E&%2A()%2F%3D"); assertToPartitionValues("pk=__HIVE_DEFAULT_PARTITION__"); } private static void assertToPartitionValues(String partitionName) throws MetaException { List<String> actual = toPartitionValues(partitionName); AbstractList<String> expected = new ArrayList<>(); for (String s : actual) { expected.add(null); } Warehouse.makeValsFromName(partitionName, expected); assertEquals(actual, expected); } private static long parse(DateTime time, String pattern) { return parseHiveTimestamp(DateTimeFormat.forPattern(pattern).print(time), nonDefaultTimeZone()); } private static long unixTime(DateTime time, int factionalDigits) { int factor = (int) Math.pow(10, Math.max(0, 3 - factionalDigits)); return (time.getMillis() / factor) * factor; } static DateTimeZone nonDefaultTimeZone() { String defaultId = DateTimeZone.getDefault().getID(); for (String id : DateTimeZone.getAvailableIDs()) { if (!id.equals(defaultId)) { DateTimeZone zone = DateTimeZone.forID(id); if (zone.getStandardOffset(0) != 0) { return zone; } } } throw new IllegalStateException("no non-default timezone"); } }