From e46f1f63e07616703609352637e7d605a5971a82 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Thu, 22 Oct 2026 23:58:11 +0800 Subject: [PATCH] fix(promql): keep fill_left and fill_right on their written sides under group_right Signed-off-by: Dennis Zhuang --- src/promql/src/vector_match.rs | 17 ++-- src/promql/src/vector_match/fill_cases.txt | 91 +++++++++++++--------- src/promql/src/vector_match/tests.rs | 4 +- 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/promql/src/vector_match.rs b/src/promql/src/vector_match.rs index e5e069f5485..c2e9e258f47 100644 --- a/src/promql/src/vector_match.rs +++ b/src/promql/src/vector_match.rs @@ -144,10 +144,8 @@ pub struct BinaryMatching { } /// The values of `fill`, `fill_left` and `fill_right`, which stand in for a sample that has no -/// match on the other side. -/// -/// Prometheus applies them after it swaps the operands of `group_right`, so there `fill_left` -/// stands in for a missing right-hand sample and `fill_right` for a missing left-hand one. +/// match on the other side: `lhs` for a missing left-hand sample and `rhs` for a missing +/// right-hand one, as the query writes them, `group_right` included (prometheus/prometheus#19939). #[derive(Clone, Copy, Debug, Default)] pub struct FillValues { pub lhs: Option, @@ -736,7 +734,16 @@ fn binary_field( } None => FieldMetadata::default(), }; - let fill = matching.fill; + // The walk below fills `rhs` for a missing one-side sample and `lhs` for a missing many-side + // one, so under `group_right`, whose one side is the left, the two trade places. + let fill = if one_is_left { + FillValues { + lhs: matching.fill.rhs, + rhs: matching.fill.lhs, + } + } else { + matching.fill + }; // Prometheus short-circuits a point where either side is empty, before any check; with a fill // value only a point where both are empty. let filling = fill.lhs.is_some() || fill.rhs.is_some(); diff --git a/src/promql/src/vector_match/fill_cases.txt b/src/promql/src/vector_match/fill_cases.txt index 3d6213c2c89..79f64f6e841 100644 --- a/src/promql/src/vector_match/fill_cases.txt +++ b/src/promql/src/vector_match/fill_cases.txt @@ -1,4 +1,4 @@ -# Generated by promql-compat cmd/narthex-golden-vector built for amd64 (Prometheus v3.15.0 +# Generated by promql-compat cmd/narthex-golden-vector built for amd64 (Prometheus v0.314.0-rc.0.0.20261013115751-351c7f6548b2 # engine, seed 1, 200 cases per kind, -experimental fill). Each case lists its operation, the grid, the # input series and either the result series or the error. Points are `grid index:hex bits`. case binary - false ignoring zone one - 1 1 @@ -197,7 +197,7 @@ grid 100000 10000 1 series __name__=a,host=h2,job=y,zone=z1 ; 0:4086be0000000000 series __name__=b,host=h2,job=y,zone=z1 ; 0:c0898b0000000000 series __name__=b,host=h1,job=y ; 0:c072680000000000 -result host=h1 ; 0:7ff8000000000001 +result host=h1 ; 0:3f8162a981f4b312 result host=h2,job=y,zone=z1 ; 0:bfec7dbfb7568f5e end case binary ^ false on job one - - 1 @@ -247,9 +247,9 @@ series __name__=a,host=h2,job=x,zone=z1 ; 1:406cf80000000000 2:4071a40000000000 series __name__=a,host=h1,job=y ; 0:408eb30000000000 1:c085ad0000000000 2:4066e80000000000 3:407ea60000000000 5:c080320000000000 series __name__=a,host=h2,job=y,zone=z1 ; series __name__=b,host=h2,job=x ; 6:c07a260000000000 -result host=h1 ; 0:408eb30000000000 1:c085ad0000000000 2:4066e80000000000 3:407ea60000000000 5:c080320000000000 -result host=h2,job=x ; 6:7ff0000000000000 -result host=h2,zone=z1 ; 1:406cf80000000000 2:4071a40000000000 5:c08a6e0000000000 6:408a5d0000000000 +result host=h1 ; 0:7ff0000000000000 1:7ff0000000000000 2:7ff0000000000000 3:7ff0000000000000 5:7ff0000000000000 +result host=h2,job=x ; 6:c07a260000000000 +result host=h2,zone=z1 ; 1:7ff0000000000000 2:7ff0000000000000 5:7ff0000000000000 6:7ff0000000000000 end case binary / false ignoring job left zone - 1 grid 100000 10000 7 @@ -312,13 +312,13 @@ series __name__=b,host=h2,job=y,zone=z1 ; 2:c07a780000000000 3:406a400000000000 series __name__=b,host=h1,job=x ; 5:7ff8000000000001 6:4084bf0000000000 series __name__=b,host=h1,job=x,zone=z1 ; 5:c06f5c0000000000 7:7ff8000000000001 series __name__=b,host=h2,job=y ; 1:c0746e0000000000 2:40870f0000000000 3:4083c60000000000 -result host=h1,job=x ; 7:fff0000000000000 -result host=h1,job=x,zone=z1 ; 3:7ff8000000000001 4:7ff0000000000000 5:c103348fe0000000 6:7ff0000000000000 -result host=h2,job=y ; 4:7ff0000000000000 5:7ff0000000000000 7:fff0000000000000 -result job=x ; 5:7ff8000000000001 6:c099eec000000000 +result host=h1,job=x ; 7:4081530000000000 +result host=h1,job=x,zone=z1 ; 3:7ff8000000000001 4:c0858d8000000000 5:c103348fe0000000 6:c0a3164000000000 +result host=h2,job=y ; 4:c083600000000000 5:c0985d8000000000 7:4081558000000000 +result job=x ; 5:7ff8000000000001 6:7ff0000000000000 result job=x,zone=z1 ; 7:7ff8000000000001 -result job=y ; 1:4089898000000000 2:c09cd2c000000000 3:c098b78000000000 -result job=y,zone=z1 ; 2:40908b0000000000 3:c080680000000000 4:c06bc60000000000 +result job=y ; 1:fff0000000000000 2:7ff0000000000000 3:7ff0000000000000 +result job=y,zone=z1 ; 2:fff0000000000000 3:7ff0000000000000 4:7ff0000000000000 end case binary % false ignoring host,job,zone right host,zone NaN NaN grid 100000 10000 12 @@ -336,7 +336,6 @@ series __name__=a,host=h1,job=x ; 0:c067700000000000 series __name__=b,host=h1,job=y,zone=z1 ; series __name__=b,host=h1,job=x ; 0:4065d80000000000 result host=h1,job=x ; 0:c029800000000000 -result host=h2,job=y ; 0:7ff0000000000000 end case binary > true on host,job,zone right - 0 - grid 100000 10000 11 @@ -347,14 +346,16 @@ series __name__=b,host=h1,job=x,zone=z1 ; 7:4085780000000000 8:c085210000000000 series __name__=b,host=h1,job=x ; 5:c0789e0000000000 7:7ff8000000000001 series __name__=b,host=h2,job=y ; 8:404d400000000000 series __name__=b,host=h1,job=x,zone=z2 ; 10:40864f0000000000 -result host=h1,job=x ; 3:0 -result host=h1,job=x,zone=z1 ; 2:0 3:3ff0000000000000 4:0 5:3ff0000000000000 6:0 7:0 8:0 -result host=h1,job=y ; 2:3ff0000000000000 3:0 4:0 6:0 7:3ff0000000000000 8:0 +result host=h1,job=x ; 5:3ff0000000000000 7:0 +result host=h1,job=x,zone=z1 ; 7:0 8:0 9:3ff0000000000000 +result host=h1,job=x,zone=z2 ; 10:0 +result host=h2,job=y ; 8:0 end case binary < false ignoring job,zone right - - 1 grid 100000 10000 4 series __name__=a,host=h1,job=y,zone=z1 ; 0:4087720000000000 1:4082dd0000000000 2:0 3:c07b700000000000 series __name__=b,host=h1,job=y,zone=z1 ; 0:c0705a0000000000 1:c0866e0000000000 +result host=h1 ; 2:0 3:c07b700000000000 end case binary + false none - one - NaN - grid 100000 10000 12 @@ -441,6 +442,9 @@ series __name__=a,host=h2,job=x,zone=z1 ; 0:c0878a0000000000 series __name__=a,host=h1,job=y ; 0:c0838a0000000000 series __name__=b,host=h1,job=y ; series __name__=b,host=h1,job=y,zone=z2 ; +result job=x ; 0:7ff0000000000000 +result job=x,zone=z1 ; 0:7ff0000000000000 +result job=y ; 0:7ff0000000000000 end case binary == true ignoring zone left job Inf Inf grid 100000 10000 5 @@ -480,7 +484,9 @@ series __name__=a,host=h1,job=y ; 8:7e37e43c8800759c series __name__=a,host=h2,job=y ; 6:c05e480000000000 7:c084800000000000 series __name__=a,host=h2,job=y,zone=z1 ; 1:c08c670000000000 2:407bd00000000000 3:0 4:4078840000000000 5:40781a0000000000 6:40849c0000000000 8:408ea10000000000 9:40743e0000000000 10:4075fa0000000000 series __name__=b,host=h1,job=y ; 7:c08a420000000000 9:405f180000000000 -result host=h1,job=y ; 7:0 9:3ff0000000000000 +result host=h1 ; 8:0 +result host=h2 ; 6:3ff0000000000000 7:3ff0000000000000 +result host=h2,zone=z1 ; 1:3ff0000000000000 2:0 3:0 4:0 5:0 6:0 8:0 9:0 10:0 end case binary % false on job left zone NaN NaN grid 100000 10000 1 @@ -542,8 +548,9 @@ series __name__=a,host=h2,job=y ; 5:4086fd0000000000 6:408ced0000000000 8:c07d6e series __name__=a,host=h1,job=x ; 4:407b060000000000 5:c068b40000000000 6:c07bee0000000000 series __name__=b,host=h2,job=y ; 4:4059c00000000000 5:4083760000000000 series __name__=b,host=h1,job=x ; 2:c084730000000000 3:408ac60000000000 4:4042d00000000000 5:c08daf0000000000 6:40736c0000000000 7:40785a0000000000 -result __name__=b,host=h1,job=x ; 6:c07bee0000000000 -result host=h2,job=y ; 8:c07d6e0000000000 +result __name__=b,host=h1,job=x ; 3:0 6:c07bee0000000000 7:0 +result __name__=b,host=h2,job=y ; 4:0 +result host=h2,job=y ; 6:408ced0000000000 8:c07d6e0000000000 end case binary / false none - one - - Inf grid 100000 10000 4 @@ -701,8 +708,6 @@ grid 100000 10000 8 series __name__=a,host=h2,job=y ; series __name__=b,host=h2,job=x ; 1:40800c0000000000 2:40756e0000000000 series __name__=b,host=h2,job=y ; 2:407a100000000000 5:c08efe0000000000 6:4051a00000000000 7:40750e0000000000 -result host=h2,job=x ; 1:0 2:0 -result host=h2,job=y ; 2:0 5:0 6:0 7:0 end case binary * false ignoring job one - Inf Inf grid 100000 10000 10 @@ -746,7 +751,7 @@ series __name__=a,host=h2,job=x ; series __name__=b,host=h1,job=x ; 5:c077520000000000 series __name__=b,host=h2,job=x,zone=z1 ; 3:40746c0000000000 4:0 5:4076260000000000 result host=h1,job=x ; 5:bff5479c8412de20 -result host=h2,job=x,zone=z1 ; 3:0 4:fff8000000000000 5:0 +result host=h2,job=y ; 2:fff0000000000000 3:7ff0000000000000 4:fff0000000000000 5:fff0000000000000 end case binary == false none - one - - 0 grid 100000 10000 4 @@ -816,6 +821,8 @@ series __name__=b,host=h1,job=x ; 4:405fd00000000000 series __name__=b,host=h2,job=x,zone=z1 ; 2:c088f70000000000 3:c08ed80000000000 result __name__=b,host=h1,job=x,zone=z1 ; 2:c083350000000000 result __name__=b,host=h2,job=x,zone=z1 ; 3:c065f80000000000 +result host=h2 ; 2:4072720000000000 +result host=h2,zone=z1 ; 5:408f3d0000000000 end case binary % false ignoring - left host,job,zone - 1 grid 100000 10000 5 @@ -885,7 +892,8 @@ grid 100000 10000 8 series __name__=a,host=h1,job=x ; 4:c07afe0000000000 5:4083ab0000000000 series __name__=b,host=h1,job=x ; 2:c089f00000000000 series __name__=b,host=h2,job=y ; 0:7ff0000000000000 1:4085c60000000000 -result host=h1 ; 4:0 5:0 +result host=h1,job=x ; 2:0 +result host=h2,job=y ; 0:0 1:0 end case binary >= false on host,job left zone - 1 grid 100000 10000 3 @@ -998,6 +1006,8 @@ series __name__=a,host=h2,job=x ; 5:40844e0000000000 series __name__=a,host=h1,job=y,zone=z1 ; 3:c072a40000000000 4:4064a00000000000 5:40797e0000000000 6:c086d30000000000 series __name__=b,host=h1,job=y,zone=z1 ; 5:c0805a0000000000 series __name__=b,host=h2,job=x,zone=z1 ; 5:c076a80000000000 6:4088a20000000000 7:40833b0000000000 +result job=x ; 5:40844e0000000000 +result job=y,zone=z1 ; 3:c072a40000000000 4:4064a00000000000 6:c086d30000000000 end case binary > false on - one - - NaN grid 100000 10000 9 @@ -1151,7 +1161,6 @@ case binary <= true ignoring zone,__name__ right host,zone - 0 grid 100000 10000 10 series __name__=a,host=h2,job=y,zone=z1 ; series __name__=b,host=h2,job=y,zone=z1 ; 9:c06bd40000000000 -result host=h2,job=y ; 9:0 end case binary > false on zone one - 0 - grid 100000 10000 2 @@ -1235,8 +1244,6 @@ grid 100000 10000 6 series __name__=a,host=h2,job=x ; series __name__=b,host=h2,job=x,zone=z1 ; 3:403ae00000000000 4:c08a2b0000000000 series __name__=b,host=h2,job=y ; 5:c086880000000000 -result host=h2,job=x,zone=z1 ; 3:3ff0000000000000 4:3ff0000000000000 -result host=h2,job=y ; 5:3ff0000000000000 end case binary < false none - one - Inf Inf grid 100000 10000 6 @@ -1327,7 +1334,9 @@ series __name__=a,host=h2,job=x ; 2:407a6a0000000000 series __name__=a,host=h2,job=y ; 0:0 1:4080950000000000 2:4089ce0000000000 3:c079060000000000 series __name__=a,host=h2,job=x,zone=z1 ; 5:4070680000000000 series __name__=b,host=h2,job=y ; 1:4058480000000000 2:4080f50000000000 -result host=h2,job=y ; 1:76e18773d32422b0 2:7ff0000000000000 +result host=h2,job=x ; 2:3ff0000000000000 +result host=h2,job=x,zone=z1 ; 5:3ff0000000000000 +result host=h2,job=y ; 0:3ff0000000000000 1:76e18773d32422b0 2:7ff0000000000000 3:3ff0000000000000 end case binary - false ignoring - right job,zone NaN - grid 100000 10000 5 @@ -1339,9 +1348,10 @@ series __name__=b,host=h2,job=x ; 3:4049600000000000 series __name__=b,host=h2,job=x,zone=z2 ; 1:c089410000000000 series __name__=b,host=h1,job=y,zone=z2 ; 1:4063e00000000000 series __name__=b,host=h1,job=y ; 2:c0801b0000000000 3:c086a20000000000 4:4074960000000000 -result host=h1,job=y ; 4:407fac0000000000 -result host=h2,job=x ; 2:7ff8000000000001 3:c0808b0000000000 -result host=h2,job=y ; 4:7ff8000000000001 +result host=h1,job=y ; 2:7ff8000000000001 3:7ff8000000000001 4:407fac0000000000 +result host=h1,job=y,zone=z2 ; 1:7ff8000000000001 +result host=h2,job=x ; 3:c0808b0000000000 +result host=h2,job=x,zone=z2 ; 1:7ff8000000000001 end case binary <= false ignoring host one - - 1 grid 100000 10000 2 @@ -1362,8 +1372,8 @@ series __name__=a,host=h1,job=y ; series __name__=a,host=h2,job=x ; 0:4046e00000000000 1:c081960000000000 2:40812b0000000000 3:c08f1c0000000000 4:4079d40000000000 series __name__=b,host=h2,job=x,zone=z1 ; 3:4089100000000000 series __name__=b,host=h1,job=x ; 1:c085590000000000 2:4089750000000000 3:4021800000000000 -result host=h1,job=x ; 1:7ff8000000000001 2:7ff8000000000001 3:7ff8000000000001 -result host=h2,job=x,zone=z1 ; 3:7ff8000000000001 +result host=h1,zone=z1 ; 1:7ff8000000000001 2:7ff8000000000001 4:7ff8000000000001 +result host=h2 ; 0:7ff8000000000001 1:7ff8000000000001 2:7ff8000000000001 3:7ff8000000000001 4:7ff8000000000001 end case binary - false on zone right job -2.5 0 grid 100000 10000 5 @@ -1373,11 +1383,11 @@ series __name__=b,host=h2,job=x,zone=z1 ; series __name__=b,host=h2,job=y,zone=z1 ; 0:c0706a0000000000 1:4088500000000000 series __name__=b,host=h1,job=x ; 3:c04cb00000000000 series __name__=b,host=h2,job=x ; 4:7ff8000000000001 -result host=h1 ; 3:404cb00000000000 +result host=h1 ; 3:404b700000000000 result host=h2,job=x ; 4:7ff8000000000001 result host=h2,job=y,zone=z1 ; 1:c074aa0000000000 -result host=h2,zone=z1 ; 0:40706a0000000000 -result job=y,zone=z1 ; 2:408f130000000000 3:7ff8000000000001 4:fff0000000000000 +result host=h2,zone=z1 ; 0:4070420000000000 +result job=y,zone=z1 ; 2:408eff0000000000 3:7ff8000000000001 4:fff0000000000000 end case binary <= true ignoring host left - 0 1 grid 100000 10000 1 @@ -1500,6 +1510,7 @@ case binary * false ignoring host,zone right job,zone - 1 grid 100000 10000 1 series __name__=a,host=h2,job=x ; 0:4070d80000000000 series __name__=b,host=h2,job=y ; +result job=x ; 0:4070d80000000000 end case binary % false on - left host - -2.5 grid 100000 10000 8 @@ -1590,6 +1601,7 @@ series __name__=a,host=h2,job=y ; 4:c08e420000000000 5:407ae20000000000 6:7ff800 series __name__=a,host=h1,job=y ; 2:c08bf20000000000 series __name__=b,host=h1,job=x ; 4:4051c00000000000 result host=h1,job=x ; 4:3ff0000000000000 +result job=y ; 2:3ff0000000000000 4:3ff0000000000000 5:0 6:0 end case binary - false on zone left job NaN - grid 100000 10000 3 @@ -1652,6 +1664,9 @@ series __name__=a,host=h2,job=y ; 2:7ff8000000000001 4:40821e0000000000 series __name__=b,host=h2,job=y ; 7:c08a5d0000000000 series __name__=b,host=h1,job=y ; 1:408bd70000000000 2:4056380000000000 3:fff0000000000000 series __name__=b,host=h2,job=y,zone=z2 ; 7:4088e20000000000 8:4080ad0000000000 +result __name__=b,host=h1,job=y ; 1:7ff0000000000000 2:7ff0000000000000 3:7ff0000000000000 +result __name__=b,host=h2,job=y ; 7:7ff0000000000000 +result __name__=b,host=h2,job=y,zone=z2 ; 7:7ff0000000000000 8:7ff0000000000000 end case binary % false on job left - -2.5 -2.5 grid 100000 10000 8 @@ -1726,9 +1741,11 @@ series __name__=a,host=h1,job=y,zone=z1 ; 4:4080f70000000000 5:c058380000000000 series __name__=b,host=h2,job=y ; 5:4084e80000000000 6:7ff8000000000001 7:40874b0000000000 series __name__=b,host=h2,job=x,zone=z2 ; 0:4072760000000000 3:40809b0000000000 5:7ff8000000000001 series __name__=b,host=h2,job=x ; 4:c064a00000000000 5:fff0000000000000 -result host=h2,job=x ; 4:0 5:7ff8000000000001 -result host=h2,job=x,zone=z2 ; 0:7ff8000000000001 3:7ff8000000000001 5:7ff8000000000001 -result host=h2,job=y ; 5:7ff8000000000001 6:7ff8000000000001 7:7ff8000000000001 +result host=h1,job=x ; 2:7ff8000000000001 3:7ff8000000000001 4:7ff8000000000001 5:7ff8000000000001 7:7ff8000000000001 +result host=h1,job=y,zone=z1 ; 4:7ff8000000000001 5:7ff8000000000001 +result host=h2,job=x ; 4:0 +result host=h2,job=x,zone=z1 ; 1:7ff8000000000001 2:7ff8000000000001 3:7ff8000000000001 4:7ff8000000000001 5:7ff8000000000001 +result host=h2,job=y ; 6:7ff8000000000001 end case binary - false ignoring host,zone left host,job,zone - 1 grid 100000 10000 10 diff --git a/src/promql/src/vector_match/tests.rs b/src/promql/src/vector_match/tests.rs index ec7671c9eb6..1ce00063033 100644 --- a/src/promql/src/vector_match/tests.rs +++ b/src/promql/src/vector_match/tests.rs @@ -703,8 +703,8 @@ fn vector_operations_match_prometheus() { ); } -/// Binary operations with fill modifiers, evaluated by the Prometheus v3.15.0 engine; see the -/// header of `fill_cases.txt`. +/// Binary operations with fill modifiers, evaluated by the Prometheus engine named in the header of +/// `fill_cases.txt`. #[test] fn fill_modifiers_match_prometheus() { let (matched, failed) = check_cases(include_str!("fill_cases.txt"));