diff --git a/.swp b/.swp deleted file mode 100644 index 1269dcf1d1617..0000000000000 Binary files a/.swp and /dev/null differ diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/stddev_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/description/stddev_over_time.md new file mode 100644 index 0000000000000..42db5b4412aa9 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/stddev_over_time.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +Calculates the population standard deviation over time of a numeric field. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/stdvar_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/description/stdvar_over_time.md new file mode 100644 index 0000000000000..16ec531dba29f --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/stdvar_over_time.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +Calculates the population variance over time of a numeric field. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/description/variance.md b/docs/reference/query-languages/esql/_snippets/functions/description/variance.md new file mode 100644 index 0000000000000..d9b489b9037bd --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/description/variance.md @@ -0,0 +1,6 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Description** + +The population variance of a numeric field. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/stddev_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/examples/stddev_over_time.md new file mode 100644 index 0000000000000..022d6dfa95f42 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/stddev_over_time.md @@ -0,0 +1,18 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +TS k8s +| STATS max_stddev_cost=MAX(STDDEV_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +``` + +| cluster:keyword | time_bucket:datetime | max_stddev_cost:double | +| --- | --- | --- | +| staging | 2024-05-10T00:03:00.000Z | 5.4375 | +| staging | 2024-05-10T00:09:00.000Z | 5.1875 | +| qa | 2024-05-10T00:18:00.000Z | 4.097764 | +| qa | 2024-05-10T00:21:00.000Z | 4.0 | +| staging | 2024-05-10T00:20:00.000Z | 3.9375 | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/stdvar_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/examples/stdvar_over_time.md new file mode 100644 index 0000000000000..1aa98d1f64e28 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/stdvar_over_time.md @@ -0,0 +1,17 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +TS k8s +| STATS avg_var_cost=AVG(VARIANCE_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +``` + +| cluster:keyword | time_bucket:datetime | avg_var_cost:double | +| --- | --- | --- | +| staging | 2024-05-10T00:03:00.000Z | 20.478516 | +| qa | 2024-05-10T00:21:00.000Z | 16.0 | +| qa | 2024-05-10T00:18:00.000Z | 11.192274 | +| staging | 2024-05-10T00:09:00.000Z | 10.446904 | + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/examples/variance.md b/docs/reference/query-languages/esql/_snippets/functions/examples/variance.md new file mode 100644 index 0000000000000..b3efac50b7ae7 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/examples/variance.md @@ -0,0 +1,9 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Example** + +```esql +null +``` + + diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/stddev_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/layout/stddev_over_time.md new file mode 100644 index 0000000000000..99d2d639f4cf5 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/stddev_over_time.md @@ -0,0 +1,27 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `STDDEV_OVER_TIME` [esql-stddev_over_time] +```{applies_to} +stack: preview 9.2.0 +serverless: preview +``` + +**Syntax** + +:::{image} ../../../images/functions/stddev_over_time.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/stddev_over_time.md +::: + +:::{include} ../description/stddev_over_time.md +::: + +:::{include} ../types/stddev_over_time.md +::: + +:::{include} ../examples/stddev_over_time.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/stdvar_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/layout/stdvar_over_time.md new file mode 100644 index 0000000000000..24aa0696c3e4a --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/stdvar_over_time.md @@ -0,0 +1,27 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `STDVAR_OVER_TIME` [esql-stdvar_over_time] +```{applies_to} +stack: preview 9.2.0 +serverless: preview +``` + +**Syntax** + +:::{image} ../../../images/functions/stdvar_over_time.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/stdvar_over_time.md +::: + +:::{include} ../description/stdvar_over_time.md +::: + +:::{include} ../types/stdvar_over_time.md +::: + +:::{include} ../examples/stdvar_over_time.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/layout/variance.md b/docs/reference/query-languages/esql/_snippets/functions/layout/variance.md new file mode 100644 index 0000000000000..4db08b9e8caae --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/layout/variance.md @@ -0,0 +1,23 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +## `VARIANCE` [esql-variance] + +**Syntax** + +:::{image} ../../../images/functions/variance.svg +:alt: Embedded +:class: text-center +::: + + +:::{include} ../parameters/variance.md +::: + +:::{include} ../description/variance.md +::: + +:::{include} ../types/variance.md +::: + +:::{include} ../examples/variance.md +::: diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/stddev_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/stddev_over_time.md new file mode 100644 index 0000000000000..0ac6e4bf13042 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/stddev_over_time.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`number` +: Expression that outputs values to calculate the standard deviation of. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/stdvar_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/stdvar_over_time.md new file mode 100644 index 0000000000000..52a0a163e5a9d --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/stdvar_over_time.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`number` +: Expression that outputs values to calculate the variance of. + diff --git a/docs/reference/query-languages/esql/_snippets/functions/parameters/variance.md b/docs/reference/query-languages/esql/_snippets/functions/parameters/variance.md new file mode 100644 index 0000000000000..e003b3562deeb --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/parameters/variance.md @@ -0,0 +1,7 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Parameters** + +`number` +: + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/stddev_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/types/stddev_over_time.md new file mode 100644 index 0000000000000..e204309f17bb1 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/stddev_over_time.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| number | result | +| --- | --- | +| double | double | +| integer | double | +| long | double | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/stdvar_over_time.md b/docs/reference/query-languages/esql/_snippets/functions/types/stdvar_over_time.md new file mode 100644 index 0000000000000..e204309f17bb1 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/stdvar_over_time.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| number | result | +| --- | --- | +| double | double | +| integer | double | +| long | double | + diff --git a/docs/reference/query-languages/esql/_snippets/functions/types/variance.md b/docs/reference/query-languages/esql/_snippets/functions/types/variance.md new file mode 100644 index 0000000000000..e204309f17bb1 --- /dev/null +++ b/docs/reference/query-languages/esql/_snippets/functions/types/variance.md @@ -0,0 +1,10 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +**Supported types** + +| number | result | +| --- | --- | +| double | double | +| integer | double | +| long | double | + diff --git a/docs/reference/query-languages/esql/images/functions/stddev_over_time.svg b/docs/reference/query-languages/esql/images/functions/stddev_over_time.svg new file mode 100644 index 0000000000000..c314d6a193df8 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/stddev_over_time.svg @@ -0,0 +1 @@ +STDDEV_OVER_TIME(number) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/stdvar_over_time.svg b/docs/reference/query-languages/esql/images/functions/stdvar_over_time.svg new file mode 100644 index 0000000000000..ebef8c3c83310 --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/stdvar_over_time.svg @@ -0,0 +1 @@ +VARIANCE_OVER_TIME(number) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/images/functions/variance.svg b/docs/reference/query-languages/esql/images/functions/variance.svg new file mode 100644 index 0000000000000..08eb2333082fc --- /dev/null +++ b/docs/reference/query-languages/esql/images/functions/variance.svg @@ -0,0 +1 @@ +VARIANCE(number) \ No newline at end of file diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/stddev_over_time.json b/docs/reference/query-languages/esql/kibana/definition/functions/stddev_over_time.json new file mode 100644 index 0000000000000..2a83817caf616 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/stddev_over_time.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "time_series_agg", + "name" : "stddev_over_time", + "description" : "Calculates the population standard deviation over time of a numeric field.", + "signatures" : [ + { + "params" : [ + { + "name" : "number", + "type" : "double", + "optional" : false, + "description" : "Expression that outputs values to calculate the standard deviation of." + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "integer", + "optional" : false, + "description" : "Expression that outputs values to calculate the standard deviation of." + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "long", + "optional" : false, + "description" : "Expression that outputs values to calculate the standard deviation of." + } + ], + "variadic" : false, + "returnType" : "double" + } + ], + "examples" : [ + "TS k8s\n| STATS max_stddev_cost=MAX(STDDEV_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute)" + ], + "preview" : true, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/stdvar_over_time.json b/docs/reference/query-languages/esql/kibana/definition/functions/stdvar_over_time.json new file mode 100644 index 0000000000000..b6312d700ab06 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/stdvar_over_time.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "time_series_agg", + "name" : "stdvar_over_time", + "description" : "Calculates the population variance over time of a numeric field.", + "signatures" : [ + { + "params" : [ + { + "name" : "number", + "type" : "double", + "optional" : false, + "description" : "Expression that outputs values to calculate the variance of." + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "integer", + "optional" : false, + "description" : "Expression that outputs values to calculate the variance of." + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "long", + "optional" : false, + "description" : "Expression that outputs values to calculate the variance of." + } + ], + "variadic" : false, + "returnType" : "double" + } + ], + "examples" : [ + "TS k8s\n| STATS avg_var_cost=AVG(VARIANCE_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute)" + ], + "preview" : true, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/variance.json b/docs/reference/query-languages/esql/kibana/definition/functions/variance.json new file mode 100644 index 0000000000000..e6cddc4f79d13 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/definition/functions/variance.json @@ -0,0 +1,49 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it.", + "type" : "agg", + "name" : "variance", + "description" : "The population variance of a numeric field.", + "signatures" : [ + { + "params" : [ + { + "name" : "number", + "type" : "double", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "integer", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "double" + }, + { + "params" : [ + { + "name" : "number", + "type" : "long", + "optional" : false, + "description" : "" + } + ], + "variadic" : false, + "returnType" : "double" + } + ], + "examples" : [ + null + ], + "preview" : false, + "snapshot_only" : false +} diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/stddev_over_time.md b/docs/reference/query-languages/esql/kibana/docs/functions/stddev_over_time.md new file mode 100644 index 0000000000000..decd95b2fefdc --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/stddev_over_time.md @@ -0,0 +1,9 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### STDDEV OVER TIME +Calculates the population standard deviation over time of a numeric field. + +```esql +TS k8s +| STATS max_stddev_cost=MAX(STDDEV_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/stdvar_over_time.md b/docs/reference/query-languages/esql/kibana/docs/functions/stdvar_over_time.md new file mode 100644 index 0000000000000..ff1bea59007b8 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/stdvar_over_time.md @@ -0,0 +1,9 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### STDVAR OVER TIME +Calculates the population variance over time of a numeric field. + +```esql +TS k8s +| STATS avg_var_cost=AVG(VARIANCE_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +``` diff --git a/docs/reference/query-languages/esql/kibana/docs/functions/variance.md b/docs/reference/query-languages/esql/kibana/docs/functions/variance.md new file mode 100644 index 0000000000000..febfa44b540e6 --- /dev/null +++ b/docs/reference/query-languages/esql/kibana/docs/functions/variance.md @@ -0,0 +1,8 @@ +% This is generated by ESQL's AbstractFunctionTestCase. Do not edit it. See ../README.md for how to regenerate it. + +### VARIANCE +The population variance of a numeric field. + +```esql +null +``` diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevDoubleAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevDoubleAggregator.java index 8cf0809164aa1..cb2bc98c79e65 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevDoubleAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevDoubleAggregator.java @@ -28,35 +28,35 @@ @GroupingAggregator public class StdDevDoubleAggregator { - public static StdDevStates.SingleState initSingle() { - return new StdDevStates.SingleState(); + public static VarianceStates.SingleState initSingle(boolean stdDev) { + return new VarianceStates.SingleState(stdDev); } - public static void combine(StdDevStates.SingleState state, double value) { + public static void combine(VarianceStates.SingleState state, double value) { state.add(value); } - public static void combineIntermediate(StdDevStates.SingleState state, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.SingleState state, double mean, double m2, long count) { state.combine(mean, m2, count); } - public static Block evaluateFinal(StdDevStates.SingleState state, DriverContext driverContext) { + public static Block evaluateFinal(VarianceStates.SingleState state, DriverContext driverContext) { return state.evaluateFinal(driverContext); } - public static StdDevStates.GroupingState initGrouping(BigArrays bigArrays) { - return new StdDevStates.GroupingState(bigArrays); + public static VarianceStates.GroupingState initGrouping(BigArrays bigArrays, boolean stdDev) { + return new VarianceStates.GroupingState(bigArrays, stdDev); } - public static void combine(StdDevStates.GroupingState current, int groupId, double value) { + public static void combine(VarianceStates.GroupingState current, int groupId, double value) { current.add(groupId, value); } - public static void combineIntermediate(StdDevStates.GroupingState state, int groupId, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.GroupingState state, int groupId, double mean, double m2, long count) { state.combine(groupId, mean, m2, count); } - public static Block evaluateFinal(StdDevStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal(VarianceStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevFloatAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevFloatAggregator.java index 7fd851a16ab8f..2179e2053513e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevFloatAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevFloatAggregator.java @@ -28,35 +28,35 @@ @GroupingAggregator public class StdDevFloatAggregator { - public static StdDevStates.SingleState initSingle() { - return new StdDevStates.SingleState(); + public static VarianceStates.SingleState initSingle(boolean stdDev) { + return new VarianceStates.SingleState(stdDev); } - public static void combine(StdDevStates.SingleState state, float value) { + public static void combine(VarianceStates.SingleState state, float value) { state.add(value); } - public static void combineIntermediate(StdDevStates.SingleState state, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.SingleState state, double mean, double m2, long count) { state.combine(mean, m2, count); } - public static Block evaluateFinal(StdDevStates.SingleState state, DriverContext driverContext) { + public static Block evaluateFinal(VarianceStates.SingleState state, DriverContext driverContext) { return state.evaluateFinal(driverContext); } - public static StdDevStates.GroupingState initGrouping(BigArrays bigArrays) { - return new StdDevStates.GroupingState(bigArrays); + public static VarianceStates.GroupingState initGrouping(BigArrays bigArrays, boolean stdDev) { + return new VarianceStates.GroupingState(bigArrays, stdDev); } - public static void combine(StdDevStates.GroupingState current, int groupId, float value) { + public static void combine(VarianceStates.GroupingState current, int groupId, float value) { current.add(groupId, value); } - public static void combineIntermediate(StdDevStates.GroupingState state, int groupId, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.GroupingState state, int groupId, double mean, double m2, long count) { state.combine(groupId, mean, m2, count); } - public static Block evaluateFinal(StdDevStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal(VarianceStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevIntAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevIntAggregator.java index 30adf0e28b1b4..851b611ed7f29 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevIntAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevIntAggregator.java @@ -28,35 +28,35 @@ @GroupingAggregator public class StdDevIntAggregator { - public static StdDevStates.SingleState initSingle() { - return new StdDevStates.SingleState(); + public static VarianceStates.SingleState initSingle(boolean stdDev) { + return new VarianceStates.SingleState(stdDev); } - public static void combine(StdDevStates.SingleState state, int value) { + public static void combine(VarianceStates.SingleState state, int value) { state.add(value); } - public static void combineIntermediate(StdDevStates.SingleState state, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.SingleState state, double mean, double m2, long count) { state.combine(mean, m2, count); } - public static Block evaluateFinal(StdDevStates.SingleState state, DriverContext driverContext) { + public static Block evaluateFinal(VarianceStates.SingleState state, DriverContext driverContext) { return state.evaluateFinal(driverContext); } - public static StdDevStates.GroupingState initGrouping(BigArrays bigArrays) { - return new StdDevStates.GroupingState(bigArrays); + public static VarianceStates.GroupingState initGrouping(BigArrays bigArrays, boolean stdDev) { + return new VarianceStates.GroupingState(bigArrays, stdDev); } - public static void combine(StdDevStates.GroupingState current, int groupId, int value) { + public static void combine(VarianceStates.GroupingState current, int groupId, int value) { current.add(groupId, value); } - public static void combineIntermediate(StdDevStates.GroupingState state, int groupId, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.GroupingState state, int groupId, double mean, double m2, long count) { state.combine(groupId, mean, m2, count); } - public static Block evaluateFinal(StdDevStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal(VarianceStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevLongAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevLongAggregator.java index 4f6b5008d79eb..1c1d90e187000 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevLongAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/StdDevLongAggregator.java @@ -28,35 +28,35 @@ @GroupingAggregator public class StdDevLongAggregator { - public static StdDevStates.SingleState initSingle() { - return new StdDevStates.SingleState(); + public static VarianceStates.SingleState initSingle(boolean stdDev) { + return new VarianceStates.SingleState(stdDev); } - public static void combine(StdDevStates.SingleState state, long value) { + public static void combine(VarianceStates.SingleState state, long value) { state.add(value); } - public static void combineIntermediate(StdDevStates.SingleState state, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.SingleState state, double mean, double m2, long count) { state.combine(mean, m2, count); } - public static Block evaluateFinal(StdDevStates.SingleState state, DriverContext driverContext) { + public static Block evaluateFinal(VarianceStates.SingleState state, DriverContext driverContext) { return state.evaluateFinal(driverContext); } - public static StdDevStates.GroupingState initGrouping(BigArrays bigArrays) { - return new StdDevStates.GroupingState(bigArrays); + public static VarianceStates.GroupingState initGrouping(BigArrays bigArrays, boolean stdDev) { + return new VarianceStates.GroupingState(bigArrays, stdDev); } - public static void combine(StdDevStates.GroupingState current, int groupId, long value) { + public static void combine(VarianceStates.GroupingState current, int groupId, long value) { current.add(groupId, value); } - public static void combineIntermediate(StdDevStates.GroupingState state, int groupId, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.GroupingState state, int groupId, double mean, double m2, long count) { state.combine(groupId, mean, m2, count); } - public static Block evaluateFinal(StdDevStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal(VarianceStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunction.java index 208a293f7aeb8..727b0a6226f31 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunction.java @@ -31,20 +31,23 @@ public final class StdDevDoubleAggregatorFunction implements AggregatorFunction private final DriverContext driverContext; - private final StdDevStates.SingleState state; + private final VarianceStates.SingleState state; private final List channels; + private final boolean stdDev; + public StdDevDoubleAggregatorFunction(DriverContext driverContext, List channels, - StdDevStates.SingleState state) { + VarianceStates.SingleState state, boolean stdDev) { this.driverContext = driverContext; this.channels = channels; this.state = state; + this.stdDev = stdDev; } public static StdDevDoubleAggregatorFunction create(DriverContext driverContext, - List channels) { - return new StdDevDoubleAggregatorFunction(driverContext, channels, StdDevDoubleAggregator.initSingle()); + List channels, boolean stdDev) { + return new StdDevDoubleAggregatorFunction(driverContext, channels, StdDevDoubleAggregator.initSingle(stdDev), stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunctionSupplier.java index 5310a11c1fddb..ada74a2a5fc1e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleAggregatorFunctionSupplier.java @@ -15,7 +15,10 @@ * This class is generated. Edit {@code AggregatorFunctionSupplierImplementer} instead. */ public final class StdDevDoubleAggregatorFunctionSupplier implements AggregatorFunctionSupplier { - public StdDevDoubleAggregatorFunctionSupplier() { + private final boolean stdDev; + + public StdDevDoubleAggregatorFunctionSupplier(boolean stdDev) { + this.stdDev = stdDev; } @Override @@ -31,13 +34,13 @@ public List groupingIntermediateStateDesc() { @Override public StdDevDoubleAggregatorFunction aggregator(DriverContext driverContext, List channels) { - return StdDevDoubleAggregatorFunction.create(driverContext, channels); + return StdDevDoubleAggregatorFunction.create(driverContext, channels, stdDev); } @Override public StdDevDoubleGroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { - return StdDevDoubleGroupingAggregatorFunction.create(channels, driverContext); + return StdDevDoubleGroupingAggregatorFunction.create(channels, driverContext, stdDev); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java index b4337f1030adb..1738282c7ee0b 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java @@ -31,22 +31,25 @@ public final class StdDevDoubleGroupingAggregatorFunction implements GroupingAgg new IntermediateStateDesc("m2", ElementType.DOUBLE), new IntermediateStateDesc("count", ElementType.LONG) ); - private final StdDevStates.GroupingState state; + private final VarianceStates.GroupingState state; private final List channels; private final DriverContext driverContext; + private final boolean stdDev; + public StdDevDoubleGroupingAggregatorFunction(List channels, - StdDevStates.GroupingState state, DriverContext driverContext) { + VarianceStates.GroupingState state, DriverContext driverContext, boolean stdDev) { this.channels = channels; this.state = state; this.driverContext = driverContext; + this.stdDev = stdDev; } public static StdDevDoubleGroupingAggregatorFunction create(List channels, - DriverContext driverContext) { - return new StdDevDoubleGroupingAggregatorFunction(channels, StdDevDoubleAggregator.initGrouping(driverContext.bigArrays()), driverContext); + DriverContext driverContext, boolean stdDev) { + return new StdDevDoubleGroupingAggregatorFunction(channels, StdDevDoubleAggregator.initGrouping(driverContext.bigArrays(), stdDev), driverContext, stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunction.java index c82d0a3ab01d3..0dc56fc22040c 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunction.java @@ -33,20 +33,23 @@ public final class StdDevFloatAggregatorFunction implements AggregatorFunction { private final DriverContext driverContext; - private final StdDevStates.SingleState state; + private final VarianceStates.SingleState state; private final List channels; + private final boolean stdDev; + public StdDevFloatAggregatorFunction(DriverContext driverContext, List channels, - StdDevStates.SingleState state) { + VarianceStates.SingleState state, boolean stdDev) { this.driverContext = driverContext; this.channels = channels; this.state = state; + this.stdDev = stdDev; } public static StdDevFloatAggregatorFunction create(DriverContext driverContext, - List channels) { - return new StdDevFloatAggregatorFunction(driverContext, channels, StdDevFloatAggregator.initSingle()); + List channels, boolean stdDev) { + return new StdDevFloatAggregatorFunction(driverContext, channels, StdDevFloatAggregator.initSingle(stdDev), stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunctionSupplier.java index 52ffb0f5d580d..a233f89757350 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatAggregatorFunctionSupplier.java @@ -15,7 +15,10 @@ * This class is generated. Edit {@code AggregatorFunctionSupplierImplementer} instead. */ public final class StdDevFloatAggregatorFunctionSupplier implements AggregatorFunctionSupplier { - public StdDevFloatAggregatorFunctionSupplier() { + private final boolean stdDev; + + public StdDevFloatAggregatorFunctionSupplier(boolean stdDev) { + this.stdDev = stdDev; } @Override @@ -31,13 +34,13 @@ public List groupingIntermediateStateDesc() { @Override public StdDevFloatAggregatorFunction aggregator(DriverContext driverContext, List channels) { - return StdDevFloatAggregatorFunction.create(driverContext, channels); + return StdDevFloatAggregatorFunction.create(driverContext, channels, stdDev); } @Override public StdDevFloatGroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { - return StdDevFloatGroupingAggregatorFunction.create(channels, driverContext); + return StdDevFloatGroupingAggregatorFunction.create(channels, driverContext, stdDev); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java index 7e513e1f9dc35..5ee9758c98d45 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java @@ -33,22 +33,25 @@ public final class StdDevFloatGroupingAggregatorFunction implements GroupingAggr new IntermediateStateDesc("m2", ElementType.DOUBLE), new IntermediateStateDesc("count", ElementType.LONG) ); - private final StdDevStates.GroupingState state; + private final VarianceStates.GroupingState state; private final List channels; private final DriverContext driverContext; + private final boolean stdDev; + public StdDevFloatGroupingAggregatorFunction(List channels, - StdDevStates.GroupingState state, DriverContext driverContext) { + VarianceStates.GroupingState state, DriverContext driverContext, boolean stdDev) { this.channels = channels; this.state = state; this.driverContext = driverContext; + this.stdDev = stdDev; } public static StdDevFloatGroupingAggregatorFunction create(List channels, - DriverContext driverContext) { - return new StdDevFloatGroupingAggregatorFunction(channels, StdDevFloatAggregator.initGrouping(driverContext.bigArrays()), driverContext); + DriverContext driverContext, boolean stdDev) { + return new StdDevFloatGroupingAggregatorFunction(channels, StdDevFloatAggregator.initGrouping(driverContext.bigArrays(), stdDev), driverContext, stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunction.java index 6b9f7f4e561ac..0a59974587b59 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunction.java @@ -33,20 +33,23 @@ public final class StdDevIntAggregatorFunction implements AggregatorFunction { private final DriverContext driverContext; - private final StdDevStates.SingleState state; + private final VarianceStates.SingleState state; private final List channels; + private final boolean stdDev; + public StdDevIntAggregatorFunction(DriverContext driverContext, List channels, - StdDevStates.SingleState state) { + VarianceStates.SingleState state, boolean stdDev) { this.driverContext = driverContext; this.channels = channels; this.state = state; + this.stdDev = stdDev; } public static StdDevIntAggregatorFunction create(DriverContext driverContext, - List channels) { - return new StdDevIntAggregatorFunction(driverContext, channels, StdDevIntAggregator.initSingle()); + List channels, boolean stdDev) { + return new StdDevIntAggregatorFunction(driverContext, channels, StdDevIntAggregator.initSingle(stdDev), stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunctionSupplier.java index 2f43a867bf83e..9475818c918d7 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntAggregatorFunctionSupplier.java @@ -15,7 +15,10 @@ * This class is generated. Edit {@code AggregatorFunctionSupplierImplementer} instead. */ public final class StdDevIntAggregatorFunctionSupplier implements AggregatorFunctionSupplier { - public StdDevIntAggregatorFunctionSupplier() { + private final boolean stdDev; + + public StdDevIntAggregatorFunctionSupplier(boolean stdDev) { + this.stdDev = stdDev; } @Override @@ -31,13 +34,13 @@ public List groupingIntermediateStateDesc() { @Override public StdDevIntAggregatorFunction aggregator(DriverContext driverContext, List channels) { - return StdDevIntAggregatorFunction.create(driverContext, channels); + return StdDevIntAggregatorFunction.create(driverContext, channels, stdDev); } @Override public StdDevIntGroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { - return StdDevIntGroupingAggregatorFunction.create(channels, driverContext); + return StdDevIntGroupingAggregatorFunction.create(channels, driverContext, stdDev); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java index 1145ccfd4bce3..2c0c427b9266e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java @@ -32,22 +32,25 @@ public final class StdDevIntGroupingAggregatorFunction implements GroupingAggreg new IntermediateStateDesc("m2", ElementType.DOUBLE), new IntermediateStateDesc("count", ElementType.LONG) ); - private final StdDevStates.GroupingState state; + private final VarianceStates.GroupingState state; private final List channels; private final DriverContext driverContext; + private final boolean stdDev; + public StdDevIntGroupingAggregatorFunction(List channels, - StdDevStates.GroupingState state, DriverContext driverContext) { + VarianceStates.GroupingState state, DriverContext driverContext, boolean stdDev) { this.channels = channels; this.state = state; this.driverContext = driverContext; + this.stdDev = stdDev; } public static StdDevIntGroupingAggregatorFunction create(List channels, - DriverContext driverContext) { - return new StdDevIntGroupingAggregatorFunction(channels, StdDevIntAggregator.initGrouping(driverContext.bigArrays()), driverContext); + DriverContext driverContext, boolean stdDev) { + return new StdDevIntGroupingAggregatorFunction(channels, StdDevIntAggregator.initGrouping(driverContext.bigArrays(), stdDev), driverContext, stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunction.java index 0e53e5f2d461e..edf7b4fbecb44 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunction.java @@ -31,20 +31,23 @@ public final class StdDevLongAggregatorFunction implements AggregatorFunction { private final DriverContext driverContext; - private final StdDevStates.SingleState state; + private final VarianceStates.SingleState state; private final List channels; + private final boolean stdDev; + public StdDevLongAggregatorFunction(DriverContext driverContext, List channels, - StdDevStates.SingleState state) { + VarianceStates.SingleState state, boolean stdDev) { this.driverContext = driverContext; this.channels = channels; this.state = state; + this.stdDev = stdDev; } public static StdDevLongAggregatorFunction create(DriverContext driverContext, - List channels) { - return new StdDevLongAggregatorFunction(driverContext, channels, StdDevLongAggregator.initSingle()); + List channels, boolean stdDev) { + return new StdDevLongAggregatorFunction(driverContext, channels, StdDevLongAggregator.initSingle(stdDev), stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunctionSupplier.java index 364fc4820c283..bacba99142e41 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongAggregatorFunctionSupplier.java @@ -15,7 +15,10 @@ * This class is generated. Edit {@code AggregatorFunctionSupplierImplementer} instead. */ public final class StdDevLongAggregatorFunctionSupplier implements AggregatorFunctionSupplier { - public StdDevLongAggregatorFunctionSupplier() { + private final boolean stdDev; + + public StdDevLongAggregatorFunctionSupplier(boolean stdDev) { + this.stdDev = stdDev; } @Override @@ -31,13 +34,13 @@ public List groupingIntermediateStateDesc() { @Override public StdDevLongAggregatorFunction aggregator(DriverContext driverContext, List channels) { - return StdDevLongAggregatorFunction.create(driverContext, channels); + return StdDevLongAggregatorFunction.create(driverContext, channels, stdDev); } @Override public StdDevLongGroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { - return StdDevLongGroupingAggregatorFunction.create(channels, driverContext); + return StdDevLongGroupingAggregatorFunction.create(channels, driverContext, stdDev); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java index 5e2dde7ea1fde..60aea98c728bf 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java @@ -31,22 +31,25 @@ public final class StdDevLongGroupingAggregatorFunction implements GroupingAggre new IntermediateStateDesc("m2", ElementType.DOUBLE), new IntermediateStateDesc("count", ElementType.LONG) ); - private final StdDevStates.GroupingState state; + private final VarianceStates.GroupingState state; private final List channels; private final DriverContext driverContext; + private final boolean stdDev; + public StdDevLongGroupingAggregatorFunction(List channels, - StdDevStates.GroupingState state, DriverContext driverContext) { + VarianceStates.GroupingState state, DriverContext driverContext, boolean stdDev) { this.channels = channels; this.state = state; this.driverContext = driverContext; + this.stdDev = stdDev; } public static StdDevLongGroupingAggregatorFunction create(List channels, - DriverContext driverContext) { - return new StdDevLongGroupingAggregatorFunction(channels, StdDevLongAggregator.initGrouping(driverContext.bigArrays()), driverContext); + DriverContext driverContext, boolean stdDev) { + return new StdDevLongGroupingAggregatorFunction(channels, StdDevLongAggregator.initGrouping(driverContext.bigArrays(), stdDev), driverContext, stdDev); } public static List intermediateStateDesc() { diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/StdDevStates.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/VarianceStates.java similarity index 93% rename from x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/StdDevStates.java rename to x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/VarianceStates.java index 5b48498d83294..a4b6b2a04d593 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/StdDevStates.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/VarianceStates.java @@ -16,20 +16,22 @@ import org.elasticsearch.compute.operator.DriverContext; import org.elasticsearch.core.Releasables; -public final class StdDevStates { +public final class VarianceStates { - private StdDevStates() {} + private VarianceStates() {} static final class SingleState implements AggregatorState { private final WelfordAlgorithm welfordAlgorithm; + private final boolean stdDev; - SingleState() { - this(0, 0, 0); + SingleState(boolean stdDev) { + this(0, 0, 0, stdDev); } - SingleState(double mean, double m2, long count) { + SingleState(double mean, double m2, long count, boolean stdDev) { this.welfordAlgorithm = new WelfordAlgorithm(mean, m2, count); + this.stdDev = stdDev; } public void add(long value) { @@ -73,7 +75,7 @@ public long count() { } public double evaluateFinal() { - return welfordAlgorithm.evaluate(); + return welfordAlgorithm.evaluate(stdDev); } public Block evaluateFinal(DriverContext driverContext) { @@ -90,10 +92,12 @@ static final class GroupingState implements GroupingAggregatorState { private ObjectArray states; private final BigArrays bigArrays; + private final boolean stdDev; - GroupingState(BigArrays bigArrays) { + GroupingState(BigArrays bigArrays, boolean stdDev) { this.states = bigArrays.newObjectArray(1); this.bigArrays = bigArrays; + this.stdDev = stdDev; } WelfordAlgorithm getOrNull(int position) { @@ -189,7 +193,7 @@ public Block evaluateFinal(IntVector selected, DriverContext driverContext) { if (count == 0 || Double.isFinite(m2) == false) { builder.appendNull(); } else { - builder.appendDouble(st.evaluate()); + builder.appendDouble(st.evaluate(stdDev)); } } else { builder.appendNull(); diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/WelfordAlgorithm.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/WelfordAlgorithm.java index 8ccb985507247..2ab4c75624cb2 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/WelfordAlgorithm.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/WelfordAlgorithm.java @@ -73,7 +73,16 @@ public void add(double meanValue, double m2Value, long countValue) { count += countValue; } - public double evaluate() { - return count < 2 ? 0 : Math.sqrt(m2 / count); + /** + * Evaluate the variance or standard deviation. + * @param stdDev if true, compute standard deviation, otherwise variance + * @return + */ + public double evaluate(boolean stdDev) { + if (stdDev == false) { + return count < 2 ? 0 : m2 / count; + } else { + return count < 2 ? 0 : Math.sqrt(m2 / count); + } } } diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-StdDevAggregator.java.st b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-StdDevAggregator.java.st index 5cb3197ce0e3c..0705a24024875 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-StdDevAggregator.java.st +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-StdDevAggregator.java.st @@ -28,35 +28,35 @@ import org.elasticsearch.compute.operator.DriverContext; @GroupingAggregator public class StdDev$Type$Aggregator { - public static StdDevStates.SingleState initSingle() { - return new StdDevStates.SingleState(); + public static VarianceStates.SingleState initSingle(boolean stdDev) { + return new VarianceStates.SingleState(stdDev); } - public static void combine(StdDevStates.SingleState state, $type$ value) { + public static void combine(VarianceStates.SingleState state, $type$ value) { state.add(value); } - public static void combineIntermediate(StdDevStates.SingleState state, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.SingleState state, double mean, double m2, long count) { state.combine(mean, m2, count); } - public static Block evaluateFinal(StdDevStates.SingleState state, DriverContext driverContext) { + public static Block evaluateFinal(VarianceStates.SingleState state, DriverContext driverContext) { return state.evaluateFinal(driverContext); } - public static StdDevStates.GroupingState initGrouping(BigArrays bigArrays) { - return new StdDevStates.GroupingState(bigArrays); + public static VarianceStates.GroupingState initGrouping(BigArrays bigArrays, boolean stdDev) { + return new VarianceStates.GroupingState(bigArrays, stdDev); } - public static void combine(StdDevStates.GroupingState current, int groupId, $type$ value) { + public static void combine(VarianceStates.GroupingState current, int groupId, $type$ value) { current.add(groupId, value); } - public static void combineIntermediate(StdDevStates.GroupingState state, int groupId, double mean, double m2, long count) { + public static void combineIntermediate(VarianceStates.GroupingState state, int groupId, double mean, double m2, long count) { state.combine(groupId, mean, m2, count); } - public static Block evaluateFinal(StdDevStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal(VarianceStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec index 4109312b16f1c..a60f031ba2b58 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/k8s-timeseries.csv-spec @@ -592,4 +592,84 @@ max_cost:integer | pod:keyword | time_bucket:datetime | max_cluster_cost:int 581 | one | 2024-05-10T00:00:00.000Z | 1209 | staging 1209 | three | 2024-05-10T00:00:00.000Z | 1209 | staging 973 | two | 2024-05-10T00:00:00.000Z | 1209 | staging +; + +max_of_stddev_over_time +required_capability: ts_command_v0 +required_capability: variance_stddev_over_time +// tag::stddev_over_time[] +TS k8s +| STATS max_stddev_cost=MAX(STDDEV_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +// end::stddev_over_time[] +| EVAL max_stddev_cost = ROUND(max_stddev_cost, 6) +| SORT max_stddev_cost DESC, time_bucket DESC, cluster | LIMIT 10; + +// tag::stddev_over_time-result[] +cluster:keyword | time_bucket:datetime | max_stddev_cost:double +staging | 2024-05-10T00:03:00.000Z | 5.4375 +staging | 2024-05-10T00:09:00.000Z | 5.1875 +qa | 2024-05-10T00:18:00.000Z | 4.097764 +qa | 2024-05-10T00:21:00.000Z | 4.0 +staging | 2024-05-10T00:20:00.000Z | 3.9375 +// end::stddev_over_time-result[] +prod | 2024-05-10T00:18:00.000Z | 3.93353 +qa | 2024-05-10T00:08:00.000Z | 3.89444 +qa | 2024-05-10T00:17:00.000Z | 3.882385 +staging | 2024-05-10T00:13:00.000Z | 3.835597 +staging | 2024-05-10T00:12:00.000Z | 3.8125 + +; + +avg_stdvar_over_time +required_capability: ts_command_v0 +required_capability: variance_stddev_over_time +// tag::stdvar_over_time[] +TS k8s +| STATS avg_var_cost=AVG(VARIANCE_OVER_TIME(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +// end::stdvar_over_time[] +| EVAL avg_var_cost = ROUND(avg_var_cost, 6) +| SORT avg_var_cost DESC, time_bucket DESC, cluster | LIMIT 10; + +// tag::stdvar_over_time-result[] +cluster:keyword | time_bucket:datetime | avg_var_cost:double +staging | 2024-05-10T00:03:00.000Z | 20.478516 +qa | 2024-05-10T00:21:00.000Z | 16.0 +qa | 2024-05-10T00:18:00.000Z | 11.192274 +staging | 2024-05-10T00:09:00.000Z | 10.446904 +// end::stdvar_over_time-result[] +qa | 2024-05-10T00:17:00.000Z | 10.398003 +qa | 2024-05-10T00:08:00.000Z | 10.114583 +staging | 2024-05-10T00:20:00.000Z | 7.910156 +staging | 2024-05-10T00:13:00.000Z | 7.355903 +prod | 2024-05-10T00:02:00.000Z | 6.570313 +prod | 2024-05-10T00:18:00.000Z | 5.157552 + +; + +stddev_sq_and_var_over_time_are_consistent +required_capability: ts_command_v0 +required_capability: variance_stddev_over_time + +TS k8s +| STATS sd=max(stddev_over_time(network.cost)), var=max(stdvar_over_time(network.cost)) BY cluster, time_bucket = TBUCKET(1minute) +| EVAL sd_squared = sd * sd +| EVAL sd_squared = ROUND(sd_squared, 6), var = ROUND(var, 6), sd = ROUND(sd, 6) +| KEEP sd, var, sd_squared, cluster, time_bucket +| SORT cluster, time_bucket +| LIMIT 10; + +sd:double | var:double | sd_squared:double | cluster:keyword | time_bucket:datetime +1.4375 | 2.066406 | 2.066406 | prod | 2024-05-10T00:00:00.000Z +0.0 | 0.0 | 0.0 | prod | 2024-05-10T00:01:00.000Z +3.625 | 13.140625 | 13.140625 | prod | 2024-05-10T00:02:00.000Z +0.0 | 0.0 | 0.0 | prod | 2024-05-10T00:03:00.000Z +0.0 | 0.0 | 0.0 | prod | 2024-05-10T00:04:00.000Z +2.75 | 7.5625 | 7.5625 | prod | 2024-05-10T00:05:00.000Z +0.0 | 0.0 | 0.0 | prod | 2024-05-10T00:06:00.000Z +1.9375 | 3.753906 | 3.753906 | prod | 2024-05-10T00:08:00.000Z +3.406999 | 11.607639 | 11.607639 | prod | 2024-05-10T00:09:00.000Z +0.0 | 0.0 | 0.0 | prod | 2024-05-10T00:10:00.000Z + + + ; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec index 61ca316a39dbc..e22c87d1d9eb3 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/stats.csv-spec @@ -2969,6 +2969,22 @@ std_dev_height:double // end::stdev-result[] ; +stdVariance +required_capability: variance_stddev_over_time + +// tag::stdvar[] +FROM employees +| STATS std_var_height = STD_VAR(height) +// end::stdVar[] +| EVAL std_var_height = ROUND(std_var_height, 7) +; + +// tag::stdvar-result[] +std_var_height:double +0.0425888 +// end::stdVar-result[] +; + stdDeviationNested required_capability: std_dev // tag::docsStatsStdDevNestedExpression[] @@ -2985,6 +3001,18 @@ stddev_salary_change:double ; +stdVarianceNested +required_capability: variance_stddev_over_time + +FROM employees +| STATS stdvar_salary_change = STD_VAR(MV_MAX(salary_change)) +| EVAL stdvar_salary_change = ROUND(stdvar_salary_change, 5) +; + +stdvar_salary_change:double +47.27703 +; + stdDeviationWithLongs required_capability: std_dev FROM employees @@ -2996,6 +3024,17 @@ std_dev:double 5.7601043E7 ; +stdVarianceWithLongs +required_capability: variance_stddev_over_time +FROM employees +| STATS var = variance(avg_worked_seconds) +| EVAL var = ROUND(var, 7) +; + +var:double +3.317880108280233E15 +; + stdDeviationWithInts required_capability: std_dev FROM employees @@ -3007,6 +3046,17 @@ std_dev:double 13765.1255 ; +stdVarianceWithInts +required_capability: variance_stddev_over_time +FROM employees +| STATS std_var = STD_VAR(salary) +| EVAL std_var = ROUND(std_var, 5) +; + +std_var:double +1.894786801075E8 +; + stdDeviationConstantValue required_capability: std_dev FROM employees @@ -3059,10 +3109,10 @@ stdDeviationNoRows required_capability: std_dev FROM employees | WHERE languages IS null -| STATS STD_DEV(languages) +| STATS sd=STD_DEV(languages) ; -STD_DEV(languages):double +sd:double null ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 9040002085f9b..742c1d1c08bf1 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -1468,7 +1468,7 @@ public enum Cap { * Percentile over time and other ts-aggregations */ PERCENTILE_OVER_TIME, - + VARIANCE_STDDEV_OVER_TIME, /** * INLINE STATS fix incorrect prunning of null filtering * https://github.com/elastic/elasticsearch/pull/135011 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index 2f4d72338b4fc..6b79e90082fdc 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -49,10 +49,13 @@ import org.elasticsearch.xpack.esql.expression.function.aggregate.SpatialCentroid; import org.elasticsearch.xpack.esql.expression.function.aggregate.SpatialExtent; import org.elasticsearch.xpack.esql.expression.function.aggregate.StdDev; +import org.elasticsearch.xpack.esql.expression.function.aggregate.StdDevOverTime; import org.elasticsearch.xpack.esql.expression.function.aggregate.Sum; import org.elasticsearch.xpack.esql.expression.function.aggregate.SumOverTime; import org.elasticsearch.xpack.esql.expression.function.aggregate.Top; import org.elasticsearch.xpack.esql.expression.function.aggregate.Values; +import org.elasticsearch.xpack.esql.expression.function.aggregate.Variance; +import org.elasticsearch.xpack.esql.expression.function.aggregate.VarianceOverTime; import org.elasticsearch.xpack.esql.expression.function.aggregate.WeightedAvg; import org.elasticsearch.xpack.esql.expression.function.fulltext.Kql; import org.elasticsearch.xpack.esql.expression.function.fulltext.Match; @@ -355,6 +358,7 @@ private static FunctionDefinition[][] functions() { def(Percentile.class, bi(Percentile::new), "percentile"), def(Sample.class, bi(Sample::new), "sample"), def(StdDev.class, uni(StdDev::new), "std_dev"), + def(Variance.class, uni(Variance::new), "variance", "std_var"), def(Sum.class, uni(Sum::new), "sum"), def(Top.class, tri(Top::new), "top"), def(Values.class, uni(Values::new), "values"), @@ -527,6 +531,8 @@ private static FunctionDefinition[][] functions() { def(MaxOverTime.class, uni(MaxOverTime::new), "max_over_time"), def(MinOverTime.class, uni(MinOverTime::new), "min_over_time"), def(SumOverTime.class, uni(SumOverTime::new), "sum_over_time"), + def(StdDevOverTime.class, uni(StdDevOverTime::new), "stddev_over_time"), + def(VarianceOverTime.class, uni(VarianceOverTime::new), "variance_over_time", "stdvar_over_time"), def(CountOverTime.class, uni(CountOverTime::new), "count_over_time"), def(CountDistinctOverTime.class, bi(CountDistinctOverTime::new), "count_distinct_over_time"), def(PresentOverTime.class, uni(PresentOverTime::new), "present_over_time"), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java index d604a72dce08c..727238ca524c4 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java @@ -33,12 +33,15 @@ public static List getNamedWriteables() { SpatialCentroid.ENTRY, SpatialExtent.ENTRY, StdDev.ENTRY, + Variance.ENTRY, Sum.ENTRY, Top.ENTRY, Values.ENTRY, MinOverTime.ENTRY, MaxOverTime.ENTRY, AvgOverTime.ENTRY, + StdDevOverTime.ENTRY, + VarianceOverTime.ENTRY, Last.ENTRY, LastOverTime.ENTRY, FirstOverTime.ENTRY, diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDev.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDev.java index 22a97c2ccb5b3..af4428199e322 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDev.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDev.java @@ -100,13 +100,13 @@ public StdDev withFilter(Expression filter) { public final AggregatorFunctionSupplier supplier() { DataType type = field().dataType(); if (type == DataType.LONG) { - return new StdDevLongAggregatorFunctionSupplier(); + return new StdDevLongAggregatorFunctionSupplier(true); } if (type == DataType.INTEGER) { - return new StdDevIntAggregatorFunctionSupplier(); + return new StdDevIntAggregatorFunctionSupplier(true); } if (type == DataType.DOUBLE) { - return new StdDevDoubleAggregatorFunctionSupplier(); + return new StdDevDoubleAggregatorFunctionSupplier(true); } throw EsqlIllegalArgumentException.illegalDataType(type); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevOverTime.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevOverTime.java new file mode 100644 index 0000000000000..262b6c71aa027 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevOverTime.java @@ -0,0 +1,100 @@ +/* + * 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.function.aggregate; + +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.xpack.esql.core.expression.Expression; +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.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; +import org.elasticsearch.xpack.esql.expression.function.FunctionType; +import org.elasticsearch.xpack.esql.expression.function.Param; + +import java.io.IOException; +import java.util.List; + +import static java.util.Collections.emptyList; + +/** + * Similar to {@link StdDev}, but it is used to calculate the standard deviation over a time series of values from the given field. + */ +public class StdDevOverTime extends TimeSeriesAggregateFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "StdDevOverTime", + StdDevOverTime::new + ); + + @FunctionInfo( + returnType = "double", + description = "Calculates the population standard deviation over time of a numeric field.", + type = FunctionType.TIME_SERIES_AGGREGATE, + appliesTo = { @FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.PREVIEW, version = "9.2.0") }, + preview = true, + examples = { @Example(file = "k8s-timeseries", tag = "stddev_over_time") } + ) + public StdDevOverTime( + Source source, + @Param( + name = "number", + type = { "double", "integer", "long" }, + description = "Expression that outputs values to calculate the standard deviation of." + ) Expression field + ) { + this(source, field, Literal.TRUE); + } + + public StdDevOverTime(Source source, Expression field, Expression filter) { + super(source, field, filter, emptyList()); + } + + private StdDevOverTime(StreamInput in) throws IOException { + super(in); + } + + @Override + protected TypeResolution resolveType() { + return perTimeSeriesAggregation().resolveType(); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return perTimeSeriesAggregation().dataType(); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, StdDevOverTime::new, field(), filter()); + } + + @Override + public StdDevOverTime replaceChildren(List newChildren) { + return new StdDevOverTime(source(), newChildren.get(0), newChildren.get(1)); + } + + @Override + public StdDevOverTime withFilter(Expression filter) { + return new StdDevOverTime(source(), field(), filter); + } + + @Override + public AggregateFunction perTimeSeriesAggregation() { + return new StdDev(source(), field(), filter()); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Variance.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Variance.java new file mode 100644 index 0000000000000..2f6a9595d0c05 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Variance.java @@ -0,0 +1,105 @@ +/* + * 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.function.aggregate; + +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.aggregation.AggregatorFunctionSupplier; +import org.elasticsearch.compute.aggregation.StdDevDoubleAggregatorFunctionSupplier; +import org.elasticsearch.compute.aggregation.StdDevIntAggregatorFunctionSupplier; +import org.elasticsearch.compute.aggregation.StdDevLongAggregatorFunctionSupplier; +import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Expression; +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.expression.function.Example; +import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; +import org.elasticsearch.xpack.esql.expression.function.FunctionType; +import org.elasticsearch.xpack.esql.expression.function.Param; +import org.elasticsearch.xpack.esql.planner.ToAggregator; + +import java.io.IOException; +import java.util.List; + +import static java.util.Collections.emptyList; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; + +public class Variance extends AggregateFunction implements ToAggregator { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Variance", Variance::new); + + @FunctionInfo( + returnType = "double", + description = "The population variance of a numeric field.", + type = FunctionType.AGGREGATE, + examples = { @Example(file = "stats", tag = "stdvar") } + ) + public Variance(Source source, @Param(name = "number", type = { "double", "integer", "long" }) Expression field) { + this(source, field, Literal.TRUE); + } + + public Variance(Source source, Expression field, Expression filter) { + super(source, field, filter, emptyList()); + } + + private Variance(StreamInput in) throws IOException { + super(in); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return DataType.DOUBLE; + } + + @Override + protected Expression.TypeResolution resolveType() { + return isType( + field(), + dt -> dt.isNumeric() && dt != DataType.UNSIGNED_LONG, + sourceText(), + DEFAULT, + "numeric except unsigned_long or counter types" + ); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, Variance::new, field(), filter()); + } + + @Override + public Variance replaceChildren(List newChildren) { + return new Variance(source(), newChildren.get(0), newChildren.get(1)); + } + + public Variance withFilter(Expression filter) { + return new Variance(source(), field(), filter); + } + + @Override + public final AggregatorFunctionSupplier supplier() { + DataType type = field().dataType(); + if (type == DataType.LONG) { + return new StdDevLongAggregatorFunctionSupplier(false); + } + if (type == DataType.INTEGER) { + return new StdDevIntAggregatorFunctionSupplier(false); + } + if (type == DataType.DOUBLE) { + return new StdDevDoubleAggregatorFunctionSupplier(false); + } + throw EsqlIllegalArgumentException.illegalDataType(type); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceOverTime.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceOverTime.java new file mode 100644 index 0000000000000..36821ce323580 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceOverTime.java @@ -0,0 +1,100 @@ +/* + * 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.function.aggregate; + +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.xpack.esql.core.expression.Expression; +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.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; +import org.elasticsearch.xpack.esql.expression.function.FunctionType; +import org.elasticsearch.xpack.esql.expression.function.Param; + +import java.io.IOException; +import java.util.List; + +import static java.util.Collections.emptyList; + +/** + * Similar to {@link Variance}, but it is used to calculate the variance over a time series of values from the given field. + */ +public class VarianceOverTime extends TimeSeriesAggregateFunction { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "VarianceOverTime", + VarianceOverTime::new + ); + + @FunctionInfo( + returnType = "double", + description = "Calculates the population variance over time of a numeric field.", + type = FunctionType.TIME_SERIES_AGGREGATE, + appliesTo = { @FunctionAppliesTo(lifeCycle = FunctionAppliesToLifecycle.PREVIEW, version = "9.2.0") }, + preview = true, + examples = { @Example(file = "k8s-timeseries", tag = "stdvar_over_time") } + ) + public VarianceOverTime( + Source source, + @Param( + name = "number", + type = { "double", "integer", "long" }, + description = "Expression that outputs values to calculate the variance of." + ) Expression field + ) { + this(source, field, Literal.TRUE); + } + + public VarianceOverTime(Source source, Expression field, Expression filter) { + super(source, field, filter, emptyList()); + } + + private VarianceOverTime(StreamInput in) throws IOException { + super(in); + } + + @Override + protected TypeResolution resolveType() { + return perTimeSeriesAggregation().resolveType(); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return perTimeSeriesAggregation().dataType(); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, VarianceOverTime::new, field(), filter()); + } + + @Override + public VarianceOverTime replaceChildren(List newChildren) { + return new VarianceOverTime(source(), newChildren.get(0), newChildren.get(1)); + } + + @Override + public VarianceOverTime withFilter(Expression filter) { + return new VarianceOverTime(source(), field(), filter); + } + + @Override + public AggregateFunction perTimeSeriesAggregation() { + return new Variance(source(), field(), filter()); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevTests.java index f78e04ec94e82..f070852dafddb 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdDevTests.java @@ -60,7 +60,7 @@ private static TestCaseSupplier makeSupplier(TestCaseSupplier.TypedDataSupplier var value = ((Number) fieldValue).doubleValue(); welfordAlgorithm.add(value); } - var result = welfordAlgorithm.evaluate(); + var result = welfordAlgorithm.evaluate(true); var expected = Double.isFinite(result) ? result : null; return new TestCaseSupplier.TestCase( List.of(fieldTypedData), diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StddevOverTimeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StddevOverTimeTests.java new file mode 100644 index 0000000000000..8956ec1ac13a3 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StddevOverTimeTests.java @@ -0,0 +1,34 @@ +/* + * 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.function.aggregate; + +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.List; +import java.util.function.Supplier; + +public class StddevOverTimeTests extends AbstractFunctionTestCase { + public StddevOverTimeTests(Supplier testCaseSupplier) { + testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + return StdDevTests.parameters(); + } + + @Override + protected Expression build(Source source, List args) { + return new StdDevOverTime(source, args.get(0)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdvarOverTimeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdvarOverTimeTests.java new file mode 100644 index 0000000000000..c9911a041c849 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/StdvarOverTimeTests.java @@ -0,0 +1,34 @@ +/* + * 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.function.aggregate; + +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.List; +import java.util.function.Supplier; + +public class StdvarOverTimeTests extends AbstractFunctionTestCase { + public StdvarOverTimeTests(Supplier testCaseSupplier) { + testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + return VarianceTests.parameters(); + } + + @Override + protected Expression build(Source source, List args) { + return new VarianceOverTime(source, args.get(0)); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceTests.java new file mode 100644 index 0000000000000..99b853b24c3d2 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/VarianceTests.java @@ -0,0 +1,74 @@ +/* + * 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.function.aggregate; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.elasticsearch.compute.aggregation.WelfordAlgorithm; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractAggregationTestCase; +import org.elasticsearch.xpack.esql.expression.function.MultiRowTestCaseSupplier; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.hamcrest.Matchers.equalTo; + +public class VarianceTests extends AbstractAggregationTestCase { + public VarianceTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + var suppliers = new ArrayList(); + + Stream.of( + MultiRowTestCaseSupplier.intCases(1, 1000, Integer.MIN_VALUE, Integer.MAX_VALUE, true), + MultiRowTestCaseSupplier.longCases(1, 1000, Long.MIN_VALUE, Long.MAX_VALUE, true), + MultiRowTestCaseSupplier.doubleCases(1, 1000, -Double.MAX_VALUE, Double.MAX_VALUE, true) + ).flatMap(List::stream).map(VarianceTests::makeSupplier).collect(Collectors.toCollection(() -> suppliers)); + + return parameterSuppliersFromTypedDataWithDefaultChecks(suppliers, true); + } + + @Override + protected Expression build(Source source, List args) { + return new Variance(source, args.get(0)); + } + + private static TestCaseSupplier makeSupplier(TestCaseSupplier.TypedDataSupplier fieldSupplier) { + return new TestCaseSupplier(List.of(fieldSupplier.type()), () -> { + var fieldTypedData = fieldSupplier.get(); + var fieldValues = fieldTypedData.multiRowData(); + + WelfordAlgorithm welfordAlgorithm = new WelfordAlgorithm(); + + for (var fieldValue : fieldValues) { + var value = ((Number) fieldValue).doubleValue(); + welfordAlgorithm.add(value); + } + var result = welfordAlgorithm.evaluate(false); + var expected = Double.isFinite(result) ? result : null; + return new TestCaseSupplier.TestCase( + List.of(fieldTypedData), + // Note that this stddev because it's the operator that implements both of these + standardAggregatorName("StdDev", fieldSupplier.type()), + DataType.DOUBLE, + equalTo(expected) + ); + }); + } +}