simplify: reuse what the repo already had, and fix two defects the review found - #390
Merged
Conversation
…wrong
A four-angle review of the last three merged PRs. Two findings were defects,
not untidiness.
**SQL Server reported size and rows multiplied by the column count.** The
probe's scalars were `SUM(...) OVER ()` beside a `LEFT JOIN sys.columns`, which
fans the result to one row per column; the window then summed the fanned set. A
20-column table reported 20x its rows and 20x its size, and `size_bytes` — the
figure a doc comment in this very diff calls "the kind of figure people act on".
The row count had the defect already and the new size line copied its shape.
Both now come from a CROSS APPLY that aggregates on its own row set. Size
counts every partition, since the hint promises table *and* indexes; rows count
only index_id 0/1, or every index would multiply them again. My test asserted
`toContain('used_page_count')`, which could never have caught this.
**The orphan query was invalid on Oracle.** It aliased tables with `AS`, and
Oracle answers ORA-03048. Verified both ways on Oracle 23: with `AS`, the error;
without it, the query runs. A bare correlation name is accepted everywhere this
ships, so no dialect branch — one spelling, and a test across five dialects.
Reuse, which is what the review was for:
- `formatBytes` already existed in @foxschema/sql, imported by three sibling
components. I had written a fourth copy, worse than the original — it took
`number` where the shared one takes `number | null | undefined`, so I also
added a null guard at the call site that the real one makes unnecessary, and
tests for behaviour dba-utilities.test.ts already covered. All deleted.
- Row counts used bare `.toLocaleString()`, which follows the host locale, two
clicks from a schema explorer that uses `formatRowCount` and pins en-US.
- The FK identity key was spelled three times, once with `', '` against `','`.
The two Peek copies had to stay byte-identical or a count written under one
key was never found under the other. Now `fkKey`.
- `foreignKeys` re-implemented `findCachedTable` from a module the file already
imports — and more weakly, matching a bare name across schemas.
- The new per-FK row wrote out `panelCls` plus its exact padding, in the file
that imports `Panel`. That is the clearest evidence the primitive was not yet
the easy path.
Efficiency: the orphan check ran one request per foreign key, serially, and
/sql/execute opens and closes a connection per request — so six keys meant six
handshakes paid one after another, and one failure discarded every scan already
paid for. `executeSql` already takes an array and runs it on one connection with
per-statement isolation, so it is now a single request that keeps the counts
that succeeded. Verified live: two orphan statements in one request return 1 and
1 over planted data. Unbounded Promise.all would have been worse than either,
since each call creates its own connection.
Also: `pg_total_relation_size` was in the target list of a query returning one
row per column, and each evaluation stats every fork, the TOAST relation and
every index. It is now an uncorrelated scalar subquery, evaluated once.
Smaller: narrowed two whole-store selectors that re-ran the catalog probe on
unrelated connections; memoised AccountStage's two derivations, which re-ran on
every keystroke in the principal filter; made its props required and deleted an
unreachable branch; dropped `Panel`'s `padded`, which had no caller outside the
test written for it; removed the `sql.raw` escape hatch from the orphan builder
in favour of a closed shape parameter.
Suite 3655 passed, eslint 0 errors, typecheck clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_b0c7de60-93b2-4f18-a2c0-8d464959605e) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four review angles over the last three merged PRs. Two findings were defects, not untidiness.
Two things were wrong
SQL Server reported size and rows multiplied by the column count.
packages/sql/src/providers/sqlServer/sqlserver.table-insight.tsThe scalars were
SUM(...) OVER ()beside aLEFT JOIN sys.columns, which fans the result to one row per column — the window then summed the fanned set. A 20-column table reported 20× its rows and 20× its size. The row count had this already; the newsize_bytesline copied the broken shape.Now a
CROSS APPLYthat aggregates on its own row set. Size counts every partition (the hint promises table and indexes); rows count onlyindex_id0/1, or every index would multiply them again.My test asserted
sql.toContain('used_page_count')— it could never have caught this. Still unverified live: that container will not start here.The orphan query was invalid on Oracle. It aliased tables with
AS. Verified both ways on Oracle 23:A bare correlation name is accepted on every engine here, so no dialect branch — one spelling, tested across five dialects.
Reuse — the point of the exercise
formatBytesalready existed in@foxschema/sql, imported by three sibling components. I wrote a fourth copy, worse than the original: it tooknumberwhere the shared one takesnumber | null | undefined, so I also added a call-site null guard the real one makes unnecessary, plus tests re-coveringdba-utilities.test.ts. All deleted..toLocaleString()— host-locale dependent — two clicks from a schema explorer that usesformatRowCount, which pinsen-USprecisely so UI and tests do not vary by machine.', 'against','. The two Peek copies had to stay byte-identical or a count written under one key was never found under the other. NowfkKey.foreignKeysre-implementedfindCachedTablefrom a module the file already imports — and more weakly, matching a bare name across schemas.panelClsplus its exact padding, in the file that importsPanel. The clearest evidence the primitive was not yet the easy path.Efficiency
The orphan check ran one request per foreign key, serially — and
/sql/executeopens and closes a connection per request, so six keys meant six handshakes back to back, with one failure discarding every scan already paid for.executeSqlalready accepts an array and runs it on one connection with per-statement isolation. Now a single request that keeps whatever succeeded. Verified live: two orphan statements in one request return 1 and 1 over planted data.Unbounded
Promise.allwould have been worse than either, since each call creates its own connection.Separately,
pg_total_relation_sizesat in the target list of a query returning one row per column, and each evaluation stats every fork, the TOAST relation and every index. Now an uncorrelated scalar subquery, evaluated once.Smaller
Narrowed two whole-store selectors that re-ran the catalog probe on unrelated connections; memoised
AccountStage's derivations (they re-ran on every keystroke in the principal filter); made its props required and deleted an unreachable branch; droppedPanel'spadded, which had no caller outside its own test; removed thesql.rawhole from the orphan builder in favour of a closed shape parameter.Suite 3655 passed · eslint 0 errors · typecheck clean.
Deliberately not fixed here
Four findings are real but larger than this change, and I would rather they be seen than buried:
shared/lib/provider-settings.tsis a 330-line hand copy of the@foxschema/sqlprovider layer, and has already drifted —postgresSettings.schemaRequiredisfalsein the frontend andtruein the package. It already delegates for 5 of 16 dialects, so the boundary is proven crossable.surfaces.tsxis barely adopted — 4 files import it; ~27 exact copies ofsectionLabelClsremain across 15 files, and the label survives in 16 spellings. Extraction without migration risks being a ninth variant. Worth a codemod plus anaming.test.ts-style guard, which is how this repo already enforces conventions.ResultGridLikeis declared twice in files that already import from each other.dba-utilities— including Redshift, where the repo already has a workingsvv_table_infoquery, so Peek Insight shows—for a size Utilities prints correctly.🤖 Generated with Claude Code
Note
Medium Risk
Touches SQL generation for orphan checks and SQL Server catalog probes used by Peek Insight; logic is tested but wrong SQL would affect multi-FK orphan scans and SQL Server row/size display.
Overview
Fixes two catalog/query bugs and consolidates Data Peek Insight behavior around shared helpers and fewer round trips.
SQL Server table insight no longer multiplies estimated rows and size by column count: table-level totals move into a
CROSS APPLYaggregate instead ofSUM(...) OVER ()beside thesys.columnsjoin.Orphan FK SQL drops
ASon table aliases so Oracle accepts the statement;fkKeyunifies FK map keys and orphan peek titles (fixing mismatched join separators that showed every FK as “not checked”).Peek Insight reuses
formatBytes/formatRowCountfrom@foxschema/sql, resolves FKs withfindCachedTable, reads dialect from the connection store, batches orphan counts in oneexecuteSqlcall (keeping partial successes), and narrows Zustand selectors to cut unnecessary refetches.AccessPermissionPanelmemoizesAccountStagederivations;Panelalways includes padding (paddedremoved).Reviewed by Cursor Bugbot for commit 75f1e5e. Bugbot is set up for automated code reviews on this repo. Configure here.