| From: | Kirk Roybal <kirk(dot)roybal(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers(at)postgresql(dot)org |
| Subject: | Re: [PATCH] Add PROMPT_COMMAND and dynamic prompt support to psql |
| Date: | 2026-08-04 15:49:43 |
| Message-ID: | CAE==DwevFQkHCBzXRrwtGj4eLc-QCG_gUctqONqPvv7abC2ZMg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
v2 follow-up: one-page merge rationale, explicit review ask, and a TAP test
(as offered in the original post). Patch attached.
========================================================================
Why merge this (one page)
========================================================================
Problem
-------
Interactive psql prompts are static between PROMPT1/PROMPT2 redefinitions.
Users who want connection context, transaction state, or last-command status
in the prompt today either fork psql or abuse %`shell` on every redraw.
There
is no bash-shaped hook to regenerate the prompt once per readline.
Bash-shaped solution
--------------------
Mirror bash, not invent a plugin API:
* PROMPT_COMMAND — if set, run a shell command before each interactive
prompt; capture the first line of stdout (existing prompt buffer limit).
* %D — PROMPT1/PROMPT2 escape for that captured line (renderer output).
* SHELL_EXIT — last *user* command status (SQL or \!); PROMPT_COMMAND does
not overwrite it, so themes can show the prior command’s outcome.
* Prompt refresh — run_prompt_command() immediately before readline() in
input.c (not rl_pre_input_hook, which left the prompt blank until a
key).
* \connect housekeeping — reset ROW_COUNT / SHELL_EXIT after successful
\connect; optional :txid refresh when that variable already exists.
Zero behavior change unless configured
--------------------------------------
Defaults are inert:
| Knob | Default | Effect when unset/off |
|-------------------------|---------|------------------------------------|
| PROMPT_COMMAND | unset | no shell, no popen |
| %D | unused | empty substitution if referenced |
| PROMPT_SESSION_EXPORT | off | no PG*/PSQL_* export into subprocess |
| SHELL_EXIT | "0" | new variable only; scripts ignore it |
Non-interactive use, existing scripts, and default interactive sessions are
unchanged. No .psqlrc change ⇒ no new behavior.
Security / gating story (PROMPT_SESSION_EXPORT + shell)
-------------------------------------------------------
PROMPT_COMMAND uses popen() — the same trust model as existing %`command`
prompt escapes and \!. It only runs when the user (or their .psqlrc)
explicitly sets PROMPT_COMMAND.
PROMPT_SESSION_EXPORT is a separate, default-off gate:
* Off (default): PROMPT_COMMAND subprocess inherits the normal process
environment only; no extra session dump.
* On: export current-session PG* / PSQL_* (database, user, host, port,
PSQL_TXN, PSQL_ROW_COUNT, PSQL_SHELL_EXIT, PSQL_SUPERUSER, optional
PSQL_TXID) so external renderers need not re-query.
Keeping export opt-in means “I only want %D from a fixed command” never
leaks connection metadata into the child env. Reviewers who want a
narrower first commit can take PROMPT_COMMAND + %D + SHELL_EXIT alone and
leave PROMPT_SESSION_EXPORT for a follow-up.
========================================================================
Looking for a reviewer to walk this path
========================================================================
Please walk the psql + readline path (not a general “please review”):
1. src/bin/psql/input.c
— run_prompt_command() immediately before readline() / gets_fromFile
2. src/bin/psql/prompt.c + prompt.h
— run_prompt_command(), export_prompt_environment(),
prompt_session_export_enabled(), %D in get_prompt(),
reset_prompt_status_after_connect()
3. src/bin/psql/mainloop.c
— gets_interactive() call sites (when prompts are drawn)
4. src/bin/psql/common.c
— SetLastExitVariable() / SHELL_EXIT; confirm PROMPT_COMMAND does not
call it
5. src/bin/psql/command.c
— reset_prompt_status_after_connect() after successful \connect
6. src/bin/psql/help.c + startup.c
— --help=variables / initial SHELL_EXIT
7. src/bin/psql/t/040_prompt_command.pl
— TAP coverage (below)
Optional companion doc (not installed):
src/bin/psql/powerline-integration.md
========================================================================
Testing (v2: TAP added)
========================================================================
src/bin/psql/t/040_prompt_command.pl (registered in meson.build):
Non-interactive:
* SHELL_EXIT after successful SQL, failed SQL, \! true, \! false
* \connect clears ROW_COUNT and SHELL_EXIT
* --help=variables lists PROMPT_COMMAND, PROMPT_SESSION_EXPORT,
SHELL_EXIT
Interactive (IO::Pty + readline, same pattern as t/010 / t/030):
* PROMPT_COMMAND + %D in PROMPT1
* first line only of multi-line PROMPT_COMMAND stdout
* %D empty when PROMPT_COMMAND unset
* PROMPT_SESSION_EXPORT off → PSQL_TXN / PSQL_SUPERUSER not exported
* PROMPT_SESSION_EXPORT on → PSQL_TXN / PSQL_SUPERUSER exported
* PROMPT_COMMAND does not overwrite SHELL_EXIT after a failed SQL
Manual still useful for visual / powerline end-to-end; automation no longer
depends on it for the core knobs.
========================================================================
v2 patch notes
========================================================================
Relative to the original submission:
* Added src/bin/psql/t/040_prompt_command.pl
* Listed that test in src/bin/psql/meson.build
* No intentional functional change to the feature code
Happy to rename variables, drop PROMPT_SESSION_EXPORT from v1, or further
split if that helps commit.
Companion (not part of this patch):
https://github.com/powerline/powerline/pull/2287
Fork branch:
https://github.com/bithead2k/postgres/tree/psql-prompt-command
Comments welcome.
Regards,
Kirk Roybal
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Add-PROMPT_COMMAND-and-dynamic-prompt-support-to-psq.patch | text/x-patch | 23.5 KB |
| 0003-Add-TAP-coverage-for-PROMPT_COMMAND-and-session-expo.patch | text/x-patch | 9.1 KB |
| 0002-Add-powerline-prompt-example-screenshot-to-integrati.patch | text/x-patch | 134.8 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Bharath Rupireddy | 2026-08-04 15:55:11 | Re: enhance wraparound warnings |
| Previous Message | Álvaro Herrera | 2026-08-04 15:14:43 | Re: Fix a host of strto*() bugs |