Skip to content

fix(memory): insert_or_supersede_with_metrics violates unique index on supersede #3635

@bug-ops

Description

@bug-ops

Description

GraphStore::insert_or_supersede_with_metrics() calls insert_new_edge before invalidate_prior_head, which violates the partial unique index uq_graph_edges_active_head when a second edge replaces an existing active head.

Reproduction Steps

  1. Insert edge A→B with relation R
  2. Insert a different edge A→B with relation R (should supersede the first)
  3. Observe: SQLite error 2067 (UNIQUE constraint failed) because new edge is inserted while old head is still active = true

Expected Behavior

Supersede path should:

  1. invalidate_prior_head (set old head active = false)
  2. insert_new_edge (insert new head with active = true)

Actual Behavior

Order is reversed: insert_new_edge runs first, hitting the unique index while the old head is still active.

Suggested Fix

Swap operation order in insert_or_supersede_with_metrics, or mark the index as DEFERRABLE INITIALLY DEFERRED if the transaction semantics require it.

Environment

  • Version: 0.20.1
  • Features: full

Notes

Found during unit test development for PR #3631/#3629. The APEX-MEM write path itself is correct — this bug is in the pre-existing store implementation. Does not affect this PR (APEX-MEM path is off by default).

Metadata

Metadata

Assignees

Labels

P2High value, medium complexitybugSomething isn't workingmemoryzeph-memory crate (SQLite)

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions