Skip to content

fix(knowledge): count knowledge-base list totals with a lateral aggregate - #8560

Closed
waleedlatif1 wants to merge 3 commits into
stagingfrom
fix/kb-list-counts-plan
Closed

waleedlatif1 wants to merge 3 commits into
stagingfrom
fix/kb-list-counts-plan

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • The counted knowledge-base list (GET /api/v2/knowledge, the v1 list, and the internal list with counts) left-joined documents under the reader's ACL predicate and grouped by base. When the planner overestimated a workspace's active bases (soft-deleted bases skew the estimate), it flipped to a hash join fed by a bitmap over doc_acl_gin_idx. Every ordinary document carries the shared ws token, so that bitmap read every tenant's documents to total one base, and the list took ~50 s instead of milliseconds
  • Totals are now a LATERAL aggregate correlated on the base, so each base is always counted through its own knowledge_base_id index (doc_active_kb_token_count_idx). With sort keys on the base alone, the planner also sorts and limits bases before counting them; at worst it totals every base, as the old query always did
  • Results are unchanged: same three active-document conditions, same access predicate, same order and limit. An aggregate always yields one row, so a base with no readable documents still lists at zero
  • The live-source supplement (readLiveSourceDocumentCounts) is untouched: its batches are already restricted to explicit connector IDs
  • The shared drizzle mock gains innerJoinLateral/leftJoinLateral and a count() that aliases like drizzle's SQL expression

Type of Change

  • Bug fix

Testing

  • New lib/knowledge/__integration__/list-totals-plan.integration.ts: runs the v2 list use case on real PostgreSQL, captures the counted-list SQL, and EXPLAINs it with nested loops disabled; every document scan must be correlated on its knowledge base. Red against the previous JOIN + GROUP BY, green with the lateral aggregate
  • Reproduced the bad plan with EXPLAIN on production statistics: the old query hash-joins a GIN bitmap over the whole document table at an estimate of 247 bases; at 106 it nests. The SQL this change emits, captured from getWorkspaceKnowledgeBases itself, plans a per-base Index Scan using doc_active_kb_token_count_idx (Index Cond: knowledge_base_id = knowledge_base.id) under the Limit for the same estimate, for both createdAt and name sorts
  • Where the old query already nested, the new one runs the identical per-base index scan with the same buffer count
  • Compared old vs new results row-for-row across 19 bases in three workspaces: 0 differing rows. Verified a base with no matching documents returns 0/0 rather than dropping out
  • bun run test:integration for app/api/v1/knowledge, lib/knowledge/__integration__, and app/api/v2/knowledge (real Postgres): 477 passed. These cover ACL-filtered totals on list and detail reads, search-index bases, and the counts flag
  • lib/knowledge/service.test.ts, lib/knowledge/application/knowledge-bases.test.ts, root bun run test (19/19 tasks), bun run lint, block-registry check, bun run check:audits (57 audits), docs-manifest:check, apps/sim type-check

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…gate

The counted knowledge-base list left-joined documents under the reader's ACL
predicate and grouped by base. When the planner overestimated how many active
bases a workspace has (soft-deleted bases skew the estimate), it switched to a
hash join fed by a bitmap over the document ACL GIN index. Every ordinary
document carries the shared `ws` token, so that bitmap covered every tenant's
documents just to total one base's.

Totals are now a LATERAL aggregate correlated on the base, so each base is
counted through its own knowledge_base_id index and the page limit stops
counting past the page. Results are unchanged: same filters, same order, and
an aggregate always yields one row, so empty bases stay at zero.

The shared drizzle mock gains innerJoinLateral/leftJoinLateral and a count()
that aliases like drizzle's SQL expression.
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 2, 2026 8:09am UTC

Request Review

@greptile-apps

greptile-apps Bot commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[High risk] Restructures knowledge-base document counting with lateral joins.

The PR appears safe to merge; no outstanding findings or new actionable issues remain.

Summary

The PR replaces grouped document counts with a per-knowledge-base lateral aggregate and adds a PostgreSQL query-plan regression test.

  • The changes since the previous review complete fixture teardown.
  • No new actionable issues were identified.

Reviews (4) · Last reviewed commit: "test(knowledge): tear down every fixture..."

Comment thread apps/sim/lib/knowledge/service.test.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 3 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/lib/knowledge/service.ts
EXPLAIN the exact counted-list SQL with nested loops disabled and require every document scan to be correlated on its knowledge base, so a set-based join over the ACL index fails the build. Drop the comment's page-limit claim, which is the planner's cost choice rather than a guarantee, and a redundant mock-call assertion.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 4 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

…test

Delete the fixture organization and both users alongside the workspace, matching the v1 knowledge route test that seeds the same fixture; permissions cascade from the users.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@icecrasher321

Copy link
Copy Markdown
Collaborator

should be fixed in #8560

@waleedlatif1
waleedlatif1 deleted the fix/kb-list-counts-plan branch October 2, 2026 20:23

This branch was previously deployed

1 inactive deployment
Preview — 4f72a210 Deployed Oct 2, 2026 by vercel[bot]
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