Skip to content

Align heterogeneous equality with CEL spec#903

Merged
snazy merged 1 commit into
projectnessie:mainfrom
snazy:het-equality
Jul 17, 2026
Merged

Align heterogeneous equality with CEL spec#903
snazy merged 1 commit into
projectnessie:mainfrom
snazy:het-equality

Conversation

@snazy

@snazy snazy commented Jul 16, 2026

Copy link
Copy Markdown
Member

Runtime equality converted strings to numeric and boolean values in several scalar implementations, so expressions such as dyn(1) == dyn('1') could evaluate true and Val.equals could disagree with hash-based map key lookup.

Preserve heterogeneous numeric equality, but make non-numeric concrete type mismatches evaluate false. Update scalar equality tests and add interpreter regressions for dynamic string/numeric comparisons and mixed string/numeric map keys.

Runtime equality converted strings to numeric and boolean values in several scalar implementations, so expressions such as dyn(1) == dyn('1') could evaluate true and Val.equals could disagree with hash-based map key lookup.

Preserve heterogeneous numeric equality, but make non-numeric concrete type mismatches evaluate false. Update scalar equality tests and add interpreter regressions for dynamic string/numeric comparisons and mixed string/numeric map keys.
@snazy
snazy requested a review from XN137 July 16, 2026 15:54
.expr("{1u: 1.0, 2: 2.0, 3u: 3.0}[3.1]")
.err("no such key: double{3.1}"),
new TestCase(InterpreterTestCase.map_key_string_and_int_are_distinct)
.expr("{1: 'int', '1': 'string'}['1']")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a test that covers trying to use two equal keys in the same map literal?
did this used to fail or had "last one wins" semantics?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a test that covers trying to use two equal keys in the same map literal?

Yes, for equal heterogeneous numeric keys (somewhere below .expr("{0: 1, 0u: 2}[0.0]"). For exact duplicate same-type keys, no.

did this used to fail or had "last one wins" semantics?

Honestly, I don't know.

assertThat(uintOf(0).equal(doubleOf(0))).isSameAs(True);
assertThat(uintOf(0).equal(doubleOf(1))).isSameAs(False);
assertThat(uintOf(0).equal(stringOf("0"))).isSameAs(True);
assertThat(uintOf(0).equal(stringOf("0"))).isSameAs(False);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt it surprising that conformance tests did not cover cases like this?
(i am assuming all are passing, or does this change reduce the number of failing conformance tests?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I suspect, the conformance tests still use the "old" CEL-spec, where this was allowed.

@Test
void doubleEqual() {
assertThat(doubleOf(0).equal(False)).matches(Err::isError);
assertThat(doubleOf(0).equal(False)).isSameAs(False);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am no expert on the CEL spec, so just wondering what you think about:

Type-checking asserts that arguments to equality operators must be the same type. If the argument types differ, the type-checker will raise an error. However, if at least one argument is dynamically typed, the type-checker considers all arguments dynamic and defers type-agreement checks to the interpreter.

https://github.com/cel-expr/cel-spec/blob/master/doc/langdef.md#equality

would it be preferable to throw an error for equal on incompatible types?
or is this the "dynamically typed" scenario?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CEL-spec just say "those are not equal". Mean, that's the same as Java "foo".equals(1) == false

@snazy
snazy merged commit 01ca088 into projectnessie:main Jul 17, 2026
2 checks passed
@snazy
snazy deleted the het-equality branch July 17, 2026 08:30
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.

2 participants