diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/AttributeSort.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/AttributeSort.java deleted file mode 100644 index 7c87ee2d2959f..0000000000000 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/AttributeSort.java +++ /dev/null @@ -1,46 +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.core.querydsl.container; - -import org.elasticsearch.xpack.esql.core.expression.Attribute; - -import java.util.Objects; - -public class AttributeSort extends Sort { - - private final Attribute attribute; - - public AttributeSort(Attribute attribute, Direction direction, Missing missing) { - super(direction, missing); - this.attribute = attribute; - } - - public Attribute attribute() { - return attribute; - } - - @Override - public int hashCode() { - return Objects.hash(attribute, direction(), missing()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - AttributeSort other = (AttributeSort) obj; - return Objects.equals(direction(), other.direction()) - && Objects.equals(missing(), other.missing()) - && Objects.equals(attribute, other.attribute); - } -} diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/Sort.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/Sort.java deleted file mode 100644 index e6b3926745ea1..0000000000000 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/querydsl/container/Sort.java +++ /dev/null @@ -1,97 +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.core.querydsl.container; - -import org.elasticsearch.search.aggregations.bucket.composite.MissingOrder; -import org.elasticsearch.search.sort.SortOrder; -import org.elasticsearch.xpack.esql.core.expression.Order.NullsPosition; -import org.elasticsearch.xpack.esql.core.expression.Order.OrderDirection; - -public abstract class Sort { - - public enum Direction { - ASC, - DESC; - - public static Direction from(OrderDirection dir) { - return dir == null || dir == OrderDirection.ASC ? ASC : DESC; - } - - public SortOrder asOrder() { - return this == Direction.ASC ? SortOrder.ASC : SortOrder.DESC; - } - } - - public enum Missing { - FIRST("_first", MissingOrder.FIRST), - LAST("_last", MissingOrder.LAST), - /** - * Nulls position has not been specified by the user and an appropriate default will be used. - * - * The default values are chosen such that it stays compatible with previous behavior. Unfortunately, this results in - * inconsistencies across different types of queries (see https://github.com/elastic/elasticsearch/issues/77068). - */ - ANY(null, null); - - private final String searchOrder; - private final MissingOrder aggregationOrder; - - Missing(String searchOrder, MissingOrder aggregationOrder) { - this.searchOrder = searchOrder; - this.aggregationOrder = aggregationOrder; - } - - public static Missing from(NullsPosition pos) { - return switch (pos) { - case FIRST -> FIRST; - case LAST -> LAST; - default -> ANY; - }; - } - - public String searchOrder() { - return searchOrder(null); - } - - /** - * Preferred order of null values in non-aggregation queries. - */ - public String searchOrder(Direction fallbackDirection) { - if (searchOrder != null) { - return searchOrder; - } else { - return switch (fallbackDirection) { - case ASC -> LAST.searchOrder; - case DESC -> FIRST.searchOrder; - }; - } - } - - /** - * Preferred order of null values in aggregation queries. - */ - public MissingOrder aggregationOrder() { - return aggregationOrder; - } - } - - private final Direction direction; - private final Missing missing; - - protected Sort(Direction direction, Missing nulls) { - this.direction = direction; - this.missing = nulls; - } - - public Direction direction() { - return direction; - } - - public Missing missing() { - return missing; - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EsQueryExec.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EsQueryExec.java index b8f96709a583f..32d2186e4cce0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EsQueryExec.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/EsQueryExec.java @@ -11,12 +11,12 @@ import org.elasticsearch.index.IndexMode; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; +import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; import org.elasticsearch.xpack.esql.core.expression.Order; import org.elasticsearch.xpack.esql.core.index.EsIndex; -import org.elasticsearch.xpack.esql.core.querydsl.container.Sort; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.NodeUtils; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -46,8 +46,8 @@ public class EsQueryExec extends LeafExec implements EstimatesRowSize { public record FieldSort(FieldAttribute field, Order.OrderDirection direction, Order.NullsPosition nulls) { public FieldSortBuilder fieldSortBuilder() { FieldSortBuilder builder = new FieldSortBuilder(field.name()); - builder.order(Sort.Direction.from(direction).asOrder()); - builder.missing(Sort.Missing.from(nulls).searchOrder()); + builder.order(Direction.from(direction).asOrder()); + builder.missing(Missing.from(nulls).searchOrder()); builder.unmappedType(field.dataType().esType()); return builder; } @@ -206,4 +206,47 @@ public String nodeString() { + estimatedRowSize + "]"; } + + public enum Direction { + ASC, + DESC; + + public static Direction from(Order.OrderDirection dir) { + return dir == null || dir == Order.OrderDirection.ASC ? ASC : DESC; + } + + public SortOrder asOrder() { + return this == Direction.ASC ? SortOrder.ASC : SortOrder.DESC; + } + } + + public enum Missing { + FIRST("_first"), + LAST("_last"), + /** + * Nulls position has not been specified by the user and an appropriate default will be used. + * + * The default values are chosen such that it stays compatible with previous behavior. Unfortunately, this results in + * inconsistencies across different types of queries (see https://github.com/elastic/elasticsearch/issues/77068). + */ + ANY(null); + + private final String searchOrder; + + Missing(String searchOrder) { + this.searchOrder = searchOrder; + } + + public static Missing from(Order.NullsPosition pos) { + return switch (pos) { + case FIRST -> FIRST; + case LAST -> LAST; + default -> ANY; + }; + } + + public String searchOrder() { + return searchOrder; + } + } }