SQL: use calendar interval of 1y instead of fixed interval for grouping by YEAR and HISTOGRAMs (#47558)

(cherry picked from commit 55f5463eee4ecea3537df4b34645f1d87472a802)
This commit is contained in:
Andrei Stefan 2019-10-09 11:22:41 +03:00 committed by Andrei Stefan
parent 54c2aec38a
commit 75a7daae73
9 changed files with 180 additions and 130 deletions

View File

@ -86,6 +86,16 @@ the multiple of a day. E.g.: for `HISTOGRAM(CAST(birth_date AS DATE), INTERVAL '
actually used will be `INTERVAL '2' DAY`. If the interval specified is less than 1 day, e.g.: actually used will be `INTERVAL '2' DAY`. If the interval specified is less than 1 day, e.g.:
`HISTOGRAM(CAST(birth_date AS DATE), INTERVAL '20' HOUR)` then the interval used will be `INTERVAL '1' DAY`. `HISTOGRAM(CAST(birth_date AS DATE), INTERVAL '20' HOUR)` then the interval used will be `INTERVAL '1' DAY`.
[IMPORTANT]
All intervals specified for a date/time HISTOGRAM will use a <<search-aggregations-bucket-datehistogram-aggregation,fixed interval>>
in their `date_histogram` aggregation definition, with the notable exception of `INTERVAL '1' YEAR` where a calendar interval is used.
The choice for a calendar interval was made for having a more intuitive result for YEAR groupings. Calendar intervals consider a one year
bucket as the one starting on January 1st that specific year, whereas a fixed interval one-year-bucket considers one year as a number
of milliseconds (for example, `31536000000ms` corresponding to 365 days, 24 hours per day, 60 minutes per hour etc.). With fixed intervals,
the day of February 5th, 2019 for example, belongs to a bucket that starts on December 20th, 2018 and {es} (and implicitly {es-sql}) would
have returned the year 2018 for a date that's actually in 2019. With calendar interval this behavior is more intuitive, having the day of
February 5th, 2019 actually belonging to the 2019 year bucket.
[IMPORTANT] [IMPORTANT]
Histogram in SQL cannot be applied applied on **TIME** type. Histogram in SQL cannot be applied applied on **TIME** type.
E.g.: `HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES)` is currently not supported. E.g.: `HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES)` is currently not supported.

View File

@ -273,47 +273,46 @@ histogramDateTime
schema::h:ts|c:l schema::h:ts|c:l
SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY h; SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY h;
h | c h | c
--------------------+--------------- ------------------------+---------------
null |10 null |10
1951-04-11T00:00:00Z|1 1952-01-01T00:00:00.000Z|8
1952-04-05T00:00:00Z|10 1953-01-01T00:00:00.000Z|11
1953-03-31T00:00:00Z|10 1954-01-01T00:00:00.000Z|8
1954-03-26T00:00:00Z|7 1955-01-01T00:00:00.000Z|4
1955-03-21T00:00:00Z|4 1956-01-01T00:00:00.000Z|5
1956-03-15T00:00:00Z|4 1957-01-01T00:00:00.000Z|4
1957-03-10T00:00:00Z|6 1958-01-01T00:00:00.000Z|7
1958-03-05T00:00:00Z|6 1959-01-01T00:00:00.000Z|9
1959-02-28T00:00:00Z|9 1960-01-01T00:00:00.000Z|8
1960-02-23T00:00:00Z|7 1961-01-01T00:00:00.000Z|8
1961-02-17T00:00:00Z|8 1962-01-01T00:00:00.000Z|6
1962-02-12T00:00:00Z|6 1963-01-01T00:00:00.000Z|7
1963-02-07T00:00:00Z|7 1964-01-01T00:00:00.000Z|4
1964-02-02T00:00:00Z|5 1965-01-01T00:00:00.000Z|1
; ;
histogramDateTimeWithCountAndOrder histogramDateTimeWithCountAndOrder
schema::h:ts|c:l schema::h:ts|c:l
SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY h ORDER BY h DESC; SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY h ORDER BY h DESC;
h | c h | c
--------------------+--------------- ------------------------+---------------
1964-02-02T00:00:00Z|5 1965-01-01T00:00:00.000Z|1
1963-02-07T00:00:00Z|7 1964-01-01T00:00:00.000Z|4
1962-02-12T00:00:00Z|6 1963-01-01T00:00:00.000Z|7
1961-02-17T00:00:00Z|8 1962-01-01T00:00:00.000Z|6
1960-02-23T00:00:00Z|7 1961-01-01T00:00:00.000Z|8
1959-02-28T00:00:00Z|9 1960-01-01T00:00:00.000Z|8
1958-03-05T00:00:00Z|6 1959-01-01T00:00:00.000Z|9
1957-03-10T00:00:00Z|6 1958-01-01T00:00:00.000Z|7
1956-03-15T00:00:00Z|4 1957-01-01T00:00:00.000Z|4
1955-03-21T00:00:00Z|4 1956-01-01T00:00:00.000Z|5
1954-03-26T00:00:00Z|7 1955-01-01T00:00:00.000Z|4
1953-03-31T00:00:00Z|10 1954-01-01T00:00:00.000Z|8
1952-04-05T00:00:00Z|10 1953-01-01T00:00:00.000Z|11
1951-04-11T00:00:00Z|1 1952-01-01T00:00:00.000Z|8
null |10 null |10
; ;
histogramDateTimeWithMonthOnTop histogramDateTimeWithMonthOnTop
@ -369,23 +368,23 @@ histogramGroupByWithoutAlias
schema::h:ts|c:l schema::h:ts|c:l
SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY HISTOGRAM(birth_date, INTERVAL 1 YEAR) ORDER BY h DESC; SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) as c FROM test_emp GROUP BY HISTOGRAM(birth_date, INTERVAL 1 YEAR) ORDER BY h DESC;
h | c h | c
--------------------+--------------- ------------------------+---------------
1964-02-02T00:00:00Z|5 1965-01-01T00:00:00.000Z|1
1963-02-07T00:00:00Z|7 1964-01-01T00:00:00.000Z|4
1962-02-12T00:00:00Z|6 1963-01-01T00:00:00.000Z|7
1961-02-17T00:00:00Z|8 1962-01-01T00:00:00.000Z|6
1960-02-23T00:00:00Z|7 1961-01-01T00:00:00.000Z|8
1959-02-28T00:00:00Z|9 1960-01-01T00:00:00.000Z|8
1958-03-05T00:00:00Z|6 1959-01-01T00:00:00.000Z|9
1957-03-10T00:00:00Z|6 1958-01-01T00:00:00.000Z|7
1956-03-15T00:00:00Z|4 1957-01-01T00:00:00.000Z|4
1955-03-21T00:00:00Z|4 1956-01-01T00:00:00.000Z|5
1954-03-26T00:00:00Z|7 1955-01-01T00:00:00.000Z|4
1953-03-31T00:00:00Z|10 1954-01-01T00:00:00.000Z|8
1952-04-05T00:00:00Z|10 1953-01-01T00:00:00.000Z|11
1951-04-11T00:00:00Z|1 1952-01-01T00:00:00.000Z|8
null |10 null |10
; ;
countAll countAll

View File

@ -811,23 +811,23 @@ schema::h:ts|c:l
SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) AS c FROM emp GROUP BY h; SELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) AS c FROM emp GROUP BY h;
h | c h | c
--------------------+--------------- ------------------------+---------------
null |10 null |10
1951-04-11T00:00:00Z|1 1952-01-01T00:00:00.000Z|8
1952-04-05T00:00:00Z|10 1953-01-01T00:00:00.000Z|11
1953-03-31T00:00:00Z|10 1954-01-01T00:00:00.000Z|8
1954-03-26T00:00:00Z|7 1955-01-01T00:00:00.000Z|4
1955-03-21T00:00:00Z|4 1956-01-01T00:00:00.000Z|5
1956-03-15T00:00:00Z|4 1957-01-01T00:00:00.000Z|4
1957-03-10T00:00:00Z|6 1958-01-01T00:00:00.000Z|7
1958-03-05T00:00:00Z|6 1959-01-01T00:00:00.000Z|9
1959-02-28T00:00:00Z|9 1960-01-01T00:00:00.000Z|8
1960-02-23T00:00:00Z|7 1961-01-01T00:00:00.000Z|8
1961-02-17T00:00:00Z|8 1962-01-01T00:00:00.000Z|6
1962-02-12T00:00:00Z|6 1963-01-01T00:00:00.000Z|7
1963-02-07T00:00:00Z|7 1964-01-01T00:00:00.000Z|4
1964-02-02T00:00:00Z|5 1965-01-01T00:00:00.000Z|1
// end::histogramDateTime // end::histogramDateTime
; ;

View File

@ -101,13 +101,13 @@ SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages
mi:i | ma:i | year:i |ROUND(AVG(languages), 1):d|TRUNCATE(AVG(languages), 1):d| COUNT(*):l mi:i | ma:i | year:i |ROUND(AVG(languages), 1):d|TRUNCATE(AVG(languages), 1):d| COUNT(*):l
---------------+---------------+---------------+--------------------------+-----------------------------+--------------- ---------------+---------------+---------------+--------------------------+-----------------------------+---------------
25324 |70011 |1986 |3.0 |3.0 |15 25324 |70011 |1987 |3.0 |3.0 |15
25945 |73578 |1987 |2.9 |2.8 |9 25945 |73578 |1988 |2.9 |2.8 |9
25976 |74970 |1988 |3.0 |3.0 |13 25976 |74970 |1989 |3.0 |3.0 |13
31120 |71165 |1989 |3.1 |3.0 |12 31120 |71165 |1990 |3.1 |3.0 |12
30404 |58715 |1992 |3.0 |3.0 |3 30404 |58715 |1993 |3.0 |3.0 |3
35742 |67492 |1993 |2.8 |2.7 |4 35742 |67492 |1994 |2.8 |2.7 |4
45656 |45656 |1995 |3.0 |3.0 |1 45656 |45656 |1996 |3.0 |3.0 |1
; ;
minMaxRoundWithHavingRound minMaxRoundWithHavingRound
@ -115,17 +115,17 @@ SELECT MIN(salary) mi, MAX(salary) ma, YEAR(hire_date) year, ROUND(AVG(languages
mi:i | ma:i | year:i |ROUND(AVG(languages),1):d| COUNT(*):l mi:i | ma:i | year:i |ROUND(AVG(languages),1):d| COUNT(*):l
---------------+---------------+---------------+-------------------------+--------------- ---------------+---------------+---------------+-------------------------+---------------
26436 |74999 |1984 |3.1 |11 26436 |74999 |1985 |3.1 |11
31897 |61805 |1985 |3.5 |11 31897 |61805 |1986 |3.5 |11
25324 |70011 |1986 |3.0 |15 25324 |70011 |1987 |3.0 |15
25945 |73578 |1987 |2.9 |9 25945 |73578 |1988 |2.9 |9
25976 |74970 |1988 |3.0 |13 25976 |74970 |1989 |3.0 |13
31120 |71165 |1989 |3.1 |12 31120 |71165 |1990 |3.1 |12
32568 |65030 |1990 |3.3 |6 32568 |65030 |1991 |3.3 |6
27215 |60781 |1991 |4.1 |8 27215 |60781 |1992 |4.1 |8
30404 |58715 |1992 |3.0 |3 30404 |58715 |1993 |3.0 |3
35742 |67492 |1993 |2.8 |4 35742 |67492 |1994 |2.8 |4
45656 |45656 |1995 |3.0 |1 45656 |45656 |1996 |3.0 |1
; ;
groupByAndOrderByTruncateWithPositiveParameter groupByAndOrderByTruncateWithPositiveParameter

View File

@ -22,7 +22,13 @@ public abstract class DateTimeHistogramFunction extends DateTimeFunction {
} }
/** /**
* used for aggregration (date histogram) * used for aggregation (date histogram)
*/ */
public abstract long interval(); public long fixedInterval() {
return -1;
}
public String calendarInterval() {
return null;
}
} }

View File

@ -5,20 +5,20 @@
*/ */
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime; package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2; import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2;
import org.elasticsearch.xpack.sql.tree.Source;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.concurrent.TimeUnit;
/** /**
* Extract the year from a datetime. * Extract the year from a datetime.
*/ */
public class Year extends DateTimeHistogramFunction { public class Year extends DateTimeHistogramFunction {
private static long YEAR_IN_MILLIS = TimeUnit.DAYS.toMillis(1) * 365L; public static String YEAR_INTERVAL = DateHistogramInterval.YEAR.toString();
public Year(Source source, Expression field, ZoneId zoneId) { public Year(Source source, Expression field, ZoneId zoneId) {
super(source, field, zoneId, DateTimeExtractor.YEAR); super(source, field, zoneId, DateTimeExtractor.YEAR);
@ -45,7 +45,7 @@ public class Year extends DateTimeHistogramFunction {
} }
@Override @Override
public long interval() { public String calendarInterval() {
return YEAR_IN_MILLIS; return YEAR_INTERVAL;
} }
} }

View File

@ -41,9 +41,11 @@ import org.elasticsearch.xpack.sql.expression.function.grouping.Histogram;
import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeFunction;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeHistogramFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeHistogramFunction;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.Year;
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoShape; import org.elasticsearch.xpack.sql.expression.function.scalar.geo.GeoShape;
import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StDistance; import org.elasticsearch.xpack.sql.expression.function.scalar.geo.StDistance;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.expression.literal.IntervalYearMonth;
import org.elasticsearch.xpack.sql.expression.literal.Intervals; import org.elasticsearch.xpack.sql.expression.literal.Intervals;
import org.elasticsearch.xpack.sql.expression.predicate.Range; import org.elasticsearch.xpack.sql.expression.predicate.Range;
import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MatchQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MatchQueryPredicate;
@ -109,6 +111,7 @@ import org.elasticsearch.xpack.sql.util.DateUtils;
import org.elasticsearch.xpack.sql.util.ReflectionUtils; import org.elasticsearch.xpack.sql.util.ReflectionUtils;
import java.time.OffsetTime; import java.time.OffsetTime;
import java.time.Period;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -279,7 +282,11 @@ final class QueryTranslator {
// dates are handled differently because of date histograms // dates are handled differently because of date histograms
if (exp instanceof DateTimeHistogramFunction) { if (exp instanceof DateTimeHistogramFunction) {
DateTimeHistogramFunction dthf = (DateTimeHistogramFunction) exp; DateTimeHistogramFunction dthf = (DateTimeHistogramFunction) exp;
key = new GroupByDateHistogram(aggId, nameOf(exp), dthf.interval(), dthf.zoneId()); if (dthf.calendarInterval() != null) {
key = new GroupByDateHistogram(aggId, nameOf(exp), dthf.calendarInterval(), dthf.zoneId());
} else {
key = new GroupByDateHistogram(aggId, nameOf(exp), dthf.fixedInterval(), dthf.zoneId());
}
} }
// all other scalar functions become a script // all other scalar functions become a script
else if (exp instanceof ScalarFunction) { else if (exp instanceof ScalarFunction) {
@ -294,19 +301,33 @@ final class QueryTranslator {
// date histogram // date histogram
if (h.dataType().isDateBased()) { if (h.dataType().isDateBased()) {
long intervalAsMillis = Intervals.inMillis(h.interval()); Object value = h.interval().value();
if (value instanceof IntervalYearMonth
// When the histogram in SQL is applied on DATE type instead of DATETIME, the interval && ((IntervalYearMonth) value).interval().equals(Period.of(1, 0, 0))) {
// specified is truncated to the multiple of a day. If the interval specified is less String calendarInterval = Year.YEAR_INTERVAL;
// than 1 day, then the interval used will be `INTERVAL '1' DAY`.
if (h.dataType() == DATE) { // When the histogram is `INTERVAL '1' YEAR`, the interval used in the ES date_histogram will be
intervalAsMillis = DateUtils.minDayInterval(intervalAsMillis); // a calendar_interval with value "1y". All other intervals will be fixed_intervals expressed in ms.
} if (field instanceof FieldAttribute) {
key = new GroupByDateHistogram(aggId, nameOf(field), calendarInterval, h.zoneId());
if (field instanceof FieldAttribute) { } else if (field instanceof Function) {
key = new GroupByDateHistogram(aggId, nameOf(field), intervalAsMillis, h.zoneId()); key = new GroupByDateHistogram(aggId, ((Function) field).asScript(), calendarInterval, h.zoneId());
} else if (field instanceof Function) { }
key = new GroupByDateHistogram(aggId, ((Function) field).asScript(), intervalAsMillis, h.zoneId()); } else {
long intervalAsMillis = Intervals.inMillis(h.interval());
// When the histogram in SQL is applied on DATE type instead of DATETIME, the interval
// specified is truncated to the multiple of a day. If the interval specified is less
// than 1 day, then the interval used will be `INTERVAL '1' DAY`.
if (h.dataType() == DATE) {
intervalAsMillis = DateUtils.minDayInterval(intervalAsMillis);
}
if (field instanceof FieldAttribute) {
key = new GroupByDateHistogram(aggId, nameOf(field), intervalAsMillis, h.zoneId());
} else if (field instanceof Function) {
key = new GroupByDateHistogram(aggId, ((Function) field).asScript(), intervalAsMillis, h.zoneId());
}
} }
} }
// numeric histogram // numeric histogram

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.sql.querydsl.agg;
import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder; import org.elasticsearch.search.aggregations.bucket.composite.CompositeValuesSourceBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.DateHistogramValuesSourceBuilder; import org.elasticsearch.search.aggregations.bucket.composite.DateHistogramValuesSourceBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction; import org.elasticsearch.xpack.sql.querydsl.container.Sort.Direction;
@ -19,52 +20,65 @@ import java.util.Objects;
*/ */
public class GroupByDateHistogram extends GroupByKey { public class GroupByDateHistogram extends GroupByKey {
private final long interval; private final long fixedInterval;
private final String calendarInterval;
private final ZoneId zoneId; private final ZoneId zoneId;
public GroupByDateHistogram(String id, String fieldName, long interval, ZoneId zoneId) { public GroupByDateHistogram(String id, String fieldName, long fixedInterval, ZoneId zoneId) {
this(id, fieldName, null, null, interval, zoneId); this(id, fieldName, null, null, fixedInterval, null, zoneId);
} }
public GroupByDateHistogram(String id, ScriptTemplate script, long interval, ZoneId zoneId) { public GroupByDateHistogram(String id, ScriptTemplate script, long fixedInterval, ZoneId zoneId) {
this(id, null, script, null, interval, zoneId); this(id, null, script, null, fixedInterval, null, zoneId);
}
public GroupByDateHistogram(String id, String fieldName, String calendarInterval, ZoneId zoneId) {
this(id, fieldName, null, null, -1L, calendarInterval, zoneId);
}
public GroupByDateHistogram(String id, ScriptTemplate script, String calendarInterval, ZoneId zoneId) {
this(id, null, script, null, -1L, calendarInterval, zoneId);
} }
private GroupByDateHistogram(String id, String fieldName, ScriptTemplate script, Direction direction, long interval, private GroupByDateHistogram(String id, String fieldName, ScriptTemplate script, Direction direction, long fixedInterval,
ZoneId zoneId) { String calendarInterval, ZoneId zoneId) {
super(id, fieldName, script, direction); super(id, fieldName, script, direction);
this.interval = interval; if (fixedInterval <= 0 && (calendarInterval == null || calendarInterval.trim().isEmpty())) {
throw new SqlIllegalArgumentException("Either fixed interval or calendar interval needs to be specified");
}
this.fixedInterval = fixedInterval;
this.calendarInterval = calendarInterval;
this.zoneId = zoneId; this.zoneId = zoneId;
} }
// For testing // For testing
public long interval() { public long fixedInterval() {
return interval; return fixedInterval;
} }
@Override @Override
protected CompositeValuesSourceBuilder<?> createSourceBuilder() { protected CompositeValuesSourceBuilder<?> createSourceBuilder() {
return new DateHistogramValuesSourceBuilder(id()) DateHistogramValuesSourceBuilder builder = new DateHistogramValuesSourceBuilder(id()).timeZone(zoneId);
.fixedInterval(new DateHistogramInterval(interval + "ms")) return calendarInterval != null ? builder.calendarInterval(new DateHistogramInterval(calendarInterval))
.timeZone(zoneId); : builder.fixedInterval(new DateHistogramInterval(fixedInterval + "ms"));
} }
@Override @Override
protected GroupByKey copy(String id, String fieldName, ScriptTemplate script, Direction direction) { protected GroupByKey copy(String id, String fieldName, ScriptTemplate script, Direction direction) {
return new GroupByDateHistogram(id, fieldName, script, direction, interval, zoneId); return new GroupByDateHistogram(id, fieldName, script, direction, fixedInterval, calendarInterval, zoneId);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), interval, zoneId); return Objects.hash(super.hashCode(), fixedInterval, calendarInterval, zoneId);
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (super.equals(obj)) { if (super.equals(obj)) {
GroupByDateHistogram other = (GroupByDateHistogram) obj; GroupByDateHistogram other = (GroupByDateHistogram) obj;
return Objects.equals(interval, other.interval) return Objects.equals(fixedInterval, other.fixedInterval)
&& Objects.equals(calendarInterval, other.calendarInterval)
&& Objects.equals(zoneId, other.zoneId); && Objects.equals(zoneId, other.zoneId);
} }
return false; return false;

View File

@ -915,7 +915,7 @@ public class QueryTranslatorTests extends ESTestCase {
assertEquals(DataType.INTEGER, eqe.output().get(0).dataType()); assertEquals(DataType.INTEGER, eqe.output().get(0).dataType());
assertThat(eqe.queryContainer().aggs().asAggBuilder().toString().replaceAll("\\s+", ""), assertThat(eqe.queryContainer().aggs().asAggBuilder().toString().replaceAll("\\s+", ""),
endsWith("\"date_histogram\":{\"field\":\"date\",\"missing_bucket\":true,\"value_type\":\"date\",\"order\":\"asc\"," endsWith("\"date_histogram\":{\"field\":\"date\",\"missing_bucket\":true,\"value_type\":\"date\",\"order\":\"asc\","
+ "\"fixed_interval\":\"31536000000ms\",\"time_zone\":\"Z\"}}}]}}}")); + "\"calendar_interval\":\"1y\",\"time_zone\":\"Z\"}}}]}}}"));
} }
public void testGroupByHistogramWithDate() { public void testGroupByHistogramWithDate() {
@ -940,7 +940,7 @@ public class QueryTranslatorTests extends ESTestCase {
EsQueryExec eqe = (EsQueryExec) p; EsQueryExec eqe = (EsQueryExec) p;
assertEquals(1, eqe.queryContainer().aggs().groups().size()); assertEquals(1, eqe.queryContainer().aggs().groups().size());
assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass()); assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass());
assertEquals(86400000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).interval()); assertEquals(86400000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).fixedInterval());
} }
public void testGroupByHistogramWithDateTruncateIntervalToDayMultiples() { public void testGroupByHistogramWithDateTruncateIntervalToDayMultiples() {
@ -951,7 +951,7 @@ public class QueryTranslatorTests extends ESTestCase {
EsQueryExec eqe = (EsQueryExec) p; EsQueryExec eqe = (EsQueryExec) p;
assertEquals(1, eqe.queryContainer().aggs().groups().size()); assertEquals(1, eqe.queryContainer().aggs().groups().size());
assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass()); assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass());
assertEquals(172800000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).interval()); assertEquals(172800000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).fixedInterval());
} }
{ {
PhysicalPlan p = optimizeAndPlan("SELECT MAX(int) FROM test GROUP BY " + PhysicalPlan p = optimizeAndPlan("SELECT MAX(int) FROM test GROUP BY " +
@ -960,7 +960,7 @@ public class QueryTranslatorTests extends ESTestCase {
EsQueryExec eqe = (EsQueryExec) p; EsQueryExec eqe = (EsQueryExec) p;
assertEquals(1, eqe.queryContainer().aggs().groups().size()); assertEquals(1, eqe.queryContainer().aggs().groups().size());
assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass()); assertEquals(GroupByDateHistogram.class, eqe.queryContainer().aggs().groups().get(0).getClass());
assertEquals(259200000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).interval()); assertEquals(259200000L, ((GroupByDateHistogram) eqe.queryContainer().aggs().groups().get(0)).fixedInterval());
} }
} }