Repository navigation
fix: Kepler table-layer dataset identity handling for DuckDB-backed maps - #703
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughKepler adds a policy-driven table-selection module and stores resolved ChangesTable identity consistency across schemas
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/kepler/src/keplerTableIdentity.ts (1)
117-124: 💤 Low valueConsider checking
currentDatabasein addition tocurrentSchema.The filter on line 118 only checks schema equality, but
isCurrentTablechecks both database and schema. If an attached database has the same schema name (e.g.,"main"), those tables would appear in the dropdown—which may be unintended.This inconsistency likely won't cause functional issues since
getKeplerDatasetIdForTablewill still produce correct qualified IDs for cross-database tables, but it may show unexpected entries in the dropdown.Proposed fix for consistency
for (const table of dbTables) { - if (table.table.schema !== context.currentSchema) continue; + if ( + table.table.database !== context.currentDatabase || + table.table.schema !== context.currentSchema + ) { + continue; + } const value = getKeplerDatasetIdForTable(table, context);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/kepler/src/keplerTableIdentity.ts` around lines 117 - 124, The loop building optionsByValue filters tables by schema only (context.currentSchema) which is inconsistent with isCurrentTable that checks both database and schema; update the filter in the for loop over dbTables to also verify the table's database matches context.currentDatabase (or treat attached DBs appropriately) before calling getKeplerDatasetIdForTable and getKeplerTableLabel so dropdown entries only include tables from the current database+schema scope.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/kepler/src/keplerTableIdentity.ts`:
- Around line 117-124: The loop building optionsByValue filters tables by schema
only (context.currentSchema) which is inconsistent with isCurrentTable that
checks both database and schema; update the filter in the for loop over dbTables
to also verify the table's database matches context.currentDatabase (or treat
attached DBs appropriately) before calling getKeplerDatasetIdForTable and
getKeplerTableLabel so dropdown entries only include tables from the current
database+schema scope.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d9002ff7-bbc5-4544-8cc3-908f91f6f2cf
📒 Files selected for processing (4)
packages/kepler/src/KeplerSlice.tspackages/kepler/src/components/CustomLayerManager.tsxpackages/kepler/src/index.tspackages/kepler/src/keplerTableIdentity.ts
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/kepler/src/KeplerSlice.ts (1)
606-645:⚠️ Potential issue | 🟠 Major | ⚡ Quick winSeparate dataset ID from SQL table reference in
addTableToMap.
tableNameis currently used as both Kepler dataset id (info.id) and SQL query target. With customtableSelection.getDatasetIdForTable/findTableForDatasetId, dataset ids can be aliases that are not queryable SQL identifiers, so restore/add flows can fail even after successful table resolution.💡 Proposed fix
addTableToMap: async (mapId, tableName, options = {}, config = {}) => { + const resolvedTable = findKeplerTableForDatasetId( + get().db.tables, + tableName, + get().kepler.tableSelection, + ); + const sqlTableName = resolvedTable?.table.toString() ?? tableName; const connector = await get().db.getConnector(); const duckDbColumns = await getDuckDBColumnTypes( { query: (query: string) => connector.query(query).result, } as DatabaseConnection, - tableName, + sqlTableName, ); const tableDuckDBTypes = getDuckDBColumnTypesMap(duckDbColumns); const adjustedQuery = castDuckDBTypesForKepler( - tableName, + sqlTableName, duckDbColumns, ); const arrowResult = await connector.query(adjustedQuery).result; @@ const datasets: AddDataToMapPayload['datasets'] = { data: {fields, cols, rows: [], arrowTable: arrowResult}, info: {label, id: tableName}, - metadata: {tableName}, + metadata: {tableName: sqlTableName}, };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/kepler/src/KeplerSlice.ts` around lines 606 - 645, addTableToMap currently reuses the incoming tableName as the Kepler dataset id (info.id) which breaks when dataset ids are aliases; fix by separating SQL reference from dataset id: keep the original tableName as the SQL source in metadata.tableName, then derive datasetId via the table selection API (e.g. if a table object is found via findKeplerTableForDatasetId(...) use get().kepler.tableSelection.getDatasetIdForTable(table) or otherwise fall back to getUnqualifiedSqlIdentifier(String(tableName)) || tableName), and set datasets.info.id = datasetId; ensure getKeplerTableLabel(...) still uses the resolved table object for label logic and do not replace metadata.tableName with the dataset id.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/kepler/src/components/CustomSourceDataSelector.tsx`:
- Around line 90-114: Select the raw state.kepler.map with useStoreWithKepler
and remove the heavy logic from the selector; then compute mapId and mapDatasets
from that raw map using useMemo. Concretely: replace the current selector that
computes mapId (the Object.entries + layers.some logic) with a selector that
returns state.kepler.map only (via useStoreWithKepler), then add two useMemo
hooks that derive mapId (iterate entries and find layerId match) and mapDatasets
(lookup mapId -> visState.datasets) so derivation is outside the Zustand
selector.
---
Outside diff comments:
In `@packages/kepler/src/KeplerSlice.ts`:
- Around line 606-645: addTableToMap currently reuses the incoming tableName as
the Kepler dataset id (info.id) which breaks when dataset ids are aliases; fix
by separating SQL reference from dataset id: keep the original tableName as the
SQL source in metadata.tableName, then derive datasetId via the table selection
API (e.g. if a table object is found via findKeplerTableForDatasetId(...) use
get().kepler.tableSelection.getDatasetIdForTable(table) or otherwise fall back
to getUnqualifiedSqlIdentifier(String(tableName)) || tableName), and set
datasets.info.id = datasetId; ensure getKeplerTableLabel(...) still uses the
resolved table object for label logic and do not replace metadata.tableName with
the dataset id.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 192ecf5b-1d52-4bb1-8340-689f5d436435
📒 Files selected for processing (7)
packages/kepler/src/KeplerSlice.tspackages/kepler/src/components/CustomFilterManager.tsxpackages/kepler/src/components/CustomLayerManager.tsxpackages/kepler/src/components/CustomSourceDataSelector.tsxpackages/kepler/src/components/KeplerInjector.tsxpackages/kepler/src/components/KeplerTableSourceSelector.tsxpackages/kepler/src/keplerTableSelection.ts
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
Changes:
Added keplerTableIdentity.ts to centralize Kepler dataset-id policy for DuckDB tables.
Use bare dataset ids for tables in the current DuckDB database/schema.
Use qualified table references for attached databases or non-current schemas.
Added restore resolution that accepts both bare current-schema ids and qualified table references.
Updated CustomLayerManager Add Layer options to use the shared identity helper.
Improved Add Layer labels to omit current DB/schema and avoid SQL identifier quotes.
Re-exported the helper APIs from @sqlrooms/kepler.
Why:
Kepler persists layer config by dataId, while table data is reloaded later from DuckDB. Keeping this identity policy centralized prevents map layers from disappearing on project reload and avoids collisions with attached databases.
Summary by CodeRabbit
New Features
Tests
Documentation