This is an automated email from the ASF dual-hosted git repository. cwylie pushed a commit to branch 0.15.1-incubating in repository https://gitbox.apache.org/repos/asf/incubator-druid.git
commit cf6e464f507d12d46b6c4ccc5d7982afc5a6cf45 Author: Xue Yu <[email protected]> AuthorDate: Tue Jun 4 16:16:31 2019 +0800 fix timestamp ceil lower bound bug (#7823) --- .../query/expression/TimestampCeilExprMacro.java | 15 +++- .../druid/query/expression/ExprMacroTest.java | 2 + .../apache/druid/sql/calcite/CalciteQueryTest.java | 83 ++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/processing/src/main/java/org/apache/druid/query/expression/TimestampCeilExprMacro.java b/processing/src/main/java/org/apache/druid/query/expression/TimestampCeilExprMacro.java index a775c69..37b35d8 100644 --- a/processing/src/main/java/org/apache/druid/query/expression/TimestampCeilExprMacro.java +++ b/processing/src/main/java/org/apache/druid/query/expression/TimestampCeilExprMacro.java @@ -26,6 +26,7 @@ import org.apache.druid.java.util.common.granularity.PeriodGranularity; import org.apache.druid.math.expr.Expr; import org.apache.druid.math.expr.ExprEval; import org.apache.druid.math.expr.ExprMacroTable; +import org.joda.time.DateTime; import javax.annotation.Nonnull; import java.util.List; @@ -72,7 +73,12 @@ public class TimestampCeilExprMacro implements ExprMacroTable.ExprMacro // Return null if the argument if null. return ExprEval.of(null); } - return ExprEval.of(granularity.bucketEnd(DateTimes.utc(arg.eval(bindings).asLong())).getMillis()); + DateTime argTime = DateTimes.utc(arg.eval(bindings).asLong()); + DateTime bucketStartTime = granularity.bucketStart(argTime); + if (argTime.equals(bucketStartTime)) { + return ExprEval.of(bucketStartTime.getMillis()); + } + return ExprEval.of(granularity.increment(bucketStartTime).getMillis()); } @Override @@ -107,7 +113,12 @@ public class TimestampCeilExprMacro implements ExprMacroTable.ExprMacro public ExprEval eval(final ObjectBinding bindings) { final PeriodGranularity granularity = getGranularity(args, bindings); - return ExprEval.of(granularity.bucketEnd(DateTimes.utc(args.get(0).eval(bindings).asLong())).getMillis()); + DateTime argTime = DateTimes.utc(args.get(0).eval(bindings).asLong()); + DateTime bucketStartTime = granularity.bucketStart(argTime); + if (argTime.equals(bucketStartTime)) { + return ExprEval.of(bucketStartTime.getMillis()); + } + return ExprEval.of(granularity.increment(bucketStartTime).getMillis()); } @Override diff --git a/server/src/test/java/org/apache/druid/query/expression/ExprMacroTest.java b/server/src/test/java/org/apache/druid/query/expression/ExprMacroTest.java index bbab646..d79cff1 100644 --- a/server/src/test/java/org/apache/druid/query/expression/ExprMacroTest.java +++ b/server/src/test/java/org/apache/druid/query/expression/ExprMacroTest.java @@ -34,6 +34,7 @@ public class ExprMacroTest private static final Expr.ObjectBinding BINDINGS = Parser.withMap( ImmutableMap.<String, Object>builder() .put("t", DateTimes.of("2000-02-03T04:05:06").getMillis()) + .put("t1", DateTimes.of("2000-02-03T00:00:00").getMillis()) .put("tstr", "2000-02-03T04:05:06") .put("tstr_sql", "2000-02-03 04:05:06") .put("x", "foo") @@ -88,6 +89,7 @@ public class ExprMacroTest assertExpr("timestamp_ceil(t, 'P1D',null,'America/Los_Angeles')", DateTimes.of("2000-02-03T08").getMillis()); assertExpr("timestamp_ceil(t, 'P1D',null,CityOfAngels)", DateTimes.of("2000-02-03T08").getMillis()); assertExpr("timestamp_ceil(t, 'P1D','1970-01-01T01','Etc/UTC')", DateTimes.of("2000-02-04T01").getMillis()); + assertExpr("timestamp_ceil(t1, 'P1D')", DateTimes.of("2000-02-03").getMillis()); } @Test diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java index fb4976f..f4bc6ae 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java @@ -7684,4 +7684,87 @@ public class CalciteQueryTest extends BaseCalciteQueryTest ) ); } + + @Test + public void testTimestampDiff() throws Exception + { + testQuery( + "SELECT TIMESTAMPDIFF(DAY, TIMESTAMP '1999-01-01 00:00:00', __time), \n" + + "TIMESTAMPDIFF(DAY, __time, DATE '2001-01-01'), \n" + + "TIMESTAMPDIFF(HOUR, TIMESTAMP '1999-12-31 01:00:00', __time), \n" + + "TIMESTAMPDIFF(MINUTE, TIMESTAMP '1999-12-31 23:58:03', __time), \n" + + "TIMESTAMPDIFF(SECOND, TIMESTAMP '1999-12-31 23:59:03', __time), \n" + + "TIMESTAMPDIFF(MONTH, TIMESTAMP '1999-11-01 00:00:00', __time), \n" + + "TIMESTAMPDIFF(YEAR, TIMESTAMP '1996-11-01 00:00:00', __time), \n" + + "TIMESTAMPDIFF(QUARTER, TIMESTAMP '1996-10-01 00:00:00', __time), \n" + + "TIMESTAMPDIFF(WEEK, TIMESTAMP '1998-10-01 00:00:00', __time) \n" + + "FROM druid.foo\n" + + "LIMIT 2", + ImmutableList.of( + newScanQueryBuilder() + .dataSource(CalciteTests.DATASOURCE1) + .intervals(querySegmentSpec(Filtration.eternity())) + .virtualColumns( + expressionVirtualColumn("v0", "div((\"__time\" - 915148800000),86400000)", ValueType.LONG), + expressionVirtualColumn("v1", "div((978307200000 - \"__time\"),86400000)", ValueType.LONG), + expressionVirtualColumn("v2", "div((\"__time\" - 946602000000),3600000)", ValueType.LONG), + expressionVirtualColumn("v3", "div((\"__time\" - 946684683000),60000)", ValueType.LONG), + expressionVirtualColumn("v4", "div((\"__time\" - 946684743000),1000)", ValueType.LONG), + expressionVirtualColumn("v5", "subtract_months(\"__time\",941414400000,'UTC')", ValueType.LONG), + expressionVirtualColumn("v6", "div(subtract_months(\"__time\",846806400000,'UTC'),12)", ValueType.LONG), + expressionVirtualColumn("v7", "div(subtract_months(\"__time\",844128000000,'UTC'),3)", ValueType.LONG), + expressionVirtualColumn("v8", "div(div((\"__time\" - 907200000000),1000),604800)", ValueType.LONG) + ) + .columns("v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8") + .limit(2) + .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .context(QUERY_CONTEXT_DEFAULT) + .build() + + ), + ImmutableList.of( + new Object[]{365, 366, 23, 1, 57, 2, 3, 13, 65}, + new Object[]{366, 365, 47, 1441, 86457, 2, 3, 13, 65} + ) + ); + } + + @Test + public void testTimestampCeil() throws Exception + { + testQuery( + "SELECT CEIL(TIMESTAMP '2000-01-01 00:00:00' TO DAY), \n" + + "CEIL(TIMESTAMP '2000-01-01 01:00:00' TO DAY) \n" + + "FROM druid.foo\n" + + "LIMIT 1", + ImmutableList.of( + newScanQueryBuilder() + .dataSource(CalciteTests.DATASOURCE1) + .intervals(querySegmentSpec(Filtration.eternity())) + .virtualColumns( + expressionVirtualColumn("v0", "946684800000", ValueType.LONG), + expressionVirtualColumn("v1", "946771200000", ValueType.LONG) + ) + .columns("v0", "v1") + .limit(1) + .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .context(QUERY_CONTEXT_DEFAULT) + .build() + + ), + ImmutableList.of( + new Object[]{ + Calcites.jodaToCalciteTimestamp( + DateTimes.of("2000-01-01"), + DateTimeZone.UTC + ), + Calcites.jodaToCalciteTimestamp( + DateTimes.of("2000-01-02"), + DateTimeZone.UTC + ) + } + ) + ); + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
