mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-13 07:22:32 +00:00
* fix(promql): follow IEEE 754 float semantics in operators and aggregations - Comparisons: Arrow orders floats totally (NaN == NaN, NaN > +Inf); PromQL comparisons with NaN are false except !=. - min/max: skip NaN unless the whole group is NaN. DataFusion's grouped min/max let NaN replace and be replaced by neighbours, so the result depended on input order. - topk/bottomk rank NaN last. - round() rounds ties up and returns NaN for a zero step, like Prometheus. - sqrt() of a negative number is NaN instead of an error. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): round() without a step rounds to integers The planner passed a zero step for single-argument round(), which now yields NaN like Prometheus; pass 1 instead. Found by the compatibility harness. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): apply the sqrt guard to builtin functions and register min/max for plan decoding sqrt resolves through the session's builtin functions, not the UDF branch. Distributed plans are decoded with the serializer's session, which did not know prom_min/prom_max. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test(promql): cover NaN and rounding semantics Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): keep the nested count rewrite for PromQL min/max count(min(x) by (l)) was rewritten by count_nest_aggr only for the builtin min/max names. prom_min/prom_max return NULL for the same groups, so the rewrite stays valid. Update plan snapshots for the IEEE comparison, sqrt, topk and min/max changes. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): register prom_min/prom_max in the function registry Distributed plans split an aggregation into state and merge steps only for functions whose state function exists in FUNCTION_REGISTRY; prom_min and prom_max lived in the promql crate, so min/max stopped being pushed down to datanodes. Move them to common-function and register them before the state functions are derived. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test: update sqlness results for PromQL float semantics Plans and column names now show prom_min/prom_max, the NaN guards of comparisons and sqrt, and the NaN sort key of topk. round() results follow Prometheus' formula. Distributed min/max keep the state/merge split. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): keep column names and NULLs in IEEE comparisons and sqrt Rewriting comparisons as `a op b AND NOT (isnan(a) OR isnan(b))` changed TQL output column names and turned NULL operands into true for `!=` and false for the bool forms. Implement comparisons and sqrt as PromQL UDFs that propagate NULL and report the column name of the expression they replace; prom_min/prom_max report min/max column names the same way. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test: restore column names in sqlness results for PromQL float semantics Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test(promql): share the prom_min/prom_max groups accumulator with tests Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(promql): keep distinct names for prom_min/prom_max Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
42 lines
1.1 KiB
SQL
42 lines
1.1 KiB
SQL
-- NaN and rounding follow Prometheus (IEEE 754) rather than SQL ordering.
|
|
-- Expected results are from Prometheus 3.
|
|
|
|
create table float_semantics (
|
|
ts timestamp time index,
|
|
val double,
|
|
host string primary key
|
|
);
|
|
|
|
insert into float_semantics values
|
|
(0, 1.0, 'a'),
|
|
(0, 2.0, 'b'),
|
|
(0, 'NaN'::double, 'c'),
|
|
(0, -2.5, 'd');
|
|
|
|
tql eval (0, 0, '1s') max(float_semantics);
|
|
|
|
tql eval (0, 0, '1s') min(float_semantics);
|
|
|
|
tql eval (0, 0, '1s') topk(1, float_semantics);
|
|
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
tql eval (0, 0, '1s') float_semantics <= NaN;
|
|
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
tql eval (0, 0, '1s') float_semantics != bool NaN;
|
|
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
tql eval (0, 0, '1s') round(float_semantics);
|
|
|
|
-- SQLNESS SORT_RESULT 3 1
|
|
tql eval (0, 0, '1s') sqrt(float_semantics);
|
|
|
|
-- prom_min/prom_max have their own column names, so SQL can use them next to min/max.
|
|
select min(val) as sql_lo, prom_min(val) as prom_lo from float_semantics;
|
|
|
|
select max(val) as sql_hi, prom_max(val) as prom_hi from float_semantics;
|
|
|
|
select prom_min(val) as lo from float_semantics having min(val) < 0;
|
|
|
|
drop table float_semantics;
|