8000 bug: patterns of one query can read different database states under concurrent writes · Issue #555 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

bug: patterns of one query can read different database states under concurrent writes #555

Closed

Description

@adityamukho

Affected versions: v1.1.0 (daa80a9, selective fetch in filter_facts_for_query, #208) through v2.0.5, and v3.

Bug

A query does not read the database at one instant. selective_fact_fetch (src/query/datalog/executor.rs) calls FactStorage::get_live_facts once per entity or attribute it needs, and each call takes and releases the pending store's read lock. A transaction that commits between two calls is visible to some patterns of the query and not to others. The query then returns rows that match no committed state of the database.

Reproducer

tests/snapshot_atomicity_test.rs on branch test/snapshot-atomicity-repro (dc7fa7a):

  • patterns_of_one_query_see_one_state_in_memory
  • patterns_of_one_query_see_one_state_on_file

Every transaction writes [:pN :pair/x N] and [:pN :pair/y N] together, using execute, which is atomic. A concurrent

[:find ?e :where [?e :pair/x ?x] (not [?e :pair/y ?x])]

must always be empty. It returns an entity within milliseconds on v3 and on main. Single-threaded, the query is correct.

cargo test --test snapshot_atomicity_test patterns -- --ignored

Fix

A query must read all its facts from one snapshot: one acquisition of the read lock for every fetch, or a snapshot taken once (committed reader plus pending length) and read from. #473 spec §4.1 (#543) gives v3 this. v2.x needs its own fix.

Correction: the query above, with :pair/x positive, only ever caught #554 (execute added :pair/x before :pair/y). Lookups run in sorted attribute order, so a commit landing between the two lookups shows up only with :pair/y positive: [:find ?e :where [?e :pair/y ?v] (not [?e :pair/x ?v])]. With #554 fixed, that query fails within milliseconds and the original one passes. The reproducer now runs both.

Workaround

Do not query from one thread while another writes.

Status

v3: PR #557 (FactStorage::get_live_facts_of_scans, one read lock for all of a query's lookups; stacked on #556). v2.x backport to follow.

Activity

  1. added this to the v3.0.0 milestone on Oct 11, 2026
  2. added
    bugSomething isn't working
    known-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue
    on Oct 11, 2026
  3. added 3 commits that reference this issue on Oct 11, 2026
  4. adityamukho commented on Oct 14, 2026

    @adityamukho
    CollaboratorAuthor

    Fixed in v2.0.6 (released 2026-10-14, on crates.io). Moved to "Fixed in v2.0.6" in #421.

  5. added
    known-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue
    and removed
    known-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue
    on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdata-integrityData integrity issueknown-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0