Skip to content

fix(formula-engine): typed equality for = and <> (closes #68)#107

Merged
garritfra merged 2 commits into
mainfrom
fix/68-string-equality
May 7, 2026
Merged

fix(formula-engine): typed equality for = and <> (closes #68)#107
garritfra merged 2 commits into
mainfrom
fix/68-string-equality

Conversation

@garritfra
Copy link
Copy Markdown
Owner

Summary

  • = and <> now do typed comparison instead of coercing both operands to f64. Closes Equality operator (=) should work on strings #68.
  • Text vs. text uses Unicode-aware case-insensitive compare (matches Excel/Google Sheets).
  • Mixed-type comparisons return FALSE for = / TRUE for <> rather than #VALUE!.
  • Ordering operators (<, <=, >, >=) remain numeric-only — that's the deferred scope from Equality operator (=) should work on strings #68 and is now tracked separately in Lexicographic ordering for <, <=, >, >= on text #105.
  • A regression test (eval_ordering_on_text_still_errors) locks in the current ordering-on-text behaviour so any future relaxation is an explicit decision.
  • New = / <> entry in FORMULA_ENTRIES documenting the type-by-type rules and the case-insensitivity choice.

Excel / Sheets parity

Verified by hand against Excel and Google Sheets. Matches:

  • "foo"="foo" / "foo"="FOO" (case-insensitive) → TRUE
  • 1="1" / TRUE="TRUE" / TRUE=1 (mixed types) → FALSE
  • 1<>"1" → TRUE

Two follow-ups filed for the divergences I found while verifying:

Neither is in scope for this PR.

Test plan

  • cargo test --workspace — 36/36 eval tests pass, 32/32 integration tests pass
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • cargo fmt --all --check clean
  • 11 new eval-layer tests covering text/text, bool/bool, mixed types, the issue's IF(A1=C3, A2, 0) example with text cells, and case-insensitivity
  • Manual: existing numeric = / <> and ordering tests still pass (no regression)

🤖 Generated with Claude Code

garritfra and others added 2 commits May 7, 2026 13:49
Closes #68.

Previously `=` and `<>` unconditionally coerced both operands to
numbers, so `IF(A1=C3, A2, 0)` returned `#VALUE!` when either cell
held text. Switch the equality arm to a typed compare so values are
matched within their own type (number/text/bool/empty), with mixed
types returning FALSE for `=` and TRUE for `<>` to match Excel and
Google Sheets. Text equality is case-insensitive via Unicode-aware
`to_lowercase` — also matches Excel/Sheets `=` semantics.

Ordering operators (`<`, `<=`, `>`, `>=`) remain numeric-only; the
issue defers lexicographic ordering as a separate question, and a
test locks in the current behaviour so any future change is explicit.

Adds 11 eval-layer unit tests covering text/text, bool/bool, mixed
types, the issue's `IF(A1=C3, A2, 0)` example with text cells, and
case-insensitivity.

Documents the new semantics in `FORMULA_ENTRIES` (a new `=`/`<>`
help entry) and in the CHANGELOG under `Unreleased`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@garritfra garritfra merged commit 3f4c6af into main May 7, 2026
10 checks passed
@garritfra garritfra deleted the fix/68-string-equality branch May 7, 2026 13:52
@github-actions github-actions Bot mentioned this pull request May 6, 2026
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.

Equality operator (=) should work on strings

1 participant