Skip to content

fix: subgraph catalog entries persistance across checkpoint + reopen#688

Merged
adsharma merged 1 commit into
mainfrom
subgraph_persist
Jul 14, 2026
Merged

fix: subgraph catalog entries persistance across checkpoint + reopen#688
adsharma merged 1 commit into
mainfrom
subgraph_persist

Conversation

@adsharma

@adsharma adsharma commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Bug

DatabaseManager::createGraph() set defaultGraph to the newly created graph before the transaction committed. This caused Catalog::Get() in Transaction::publishCommit() to return the graph's catalog instead of the main catalog when incrementing the version counter. The main catalog's version was never bumped, so changedSinceLastCheckpoint() returned false during CHECKPOINT. With a valid catalogPageRange from a prior checkpoint (e.g., from pre-existing tables), the main catalog was skipped during serialization — the graph entry in the main catalog's graphs CatalogSet was lost on reopen.

Why only with pre-existing tables?

  • Without tables: catalogPageRange.startPageIdx == INVALID_PAGE_IDX, forcing unconditional catalog serialization regardless of the version check.
  • With tables: the page range was valid, so version-driven skipping was the only guard — and it always said "no changes".

Fix

Remove the automatic defaultGraph assignment in createGraph() and loadGraphsFromCatalog(). Users must explicitly USE GRAPH to work in a graph, matching Cypher semantics and the pattern used in all existing tests.

Regression test

SubgraphCatalogPersistsAfterCheckpointWithPreExistingTables reproduces the exact scenario (Hyper-Extract-style schema with 4 node/rel tables + subgraph creation + CHECKPOINT + database reopen) and verifies the subgraph survives.

… main database has pre-existing tables

Bug: DatabaseManager::createGraph() set defaultGraph to the newly created
graph before the transaction committed. This caused Catalog::Get() in
Transaction::publishCommit() to return the graph's catalog instead of the
main catalog when incrementing the version counter. The main catalog's
version was never bumped, so changedSinceLastCheckpoint() returned false
during CHECKPOINT. With a valid catalogPageRange from a prior checkpoint
(e.g., from pre-existing tables), the main catalog was skipped during
serialization — the graph entry in the graphs CatalogSet was lost on
reopen.

The bug only manifested when the database already had tables because:
- Without tables: catalogPageRange.startPageIdx == INVALID_PAGE_IDX,
  forcing unconditional catalog serialization.
- With tables: the page range was valid, so version-driven skipping
  was the only guard — and it always said 'no changes'.

Fix: Remove the automatic defaultGraph assignment in createGraph() and
loadGraphsFromCatalog(). Users must explicitly USE GRAPH to work in a
graph, matching Cypher semantics and the pattern used in all tests.

Regression test: SubgraphCatalogPersistsAfterCheckpointWithPreExistingTables
reproduces the exact scenario (Hyper-Extract-style schema + subgraph +
checkpoint + reopen) and verifies the subgraph survives.
@adsharma adsharma merged commit 867f374 into main Jul 14, 2026
4 checks passed
@adsharma adsharma deleted the subgraph_persist branch July 14, 2026 22:43
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