Scope merge direction fact counts to each entity's knowledge base by Floating-Y · Pull Request #1078 · deeplethe/utopia · GitHub
Skip to content

Scope merge direction fact counts to each entity's knowledge base - #1078

Merged
WaylandYang merged 2 commits into
deeplethe:devfrom
Floating-Y:fix/merge-direction-kb
Oct 4, 2026
Merged

WaylandYang merged 2 commits into
deeplethe:devfrom
Floating-Y:fix/merge-direction-kb

Conversation

@Floating-Y

Copy link
Copy Markdown
Contributor

Why

Follow-up to #1072. The two live-fact counts in resolution::merge_direction still omit kb_id. The existing subject/object indexes lead with kb_id, so choosing a merge direction can scan index entries from other knowledge bases.

What changes

  • Scope each count using a scalar subquery that reads the entity's kb_id by primary key. Preserve the function signature and two-query execution flow.
  • Preserve live-fact filtering, counting a self-reference only once, and retaining the smaller UUID when degrees tie. The existing same-KB foreign keys make the added predicate equivalent for valid data.
  • Add a regression to the existing store integration binary covering unequal and equal degrees, both argument orders, incoming/outgoing facts, invalidation, self-references, and multiple knowledge bases.

Only the two queries and their regression coverage change. No new index, migration, or dependency.

How it was checked

PostgreSQL 16.15 in a dedicated test container, with session-local copies of the migrated tables and indexes: 4 knowledge bases, 20,000 entities, and 240,000 facts. EXPLAIN (ANALYZE, BUFFERS) used the exact old and final SQL.

Before After
Plan BitmapOr with subject/object-only index conditions Entity primary-key InitPlan, then BitmapOr with both composite keys
Total execution buffer accesses 888 23, including the entity lookup
Count 24 24

The final plan has (kb_id = $0 AND subject_id = $1) and (kb_id = $0 AND object_id = $1) index conditions. A forced generic prepared plan also uses both composite keys and 23 buffer accesses. These synthetic-fixture measurements do not imply a stable elapsed-time speedup or production throughput result.

Passed locally:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --no-fail-fast: 1,427 passed, 0 failed, 6 ignored; includes all 298 store integration tests.
  • cargo test --locked -p utopia-store --test store merge_direction_counts_live_facts_in_each_base: passed separately.
  • pnpm install --frozen-lockfile and pnpm build in web.
  • git diff --check.

Database tests used UTOPIA_DATABASE_URL pointing to the dedicated container and UTOPIA_TEST_REQUIRE_DB=1. On Windows, the final full run used an explicit 127.0.0.1 database host and NO_PROXY=127.0.0.1,localhost,::1. No business database was used.

The six explicitly ignored live-service and isolated delivery/crash tests were not forced to run. Optional live MySQL/Trino/WebDAV services and opt-in benchmarks were not configured.

Before review

  • Every commit is signed off (git commit -s)
  • cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings and cargo test --workspace pass
  • SQL under crates/utopia-store/ was tested with UTOPIA_DATABASE_URL set (those tests skip without it)

Signed-off-by: Floating-Y <118035379+Floating-Y@users.noreply.github.com>

@WaylandYang WaylandYang left a comment

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.

Thanks @Floating-Y. The two counts in merge_direction were the ones #1072 did not reach, since they take the entity by id and have no base in hand. Reading the base by primary key first is the right way to give both sides of the OR a seek on the (kb_id, …) indexes, and the regression covers what the direction depends on: live facts only, a self-reference counted once, the smaller id on a tie. Landing it.

@WaylandYang
WaylandYang merged commit 7a063a2 into deeplethe:dev Oct 4, 2026
6 checks passed
@WaylandYang WaylandYang mentioned this pull request Oct 9, 2026
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