mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-12 15:02: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>
(cherry picked from commit f3a0841f4f)
Signed-off-by: WenyXu <wenymedia@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;
|