Repository navigation
feat: Improve SQL editor completions for DuckDB functions and columns - #665
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR removes memoization from DuckDB function APIs, refactors CodeMirror completions to use schema-driven column suggestions and delayed function docs, introduces a custom DuckDB dialect with keyword sorting, adjusts keymap and tab styling, refactors query-tab deletion state, and adds a close button to the SQL editor and modal. ChangesSQL Editor Completions and UX
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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 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.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/sql-editor/src/SqlEditorSlice.tsx (1)
263-283:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGuard against
-1open-tab index when reselecting after delete.If the deleted selected tab is not currently in
openTabs,deletingOpenIndexis-1andnewOpenTabs[newIndex]can be undefined, leavingselectedQueryIdon a removed tab.Suggested fix
- const newIndex = - deletingOpenIndex === 0 - ? 0 - : Math.min(deletingOpenIndex - 1, newOpenTabs.length - 1); + const baseIndex = + deletingOpenIndex <= 0 ? 0 : deletingOpenIndex - 1; + const newIndex = Math.min(baseIndex, newOpenTabs.length - 1);🤖 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/sql-editor/src/SqlEditorSlice.tsx` around lines 263 - 283, When reselecting after deleting a tab, guard against deletingOpenIndex being -1 by clamping it into the valid range for config.openTabs before using it: compute a safeIndex = deletingOpenIndex < 0 ? Math.min(0, newOpenTabs.length - 1) (or simply use Math.max(0, Math.min(deletingOpenIndex, newOpenTabs.length - 1))) and use that to pick newSelectedId from newOpenTabs; if newOpenTabs[newIndex] is undefined (or newOpenTabs is empty) fall back to picking a valid id from remainingQueries (e.g., remainingQueries[0]?.id) or set selectedQueryId to null, and update assignment sites that use newSelectedId/selectedQueryId accordingly (references: deletingOpenIndex, config.openTabs/newOpenTabs, remainingQueries/config.queries, newSelectedId).
🤖 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/sql-editor/src/codemirror/extensions/completion.ts`:
- Around line 84-97: The suppression logic only inspects the current line via
lineAt/completionContext.pos, so multi-line clauses like "FROM\n ord|" slip
through; change how textBeforeCursor is computed to look back a small window in
the document instead of only the current line: use completionContext.state.doc
and completionContext.pos to compute a start index (e.g. Math.max(0, pos - N)
with N ~100–300) and slice the document from that start to pos to produce
textBeforeCursor, then run the existing regex checks against that window (keep
the same regexes and return null behavior).
- Around line 29-57: The current logic only uses applyQuotedIdentifier when
needsIdentifierQuotes(...) is true, which misses reserved words like "select";
make createColumnCompletion always set apply to the custom apply function
(remove the conditional), and inside applyQuotedIdentifier compute const escaped
= escapeId(column.name) and use that for insertCompletionText; determine whether
to back up over an existing leading quote by checking whether
escaped.startsWith('"') (if true, and the char before `from` is '"' then set
replaceFrom = from - 1, otherwise leave replaceFrom = from), then call
insertCompletionText(view.state, escaped, replaceFrom, to). Reference:
createColumnCompletion, applyQuotedIdentifier, needsIdentifierQuotes, escapeId,
insertCompletionText.
In `@packages/sql-editor/src/codemirror/utils/schema-converter.ts`:
- Around line 42-43: The current logic in schema-converter.ts returns
existing.children as a NamespaceRecord whenever an object has a children
property (the block around the existing variable), which wrongly treats table
nodes (where children is a Completion[]) as namespace nodes; update the guard in
the code paths that return or merge existing.children (the if that checks
existing && !Array.isArray(existing) && 'children' in existing and the similar
block around lines 46–50) to verify children is an object map (e.g., not an
array and typeof children === 'object' && children !== null) before casting to
NamespaceRecord, and if children is an array preserve/merge it as completions
instead of treating it as a NamespaceRecord.
---
Outside diff comments:
In `@packages/sql-editor/src/SqlEditorSlice.tsx`:
- Around line 263-283: When reselecting after deleting a tab, guard against
deletingOpenIndex being -1 by clamping it into the valid range for
config.openTabs before using it: compute a safeIndex = deletingOpenIndex < 0 ?
Math.min(0, newOpenTabs.length - 1) (or simply use Math.max(0,
Math.min(deletingOpenIndex, newOpenTabs.length - 1))) and use that to pick
newSelectedId from newOpenTabs; if newOpenTabs[newIndex] is undefined (or
newOpenTabs is empty) fall back to picking a valid id from remainingQueries
(e.g., remainingQueries[0]?.id) or set selectedQueryId to null, and update
assignment sites that use newSelectedId/selectedQueryId accordingly (references:
deletingOpenIndex, config.openTabs/newOpenTabs, remainingQueries/config.queries,
newSelectedId).
🪄 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: d0f97bc1-eb30-4e5e-87d9-d29701cd1fa2
📒 Files selected for processing (12)
packages/duckdb-core/src/get-function-documentation.tspackages/duckdb-core/src/get-function-suggestions.tspackages/sql-editor/src/SqlEditor.tsxpackages/sql-editor/src/SqlEditorModal.tsxpackages/sql-editor/src/SqlEditorSlice.tsxpackages/sql-editor/src/codemirror/extensions/completion.tspackages/sql-editor/src/codemirror/extensions/duck-db/duck-db.tspackages/sql-editor/src/codemirror/extensions/duck-db/duckdb-sql.tspackages/sql-editor/src/codemirror/extensions/sql-keymap.tspackages/sql-editor/src/codemirror/utils/schema-converter.tspackages/sql-editor/src/components/SqlEditorHeader.tsxpackages/ui/src/components/tab-strip.tsx
Summary by CodeRabbit
New Features
Improvements