Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder;
import org.elasticsearch.compute.data.Page;
import org.elasticsearch.logging.Logger;
import org.elasticsearch.search.DocValueFormat;
Expand Down Expand Up @@ -40,6 +41,7 @@
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.unsignedLongAsNumber;
import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN;
import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO;
import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.aggregateMetricDoubleLiteralToString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -409,6 +411,11 @@ private static Object convertExpectedValue(Type expectedType, Object expectedVal
case Type.VERSION -> // convert BytesRef-packed Version to String
rebuildExpected(expectedValue, BytesRef.class, x -> new Version((BytesRef) x).toString());
case UNSIGNED_LONG -> rebuildExpected(expectedValue, Long.class, x -> unsignedLongAsNumber((long) x));
case AGGREGATE_METRIC_DOUBLE -> rebuildExpected(
expectedValue,
AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral.class,
x -> aggregateMetricDoubleLiteralToString((AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral) x)
);
default -> expectedValue;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.common.time.DateFormatters;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder;
import org.elasticsearch.compute.data.Block;
import org.elasticsearch.compute.data.BlockFactory;
import org.elasticsearch.compute.data.BlockUtils;
Expand Down Expand Up @@ -62,6 +63,7 @@
import static org.elasticsearch.xpack.esql.core.util.NumericUtils.asLongUnsigned;
import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN;
import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO;
import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.stringToAggregateMetricDoubleLiteral;

public final class CsvTestUtils {
private static final int MAX_WIDTH = 80;
Expand Down Expand Up @@ -480,6 +482,10 @@ public enum Type {
CARTESIAN_POINT(x -> x == null ? null : CARTESIAN.wktToWkb(x), BytesRef.class),
GEO_SHAPE(x -> x == null ? null : GEO.wktToWkb(x), BytesRef.class),
CARTESIAN_SHAPE(x -> x == null ? null : CARTESIAN.wktToWkb(x), BytesRef.class),
AGGREGATE_METRIC_DOUBLE(
x -> x == null ? null : stringToAggregateMetricDoubleLiteral(x),
AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral.class
),
UNSUPPORTED(Type::convertUnsupported, Void.class);

private static Void convertUnsupported(String s) {
Expand Down Expand Up @@ -560,11 +566,18 @@ public static Type asType(ElementType elementType, Type actualType) {
case BYTES_REF -> bytesRefBlockType(actualType);
case BOOLEAN -> BOOLEAN;
case DOC -> throw new IllegalArgumentException("can't assert on doc blocks");
case COMPOSITE -> throw new IllegalArgumentException("can't assert on composite blocks");
case COMPOSITE -> compositeBlockType(actualType);
case UNKNOWN -> throw new IllegalArgumentException("Unknown block types cannot be handled");
};
}

private static Type compositeBlockType(Type actualType) {
return switch (actualType) {
case AGGREGATE_METRIC_DOUBLE -> actualType;
default -> throw new IllegalArgumentException("can't assert on composite blocks that aren't aggregate metric doubles");
};
}

private static Type bytesRefBlockType(Type actualType) {
return switch (actualType) {
case NULL -> NULL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,31 @@ emp_no:integer | birth_date:datetime
10097 | 1952-02-27T00:00:00.000Z
10100 | 1953-04-21T00:00:00.000Z
;

convertToAggregateMetricDouble
required_capability: aggregate_metric_double_convert_to
//tag::toAggregateMetricDouble[]
ROW x = 3892095203
| EVAL agg_metric = TO_AGGREGATE_METRIC_DOUBLE(x)
//end::toAggregateMetricDouble[]
;

//tag::toAggregateMetricDouble-result[]
x:long | agg_metric:aggregate_metric_double
3892095203 | {"min":3892095203.0,"max":3892095203.0,"sum":3892095203.0,"value_count":1}
//end::toAggregateMetricDouble-result[]
;

convertToAggregateMetricDoubleMv
required_capability: aggregate_metric_double_convert_to
//tag::toAggregateMetricDoubleMv[]
ROW x = [5032, 11111, 40814]
| EVAL agg_metric = TO_AGGREGATE_METRIC_DOUBLE(x)
//end::toAggregateMetricDoubleMv[]
;

//tag::toAggregateMetricDoubleMv-result[]
x:integer | agg_metric:aggregate_metric_double
[5032, 11111, 40814] | {"min":5032.0,"max":40814.0,"sum":56957.0,"value_count":3}
//end::toAggregateMetricDoubleMv-result[]
;
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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.function.Example;
import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesTo;
import org.elasticsearch.xpack.esql.expression.function.FunctionAppliesToLifecycle;
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
Expand Down Expand Up @@ -67,14 +68,17 @@ public class ToAggregateMetricDouble extends AbstractConvertFunction {
@FunctionInfo(
returnType = "aggregate_metric_double",
description = "Encode a numeric to an aggregate_metric_double.",
examples = {
@Example(file = "convert", tag = "toAggregateMetricDouble"),
@Example(description = "The expression also accepts multi-values", file = "convert", tag = "toAggregateMetricDoubleMv") },
appliesTo = { @FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.COMING, version = "9.1") }
)
public ToAggregateMetricDouble(
Source source,
@Param(
name = "number",
type = { "double", "long", "unsigned_long", "integer", "aggregate_metric_double" },
description = "Input value. The input can be a single-valued column or an expression."
description = "Input value. The input can be a single- or multi-valued column or an expression."
) Expression field
) {
super(source, field);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateFormatters;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder;
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder.Metric;
import org.elasticsearch.compute.data.CompositeBlock;
import org.elasticsearch.compute.data.DoubleBlock;
Expand Down Expand Up @@ -701,6 +702,60 @@ public static String aggregateMetricDoubleBlockToString(CompositeBlock composite
}
}

public static String aggregateMetricDoubleLiteralToString(AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral aggMetric) {
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
builder.startObject();
if (aggMetric.min() != null) {
builder.field(Metric.MIN.getLabel(), aggMetric.min());
}
if (aggMetric.max() != null) {
builder.field(Metric.MAX.getLabel(), aggMetric.max());
}
if (aggMetric.sum() != null) {
builder.field(Metric.SUM.getLabel(), aggMetric.sum());
}
if (aggMetric.count() != null) {
builder.field(Metric.COUNT.getLabel(), aggMetric.count());
}
builder.endObject();
return Strings.toString(builder);
} catch (IOException e) {
throw new IllegalStateException("error rendering aggregate metric double", e);
}
}

public static AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral stringToAggregateMetricDoubleLiteral(String s) {
Double min = null;
Double max = null;
Double sum = null;
Integer count = null;
String[] values = s.substring(1, s.length() - 1).split(",");
for (String v : values) {
var pair = v.split(":");
String type = pair[0];
String number = pair[1];
switch (type) {
case "min":
min = Double.parseDouble(number);
break;
case "max":
max = Double.parseDouble(number);
break;
case "sum":
sum = Double.parseDouble(number);
break;
case "value_count":
count = Integer.parseInt(number);
break;
default:
throw new IllegalArgumentException(
"Received a metric that wasn't min, max, sum, or value_count: " + type + " with value: " + number
);
}
}
return new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral(min, max, sum, count);
}

public enum EsqlConverter implements Converter {

STRING_TO_DATE_PERIOD(x -> EsqlDataTypeConverter.parseTemporalAmount(x, DataType.DATE_PERIOD)),
Expand Down
Loading