What happened?
When the autocomplete popup opens for a short prefix and the user continues typing, the visible list can keep the ranking from the earlier prefix. An exact keyword can remain below a longer function candidate, and the stale first row stays selected for Return or Tab.
For example, after the popup opens for t, completing the token to true can leave the numeric function TRUNCATE(n, decimals) above the exact keyword TRUE:
SELECT * FROM GT_USER
WHERE true
The same problem is reproducible with other candidate pairs, including:
n -> null: NULLIF() can remain above NULL
i -> in: INSTR() can remain above IN
i -> is: ISNULL() can remain above IS
r -> regexp: REGEXP_REPLACE() can remain above REGEXP
This is not specific to TRUE. It occurs whenever the correct order changes as the prefix grows while both candidates survive filtering.
Steps to reproduce
- Open a SQL query editor.
- Enter a query ending in
WHERE t.
- Wait for the autocomplete popup to open for
t.
- Continue typing
rue without closing the popup.
- Observe that
TRUNCATE(n, decimals) can remain above TRUE and stays selected.
- Close the popup, remove the last character, and type it again so a fresh popup opens for the complete
true prefix.
- Observe that the fresh ranking places
TRUE above TRUNCATE.
The n -> null and i -> in sequences provide additional reproductions.
Expected behavior
The visible completion list should be filtered and ranked for the current full prefix on every incremental update. Exact matches such as TRUE, NULL, and IN should move ahead of longer prefix or fuzzy matches before the first row is selected.
Confirmed cause
QueryCompletionAdapter.completionOnCursorMove immediately returns synchronousRefilter, which calls service.filter and preserves the previous order. scheduleRefilter calculates the correct ranking after a 30 ms debounce, but stores it only in lastRefilterItems; it does not update the visible SuggestionViewModel.items.
Relevant code:
TablePro/Views/Editor/QueryCompletionAdapter.swift
TablePro/Core/Autocomplete/SQLCompletionService.swift
TablePro/Core/Autocomplete/SQLCompletionProvider.swift
LocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/Model/SuggestionViewModel.swift
A fresh completion request already performs getCandidates -> filterByPrefix -> rankResults. The stale order is specific to the open-popup cursor-update path.
Acceptance criteria
- Incremental completion updates return candidates ranked for the current prefix.
t -> true places TRUE before TRUNCATE().
n -> null places NULL before NULLIF().
i -> in places IN before INSTR().
- The first selected row matches the newly ranked first item.
- SQL and MongoDB completion behavior remains covered by targeted tests.
Environment
- TablePro: 0.68.0
- macOS: 26.6.2
- Architecture: Apple Silicon
- Database type: SQL completion path; the ranking code is shared across SQL dialects
What happened?
When the autocomplete popup opens for a short prefix and the user continues typing, the visible list can keep the ranking from the earlier prefix. An exact keyword can remain below a longer function candidate, and the stale first row stays selected for Return or Tab.
For example, after the popup opens for
t, completing the token totruecan leave the numeric functionTRUNCATE(n, decimals)above the exact keywordTRUE:The same problem is reproducible with other candidate pairs, including:
n->null:NULLIF()can remain aboveNULLi->in:INSTR()can remain aboveINi->is:ISNULL()can remain aboveISr->regexp:REGEXP_REPLACE()can remain aboveREGEXPThis is not specific to
TRUE. It occurs whenever the correct order changes as the prefix grows while both candidates survive filtering.Steps to reproduce
WHERE t.t.ruewithout closing the popup.TRUNCATE(n, decimals)can remain aboveTRUEand stays selected.trueprefix.TRUEaboveTRUNCATE.The
n->nullandi->insequences provide additional reproductions.Expected behavior
The visible completion list should be filtered and ranked for the current full prefix on every incremental update. Exact matches such as
TRUE,NULL, andINshould move ahead of longer prefix or fuzzy matches before the first row is selected.Confirmed cause
QueryCompletionAdapter.completionOnCursorMoveimmediately returnssynchronousRefilter, which callsservice.filterand preserves the previous order.scheduleRefiltercalculates the correct ranking after a 30 ms debounce, but stores it only inlastRefilterItems; it does not update the visibleSuggestionViewModel.items.Relevant code:
TablePro/Views/Editor/QueryCompletionAdapter.swiftTablePro/Core/Autocomplete/SQLCompletionService.swiftTablePro/Core/Autocomplete/SQLCompletionProvider.swiftLocalPackages/CodeEditSourceEditor/Sources/CodeEditSourceEditor/CodeSuggestion/Model/SuggestionViewModel.swiftA fresh completion request already performs
getCandidates -> filterByPrefix -> rankResults. The stale order is specific to the open-popup cursor-update path.Acceptance criteria
t->trueplacesTRUEbeforeTRUNCATE().n->nullplacesNULLbeforeNULLIF().i->inplacesINbeforeINSTR().Environment