diff --git a/benchmarks/src/main/java/org/apache/druid/benchmark/FlattenJSONBenchmarkUtil.java b/benchmarks/src/main/java/org/apache/druid/benchmark/FlattenJSONBenchmarkUtil.java index 6c0ec31d64a6..72e28f8b4a91 100644 --- a/benchmarks/src/main/java/org/apache/druid/benchmark/FlattenJSONBenchmarkUtil.java +++ b/benchmarks/src/main/java/org/apache/druid/benchmark/FlattenJSONBenchmarkUtil.java @@ -249,10 +249,23 @@ public String generateNestedEvent() throws Exception String[] dimsArray1 = {String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt())}; BenchmarkEvent nestedDims2 = new BenchmarkEvent( null, - null, null, String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), String.valueOf(rng.nextInt()), - null, null, null, null, - null, null, null, null, - dimsArray1, null, null + null, + null, + String.valueOf(rng.nextInt()), + String.valueOf(rng.nextInt()), + String.valueOf(rng.nextInt()), + String.valueOf(rng.nextInt()), + null, + null, + null, + null, + null, + null, + null, + null, + dimsArray1, + null, + null ); Long[] metricsArray1 = {rng.nextLong(), rng.nextLong(), rng.nextLong(), rng.nextLong()}; diff --git a/benchmarks/src/main/java/org/apache/druid/benchmark/TimeParseBenchmark.java b/benchmarks/src/main/java/org/apache/druid/benchmark/TimeParseBenchmark.java index 474cc79df913..647854b35de0 100644 --- a/benchmarks/src/main/java/org/apache/druid/benchmark/TimeParseBenchmark.java +++ b/benchmarks/src/main/java/org/apache/druid/benchmark/TimeParseBenchmark.java @@ -53,7 +53,7 @@ public class TimeParseBenchmark static final String DATA_FORMAT = "MM/dd/yyyy HH:mm:ss Z"; - static Function timeFn = TimestampParser.createTimestampParser(DATA_FORMAT); + static Function timeFn = TimestampParser.createTimestampParser(DATA_FORMAT, null); private String[] rows; diff --git a/codestyle/joda-time-forbidden-apis.txt b/codestyle/joda-time-forbidden-apis.txt index f2115b7abc8a..0933f796f979 100644 --- a/codestyle/joda-time-forbidden-apis.txt +++ b/codestyle/joda-time-forbidden-apis.txt @@ -60,7 +60,7 @@ org.joda.time.MutableInterval#parse(java.lang.String) org.joda.time.DateTimeZone#forID(java.lang.String) @ Use DateTimes.inferTzFromString() instead -@defaultMessage Uses default time zone, use DateTimes.UtcFormatter to parse. +@defaultMessage Uses default time zone, use DateTimes.Formatter or DateTimes.UtcFormatter to parse. org.joda.time.format.DateTimeFormatter#parseInto(org.joda.time.ReadWritableInstant, java.lang.String, int) org.joda.time.format.DateTimeFormatter#parseDateTime(java.lang.String) org.joda.time.format.DateTimeFormatter#parseMutableDateTime(java.lang.String) diff --git a/core/src/main/java/org/apache/druid/data/input/impl/TimeAndDimsParseSpec.java b/core/src/main/java/org/apache/druid/data/input/impl/TimeAndDimsParseSpec.java index 969ea9a908e3..d6083d70b0ba 100644 --- a/core/src/main/java/org/apache/druid/data/input/impl/TimeAndDimsParseSpec.java +++ b/core/src/main/java/org/apache/druid/data/input/impl/TimeAndDimsParseSpec.java @@ -37,7 +37,7 @@ public TimeAndDimsParseSpec( ) { super( - timestampSpec != null ? timestampSpec : new TimestampSpec(null, null, null), + timestampSpec != null ? timestampSpec : new TimestampSpec(null, null, null, null), dimensionsSpec != null ? dimensionsSpec : new DimensionsSpec(null, null, null) ); } diff --git a/core/src/main/java/org/apache/druid/data/input/impl/TimestampSpec.java b/core/src/main/java/org/apache/druid/data/input/impl/TimestampSpec.java index a61f98370f2c..9f9c2ec0f6a2 100644 --- a/core/src/main/java/org/apache/druid/data/input/impl/TimestampSpec.java +++ b/core/src/main/java/org/apache/druid/data/input/impl/TimestampSpec.java @@ -21,8 +21,11 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; +import org.apache.commons.lang3.StringUtils; import org.apache.druid.guice.annotations.PublicApi; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.parsers.TimestampParser; import org.joda.time.DateTime; @@ -49,7 +52,10 @@ private static class ParseCtx private final String timestampFormat; // this value should never be set for production data private final DateTime missingValue; - /** This field is a derivative of {@link #timestampFormat}; not checked in {@link #equals} and {@link #hashCode} */ + private final String timeZone; + /** + * This field is a derivative of {@link #timestampFormat}; not checked in {@link #equals} and {@link #hashCode} + */ private final Function timestampConverter; // remember last value parsed @@ -60,17 +66,29 @@ public TimestampSpec( @JsonProperty("column") String timestampColumn, @JsonProperty("format") String format, // this value should never be set for production data - @JsonProperty("missingValue") DateTime missingValue + @JsonProperty("missingValue") DateTime missingValue, + @JsonProperty("timeZone") String timeZone ) { this.timestampColumn = (timestampColumn == null) ? DEFAULT_COLUMN : timestampColumn; this.timestampFormat = format == null ? DEFAULT_FORMAT : format; - this.timestampConverter = TimestampParser.createObjectTimestampParser(timestampFormat); + this.timeZone = StringUtils.isBlank(timeZone) ? DateTimes.UTC_TIMEZONE : timeZone; + this.timestampConverter = TimestampParser.createObjectTimestampParser(timestampFormat, this.timeZone); this.missingValue = missingValue == null ? DEFAULT_MISSING_VALUE : missingValue; } + @VisibleForTesting + public TimestampSpec( + String timestampColumn, + String format, + DateTime missingValue + ) + { + this(timestampColumn, format, missingValue, null); + } + @JsonProperty("column") public String getTimestampColumn() { diff --git a/core/src/main/java/org/apache/druid/java/util/common/DateTimes.java b/core/src/main/java/org/apache/druid/java/util/common/DateTimes.java index 94f1295d2e69..6da70dc985c7 100644 --- a/core/src/main/java/org/apache/druid/java/util/common/DateTimes.java +++ b/core/src/main/java/org/apache/druid/java/util/common/DateTimes.java @@ -20,10 +20,12 @@ package org.apache.druid.java.util.common; import io.netty.util.SuppressForbidden; +import org.apache.commons.lang3.StringUtils; import org.joda.time.Chronology; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.chrono.ISOChronology; +import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; @@ -35,10 +37,11 @@ public final class DateTimes public static final DateTime EPOCH = utc(0); public static final DateTime MAX = utc(JodaUtils.MAX_INSTANT); public static final DateTime MIN = utc(JodaUtils.MIN_INSTANT); + public static final String UTC_TIMEZONE = DateTimeZone.UTC.getID(); - public static final UtcFormatter ISO_DATE_TIME = wrapFormatter(ISODateTimeFormat.dateTime()); - public static final UtcFormatter ISO_DATE_OPTIONAL_TIME = wrapFormatter(ISODateTimeFormat.dateOptionalTimeParser()); - public static final UtcFormatter ISO_DATE_OR_TIME_WITH_OFFSET = wrapFormatter( + public static final UtcFormatter ISO_DATE_TIME = wrapUtcFormatter(ISODateTimeFormat.dateTime()); + public static final UtcFormatter ISO_DATE_OPTIONAL_TIME = wrapUtcFormatter(ISODateTimeFormat.dateOptionalTimeParser()); + public static final UtcFormatter ISO_DATE_OR_TIME_WITH_OFFSET = wrapUtcFormatter( ISODateTimeFormat.dateTimeParser().withOffsetParsed() ); @@ -64,18 +67,19 @@ public static DateTimeZone inferTzFromString(String tzId) } } - /** - * Simple wrapper class to enforce UTC Chronology in formatter. Specifically, it will use - * {@link DateTimeFormatter#withChronology(Chronology)} to set the chronology to - * {@link ISOChronology#getInstanceUTC()} on the wrapped {@link DateTimeFormatter}. - */ - public static class UtcFormatter + public static class Formatter { - private final DateTimeFormatter innerFormatter; + private DateTimeFormatter innerFormatter; - private UtcFormatter(final DateTimeFormatter innerFormatter) + public Formatter(DateTimeFormatter innerFormatter) + { + this.innerFormatter = innerFormatter; + } + + public Formatter(String format, String timezone) { - this.innerFormatter = innerFormatter.withChronology(ISOChronology.getInstanceUTC()); + this.innerFormatter = DateTimeFormat.forPattern(format) + .withChronology(ISOChronology.getInstance(inferTzFromString(timezone))); } @SuppressForbidden(reason = "DateTimeFormatter#parseDateTime") @@ -90,12 +94,39 @@ public String print(final DateTime instant) } } + /** + * Simple wrapper class to enforce UTC Chronology in formatter. Specifically, it will use + * {@link DateTimeFormatter#withChronology(Chronology)} to set the chronology to + * {@link ISOChronology#getInstanceUTC()} on the wrapped {@link DateTimeFormatter}. + */ + public static class UtcFormatter extends Formatter + { + private UtcFormatter(final DateTimeFormatter innerFormatter) + { + super(innerFormatter.withChronology(ISOChronology.getInstanceUTC())); + } + } + + /** + * Create a {@link Formatter} by args + * + * @param format + * @param timeZone + * + * @return + */ + public static Formatter wrapFormatter(String format, String timeZone) + { + timeZone = StringUtils.isNotBlank(timeZone) ? timeZone : DateTimeZone.UTC.getID(); + return new Formatter(format, timeZone); + } + /** * Creates a {@link UtcFormatter} that wraps around a {@link DateTimeFormatter}. * * @param formatter inner {@link DateTimeFormatter} used to parse {@link String} */ - public static UtcFormatter wrapFormatter(final DateTimeFormatter formatter) + public static UtcFormatter wrapUtcFormatter(final DateTimeFormatter formatter) { return new UtcFormatter(formatter); } diff --git a/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java b/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java index ecd06f822f93..e819fea04a12 100644 --- a/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java +++ b/core/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java @@ -26,7 +26,6 @@ import org.apache.druid.java.util.common.IAE; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatterBuilder; import org.joda.time.format.DateTimeParser; @@ -37,12 +36,13 @@ public class TimestampParser { public static Function createTimestampParser( - final String format + final String format, + final String userTimeZone ) { if ("auto".equalsIgnoreCase(format)) { // Could be iso or millis - final DateTimes.UtcFormatter parser = DateTimes.wrapFormatter(createAutoParser()); + final DateTimes.UtcFormatter parser = DateTimes.wrapUtcFormatter(createAutoParser()); return (String input) -> { Preconditions.checkArgument(!Strings.isNullOrEmpty(input), "null timestamp"); @@ -87,7 +87,7 @@ public static Function createTimestampParser( }; } else { try { - final DateTimes.UtcFormatter formatter = DateTimes.wrapFormatter(DateTimeFormat.forPattern(format)); + final DateTimes.Formatter formatter = DateTimes.wrapFormatter(format, userTimeZone); return input -> { Preconditions.checkArgument(!Strings.isNullOrEmpty(input), "null timestamp"); return formatter.parse(ParserUtils.stripQuotes(input)); @@ -117,10 +117,11 @@ public static Function createNumericTimestampParser( } public static Function createObjectTimestampParser( - final String format + final String format, + final String timeZone ) { - final Function stringFun = createTimestampParser(format); + final Function stringFun = createTimestampParser(format, timeZone); final Function numericFun = createNumericTimestampParser(format); return o -> { diff --git a/core/src/main/java/org/apache/druid/math/expr/Function.java b/core/src/main/java/org/apache/druid/math/expr/Function.java index 24247558c133..d6559ff9f770 100644 --- a/core/src/main/java/org/apache/druid/math/expr/Function.java +++ b/core/src/main/java/org/apache/druid/math/expr/Function.java @@ -835,7 +835,7 @@ public ExprEval apply(List args, Expr.ObjectBinding bindings) if (format.type() != ExprType.STRING) { throw new IAE("second argument should be string type but got %s type", format.type()); } - formatter = DateTimes.wrapFormatter(DateTimeFormat.forPattern(format.asString())); + formatter = DateTimes.wrapUtcFormatter(DateTimeFormat.forPattern(format.asString())); } DateTime date; try { diff --git a/core/src/test/java/org/apache/druid/data/input/impl/TimestampSpecTest.java b/core/src/test/java/org/apache/druid/data/input/impl/TimestampSpecTest.java index ffbca5c1abda..73201f79ff52 100644 --- a/core/src/test/java/org/apache/druid/data/input/impl/TimestampSpecTest.java +++ b/core/src/test/java/org/apache/druid/data/input/impl/TimestampSpecTest.java @@ -61,7 +61,7 @@ public void testContextualTimestampList() }; TimestampSpec spec = new TimestampSpec("TIMEstamp", DATE_FORMAT, null); - DateTimes.UtcFormatter formatter = DateTimes.wrapFormatter(ISODateTimeFormat.dateHourMinuteSecond()); + DateTimes.UtcFormatter formatter = DateTimes.wrapUtcFormatter(ISODateTimeFormat.dateHourMinuteSecond()); for (String date : dates) { DateTime dateTime = spec.extractTimestamp(ImmutableMap.of("TIMEstamp", date)); @@ -69,4 +69,30 @@ public void testContextualTimestampList() Assert.assertEquals(expectedDateTime, dateTime); } } + + @Test + public void testExtractTimestampWithTimezone() + { + String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + String timeZone = "Asia/Shanghai"; + String[] dates = new String[]{ + "2000-01-01 00:00:00", + "2000-01-01 08:00:00", + "2000-01-01 12:00:01", + "2000-01-01 23:59:59", + }; + TimestampSpec spec = new TimestampSpec("log_time", DATE_FORMAT, null, timeZone); + + DateTimes.Formatter expectedFormatter = DateTimes.wrapFormatter(DATE_FORMAT, timeZone); + + for (String date : dates) { + DateTime actualDateTime = spec.extractTimestamp(ImmutableMap.of( + "log_time", date, + "dim1", "value1" + )); + long expectedTs = expectedFormatter.parse(date).getMillis(); + Assert.assertEquals(expectedTs, actualDateTime.getMillis()); + } + } + } diff --git a/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java b/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java index 9c0e66e10d22..c53e57ca96ec 100644 --- a/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java +++ b/core/src/test/java/org/apache/druid/java/util/common/parsers/TimestampParserTest.java @@ -58,7 +58,7 @@ public void testExtractTimeZone() @Test public void testAuto() { - final Function parser = TimestampParser.createObjectTimestampParser("auto"); + final Function parser = TimestampParser.createObjectTimestampParser("auto", null); Assert.assertEquals(DateTimes.of("2009-02-13T23:31:30Z"), parser.apply("1234567890000")); Assert.assertEquals(DateTimes.of("2009-02-13T23:31:30Z"), parser.apply("2009-02-13T23:31:30Z")); Assert.assertEquals(DateTimes.of("2009-02-13T23:31:30-08:00"), parser.apply("2009-02-13T23:31:30-08:00")); @@ -78,7 +78,7 @@ public void testAuto() @Test public void testAutoNull() { - final Function parser = TimestampParser.createObjectTimestampParser("auto"); + final Function parser = TimestampParser.createObjectTimestampParser("auto", null); expectedException.expect(NullPointerException.class); parser.apply(null); @@ -87,7 +87,7 @@ public void testAutoNull() @Test public void testAutoInvalid() { - final Function parser = TimestampParser.createObjectTimestampParser("auto"); + final Function parser = TimestampParser.createObjectTimestampParser("auto", null); expectedException.expect(IllegalArgumentException.class); parser.apply("asdf"); @@ -96,7 +96,7 @@ public void testAutoInvalid() @Test public void testRuby() { - final Function parser = TimestampParser.createObjectTimestampParser("ruby"); + final Function parser = TimestampParser.createObjectTimestampParser("ruby", null); Assert.assertEquals(DateTimes.of("2013-01-16T14:41:47.435Z"), parser.apply("1358347307.435447")); Assert.assertEquals(DateTimes.of("2013-01-16T14:41:47.435Z"), parser.apply(1358347307.435447D)); } @@ -106,7 +106,7 @@ public void testNano() { String timeNsStr = "1427504794977098494"; DateTime expectedDt = DateTimes.of("2015-3-28T01:06:34.977Z"); - final Function parser = TimestampParser.createObjectTimestampParser("nano"); + final Function parser = TimestampParser.createObjectTimestampParser("nano", null); Assert.assertEquals("Incorrect truncation of nanoseconds -> milliseconds", expectedDt, parser.apply(timeNsStr)); @@ -122,7 +122,7 @@ public void testNano() public void testTimeStampParserWithQuotes() { DateTime d = new DateTime(1994, 11, 9, 4, 0, DateTimeZone.forOffsetHours(-8)); - Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy"); + Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy", null); Assert.assertEquals(d.getMillis(), parser.apply(" \" Wed Nov 9 04:00:00 PST 1994 \" ").getMillis()); } @@ -130,7 +130,7 @@ public void testTimeStampParserWithQuotes() public void testTimeStampParserWithShortTimeZone() { DateTime d = new DateTime(1994, 11, 9, 4, 0, DateTimeZone.forOffsetHours(-8)); - Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy"); + Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy", null); Assert.assertEquals(d.getMillis(), parser.apply("Wed Nov 9 04:00:00 PST 1994").getMillis()); } @@ -141,13 +141,13 @@ public void testTimeStampParserWithLongTimeZone() long millis1 = new DateTime(1994, 11, 9, 4, 0, DateTimeZone.forOffsetHours(-8)).getMillis(); long millis2 = new DateTime(1994, 11, 9, 4, 0, DateTimeZone.forOffsetHours(-6)).getMillis(); - Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss zZ z yyyy"); + Function parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss zZ z yyyy", null); Assert.assertEquals(millis1, parser.apply("Wed Nov 9 04:00:00 GMT-0800 PST 1994").getMillis()); Assert.assertEquals(millis2, parser.apply("Wed Nov 9 04:00:00 GMT-0600 CST 1994").getMillis()); Assert.assertEquals(millis1, parser.apply("Wed Nov 9 04:00:00 UTC-0800 PST 1994").getMillis()); Assert.assertEquals(millis2, parser.apply("Wed Nov 9 04:00:00 UTC-0600 CST 1994").getMillis()); - parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss zZ yyyy"); + parser = TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss zZ yyyy", null); Assert.assertEquals(millis1, parser.apply("Wed Nov 9 04:00:00 GMT-0800 1994").getMillis()); Assert.assertEquals(millis2, parser.apply("Wed Nov 9 04:00:00 GMT-0600 1994").getMillis()); Assert.assertEquals(millis1, parser.apply("Wed Nov 9 04:00:00 UTC-0800 1994").getMillis()); @@ -157,11 +157,11 @@ public void testTimeStampParserWithLongTimeZone() @Test public void testTimeZoneAtExtremeLocations() { - Function parser = TimestampParser.createTimestampParser("EEE MMM dd yy HH:mm:ss zZ z"); + Function parser = TimestampParser.createTimestampParser("EEE MMM dd yy HH:mm:ss zZ z", null); Assert.assertEquals(new DateTime(2005, 1, 22, 13, 0, DateTimeZone.forOffsetHours(-6)).getMillis(), parser.apply("Sat Jan 22 05 13:00:00 GMT-0600 CST").getMillis()); - parser = TimestampParser.createTimestampParser("zZ z EEE MMM dd yy HH:mm:ss"); + parser = TimestampParser.createTimestampParser("zZ z EEE MMM dd yy HH:mm:ss", null); Assert.assertEquals(new DateTime(2005, 1, 22, 13, 0, DateTimeZone.forOffsetHours(-6)).getMillis(), parser.apply("GMT-0600 CST Sat Jan 22 05 13:00:00").getMillis()); } @@ -171,12 +171,12 @@ public void testJodaSymbolInsideLiteral() { DateTime d = new DateTime(1994, 11, 9, 4, 0, DateTimeZone.forOffsetHours(-8)); Assert.assertEquals(d.getMillis(), - TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy 'helloz'") + TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss z yyyy 'helloz'", null) .apply("Wed Nov 9 04:00:00 PST 1994 helloz") .getMillis() ); Assert.assertEquals(d.getMillis(), - TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss 'helloz' z yyyy 'hello'") + TimestampParser.createTimestampParser("EEE MMM dd HH:mm:ss 'helloz' z yyyy 'hello'", null) .apply("Wed Nov 9 04:00:00 helloz PST 1994 hello") .getMillis() ); diff --git a/docs/content/ingestion/ingestion-spec.md b/docs/content/ingestion/ingestion-spec.md index 46e7334aeffa..4377eb1d46bf 100644 --- a/docs/content/ingestion/ingestion-spec.md +++ b/docs/content/ingestion/ingestion-spec.md @@ -208,6 +208,7 @@ handle all formatting decisions on their own, without using the ParseSpec. |-------|------|-------------|----------| | column | String | The column of the timestamp. | yes | | format | String | iso, posix, millis, micro, nano, auto or any [Joda time](http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html) format. | no (default == 'auto' | +| timeZone | String | Specify timeZone of the timestamp, refer to the [Joda timezone list](http://joda-time.sourceforge.net/timezones.html) | no (default == 'UTC') | diff --git a/extensions-contrib/influx-extensions/src/main/java/org/apache/druid/data/input/influx/InfluxParseSpec.java b/extensions-contrib/influx-extensions/src/main/java/org/apache/druid/data/input/influx/InfluxParseSpec.java index 025c3ad08e54..209ee2011475 100644 --- a/extensions-contrib/influx-extensions/src/main/java/org/apache/druid/data/input/influx/InfluxParseSpec.java +++ b/extensions-contrib/influx-extensions/src/main/java/org/apache/druid/data/input/influx/InfluxParseSpec.java @@ -40,7 +40,7 @@ public InfluxParseSpec( ) { super( - new TimestampSpec(InfluxParser.TIMESTAMP_KEY, "millis", null), + new TimestampSpec(InfluxParser.TIMESTAMP_KEY, "millis", null, null), dimensionsSpec != null ? dimensionsSpec : new DimensionsSpec(null, null, null) ); this.measurementWhitelist = measurementWhitelist; diff --git a/extensions-contrib/time-min-max/src/main/java/org/apache/druid/query/aggregation/TimestampAggregatorFactory.java b/extensions-contrib/time-min-max/src/main/java/org/apache/druid/query/aggregation/TimestampAggregatorFactory.java index bf9b69020d39..168786671270 100644 --- a/extensions-contrib/time-min-max/src/main/java/org/apache/druid/query/aggregation/TimestampAggregatorFactory.java +++ b/extensions-contrib/time-min-max/src/main/java/org/apache/druid/query/aggregation/TimestampAggregatorFactory.java @@ -58,7 +58,7 @@ public class TimestampAggregatorFactory extends AggregatorFactory this.comparator = comparator; this.initValue = initValue; - this.timestampSpec = new TimestampSpec(fieldName, timeFormat, null); + this.timestampSpec = new TimestampSpec(fieldName, timeFormat, null, null); } @Override diff --git a/extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/AvroParseSpec.java b/extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/AvroParseSpec.java index c7912e38dde3..034f84b8f4f3 100644 --- a/extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/AvroParseSpec.java +++ b/extensions-core/avro-extensions/src/main/java/org/apache/druid/data/input/avro/AvroParseSpec.java @@ -38,7 +38,7 @@ public AvroParseSpec( ) { super( - timestampSpec != null ? timestampSpec : new TimestampSpec(null, null, null), + timestampSpec != null ? timestampSpec : new TimestampSpec(null, null, null, null), dimensionsSpec != null ? dimensionsSpec : DimensionsSpec.EMPTY, flattenSpec != null ? flattenSpec : JSONPathSpec.DEFAULT ); diff --git a/processing/src/main/java/org/apache/druid/query/expression/TimestampParseExprMacro.java b/processing/src/main/java/org/apache/druid/query/expression/TimestampParseExprMacro.java index 2b65fb54653e..53f202e96b52 100644 --- a/processing/src/main/java/org/apache/druid/query/expression/TimestampParseExprMacro.java +++ b/processing/src/main/java/org/apache/druid/query/expression/TimestampParseExprMacro.java @@ -62,7 +62,7 @@ public Expr apply(final List args) final DateTimes.UtcFormatter formatter = formatString == null ? createDefaultParser(timeZone) - : DateTimes.wrapFormatter(DateTimeFormat.forPattern(formatString).withZone(timeZone)); + : DateTimes.wrapUtcFormatter(DateTimeFormat.forPattern(formatString).withZone(timeZone)); class TimestampParseExpr implements Expr { @@ -118,7 +118,7 @@ private static DateTimes.UtcFormatter createDefaultParser(final DateTimeZone tim .appendOptional(offsetElement.getParser()) .toParser(); - return DateTimes.wrapFormatter( + return DateTimes.wrapUtcFormatter( new DateTimeFormatterBuilder() .append(ISODateTimeFormat.dateElementParser()) .appendOptional(timeOrOffset) diff --git a/processing/src/main/java/org/apache/druid/query/extraction/TimeDimExtractionFn.java b/processing/src/main/java/org/apache/druid/query/extraction/TimeDimExtractionFn.java index 8b58a8198593..1962aee7712d 100644 --- a/processing/src/main/java/org/apache/druid/query/extraction/TimeDimExtractionFn.java +++ b/processing/src/main/java/org/apache/druid/query/extraction/TimeDimExtractionFn.java @@ -65,8 +65,8 @@ public TimeDimExtractionFn( private Supplier> makeFunctionSupplier() { if (joda) { - final DateTimes.UtcFormatter parser = DateTimes.wrapFormatter(DateTimeFormat.forPattern(timeFormat)); - final DateTimes.UtcFormatter formatter = DateTimes.wrapFormatter(DateTimeFormat.forPattern(resultFormat)); + final DateTimes.UtcFormatter parser = DateTimes.wrapUtcFormatter(DateTimeFormat.forPattern(timeFormat)); + final DateTimes.UtcFormatter formatter = DateTimes.wrapUtcFormatter(DateTimeFormat.forPattern(resultFormat)); final Function fn = value -> { DateTime date; diff --git a/processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndexSchema.java b/processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndexSchema.java index 87d75f8c7e2e..8671ee7c0960 100644 --- a/processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndexSchema.java +++ b/processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndexSchema.java @@ -132,7 +132,7 @@ public Builder withTimestampSpec(InputRowParser parser) && parser.getParseSpec().getTimestampSpec() != null) { this.timestampSpec = parser.getParseSpec().getTimestampSpec(); } else { - this.timestampSpec = new TimestampSpec(null, null, null); + this.timestampSpec = new TimestampSpec(null, null, null, null); } return this; } diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/Calcites.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/Calcites.java index c251d31ee6d1..8c1d6a51356d 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/Calcites.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/Calcites.java @@ -63,8 +63,8 @@ */ public class Calcites { - private static final DateTimes.UtcFormatter CALCITE_DATE_PARSER = DateTimes.wrapFormatter(ISODateTimeFormat.dateParser()); - private static final DateTimes.UtcFormatter CALCITE_TIMESTAMP_PARSER = DateTimes.wrapFormatter( + private static final DateTimes.UtcFormatter CALCITE_DATE_PARSER = DateTimes.wrapUtcFormatter(ISODateTimeFormat.dateParser()); + private static final DateTimes.UtcFormatter CALCITE_TIMESTAMP_PARSER = DateTimes.wrapUtcFormatter( new DateTimeFormatterBuilder() .append(ISODateTimeFormat.dateParser()) .appendLiteral(' ') diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java index 9ca3233f20d9..069cbac35365 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/CalciteTests.java @@ -426,7 +426,6 @@ public AuthenticationResult createEscalatedAuthenticationResult() ); - public static final List ROWS2 = ImmutableList.of( createRow("2000-01-01", "דרואיד", "he", 1.0), createRow("2000-01-01", "druid", "en", 1.0), @@ -647,13 +646,14 @@ public static SpecificSegmentsQuerySegmentWalker createMockWalker( .shardSpec(new LinearShardSpec(0)) .build(), forbiddenIndex - ).add(DataSegment.builder() - .dataSource(DATASOURCE3) - .interval(indexNumericDims.getDataInterval()) - .version("1") - .shardSpec(new LinearShardSpec(0)) - .build(), - indexNumericDims + ).add( + DataSegment.builder() + .dataSource(DATASOURCE3) + .interval(indexNumericDims.getDataInterval()) + .version("1") + .shardSpec(new LinearShardSpec(0)) + .build(), + indexNumericDims ); }