"Invalid value for adjust-to-utc: %s", adjustToUTC); if ((Boolean) adjustToUTC) { return Types.TimestampType.withZone(); } else { return Types.TimestampType.withoutZone();
if (ts.shouldAdjustToUTC()) { return EPOCH.plus(random.nextLong() % FIFTY_YEARS_IN_MICROS, MICROS); } else {
case TIMESTAMP_MICROS: TimestampType tsMicrosType = (TimestampType) expected; if (tsMicrosType.shouldAdjustToUTC()) { return new TimestamptzReader(desc); } else { if (tsMillisType.shouldAdjustToUTC()) { return new TimestamptzMillisReader(desc); } else {
break; case TIMESTAMP: if (((Types.TimestampType) primitive).shouldAdjustToUTC()) { primitiveSchema = TIMESTAMPTZ_SCHEMA; } else {
return Types.DateType.get(); case TIMESTAMP: return Types.TimestampType.withoutZone(); case DECIMAL: return Types.DecimalType.of(schema.getPrecision(), schema.getScale());
Types.NestedField.required(3, "d", Types.DateType.get()), Types.NestedField.required(4, "t", Types.TimeType.get()), Types.NestedField.required(5, "ts", Types.TimestampType.withoutZone()), Types.NestedField.required(6, "dec", Types.DecimalType.of(9, 2)), Types.NestedField.required(7, "s", Types.StringType.get()),
case TIMESTAMP_MILLIS: case TIMESTAMP_MICROS: return Types.TimestampType.withZone(); case JSON: case BSON:
.to(Types.TimestampType.withoutZone()); Assert.assertEquals("Spec example: hash(2017-11-16T22:31:08) = -2047944441", -2047944441, Bucket.<Long>get(Types.TimestampType.withoutZone(), 100).hash(timestampVal.value())); .to(Types.TimestampType.withZone()); Assert.assertEquals("Spec example: hash(2017-11-16T14:31:08-08:00) = -2047944441", -2047944441, Bucket.<Long>get(Types.TimestampType.withZone(), 100).hash(timestamptzVal.value()));
Types.DateType.get(), Types.TimeType.get(), Types.TimestampType.withZone(), Types.TimestampType.withoutZone(), Types.StringType.get(), Types.UUIDType.get(),
case TIMESTAMP: Types.TimestampType timestamp = (Types.TimestampType) primitive; if (timestamp.shouldAdjustToUTC()) { return TimestampType$.MODULE$;
optional(25, "date", Types.DateType.get()), optional(27, "time", Types.TimeType.get()), optional(28, "timestamptz", Types.TimestampType.withZone()), optional(29, "timestamp", Types.TimestampType.withoutZone()), optional(30, "string", Types.StringType.get()), optional(31, "uuid", Types.UUIDType.get()),
if (((Types.TimestampType) type).shouldAdjustToUTC()) { long timestampMicros = ChronoUnit.MICROS.between(EPOCH, OffsetDateTime.parse(value(), DateTimeFormatter.ISO_DATE_TIME));
return Types.TimestampType.withZone();
Types.BooleanType.get(), Types.IntegerType.get(), Types.LongType.get(), Types.FloatType.get(), Types.DoubleType.get(), Types.DateType.get(), Types.TimeType.get(), Types.TimestampType.withZone(), Types.TimestampType.withoutZone(), Types.StringType.get(), Types.UUIDType.get(), Types.BinaryType.get(), Types.FixedType.ofLength(3), Types.FixedType.ofLength(4),
@Override public String toHumanString(T value) { if (value == null) { return "null"; } switch (type.typeId()) { case DATE: return TransformUtil.humanDay((Integer) value); case TIME: return TransformUtil.humanTime((Long) value); case TIMESTAMP: if (((Types.TimestampType) type).shouldAdjustToUTC()) { return TransformUtil.humanTimestampWithZone((Long) value); } else { return TransformUtil.humanTimestampWithoutZone((Long) value); } case FIXED: case BINARY: if (value instanceof ByteBuffer) { return TransformUtil.base64encode(((ByteBuffer) value).duplicate()); } else if (value instanceof byte[]) { return TransformUtil.base64encode(ByteBuffer.wrap((byte[]) value)); } else { throw new UnsupportedOperationException("Unsupported binary type: " + value.getClass()); } default: return value.toString(); } }
@Test public void testIdentityConversions() { List<Pair<Literal<?>, Type>> pairs = Arrays.asList( Pair.of(Literal.of(true), Types.BooleanType.get()), Pair.of(Literal.of(34), Types.IntegerType.get()), Pair.of(Literal.of(34L), Types.LongType.get()), Pair.of(Literal.of(34.11F), Types.FloatType.get()), Pair.of(Literal.of(34.55D), Types.DoubleType.get()), Pair.of(Literal.of("34.55"), Types.DecimalType.of(9, 2)), Pair.of(Literal.of("2017-08-18"), Types.DateType.get()), Pair.of(Literal.of("14:21:01.919"), Types.TimeType.get()), Pair.of(Literal.of("2017-08-18T14:21:01.919"), Types.TimestampType.withoutZone()), Pair.of(Literal.of("abc"), Types.StringType.get()), Pair.of(Literal.of(UUID.randomUUID()), Types.UUIDType.get()), Pair.of(Literal.of(new byte[] {0, 1, 2}), Types.FixedType.ofLength(3)), Pair.of(Literal.of(ByteBuffer.wrap(new byte[] {0, 1, 2})), Types.BinaryType.get()) ); for (Pair<Literal<?>, Type> pair : pairs) { Literal<?> lit = pair.first(); Type type = pair.second(); // first, convert the literal to the target type (date/times start as strings) Literal<?> expected = lit.to(type); // then check that converting again to the same type results in an identical literal Assert.assertSame("Converting twice should produce identical values", expected, expected.to(type)); } }
@Override public Type primitive(Type.PrimitiveType primitive) { Class<? extends DataType> expectedType = TYPES.get(primitive.typeId()); Preconditions.checkArgument(expectedType != null && expectedType.isInstance(current), "Cannot project %s to incompatible type: %s", primitive, current); // additional checks based on type switch (primitive.typeId()) { case DECIMAL: Types.DecimalType decimal = (Types.DecimalType) primitive; DecimalType d = (DecimalType) current; Preconditions.checkArgument(d.scale() == decimal.scale(), "Cannot project decimal with incompatible scale: %s != %s", d.scale(), decimal.scale()); Preconditions.checkArgument(d.precision() >= decimal.precision(), "Cannot project decimal with incompatible precision: %s < %s", d.precision(), decimal.precision()); break; case TIMESTAMP: Types.TimestampType timestamp = (Types.TimestampType) primitive; Preconditions.checkArgument(timestamp.shouldAdjustToUTC(), "Cannot project timestamp (without time zone) as timestamptz (with time zone)"); break; default: } return primitive; }
@Override public Type primitive(Type.PrimitiveType primitive) { Class<? extends DataType> expectedType = TYPES.get(primitive.typeId()); Preconditions.checkArgument(expectedType != null && expectedType.isInstance(current), "Cannot project %s to incompatible type: %s", primitive, current); // additional checks based on type switch (primitive.typeId()) { case DECIMAL: Types.DecimalType decimal = (Types.DecimalType) primitive; DecimalType d = (DecimalType) current; Preconditions.checkArgument(d.scale() == decimal.scale(), "Cannot project decimal with incompatible scale: %s != %s", d.scale(), decimal.scale()); Preconditions.checkArgument(d.precision() >= decimal.precision(), "Cannot project decimal with incompatible precision: %s < %s", d.precision(), decimal.precision()); break; case TIMESTAMP: Types.TimestampType timestamp = (Types.TimestampType) primitive; Preconditions.checkArgument(timestamp.shouldAdjustToUTC(), "Cannot project timestamp (without time zone) as timestamptz (with time zone)"); break; default: } return primitive; }
@Test public void testStringToTimestampLiteral() { // use Avro's timestamp conversion to validate the result Schema avroSchema = LogicalTypes.timestampMicros().addToSchema(Schema.create(Schema.Type.LONG)); TimeConversions.LossyTimestampMicrosConversion avroConversion = new TimeConversions.LossyTimestampMicrosConversion(); // Timestamp with explicit UTC offset, +00:00 Literal<CharSequence> timestampStr = Literal.of("2017-08-18T14:21:01.919+00:00"); Literal<Long> timestamp = timestampStr.to(Types.TimestampType.withZone()); long avroValue = avroConversion.toLong( new LocalDateTime(2017, 8, 18, 14, 21, 1, 919).toDateTime(DateTimeZone.UTC), avroSchema, avroSchema.getLogicalType()); Assert.assertEquals("Timestamp should match", avroValue, (long) timestamp.value()); // Timestamp without an explicit zone should be UTC (equal to the previous converted value) timestampStr = Literal.of("2017-08-18T14:21:01.919"); timestamp = timestampStr.to(Types.TimestampType.withoutZone()); Assert.assertEquals("Timestamp without zone should match UTC", avroValue, (long) timestamp.value()); // Timestamp with an explicit offset should be adjusted to UTC timestampStr = Literal.of("2017-08-18T14:21:01.919-07:00"); timestamp = timestampStr.to(Types.TimestampType.withZone()); avroValue = avroConversion.toLong( new LocalDateTime(2017, 8, 18, 21, 21, 1, 919).toDateTime(DateTimeZone.UTC), avroSchema, avroSchema.getLogicalType()); Assert.assertEquals("Timestamp without zone should match UTC", avroValue, (long) timestamp.value()); }
@Test public void testLiterals() throws Exception { Literal[] literals = new Literal[] { Literal.of(false), Literal.of(34), Literal.of(35L), Literal.of(36.75F), Literal.of(8.75D), Literal.of("2017-11-29").to(Types.DateType.get()), Literal.of("11:30:07").to(Types.TimeType.get()), Literal.of("2017-11-29T11:30:07.123").to(Types.TimestampType.withoutZone()), Literal.of("2017-11-29T11:30:07.123+01:00").to(Types.TimestampType.withZone()), Literal.of("abc"), Literal.of(UUID.randomUUID()), Literal.of(new byte[] { 1, 2, 3 }).to(Types.FixedType.ofLength(3)), Literal.of(new byte[] { 3, 4, 5, 6 }).to(Types.BinaryType.get()), Literal.of(new BigDecimal("122.50")), }; for (Literal<?> lit : literals) { checkValue(lit); } }