feature: query transformers #97

Open
opened 2026-07-15 17:49:02 -05:00 by noe.trevino · 0 comments
Owner

Did you check the docs?

  • I have read all the dadbod-ui.nvim docs

I run a select, get a page of rows back, and then i want to know how many rows there actually are. Or sort by a column. Or see if theres duplicates.

Every one of those means going back to the buffer and hand editing the sql, then running it again.

Describe the solution you'd like

Rewrite the statement under the cursor and run the result.

paginator.lua already does exactly this. It checks the statement is a plain select, appends a limit clause, runs it. Same move, different clause:

Action The rewrite
Row count wrap in SELECT count(*) FROM (...)
Sort from result header append ORDER BY <col> [DESC]
Filter from result header append or extend WHERE
Fetch all rows strip the paging clause
Evaluate expression wrap the visual selection in SELECT (...)
Group by SELECT col, count(*) FROM (...) GROUP BY col
Find duplicates the above, plus HAVING count(*) > 1

Two of these i really want. Evaluate expression means i can visually select now() - interval '1 day' and just run that, which is the natural thing to want in an editor where you already run a selection. And find duplicates is one line different from group by and answers a question i ask all the time.

Uses the statement classifier from #92 rather than its own guard.

Acceptance Criteria

  • row count
  • sort from the result header
  • filter from the result header
  • fetch all rows
  • evaluate a visual selection as an expression
  • group by a column
  • find duplicates
  • sorting re-runs the query when there are unfetched rows, sorts in the buffer when there arent
  • refuses anything that isnt a plain select
  • keymaps are configurable
  • implemented in all adapters where their cli allows
    • postgres
    • MySQL
    • MariaDB
    • SQL Server
    • SQLite

Describe alternatives/other solutions you've considered

Sorting client side only. Doesnt work once you paginate. If we only have page 1 and sort locally you get "the smallest of the first 200 rows", not "the smallest", and it looks right so you dont notice. DBeaver sorts locally only when everything is already fetched and otherwise re-runs with an ORDER BY. Thats the behaviour to copy.

A separate issue per transformer. Theyre all the same mechanism, splitting them into seven issues would be fake granularity.

Blocked by

### Did you check the docs? - [X] I have read all the dadbod-ui.nvim docs ### Is your feature request related to a problem? Please describe. I run a select, get a page of rows back, and then i want to know how many rows there actually are. Or sort by a column. Or see if theres duplicates. Every one of those means going back to the buffer and hand editing the sql, then running it again. ### Describe the solution you'd like Rewrite the statement under the cursor and run the result. `paginator.lua` already does exactly this. It checks the statement is a plain select, appends a limit clause, runs it. Same move, different clause: | Action | The rewrite | | --- | --- | | Row count | wrap in `SELECT count(*) FROM (...)` | | Sort from result header | append `ORDER BY <col> [DESC]` | | Filter from result header | append or extend `WHERE` | | Fetch all rows | strip the paging clause | | Evaluate expression | wrap the visual selection in `SELECT (...)` | | Group by | `SELECT col, count(*) FROM (...) GROUP BY col` | | Find duplicates | the above, plus `HAVING count(*) > 1` | Two of these i really want. Evaluate expression means i can visually select `now() - interval '1 day'` and just run that, which is the natural thing to want in an editor where you already run a selection. And find duplicates is one line different from group by and answers a question i ask all the time. Uses the statement classifier from #92 rather than its own guard. ### Acceptance Criteria - [ ] row count - [ ] sort from the result header - [ ] filter from the result header - [ ] fetch all rows - [ ] evaluate a visual selection as an expression - [ ] group by a column - [ ] find duplicates - [ ] sorting re-runs the query when there are unfetched rows, sorts in the buffer when there arent - [ ] refuses anything that isnt a plain select - [ ] keymaps are configurable - [ ] implemented in all adapters where their cli allows - [ ] postgres - [ ] MySQL - [ ] MariaDB - [ ] SQL Server - [ ] SQLite ### Describe alternatives/other solutions you've considered Sorting client side only. Doesnt work once you paginate. If we only have page 1 and sort locally you get "the smallest of the first 200 rows", not "the smallest", and it looks right so you dont notice. DBeaver sorts locally only when everything is already fetched and otherwise re-runs with an ORDER BY. Thats the behaviour to copy. A separate issue per transformer. Theyre all the same mechanism, splitting them into seven issues would be fake granularity. ### Blocked by - #101
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
noe.trevino/dadbod-ui.nvim#97
No description provided.