@@ -100,8 +100,38 @@ impl VectorMatchCardinality {
100100 }
101101}
102102
103+ /// VectorMatchFillValues contains the fill values to use for Vector matching
104+ /// when one side does not find a match on the other side.
105+ /// When a fill value is nil, no fill is applied for that side, and there
106+ /// is no output for the match group if there is no match.
107+ #[ derive( Debug , Clone , PartialEq , Default ) ]
108+ #[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
109+ pub struct VectorMatchFillValues {
110+ pub rhs : Option < f64 > ,
111+ pub lhs : Option < f64 > ,
112+ }
113+
114+ impl VectorMatchFillValues {
115+ pub fn new ( lhs : f64 , rhs : f64 ) -> Self {
116+ Self {
117+ rhs : Some ( rhs) ,
118+ lhs : Some ( lhs) ,
119+ }
120+ }
121+
122+ pub fn with_rhs ( mut self , rhs : f64 ) -> Self {
123+ self . rhs = Some ( rhs) ;
124+ self
125+ }
126+
127+ pub fn with_lhs ( mut self , lhs : f64 ) -> Self {
128+ self . lhs = Some ( lhs) ;
129+ self
130+ }
131+ }
132+
103133/// Binary Expr Modifier
104- #[ derive( Debug , Clone , PartialEq , Eq ) ]
134+ #[ derive( Debug , Clone , PartialEq ) ]
105135pub struct BinModifier {
106136 /// The matching behavior for the operation if both operands are Vectors.
107137 /// If they are not this field is None.
@@ -112,6 +142,9 @@ pub struct BinModifier {
112142 pub matching : Option < LabelModifier > ,
113143 /// If a comparison operator, return 0/1 rather than filtering.
114144 pub return_bool : bool ,
145+ /// Fill-in values to use when a series from one side does not find a match
146+ /// on the other side.
147+ pub fill_values : VectorMatchFillValues ,
115148}
116149
117150impl fmt:: Display for BinModifier {
@@ -132,6 +165,21 @@ impl fmt::Display for BinModifier {
132165 _ => ( ) ,
133166 }
134167
168+ if self . fill_values . rhs . is_some ( ) || self . fill_values . lhs . is_some ( ) {
169+ if self . fill_values . rhs == self . fill_values . lhs {
170+ let fill_value = self . fill_values . rhs . unwrap ( ) ;
171+ write ! ( s, "fill ({fill_value}) " ) ?;
172+ } else {
173+ if let Some ( fill_value) = self . fill_values . lhs {
174+ write ! ( s, "fill_left ({fill_value}) " ) ?;
175+ }
176+
177+ if let Some ( fill_value) = self . fill_values . rhs {
178+ write ! ( s, "fill_right ({fill_value}) " ) ?;
179+ }
180+ }
181+ }
182+
135183 if s. trim ( ) . is_empty ( ) {
136184 write ! ( f, "" )
137185 } else {
@@ -146,6 +194,7 @@ impl Default for BinModifier {
146194 card : VectorMatchCardinality :: OneToOne ,
147195 matching : None ,
148196 return_bool : false ,
197+ fill_values : VectorMatchFillValues :: default ( ) ,
149198 }
150199 }
151200}
@@ -166,6 +215,11 @@ impl BinModifier {
166215 self
167216 }
168217
218+ pub fn with_fill_values ( mut self , fill_values : VectorMatchFillValues ) -> Self {
219+ self . fill_values = fill_values;
220+ self
221+ }
222+
169223 pub fn is_labels_joint ( & self ) -> bool {
170224 matches ! (
171225 ( self . card. labels( ) , & self . matching) ,
@@ -255,6 +309,7 @@ where
255309 "include" : [ ] ,
256310 "labels" : labels,
257311 "on" : true ,
312+ "fillValues" : t. fill_values,
258313 } ) ;
259314 map. serialize_value ( & value) ?;
260315 }
@@ -264,6 +319,7 @@ where
264319 "include" : [ ] ,
265320 "labels" : labels,
266321 "on" : false ,
322+ "fillValues" : t. fill_values,
267323 } ) ;
268324 map. serialize_value ( & value) ?;
269325 }
@@ -274,6 +330,7 @@ where
274330 "include" : [ ] ,
275331 "labels" : [ ] ,
276332 "on" : false ,
333+ "fillValues" : t. fill_values,
277334 } ) ;
278335 map. serialize_entry ( "matching" , & value) ?;
279336 }
@@ -322,7 +379,7 @@ where
322379 map. end ( )
323380}
324381
325- #[ derive( Debug , Clone , PartialEq , Eq ) ]
382+ #[ derive( Debug , Clone , PartialEq ) ]
326383pub enum Offset {
327384 Pos ( Duration ) ,
328385 Neg ( Duration ) ,
@@ -359,7 +416,7 @@ impl fmt::Display for Offset {
359416 }
360417}
361418
362- #[ derive( Debug , Clone , PartialEq , Eq ) ]
419+ #[ derive( Debug , Clone , PartialEq ) ]
363420pub enum AtModifier {
364421 Start ,
365422 End ,
@@ -487,7 +544,7 @@ impl fmt::Display for EvalStmt {
487544/// ```
488545///
489546/// parameter is only required for `count_values`, `quantile`, `topk` and `bottomk`.
490- #[ derive( Debug , Clone , PartialEq , Eq ) ]
547+ #[ derive( Debug , Clone , PartialEq ) ]
491548#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
492549pub struct AggregateExpr {
493550 /// The used aggregation operation.
@@ -544,7 +601,7 @@ impl Prettier for AggregateExpr {
544601}
545602
546603/// UnaryExpr will negate the expr
547- #[ derive( Debug , Clone , PartialEq , Eq ) ]
604+ #[ derive( Debug , Clone , PartialEq ) ]
548605pub struct UnaryExpr {
549606 pub expr : Box < Expr > ,
550607}
@@ -587,7 +644,7 @@ impl serde::Serialize for UnaryExpr {
587644/// <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
588645/// <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
589646/// ```
590- #[ derive( Debug , Clone , PartialEq , Eq ) ]
647+ #[ derive( Debug , Clone , PartialEq ) ]
591648#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
592649pub struct BinaryExpr {
593650 /// The operation of the expression.
@@ -658,7 +715,7 @@ impl Prettier for BinaryExpr {
658715 }
659716}
660717
661- #[ derive( Debug , Clone , PartialEq , Eq ) ]
718+ #[ derive( Debug , Clone , PartialEq ) ]
662719#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
663720pub struct ParenExpr {
664721 pub expr : Box < Expr > ,
@@ -685,7 +742,7 @@ impl Prettier for ParenExpr {
685742/// ```norust
686743/// <instant_query> '[' <range> ':' [<resolution>] ']' [ @ <float_literal> ] [ offset <duration> ]
687744/// ```
688- #[ derive( Debug , Clone , PartialEq , Eq ) ]
745+ #[ derive( Debug , Clone , PartialEq ) ]
689746#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
690747pub struct SubqueryExpr {
691748 pub expr : Box < Expr > ,
@@ -805,7 +862,7 @@ impl Prettier for NumberLiteral {
805862 }
806863}
807864
808- #[ derive( Debug , Clone , PartialEq , Eq ) ]
865+ #[ derive( Debug , Clone , PartialEq ) ]
809866#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
810867pub struct StringLiteral {
811868 pub val : String ,
@@ -823,7 +880,7 @@ impl Prettier for StringLiteral {
823880 }
824881}
825882
826- #[ derive( Debug , Clone , PartialEq , Eq ) ]
883+ #[ derive( Debug , Clone , PartialEq ) ]
827884#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
828885pub struct VectorSelector {
829886 pub name : Option < String > ,
@@ -928,7 +985,7 @@ impl Prettier for VectorSelector {
928985 }
929986}
930987
931- #[ derive( Debug , Clone , PartialEq , Eq ) ]
988+ #[ derive( Debug , Clone , PartialEq ) ]
932989#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
933990pub struct MatrixSelector {
934991 #[ cfg_attr( feature = "ser" , serde( flatten) ) ]
@@ -1010,7 +1067,7 @@ impl Prettier for MatrixSelector {
10101067/// - sinh()
10111068/// - tan()
10121069/// - tanh()
1013- #[ derive( Debug , Clone , PartialEq , Eq ) ]
1070+ #[ derive( Debug , Clone , PartialEq ) ]
10141071#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
10151072pub struct Call {
10161073 pub func : Function ,
@@ -1061,7 +1118,7 @@ impl PartialEq for Extension {
10611118
10621119impl Eq for Extension { }
10631120
1064- #[ derive( Debug , Clone , PartialEq , Eq ) ]
1121+ #[ derive( Debug , Clone , PartialEq ) ]
10651122#[ cfg_attr( feature = "ser" , derive( serde:: Serialize ) ) ]
10661123#[ cfg_attr( feature = "ser" , serde( tag = "type" , rename_all = "camelCase" ) ) ]
10671124pub enum Expr {
@@ -1988,6 +2045,17 @@ mod tests {
19882045 ( "a - on(b) group_left c" , "a - on (b) group_left () c" ) ,
19892046 ( "a - ignoring(b) c" , "a - ignoring (b) c" ) ,
19902047 ( "a - ignoring() c" , "a - c" ) ,
2048+ ( "a + fill(-23) b" , "a + fill (-23) b" ) ,
2049+ ( "a + fill_left(-23) b" , "a + fill_left (-23) b" ) ,
2050+ ( "a + fill_right(42) b" , "a + fill_right (42) b" ) ,
2051+ (
2052+ "a + fill_left(-23) fill_right(42) b" ,
2053+ "a + fill_left (-23) fill_right (42) b" ,
2054+ ) ,
2055+ (
2056+ "a + on(b) group_left fill(-23) c" ,
2057+ "a + on (b) group_left () fill (-23) c" ,
2058+ ) ,
19912059 ( "up > bool 0" , "up > bool 0" ) ,
19922060 ( "a offset 1m" , "a offset 1m" ) ,
19932061 ( "a offset -7m" , "a offset -7m" ) ,
0 commit comments