Results
A run’s results open in the results pane below the editor. Each row result gets a result tab
of its own, before the Plan, Chart and Messages tabs (Messages holds each statement’s outcome). While
the shown result has pending changes, a Changes tab follows the result tabs (see
The Changes tab). In the results pane H and L move between the
tabs; Space r [ and Space r ] do it from anywhere.
╭ Explorer ────────────────────────────╮ 1 console 1 ×
│ + New connection │╭ Query · console 1 ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│▾ Connections 1 ││ local-pg / datarig 127.0.0.1:55432 Space c s switch connection │
│ ▾ ● local-pg ││ 1 -- datarig 🐘 Ctrl+E: run the statement under the cursor │
│ ▾ datarig default ││ 2▎SELECT * FROM shop.users WHERE id <= 8; ✓ 3 rows · 3ms · 14:03 │
│ ▸ analytics ││ 3 │
│ ▸ public ││ 4 SELECT u.name, o.status, o.total_amount │
│ ▸ shop ││ 5 FROM shop.orders o │
│ ││ 6 JOIN shop.users u ON u.id = o.user_id │
│ ││ 7 WHERE o.status = 'paid'; │
│ ││ 8 │
│ ││ 9 SELECT * FROM analytics.events; │
│ ││ 10 │
│ ││ 11 SELECT * FROM analytics.events ORDER BY created_at DESC; │
│ ││ 12 │
│ ││ 13 SELECT analytics.slow(30); │
│ ││ 14 │
│ │╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
│ │╭ Results · 3 rows ────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ││ [Result 1] Chart Messages H/L │
│ ││ │ PK id │ FK user_id │ UQ email │ name │ PK FK order_id │ PK line_no │ FK product_id │ doubled │
│ ││ │ int8 │ int8 │ text │ text │ int8 │ int4 │ int8 │ numeric │
│ ││ 1 │ 1 │ 1 │ user01@example.com │ ユーザー 1 │ 1 │ 1 │ 7 │ 2 │
│ ││ 2 │ 2 │ 1 │ user02@example.com │ ユーザー 2 │ 2 │ 1 │ 7 │ 2 │
│ ││ 3 │ 3 │ 1 │ user03@example.com │ ユーザー 3 │ 3 │ 1 │ 7 │ 2 │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
│ ││ │
╰──────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
NORMAL local-pg │ 3 rows · 3ms │ Enter view cell · n next page · y copy · v select · i detail · Esc back · Tab next pane · : commands · Space ? help EN
Pages
The grid shows one page at a time (page_size, 500 rows by default): n (or ]) and [ move to the
next and previous page. By default nothing stays open on the server between pages: the first
page ends its transaction, and the next page runs the statement again when it is safe to repeat
(said each time); otherwise you see the first page and why. An environment can keep the cursor
open instead; see Paging and locks.
The rows already fetched stay in a bounded memory window and spill to a private temporary file
past it. # counts every row on demand (it runs a count query), with a label that says whether
the count matches the pages you saw.
Moving around
hjklor the arrows move the cell;0and$go to the first and last column,ggandGto the first and last row of the page,Ctrl+D/Ctrl+Uscroll half a screen.- The wheel scrolls the rows, three a notch. A trackpad’s sideways swipe, a tilting wheel or
Shift with the wheel scrolls sideways by character, four a step: the columns at the edges show
the part that fits, and the headers scroll with the rows. A value longer than a column’s 40
characters is cut with
…. The selected cell stays where it is until a key or a click moves it; then the view moves just enough to show that cell whole. Entershows the cell’s value whole in the cell viewer.- The cursor’s row is tinted (its number in the accent), its cell more strongly, and so is its
column’s header (a selected range tints its columns’ headers instead). A new row keeps its
own tint and shows the cursor by its number. On the
terminaltheme the row keeps your terminal’s background: the row’s number and the underlined header show where the cursor is. vselects a range of cells,Vwhole rows,Ctrl+Aevery cell of the page; the mouse selects too. The selection is one tinted block, the separators between its columns included. The rows of a range of cells or of whole rows take the row tint and a tinted number; the selected columns’ headers are tinted too (whole columns tint their headers and cells, not the row numbers). The theme tokensgrid_cursor_rowandgrid_cursor_headerset the tints.- While a selection is there and the grid has the focus, the status line sums it up (a fresh
message comes first; in a narrow window the least and greatest values, then NULL, then the
average, are left out): its size,
then for numbers (every selected column an integer, decimal or floating-point one) the sum,
average, least and greatest value, else how many distinct values; and how many are NULL, as in
5 rows × 1 column · sum 1,013.00 · avg 253.25 · min 0.25 · max 1,000 · NULL 1. Integers and decimals add up exactly. The values are those the grid shows, a pending change over the value read, as a copy takes them; a cell with no value yet (a pending DEFAULT) is counted apart, new rows are left out, and whole columns say “fetched rows only” when the server has more. The rows are read in the background (a big selection says “summing…” at first), so keys never wait for it. A selection that grows at its end (whole columns while every row is fetched, or a range extended downwards) keeps its figures: only the new rows are read and added, and the figures so far stay on the line, marked “summing…”, until they are. Distinct values are counted up to 100,000. z(orSpace z) zooms the results pane to the whole workspace and back;+and-make it taller or shorter.Escorqgoes back to the editor.
Search
/ searches forward and ? backward: a prompt under the grid, the cursor on the first matching
cell as you type, Enter to search. Then n and N go from match to match, across pages and
around the ends with a warning, and Esc ends the search (n is the next page again; ] is
the next page all along). :noh ends it too.
The search covers every row already fetched (the spilled ones too), each cell’s full value as
the server sent it, not the cut the grid shows. NULL never matches, and nothing is fetched or
run again for it: when the server has more rows, the line under the grid says so. Patterns are
the editor’s (Rust regular expressions, case sensitive unless they start with (?i)); matching
cells are tinted.
╭ Explorer ──────────────────╮ 1 console 1 ×
│ + New connection │╭ Query · console 1 ─────────────────────────────────────────────────────────────────────╮
│▾ Connections 1 ││ local-pg / datarig 127.0.0.1:55432 Space c s switch connection │
│ ▾ ● local-pg ││ 1 -- datarig 🐘 Ctrl+E: run the statement under the cursor │
│ ▾ datarig default ││ 2▎SELECT * FROM shop.users WHERE id <= 8; ✓ 8 rows · 12ms · 14:03 │
│ ▸ analytics ││ 3 │
│ ▸ public ││ 4 SELECT u.name, o.status, o.total_amount │
│ ▸ shop ││ 5 FROM shop.orders o │
│ ││ 6 JOIN shop.users u ON u.id = o.user_id │
│ ││ 7 WHERE o.status = 'paid'; │
│ ││ 8 │
│ ││ 9 SELECT * FROM analytics.events; │
│ ││ 10 │
│ ││ 11 SELECT * FROM analytics.events ORDER BY created_at DESC; │
│ ││ 12 │
│ │╰────────────────────────────────────────────────────────────────────────────────────────╯
│ │╭ Results · 8 rows ──────────────────────────────────╮╭ Cell [Row] · I ──────────────────╮
│ ││ [Result 1] Chart Messages H/L ││ id: 5 │
│ ││ │ profile ││ name: 山田太郎 │
│ ││ │ jsonb ││ nickname: やまだ │
│ ││ 1 01大樓 … │ {"lang": "ko", "tags": ["dev", "db"]} ││ address: 東京都渋谷区道玄坂1-2-3 │
│ ││ 2 │ {} ││ profile: {"lang": "ja"} │
│ ││ 3 │ {"vip": true, "level": 7} ││ │
│ ││ 4 │ {"flags": ["🇰🇷", "🇺🇸"]} ││ │
│ ││ 5 │ {"lang": "ja"} ││ │
│ ││ 6 │ {"lang": "zh"} ││ │
│ ││ 7 View, … │ {"lang": "en"} ││ │
│ ││ 8 │ {"multiline": true} ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ /lang 2/4 ││ │
╰────────────────────────────╯╰────────────────────────────────────────────────────╯╰──────────────────────────────────╯
NORMAL local-pg │ 8 rows · 12ms │ n next match · Esc clear · Enter view cell · y copy · q back · Tab next pane EN
The inspector
i shows or hides the inspector next to the grid; I switches between its Row and Cell tabs.
It starts on the Row tab, and the tab you pick stays for the session. JSON values are
pretty-printed.
- The Row tab follows the grid’s column: it highlights that column and scrolls to it.
- After a click on the inspector,
jandk(or a click on another column) move the grid’s cell there, the grid scrolling sideways to it;Enteror a double-click shows the value whole. detail_view = "statusbar"(or:set detail_view=statusbar) shows a preview of the cell in the status bar instead of the panel.
╭ Explorer ────────────────────────────╮ 1 console 1 ×
│ + New connection │╭ Query · console 1 ───────────────────────────────────────────────────────────────────────────────────────────────────╮
│▾ Connections 1 ││ local-pg / datarig 127.0.0.1:55432 Space c s switch connection │
│ ▾ ● local-pg ││ 1 -- datarig 🐘 Ctrl+E: run the statement under the cursor │
│ ▾ datarig default ││ 2▎SELECT * FROM shop.users WHERE id <= 8; ✓ 3 rows · 3ms · 14:03 │
│ ▸ analytics ││ 3 │
│ ▸ public ││ 4 SELECT u.name, o.status, o.total_amount │
│ ▸ shop ││ 5 FROM shop.orders o │
│ ││ 6 JOIN shop.users u ON u.id = o.user_id │
│ ││ 7 WHERE o.status = 'paid'; │
│ ││ 8 │
│ ││ 9 SELECT * FROM analytics.events; │
│ ││ 10 │
│ ││ 11 SELECT * FROM analytics.events ORDER BY created_at DESC; │
│ ││ 12 │
│ ││ 13 SELECT analytics.slow(30); │
│ ││ 14 │
│ │╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
│ │╭ Results · 3 rows ────────────────────────────────────────────────────╮╭ Cell [Row] · I ──────────────────────────────╮
│ ││ [Result 1] Chart Messages H/L ││ PK id: 1 │
│ ││ │ PK id │ FK user_id │ UQ email │ name │ PK FK orde││ FK user_id: 1 │
│ ││ │ int8 │ int8 │ text │ text │ int8 ││ UQ email: user01@example.com │
│ ││ 1 │ 1 │ 1 │ user01@example.com │ ユーザー 1 │ ›││ name: ユーザー 1 │
│ ││ 2 │ 2 │ 1 │ user02@example.com │ ユーザー 2 │ ›││ PK FK order_id: 1 │
│ ││ 3 │ 3 │ 1 │ user03@example.com │ ユーザー 3 │ ›││ PK line_no: 1 │
│ ││ ││ FK product_id: 7 │
│ ││ ││ doubled: 2 │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
│ ││ ││ │
╰──────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────╯
NORMAL local-pg │ 3 rows · 3ms │ Enter view cell · n next page · y copy · v select · i detail · I cell/row · Esc back · Tab next pane · : commands EN
Copy
y copies the cell (a selected range) and Y the row (the selected rows), as TSV unless
copy_format says otherwise. The
Space r y group copies the selection, and Space r a every fetched row, as:
TSV with or without headers, CSV, JSON, indented JSON, Markdown, HTML, XML, an SQL IN list,
or SQL INSERT/UPDATE statements (only when the target table is certain). :copy <format>
does the same from the command line (for example :copy csv all).
- Copies go to the system clipboard, or through OSC 52 over SSH (
clipboard:auto,systemorosc52;osc52_max_bytesis the longest copy sent through OSC 52). - The status bar names the format:
Copied 5 rows as CSV (OSC 52). - The copied cells flash briefly and fade back (with the terminal’s own colours the flash goes
off at once);
[ui] yank_flash = "off"turns that off.
The format of y and Y
copy_format is the format y and Y copy in: tsv (the default), csv, json,
json_pretty, markdown, html, xml or insert, the same names as :copy. Set it in the
settings screen, with :set copy_format=csv, or from the grid: Space r y d (or the menu’s
“Default format for y and Y”) lists the formats with the current one marked, and picking one
makes it the default. The Space r y group and the menu’s copy formats mark the one y and Y
use.
- One cell without a selection is always copied as its value, whatever the format.
insertwrites SQLINSERTstatements only when the rows are certainly of one table (the same rule as Copy as SQL INSERT). OtherwiseyandYcopy TSV and the status bar says why.g pandppaste the cellsyandYcopied, value for value, whatever format the clipboard got.
Column names in copies
copy_header says whether a copy starts with a row of column names:
auto(the default): when more than one row is copied.yon one cell,Yon one row and a selection inside one row copy no header; a selection of two or more rows, or whole columns, starts with one.on: always, even for one cell.off: never.
It applies to TSV copies from y and Y. A CSV copy always starts with the column names
unless copy_header = "off". Copy as TSV without or with headers ignores the setting, and JSON,
Markdown, HTML, XML and the SQL formats are written the same way whatever it says.
To write a result to a file instead, see Export. To draw it, see Charts.
Editing
A result of one table can be edited in the grid: e edits a cell, o and O add rows, D
marks rows to be deleted, and the changes stay pending until you apply them. After the first
edit key that gets as far as the table, the result tab strip says whether the rows can be edited
(editable · shop.users · key id) or why not (read-only · <reason>; a reason about the
connection, such as a read-only environment, is said by the key only), then how many changes are
pending (3 pending) and, after an Apply, applied · re-run to refresh. See Editing
data.
Transactions in the results
Results read inside an open transaction are labelled uncommitted. The tab bar and the status bar show an open transaction, an aborted one, and “rollback required”; see Manual commit.