Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 8c7169e The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Duplicate code analysis1 new clone introduced by this PR.
If one of these duplicates a helper that already exists, import it instead jscpd compared this branch against |
| metadataMVs, | ||
| dateRange: callerDateRange, | ||
| timestampValueExpression, | ||
| keySampleRatio = 0, |
There was a problem hiding this comment.
🟠 major — Sampling is now the default for every caller of getMapKeys / getAllFields / getAllKeyValues, not just the filter panel
keySampleRatio = 0 is the default here and in dispatchKeyValueQueries (line 2905), so callers that never opted in now get a subset. That includes packages/api/src/mcp/tools/sources/metricNames.ts:70 (MCP metric-name listing over a text-indexed MetricName), describeSource.ts:293/339/386, controllers/ai.ts:107, and app callers of useAllFields/useGetKeyValues('all') outside the search filters. None of them have a way to ask for more. Fix: default keySampleRatio to 1 (read every part) and pass the sampled ratio only from DBSearchPageFilters. The changeset should also list @hyperdx/api, since its output changes.
Nothing blocks merge automatically, but a maintainer will expect this fixed if it is a real defect in code this PR changes. If it is about surrounding code, reply and say so instead of patching. Do not widen the PR. How to respond
| disableRowLimit, | ||
| maxKeys, | ||
| limit, | ||
| keySampleRatio, |
There was a problem hiding this comment.
🔵 minor — Changing the sample ratio in 'exact' mode refetches every facet's values even though exact mode never uses the ratio
DBSearchPageFilters passes keySampleRatio whatever showAllValues is set to, and it goes into the useGetKeyValues query key. In exact mode getKeyValuesWithMVs ignores it, so picking 10%/50%/100% re-runs every exact value query against the raw table for the same result. Add the ratio to the key only when mode === 'all' (or pass undefined from useFacets when the mode is 'exact').
Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond
| : ''; | ||
| const cacheKey = metricName | ||
| ? `${connectionId}.${databaseName}.${tableName}.${column}.${metricName}.${dateRangeCacheSuffix}.${maxKeys}.keys` | ||
| ? `${connectionId}.${databaseName}.${tableName}.${column}.${metricName}.${dateRangeCacheSuffix}.${maxKeys}.${keySampleRatio}.keys` |
There was a problem hiding this comment.
🔵 minor — getMapKeys cache key includes keySampleRatio on the rollup/scan paths, which never use it
Only the text index branches read keySampleRatio. A Map column with no key/kv text index (e.g. ResourceAttributes when only LogAttributes is indexed) still gets a new cache entry for each ratio, so changing the sample re-runs its rollup or full scan. Add the ratio to the cache key only when the text index path is taken, or keep a separate key for the text index result.
Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond
| if (!timestampValueExpression) return undefined; | ||
| const [textIndexes, serverVersion] = await Promise.all([ | ||
| this.getMapColumnTextIndexes({ databaseName, tableName, connectionId }), | ||
| this.getServerVersion({ connectionId }), |
There was a problem hiding this comment.
🔵 minor — getKeySample ignores native column text indexes, so their sampled values get no indicator and no control
getTextIndexKeyValues now samples parts for native text-indexed columns (e.g. ServiceName, TraceId). But getKeySample returns undefined unless some Map column has a key/kv index, so KeySampleControl is hidden. On a table with only native text indexes, 'all' mode values silently come from a sample, and the user can't read more except through per-key 'Load more'. Count determineKeyValueFetchingStrategy(...).nativeTextIndexLookup too when deciding whether the table is sampled.
Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond
| disableRowLimit, | ||
| maxKeys, | ||
| limit, | ||
| keySampleRatio, |
There was a problem hiding this comment.
🔵 minor — useKeySample re-runs the sampling query on every focus/remount, and its count can disagree with the cached keys it describes
The query has no staleTime, and the app QueryClient (packages/app/pages/_app.tsx:58) uses React Query's defaults (staleTime 0, refetchOnWindowFocus). getKeySample is also not memoized in MetadataCache. So every tab focus re-runs the system.parts + mergeTreeIndex cover query, while getMapKeys serves keys from its TTL-less cache built from an older pick of parts. Cache getKeySample in MetadataCache under the same key fields as getMapKeys, or give the query a staleTime that matches the key/value queries (5 min).
Advisory. Fix if it is a small defect in code this PR changes; otherwise reply in the thread. Do not widen the PR or touch files it did not already change. How to respond
PR Review
5 finding(s): 🔴 0 critical · 🟠 1 major · 🔵 4 minor 5 posted as inline comment(s) on the changed lines. Severity is the reviewer's own estimate and is used for ordering, not filtering. No finding blocks merge automatically; a maintainer decides. |
[Medium impact] The PR appears safe to merge, with a non-blocking local metadata-setting issue and two earlier suggestion issues still outstanding.
|
Deep ReviewSampling the text index of a subset of parts (ranked by size/recency plus parts that cover string primary-key values) instead of every part in the time range is a sound, well-commented approach, and the SQL is parameter-bound throughout. I independently verified the highest-risk paths: the ✅ No critical issues found. 🟡 P2 — recommended
🔵 P3 nitpicks (3)
Reviewers (9): correctness, security, performance, adversarial, kieran-typescript, julik-frontend-races, testing, maintainability, project-standards. Testing gaps: Core No finding blocks merge automatically. A maintainer will expect P0/P1 findings in code this PR changes to be fixed; P2/P3 are your call -- fix or reply. Never fix findings about surrounding code here; reply instead. Do not widen the PR. How to respond |
| const hasKeyTextIndex = [...textIndexes.values()].some( | ||
| ({ key, kv }) => key?.indexName || kv?.indexName, | ||
| ); | ||
| if (!hasKeyTextIndex || !supportsMergeTreeTextIndex(serverVersion)) { | ||
| return undefined; |
There was a problem hiding this comment.
getKeySample checks only Map text indexes, but getTextIndexKeyValues now samples native-column text indexes too. For a table with only native text indexes, the panel omits values from unselected parts without showing the sample count or ratio control.
Include native indexes in this check so users can see and enlarge the sample. Per-field “Load more” still works, but does not replace the missing notice and panel-wide control.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| metadataMVs, | ||
| dateRange: callerDateRange, | ||
| timestampValueExpression, | ||
| keySampleRatio = 0, |
There was a problem hiding this comment.
The new default sample also reaches search autocomplete, which calls useFetchFacets without keySampleRatio. A Map key found only in an older, unselected part disappears from suggestions. Typing the exact key does not load its values because searchField must first exist in the sampled field list.
Choosing 100% in the sidebar does not help because that choice is local to the sidebar. Share the sample choice with autocomplete, or provide a full lookup for a typed key.
Knowledge Base Used: Roll Back Sampled Metric Name Listing
E2E Test Results✅ All tests passed • 443 passed • 1 skipped • 1472s
Tests ran across 4 shards in parallel. |
Local mode (Vercel previews, `yarn app:dev:local`) had no way to reach Team Settings, so query settings could not be tuned there. Link to the page and show its Data and Query Settings tabs; the other tabs need the API. Query settings are saved to localStorage, and every reader of `me.team` settings now goes through getTeamClickHouseSettings so they take effect.
| const metadataMaxRowsToRead = | ||
| getTeamClickHouseSettings(me)?.metadataMaxRowsToRead; |
There was a problem hiding this comment.
The new local metadata setting ignores 0 and does not restore the default after a reset. useMetadataWithSettings only applies truthy values, while MetadataCache keeps the old limit across pages.
Save a small limit, visit Search, reset it in Team Settings, then return to Search: metadata queries still use the small limit and can return incomplete field and value lists until reload. Choosing unlimited also leaves the default limit in place. Apply 0 explicitly and restore DEFAULT_METADATA_MAX_ROWS_TO_READ when the saved value is removed.
Summary
Adds user-configurable intelligent sampling to parts when loading keys to populate filter values.
Screenshots or video
References