Skip to content

xlstream-eval: support text comparison operators in conditional criteria#188

Merged
cilladev merged 2 commits into
mainfrom
fix/countif-text-compare
Jun 7, 2026
Merged

xlstream-eval: support text comparison operators in conditional criteria#188
cilladev merged 2 commits into
mainfrom
fix/countif-text-compare

Conversation

@cilladev

@cilladev cilladev commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Fixes: #175
Fixes: #174

Problem

Two related bugs in conditional aggregate criteria:

  1. COUNTIF text operator criteria returns 0 #175: SUMIF/COUNTIF with text comparison operators (">b", ">=banana", "<banana") always returned 0. The criteria parser only handled numeric operands — non-numeric text fell through to Criteria::Equals with the full operator string as a literal, matching nothing.

  2. COUNTIF/COUNTIFS operator criteria counts unique matching values, not all rows #174: COUNTIF/COUNTIFS with any operator or wildcard criteria counted matching buckets instead of matching rows. try_operator_criteria re-folded already-finished per-bucket values using AggKind::Count, which counts feeds (one per bucket) instead of summing stored row counts.

Fix

  1. Text comparison variants: Add GreaterText, GreaterOrEqText, LessText, LessOrEqText to the Criteria enum. When an operator operand fails parse::<f64>(), the parser creates the text variant (lowercased) instead of falling through to Equals. Matching uses case-insensitive alphabetical comparison via a new text_for_compare helper, applied only to Value::Text cells.

  2. COUNT re-fold fix: try_operator_criteria now finishes with AggKind::Sum for Count kind — matching how the prelude builder stores row counts (each bucket's value is already the sum of 1.0-per-row feeds). This makes COUNTIF sum matching buckets' row counts instead of counting the number of matching buckets.

Changes

  • crates/xlstream-eval/src/criteria.rs: add 4 text-comparison enum variants; update parse() fallbacks; add text_for_compare helper; add match arms; update rustdoc.
  • crates/xlstream-eval/src/prelude.rs: try_operator_criteria uses AggKind::Sum finish for Count kind.
  • 7 unit tests: parse, greater/greater-or-eq/less/less-or-eq text matching, case insensitivity, non-text exclusion.
  • Conformance fixture with 13 Excel-populated cells: SUMIF text comparisons (5), COUNTIF text comparisons (4), COUNTIF wildcard (2), COUNTIF numeric operator (2).
  • docs/architecture/aggregates.md: sync Criteria enum listing with new variants.

Test plan

  • Regression unit tests added and pass (7 new, 33 total criteria tests)
  • Conformance fixture created (Excel-populated) and passes
  • cargo test -p xlstream-eval passes (2292 lib, no regressions)
  • make check passes

Closes #175
Closes #174

@cilladev cilladev merged commit 4dca6b0 into main Jun 7, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

COUNTIF text operator criteria returns 0 COUNTIF/COUNTIFS operator criteria counts unique matching values, not all rows

1 participant