8000 fix(query): expression = / != equate a keyword with a ref to its entity (#744) by adityamukho · Pull Request #748 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

fix(query): expression = / != equate a keyword with a ref to its entity (#744) - #748

Merged
adityamukho merged 2 commits into
v3from
fix/744-expr-keyword-ref
Oct 24, 2026
Merged

adityamukho merged 2 commits into
v3from
fix/744-expr-keyword-ref

Conversation

@adityamukho
@adityamukho adityamukho commented Oct 24, 2026 •
Copy link
Copy Markdown
Collaborator

For #744 (data-integrity, open until the v2.x backport is released).

Problem

Patterns, joins, not bodies and or branches treat the keyword :bob as equal to a ref to the entity :bob names. An expression's =/!= compared the two Values as they are, so with ?g bound to that ref, [(= ?g :bob)] kept no row and [(!= ?g :bob)] kept it. Same question, different answer, no error.

Change

  • eval_binop (src/query/datalog/executor.rs) compares =/!= with a new expr_eq: structural equality, except that a keyword equals a ref to the entity edn_to_entity_id derives from it (the derivation IdSpace::keyword_eid uses, UUID-named keywords included).
  • <, >, <=, >= on a keyword or a ref stay a type mismatch (no row). Neither is ordered today, so this introduces no new disagreement.
  • Set elements still compare as they are (feat(query): add set membership predicates #316: a keyword element never equals a ref element).

Frozen answers

tests/answers/engine_tests.txt: 24 lines change, all for [?e :person/self ?v] [(= ?e ?v)] (the fixture stores the keyword :pN on entity :pN) at its 13 temporal settings, in memory and across checkpoint/reopen. It went from 0 rows to the rows [?e :person/self ?e] returns. Each changed hash was matched to that query text.

Tests

tests/join_rules_test.rs (+4): both operand orders, a keyword constant and value, !=, a binding expression, a bound Val(Ref), a rule body, not, an or branch, a UUID-named keyword, set elements, in memory, after a checkpoint and after reopen. They failed before the fix.

Full suite: default 1,766 passed / 13 ignored; --features test-hooks 1,784 / 14 (after rebase on #743); cargo fmt --check and cargo clippy --all-features -- -D warnings clean.

Codex review: one finding (that [(= ?v :p1)] on :person/friend also changed frozen answers) checked and rejected: every changed hash is the :person/self query, and :person/friend stores keywords. Its test-gap notes (UUID keywords, or, sets) are added.

Backport to main follows as its own PR; docs site PR to follow.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Urda7FD9CYYoxdeGGJa11x

@codecov
codecov Bot commented Oct 24, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

adityamukho and others added 2 commits October 24, 2026 23:03
…ty (#744)

Patterns, joins, not bodies and or branches treat a keyword as equal to a
ref to the entity it names; eval_binop compared the two Values as they
are, so [(= ?g :bob)] kept no row where [?x :ref/friend :bob] matched one,
and != kept it. Eq/Neq now use expr_eq: structural equality, except that
a keyword equals a ref to the entity edn_to_entity_id derives from it.
Ordering comparisons on keywords and refs stay a type mismatch.

The frozen engine answer to [?e :person/self ?v] [(= ?e ?v)] (keyword
:pN on entity :pN) changes from 0 rows to the rows [?e :person/self ?e]
returns, at each temporal setting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Urda7FD9CYYoxdeGGJa11x
@adityamukho
adityamukho force-pushed the fix/744-expr-keyword-ref branch from ffddee0 to f73ec91 Compare October 24, 2026 20:03
@adityamukho
adityamukho merged commit 438b96d into v3 Oct 24, 2026
19 checks passed
@adityamukho
adityamukho deleted the fix/744-expr-keyword-ref branch October 24, 2026 20:18
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.

1 participant

0