diff --git a/docs/changelog/131341.yaml b/docs/changelog/131341.yaml
new file mode 100644
index 0000000000000..d89efddf9e014
--- /dev/null
+++ b/docs/changelog/131341.yaml
@@ -0,0 +1,5 @@
+pr: 131341
+summary: Consider min/max from predicates when transform date_trunc/bucket to `round_to`
+area: ES|QL
+type: enhancement
+issues: []
diff --git a/docs/changelog/132143.yaml b/docs/changelog/132143.yaml
new file mode 100644
index 0000000000000..e26e62462ec62
--- /dev/null
+++ b/docs/changelog/132143.yaml
@@ -0,0 +1,6 @@
+pr: 132143
+summary: Consider min/max from predicates when transform date_trunc/bucket to `round_to`
+ option 2
+area: ES|QL
+type: enhancement
+issues: []
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec
index 49b16baf30f58..06ac461cb6c62 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec
@@ -884,3 +884,108 @@ c:long | b:datetime | yr:datetime
9 | 1989-01-01T00:00:00.000Z | 1988-01-01T00:00:00.000Z
13 | 1990-01-01T00:00:00.000Z | 1989-01-01T00:00:00.000Z
;
+
+bucketYearInAggWithGTOutOfRange#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| WHERE hire_date >= "2000-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(hire_date, 1 month)
+| SORT bucket;
+
+COUNT(*):long | bucket:date
+;
+
+bucketYearInAggWithLTOutOfRange#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| WHERE hire_date <= "1980-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(hire_date, 1 year)
+| SORT bucket;
+
+COUNT(*):long | bucket:date
+;
+
+bucketYearInAggWithGTLTOutOfRange#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| WHERE hire_date <= "1980-01-01T00:00:00Z" and hire_date >= "1970-01-01"
+| STATS COUNT(*) by bucket = BUCKET(hire_date, 1 week)
+| SORT bucket;
+
+COUNT(*):long | bucket:date
+;
+
+bucketYearInAggWithEQOutOfRange#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| WHERE hire_date == "1980-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(hire_date, 1 hour)
+| SORT bucket;
+
+COUNT(*):long | bucket:date
+;
+
+bucketWithRename#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| RENAME hire_date as x, x as y
+| WHERE y >= "1980-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(y, 1 hour)
+| SORT bucket
+| LIMIT 5
+;
+
+COUNT(*):long | bucket:datetime
+1 | 1985-02-18T00:00:00.000Z
+1 | 1985-02-24T00:00:00.000Z
+1 | 1985-05-13T00:00:00.000Z
+1 | 1985-07-09T00:00:00.000Z
+1 | 1985-09-17T00:00:00.000Z
+;
+
+bucketWithEval#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| EVAL x = hire_date
+| WHERE x >= "1980-01-01T00:00:00Z" and hire_date <= "1990-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(x, 1 hour)
+| SORT bucket
+| LIMIT 5
+;
+
+COUNT(*):long | bucket:datetime
+1 | 1985-02-18T00:00:00.000Z
+1 | 1985-02-24T00:00:00.000Z
+1 | 1985-05-13T00:00:00.000Z
+1 | 1985-07-09T00:00:00.000Z
+1 | 1985-09-17T00:00:00.000Z
+;
+
+bucketWithEvalExpression#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| EVAL x = hire_date + 1 year
+| WHERE x >= "1980-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(x, 1 hour)
+| SORT bucket
+| LIMIT 5
+;
+
+COUNT(*):long | bucket:datetime
+1 | 1986-02-18T00:00:00.000Z
+1 | 1986-02-24T00:00:00.000Z
+1 | 1986-05-13T00:00:00.000Z
+1 | 1986-07-09T00:00:00.000Z
+1 | 1986-09-17T00:00:00.000Z
+;
+
+bucketWithRenameEvalExpression#[skip:-8.13.99, reason:BUCKET renamed in 8.14]
+FROM employees
+| EVAL x = hire_date + 1 year
+| RENAME x as y
+| WHERE y >= "1980-01-01T00:00:00Z"
+| STATS COUNT(*) by bucket = BUCKET(y, 1 hour)
+| SORT bucket
+| LIMIT 5
+;
+
+COUNT(*):long | bucket:datetime
+1 | 1986-02-18T00:00:00.000Z
+1 | 1986-02-24T00:00:00.000Z
+1 | 1986-05-13T00:00:00.000Z
+1 | 1986-07-09T00:00:00.000Z
+1 | 1986-09-17T00:00:00.000Z
+;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec
index 4b9e1512844b4..788a5f9877dea 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date.csv-spec
@@ -1581,4 +1581,258 @@ x:date | y:date
;
+evalDateTruncMonthIntervalWithGTEInRange
+FROM employees
+| SORT hire_date
+| WHERE hire_date >= "1990-01-01"
+| EVAL x = date_trunc(1 month, hire_date)
+| KEEP emp_no, hire_date, x
+| LIMIT 5;
+
+emp_no:integer | hire_date:date | x:date
+10082 | 1990-01-03T00:00:00.000Z | 1990-01-01T00:00:00.000Z
+10096 | 1990-01-14T00:00:00.000Z | 1990-01-01T00:00:00.000Z
+10011 | 1990-01-22T00:00:00.000Z | 1990-01-01T00:00:00.000Z
+10056 | 1990-02-01T00:00:00.000Z | 1990-02-01T00:00:00.000Z
+10086 | 1990-02-16T00:00:00.000Z | 1990-02-01T00:00:00.000Z
+;
+
+evalDateTruncHoursIntervalWithLTEInRange
+FROM employees
+| SORT hire_date desc
+| WHERE hire_date <= "1990-01-01"
+| EVAL x = date_trunc(240 hours, hire_date)
+| KEEP emp_no, hire_date, x
+| LIMIT 5;
+
+emp_no:integer | hire_date:date | x:date
+10023 | 1989-12-17T00:00:00.000Z | 1989-12-17T00:00:00.000Z
+10041 | 1989-11-12T00:00:00.000Z | 1989-11-07T00:00:00.000Z
+10069 | 1989-11-05T00:00:00.000Z | 1989-10-28T00:00:00.000Z
+10092 | 1989-09-22T00:00:00.000Z | 1989-09-18T00:00:00.000Z
+10038 | 1989-09-20T00:00:00.000Z | 1989-09-18T00:00:00.000Z
+;
+
+evalDateTruncWeeklyIntervalWithLTGTInRange
+from employees
+| SORT hire_date
+| WHERE hire_date > "1986-01-01" and hire_date < "1988-01-01"
+| EVAL x = date_trunc(1 week, hire_date)
+| KEEP emp_no, hire_date, x
+| LIMIT 5;
+
+emp_no:integer | hire_date:date | x:date
+10053 | 1986-02-04T00:00:00.000Z | 1986-02-03T00:00:00.000Z
+10066 | 1986-02-26T00:00:00.000Z | 1986-02-24T00:00:00.000Z
+10090 | 1986-03-14T00:00:00.000Z | 1986-03-10T00:00:00.000Z
+10079 | 1986-03-27T00:00:00.000Z | 1986-03-24T00:00:00.000Z
+10001 | 1986-06-26T00:00:00.000Z | 1986-06-23T00:00:00.000Z
+;
+
+evalDateTruncQuarterlyIntervalWithGTInRange
+from employees
+| SORT hire_date
+| WHERE hire_date > "1980-01-01"
+| EVAL x = date_trunc(3 month, hire_date)
+| KEEP emp_no, hire_date, x
+| LIMIT 5;
+
+emp_no:integer | hire_date:date | x:date
+10009 | 1985-02-18T00:00:00.000Z | 1985-01-01T00:00:00.000Z
+10048 | 1985-02-24T00:00:00.000Z | 1985-01-01T00:00:00.000Z
+10098 | 1985-05-13T00:00:00.000Z | 1985-04-01T00:00:00.000Z
+10076 | 1985-07-09T00:00:00.000Z | 1985-07-01T00:00:00.000Z
+10061 | 1985-09-17T00:00:00.000Z | 1985-07-01T00:00:00.000Z
+;
+
+dateTruncGroupingYearIntervalWithLTInRange
+from employees
+| WHERE hire_date < "2025-01-01"
+| EVAL y = date_trunc(1 year, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1985-01-01T00:00:00.000Z | 11
+1986-01-01T00:00:00.000Z | 11
+1987-01-01T00:00:00.000Z | 15
+1988-01-01T00:00:00.000Z | 9
+1989-01-01T00:00:00.000Z | 13
+;
+
+dateTruncGroupingYearIntervalWithLTOutOfRange
+from employees
+| WHERE hire_date < "1980-01-01"
+| EVAL y = date_trunc(1 year, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+;
+
+dateTruncGroupingYearIntervalWithGTOutOfRange
+from employees
+| WHERE hire_date > "2000-01-01"
+| EVAL y = date_trunc(1 year, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+;
+dateTruncGroupingMonthIntervalWithLTGTInRange
+from employees
+| WHERE hire_date > "1987-01-01" and hire_date < "1988-01-01"
+| EVAL y = date_trunc(1 month, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncGroupingDayIntervalWithEQInRange
+from employees
+| WHERE hire_date == "1988-02-10"
+| EVAL y = date_trunc(1 day, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1988-02-10T00:00:00.000Z | 1
+;
+
+dateTruncGroupingDayIntervalWithEQOutOfRange
+from employees
+| WHERE hire_date == "2025-01-01"
+| EVAL y = date_trunc(1 day, hire_date)
+| stats c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+;
+
+dateTruncWithEval
+from employees
+| EVAL x = hire_date
+| WHERE x > "1987-01-01" and hire_date < "1988-01-01"
+| EVAL y = date_trunc(1 month, x)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncWithEvalExpression
+from employees
+| EVAL x = hire_date + 1 year
+| WHERE x > "1987-01-01" and x < "1988-01-01"
+| EVAL y = date_trunc(1 month, x)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-02-01T00:00:00.000Z | 2
+1987-03-01T00:00:00.000Z | 2
+1987-06-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncWithRename
+FROM employees
+| RENAME hire_date as x
+| WHERE x > "1987-01-01" and x < "1988-01-01"
+| EVAL y = date_trunc(1 month, x)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncWithRenameChain
+FROM employees
+| RENAME hire_date as a, a as x
+| WHERE x > "1987-01-01" and x < "1988-01-01"
+| EVAL y = date_trunc(1 month, x)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncWithRenameBack
+FROM employees
+| RENAME hire_date as x, x as hire_date
+| WHERE hire_date > "1987-01-01" and hire_date < "1988-01-01"
+| EVAL y = date_trunc(1 month, hire_date)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
+
+dateTruncWithEvalRename
+FROM employees
+| EVAL a = hire_date
+| RENAME hire_date as b
+| WHERE a > "1987-01-01" and a < "1988-01-01"
+| EVAL y = date_trunc(1 month, b)
+| STATS c = count(emp_no) by y
+| SORT y
+| KEEP y, c
+| LIMIT 5;
+
+y:date | c:long
+1987-03-01T00:00:00.000Z | 5
+1987-04-01T00:00:00.000Z | 3
+1987-05-01T00:00:00.000Z | 1
+1987-07-01T00:00:00.000Z | 1
+1987-08-01T00:00:00.000Z | 2
+;
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/LocalSurrogateExpression.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/LocalSurrogateExpression.java
deleted file mode 100644
index f0401ae1d4f05..0000000000000
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/LocalSurrogateExpression.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression;
-
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.stats.SearchStats;
-
-/**
- * Interface signaling to the local logical plan optimizer that the declaring expression
- * has to be replaced by a different form.
- * Implement this on {@code Function}s when:
- *
- *
The expression can be rewritten to another expression on data node, with the statistics available in SearchStats.
- * Like {@code DateTrunc} and {@code Bucket} could be rewritten to {@code RoundTo} with the min/max values on the date field.
- *
- *
- */
-public interface LocalSurrogateExpression {
- /**
- * Returns the expression to be replaced by or {@code null} if this cannot be replaced.
- */
- Expression surrogate(SearchStats searchStats);
-}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java
index 01bc4dd2b4eec..131544e560e5c 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java
@@ -25,7 +25,6 @@
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.expression.LocalSurrogateExpression;
import org.elasticsearch.xpack.esql.expression.function.Example;
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
import org.elasticsearch.xpack.esql.expression.function.FunctionType;
@@ -36,7 +35,6 @@
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Div;
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Mul;
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
-import org.elasticsearch.xpack.esql.stats.SearchStats;
import java.io.IOException;
import java.util.ArrayList;
@@ -50,7 +48,6 @@
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNumeric;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType;
import static org.elasticsearch.xpack.esql.expression.Validations.isFoldable;
-import static org.elasticsearch.xpack.esql.expression.function.scalar.date.DateTrunc.maybeSubstituteWithRoundTo;
import static org.elasticsearch.xpack.esql.session.Configuration.DEFAULT_TZ;
import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateTimeToLong;
@@ -63,8 +60,7 @@
public class Bucket extends GroupingFunction.EvaluatableGroupingFunction
implements
PostOptimizationVerificationAware,
- TwoOptionalArguments,
- LocalSurrogateExpression {
+ TwoOptionalArguments {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Bucket", Bucket::new);
// TODO maybe we should just cover the whole of representable dates here - like ten years, 100 years, 1000 years, all the way up.
@@ -305,7 +301,7 @@ private Rounding.Prepared getDateRounding(FoldContext foldContext) {
return getDateRounding(foldContext, null, null);
}
- private Rounding.Prepared getDateRounding(FoldContext foldContext, Long min, Long max) {
+ public Rounding.Prepared getDateRounding(FoldContext foldContext, Long min, Long max) {
assert field.dataType() == DataType.DATETIME || field.dataType() == DataType.DATE_NANOS : "expected date type; got " + field;
if (buckets.dataType().isWholeNumber()) {
int b = ((Number) buckets.fold(foldContext)).intValue();
@@ -496,17 +492,4 @@ public Expression to() {
public String toString() {
return "Bucket{" + "field=" + field + ", buckets=" + buckets + ", from=" + from + ", to=" + to + '}';
}
-
- @Override
- public Expression surrogate(SearchStats searchStats) {
- // LocalSubstituteSurrogateExpressions should make sure this doesn't happen
- assert searchStats != null : "SearchStats cannot be null";
- return maybeSubstituteWithRoundTo(
- source(),
- field(),
- buckets(),
- searchStats,
- (interval, minValue, maxValue) -> getDateRounding(FoldContext.small(), minValue, maxValue)
- );
- }
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java
index 9b4d312e9df42..a4a63c0fdca47 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTrunc.java
@@ -8,7 +8,6 @@
package org.elasticsearch.xpack.esql.expression.function.scalar.date;
import org.elasticsearch.common.Rounding;
-import org.elasticsearch.common.TriFunction;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -17,53 +16,38 @@
import org.elasticsearch.compute.ann.Fixed;
import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator;
import org.elasticsearch.core.TimeValue;
-import org.elasticsearch.logging.LogManager;
-import org.elasticsearch.logging.Logger;
import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
-import org.elasticsearch.xpack.esql.core.expression.FoldContext;
-import org.elasticsearch.xpack.esql.core.expression.Literal;
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.core.type.MultiTypeEsField;
-import org.elasticsearch.xpack.esql.expression.LocalSurrogateExpression;
import org.elasticsearch.xpack.esql.expression.function.Example;
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
import org.elasticsearch.xpack.esql.expression.function.Param;
import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction;
-import org.elasticsearch.xpack.esql.expression.function.scalar.math.RoundTo;
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
-import org.elasticsearch.xpack.esql.stats.SearchStats;
import java.io.IOException;
import java.time.Duration;
import java.time.Period;
import java.time.ZoneId;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType;
import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME;
import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS;
-import static org.elasticsearch.xpack.esql.core.type.DataType.isDateTime;
import static org.elasticsearch.xpack.esql.session.Configuration.DEFAULT_TZ;
-import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.dateWithTypeToString;
-public class DateTrunc extends EsqlScalarFunction implements LocalSurrogateExpression {
+public class DateTrunc extends EsqlScalarFunction {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
Expression.class,
"DateTrunc",
DateTrunc::new
);
- private static final Logger logger = LogManager.getLogger(DateTrunc.class);
-
@FunctionalInterface
public interface DateTruncFactoryProvider {
ExpressionEvaluator.Factory apply(Source source, ExpressionEvaluator.Factory lhs, Rounding.Prepared rounding);
@@ -121,11 +105,11 @@ public String getWriteableName() {
return ENTRY.name;
}
- Expression interval() {
+ public Expression interval() {
return interval;
}
- Expression field() {
+ public Expression field() {
return timestampField;
}
@@ -285,56 +269,4 @@ public static ExpressionEvaluator.Factory evaluator(
) {
return evaluatorMap.get(forType).apply(source, fieldEvaluator, rounding);
}
-
- @Override
- public Expression surrogate(SearchStats searchStats) {
- // LocalSubstituteSurrogateExpressions should make sure this doesn't happen
- assert searchStats != null : "SearchStats cannot be null";
- return maybeSubstituteWithRoundTo(
- source(),
- field(),
- interval(),
- searchStats,
- (interval, minValue, maxValue) -> createRounding(interval, DEFAULT_TZ, minValue, maxValue)
- );
- }
-
- public static RoundTo maybeSubstituteWithRoundTo(
- Source source,
- Expression field,
- Expression foldableTimeExpression,
- SearchStats searchStats,
- TriFunction