Skip to content

Commit 5e1f1a6

Browse files
fix counts api to support OR and AND operators
1 parent 5b2e09f commit 5e1f1a6

2 files changed

Lines changed: 35 additions & 14 deletions

File tree

src/alerts/alert_structs.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,10 @@ pub struct ConditionConfig {
191191
#[serde(rename_all = "camelCase")]
192192
pub struct Conditions {
193193
pub operator: Option<LogicalOperator>,
194+
#[serde(default)]
194195
pub condition_config: Vec<ConditionConfig>,
196+
/// Nested condition groups for complex logic like (A OR B) AND (C OR D)
197+
pub groups: Option<Vec<Conditions>>,
195198
}
196199

197200
impl Conditions {

src/alerts/alerts_utils.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -388,21 +388,39 @@ fn extract_group_results(records: Vec<RecordBatch>, plan: LogicalPlan) -> AlertQ
388388
}
389389

390390
pub fn get_filter_string(where_clause: &Conditions) -> Result<String, String> {
391-
match &where_clause.operator {
392-
Some(op) => match op {
393-
&LogicalOperator::And => {
394-
let mut exprs = vec![];
395-
for condition in &where_clause.condition_config {
396-
exprs.push(condition_to_expr(condition)?);
397-
}
398-
Ok(exprs.join(" AND "))
399-
}
400-
_ => Err(String::from("Invalid option 'or', only 'and' is supported")),
401-
},
402-
_ => Err(String::from(
403-
"Invalid option 'null', only 'and' is supported",
404-
)),
391+
let op = where_clause
392+
.operator
393+
.as_ref()
394+
.ok_or_else(|| String::from("operator is required in conditions"))?;
395+
396+
let joiner = match op {
397+
LogicalOperator::And => " AND ",
398+
LogicalOperator::Or => " OR ",
399+
};
400+
401+
let mut exprs = vec![];
402+
403+
// Process flat condition_config entries
404+
for condition in &where_clause.condition_config {
405+
exprs.push(condition_to_expr(condition)?);
406+
}
407+
408+
// Process nested groups recursively
409+
if let Some(groups) = &where_clause.groups {
410+
for group in groups {
411+
let group_expr = get_filter_string(group)?;
412+
// Wrap each group in parentheses to preserve precedence
413+
exprs.push(format!("({group_expr})"));
414+
}
405415
}
416+
417+
if exprs.is_empty() {
418+
return Err(String::from(
419+
"conditions must have at least one condition or group",
420+
));
421+
}
422+
423+
Ok(exprs.join(joiner))
406424
}
407425

408426
fn condition_to_expr(condition: &ConditionConfig) -> Result<String, String> {

0 commit comments

Comments
 (0)