Repository navigation
fix(knowledge): count knowledge-base list totals with a lateral aggregate - #8560
waleedlatif1 wants to merge 3 commits into
Conversation
…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.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
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.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
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.
|
@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 review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
should be fixed in #8560 |
Summary
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 overdoc_acl_gin_idx. Every ordinary document carries the sharedwstoken, so that bitmap read every tenant's documents to total one base, and the list took ~50 s instead of millisecondsLATERALaggregate correlated on the base, so each base is always counted through its ownknowledge_base_idindex (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 didreadLiveSourceDocumentCounts) is untouched: its batches are already restricted to explicit connector IDsinnerJoinLateral/leftJoinLateraland acount()that aliases like drizzle'sSQLexpressionType of Change
Testing
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; everydocumentscan must be correlated on its knowledge base. Red against the previous JOIN + GROUP BY, green with the lateral aggregateEXPLAINon 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 fromgetWorkspaceKnowledgeBasesitself, plans a per-baseIndex Scan using doc_active_kb_token_count_idx(Index Cond: knowledge_base_id = knowledge_base.id) under theLimitfor the same estimate, for bothcreatedAtandnamesortsbun run test:integrationforapp/api/v1/knowledge,lib/knowledge/__integration__, andapp/api/v2/knowledge(real Postgres): 477 passed. These cover ACL-filtered totals on list and detail reads, search-index bases, and the counts flaglib/knowledge/service.test.ts,lib/knowledge/application/knowledge-bases.test.ts, rootbun run test(19/19 tasks),bun run lint, block-registry check,bun run check:audits(57 audits),docs-manifest:check,apps/simtype-checkChecklist
test-auditauthoring gate)