Skip to content

psql: add %o prompt escape for Oracle compatibility mode#1383

Open
123123213weqw wants to merge 2 commits into
IvorySQL:masterfrom
123123213weqw:psql-ora-mode-prompt-1354
Open

psql: add %o prompt escape for Oracle compatibility mode#1383
123123213weqw wants to merge 2 commits into
IvorySQL:masterfrom
123123213weqw:psql-ora-mode-prompt-1354

Conversation

@123123213weqw

@123123213weqw 123123213weqw commented Jul 7, 2026

Copy link
Copy Markdown

Add a new psql prompt escape %o that shows whether the current session is in Oracle compatibility mode, so it is easy to tell which mode psql is running in.

Changes

  • Mark ivorysql.compatible_mode as GUC_REPORT so the server pushes its value to the client, letting the prompt track in-session SET changes in real time.
  • Add a %o escape in src/bin/psql/prompt.c and src/bin/psql/ora_prompt.c: it expands to [ORA] when ivorysql.compatible_mode = 'oracle', and to empty otherwise.

Behavior

  • Off by default — the standard prompt is unchanged.
  • Opt in with:
    \set PROMPT1 '%o%/%R%x%# '
    
    Then the prompt shows [ORA]ivorysql=# in Oracle mode and ivorysql=# in PostgreSQL mode, updating live as you SET ivorysql.compatible_mode.

Notes

  • Reads the value via PQparameterStatus("ivorysql.compatible_mode"), so it requires the GUC_REPORT change above (server recompile + restart) and safely degrades to empty against an older server that does not report it.
  • Prompts are interactive-only, so scripts / CI / regression tests are unaffected.

Verified by building and running locally: in-session SET ivorysql.compatible_mode = oracle makes the %o prompt show [ORA] immediately, and SET ... = pg clears it.

Closes #1354.

Summary by CodeRabbit

  • New Features
    • Added a new psql prompt escape (%o) that inserts an [ORA] marker when connected to an IvorySQL server in Oracle database mode; otherwise it outputs nothing.
    • Updated the default PROMPT1 and PROMPT2 formats to include %o automatically.
  • Documentation
    • Extended the psql prompt substitution reference to document %o behavior and reflect the updated default prompt strings.

Add a new psql prompt escape %o that expands to "[ORA]" when the session
is in Oracle compatibility mode (ivorysql.compatible_mode = 'oracle'),
and to empty otherwise, so it is easy to tell which mode psql is in.

Mark ivorysql.compatible_mode as GUC_REPORT so the server pushes its
value to the client, letting the prompt track in-session SET changes in
real time.

The escape is added to both src/bin/psql/prompt.c and ora_prompt.c.  It
is off by default; users opt in via \set PROMPT1 '%o%/%R%x%# '.

Issue: IvorySQL#1354
Signed-off-by: wangyue789 <1939457790@qq.com>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb87499a-129f-4366-b90a-0415d92f276f

📥 Commits

Reviewing files that changed from the base of the PR and between 7f44f5c and d063058.

⛔ Files ignored due to path filters (1)
  • src/backend/utils/misc/guc_parameters.dat is excluded by !**/*.dat
📒 Files selected for processing (5)
  • doc/src/sgml/ref/psql-ref.sgml
  • src/backend/utils/misc/ivy_guc.c
  • src/bin/psql/ora_prompt.c
  • src/bin/psql/prompt.c
  • src/bin/psql/settings.h
✅ Files skipped from review due to trivial changes (3)
  • doc/src/sgml/ref/psql-ref.sgml
  • src/bin/psql/settings.h
  • src/backend/utils/misc/ivy_guc.c
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/bin/psql/prompt.c
  • src/bin/psql/ora_prompt.c

📝 Walkthrough

Walkthrough

Adds a new %o prompt escape to psql, reports the server mode parameter to the client, and updates the default prompt strings and reference documentation to include %o.

Changes

Oracle mode prompt escape

Layer / File(s) Summary
%o escape handling
src/bin/psql/prompt.c, src/bin/psql/ora_prompt.c, src/backend/utils/misc/ivy_guc.c
Adds %o parsing in both prompt implementations, reading the reported mode parameter and emitting [ORA] only when it is oracle; the backend GUC is marked for reporting so the client can see updates.
Prompt defaults and docs
src/bin/psql/settings.h, doc/src/sgml/ref/psql-ref.sgml
Updates the default prompt macros to prefix %o, and revises the psql reference text to document %o and the new default prompt strings.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant psql
  participant get_prompt
  participant PQparameterStatus
  participant PromptBuffer

  psql->>get_prompt: render prompt string
  get_prompt->>get_prompt: encounter %o
  get_prompt->>PQparameterStatus: read ivorysql.database_mode
  PQparameterStatus-->>get_prompt: return mode value
  get_prompt->>PromptBuffer: append "[ORA]" when value is "oracle"
  get_prompt-->>psql: return final prompt
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The implementation diverges from #1354: it keys off ivorysql.database_mode and changes default prompts, but the issue required compatible_mode and opt-in only. Read ivorysql.compatible_mode via PQparameterStatus, mark that GUC_REPORT, and keep the default prompt unchanged; users can opt in with %o manually.
Out of Scope Changes check ⚠️ Warning Updating DEFAULT_PROMPT1/2 to include %o changes the default prompt behavior, which was outside the linked issue’s opt-in-only requirement. Remove %o from the built-in default prompts and leave it available only when users explicitly add it to PROMPT1/PROMPT2.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding a %o psql prompt escape for Oracle compatibility mode.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@src/bin/psql/prompt.c`:
- Around line 281-289: The %o prompt marker in psql relies on
PQparameterStatus("ivorysql.compatible_mode"), but that GUC is not being
reported because it lacks the GUC_REPORT flag. Update the ivy_guc.c entry for
ivorysql.compatible_mode so it includes GUC_REPORT alongside its existing flags,
using the compatible_mode GUC definition as the target symbol to locate the
change.
🪄 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: c0656f13-1b19-4d64-b1f8-cc783dbad89f

📥 Commits

Reviewing files that changed from the base of the PR and between 7fb2571 and 1adb3e9.

⛔ Files ignored due to path filters (1)
  • src/backend/utils/misc/guc_parameters.dat is excluded by !**/*.dat
📒 Files selected for processing (2)
  • src/bin/psql/ora_prompt.c
  • src/bin/psql/prompt.c

Comment thread src/bin/psql/prompt.c
Comment on lines +281 to +289
case 'o':
if (pset.db)
{
const char *cm = PQparameterStatus(pset.db, "ivorysql.compatible_mode");

if (cm && strcmp(cm, "oracle") == 0)
strlcpy(buf, "[ORA]", sizeof(buf));
}
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm which GUC table definition is actually compiled and whether GUC_REPORT is present.
rg -n "ivorysql.compatible_mode" -A5 src/backend/utils/misc/ivy_guc.c
rg -n "gen_guc_tables|guc_parameters.dat" -n src/backend/utils/misc/Makefile src/backend/utils/misc/meson.build 2>/dev/null

Repository: IvorySQL/IvorySQL

Length of output: 670


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== build wiring =="
rg -n "guc_parameters\.dat|gen_guc_tables|ivy_guc\.c|guc" src/backend/utils/misc/Makefile src/backend/utils/misc/meson.build src/backend/utils/misc -g '!*.o' -g '!*.a' -g '!*.so'

echo
echo "== dat definition =="
rg -n "ivorysql\.compatible_mode" -A6 -B2 src/backend/utils/misc/guc_parameters.dat

echo
echo "== generated C definition context =="
rg -n "ivorysql\.compatible_mode" -A8 -B2 src/backend/utils/misc/ivy_guc.c

Repository: IvorySQL/IvorySQL

Length of output: 24446


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== GUC_REPORT handling =="
rg -n "GUC_REPORT|ParameterStatus|guc_report_list|Report" src/backend/utils/misc/guc.c src/backend/utils/misc/guc_tables.c src/backend/utils/misc/ps_status.c src/include/utils/guc.h

echo
echo "== report-path context =="
sed -n '2440,2510p' src/backend/utils/misc/guc.c

echo
echo "== table inclusion context =="
sed -n '100,140p' src/backend/utils/misc/guc_tables.c
sed -n '796,826p' src/backend/utils/misc/guc_tables.c

Repository: IvorySQL/IvorySQL

Length of output: 7190


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ivy_guc.c macro blocks around compatible_mode =="
sed -n '360,420p' src/backend/utils/misc/ivy_guc.c

echo
echo "== ivy_guc.c macro guards =="
rg -n "IVY_GUC_VAR_DEFINE|IVY_GUC_FUNC_DECLARE|IVY_GUC_FUNC_DEFINE" -A3 -B3 src/backend/utils/misc/ivy_guc.c

echo
echo "== any other compatible_mode definitions =="
rg -n "ivorysql\.compatible_mode|compatible_mode" src/backend/utils/misc src/include -g '!*.o' -g '!*.a' -g '!*.so'

Repository: IvorySQL/IvorySQL

Length of output: 3501


Add GUC_REPORT to ivorysql.compatible_mode. guc.c only sends ParameterStatus for GUCs with that flag, and guc_tables.c includes src/backend/utils/misc/ivy_guc.c at build time, where this entry currently lacks it; %o will stay empty otherwise.

🤖 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 `@src/bin/psql/prompt.c` around lines 281 - 289, The %o prompt marker in psql
relies on PQparameterStatus("ivorysql.compatible_mode"), but that GUC is not
being reported because it lacks the GUC_REPORT flag. Update the ivy_guc.c entry
for ivorysql.compatible_mode so it includes GUC_REPORT alongside its existing
flags, using the compatible_mode GUC definition as the target symbol to locate
the change.

@bigplaice

Copy link
Copy Markdown
Collaborator

Welcome to contribute to the IvorySQL community! The regression checks has started and we will review the code soon.

@bigplaice bigplaice self-assigned this Jul 8, 2026
@bigplaice

bigplaice commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator
  1. The new %o escape isn't added to doc/src/sgml/ref/psql-ref.sgml, which documents all the other prompt escapes (%i, %x, %l, %R, etc.) . Only an in-source comment was added. Worth adding a <varlistentry> there before merging.
  2. IvorySQL database can be initialized as Oracle mode or PG mode, by using -m pg/oracle in initdb command. If the database mode is oracle (db_mode == DB_ORACLE), we can enable this feature by default. So user don't bother to enable it manually.

…ases

Address review feedback from @bigplaice on PR IvorySQL#1383.

1. Document the %o prompt escape in the Prompting section of psql-ref.sgml, alongside the other escapes, and update the default-prompts note.

2. Show [ORA] by default for Oracle-mode databases. The %o escape previously read ivorysql.compatible_mode, but that GUC defaults to pg even in an initdb -m oracle database, so the indicator never appeared without manual setup. Key %o off ivorysql.database_mode (the db_mode == DB_ORACLE signal) instead, add GUC_REPORT to ivorysql.database_mode so PQparameterStatus() returns it, and include %o in the default PROMPT1/PROMPT2.

Verified: an initdb -m oracle cluster shows [ORA]postgres=# by default; an initdb -m pg cluster shows postgres=# (no [ORA]).
123123213weqw pushed a commit to 123123213weqw/IvorySQL that referenced this pull request Jul 9, 2026
…ases

Address review feedback from @bigplaice on PR IvorySQL#1383.

1. Document the %o prompt escape in the Prompting section of psql-ref.sgml, alongside the other escapes, and update the default-prompts note.

2. Show [ORA] by default for Oracle-mode databases. The %o escape previously read ivorysql.compatible_mode, but that GUC defaults to pg even in an initdb -m oracle database, so the indicator never appeared without manual setup. Key %o off ivorysql.database_mode (the db_mode == DB_ORACLE signal) instead, add GUC_REPORT to ivorysql.database_mode so PQparameterStatus() returns it, and include %o in the default PROMPT1/PROMPT2.

Verified: an initdb -m oracle cluster shows [ORA]postgres=# by default; an initdb -m pg cluster shows postgres=# (no [ORA]).
@123123213weqw

Copy link
Copy Markdown
Author

Hi @bigplaice, thanks for the review. Both points are addressed in the latest push.

1. Documentation

Added %o to the Prompting section of doc/src/sgml/ref/psql-ref.sgml, next to the other escapes, and updated the default-prompts note to reflect the new defaults ('%o%/%R%x%# ').

2. [ORA] shown by default for Oracle-mode databases

%o is now included in the default PROMPT1/PROMPT2, and it keys off ivorysql.database_mode (the db_mode == DB_ORACLE signal) rather than ivorysql.compatible_mode.

The reason for switching to database_mode: compatible_mode is the per-session parser setting and defaults to pg even in an initdb -m oracle database, so keying %o off it meant [ORA] never appeared unless the user changed the mode manually. database_mode is the stable, initdb-time structural mode, so it reliably reflects whether the cluster is an Oracle-mode database. To expose it to the client I added GUC_REPORT to ivorysql.database_mode — in both guc_parameters.dat (the codegen source) and the manual definition in ivy_guc.c — so that PQparameterStatus("ivorysql.database_mode") returns it.

Behavior of %o:

  • initdb -m oracle cluster → [ORA]postgres=#
  • initdb -m pg cluster → postgres=# (no [ORA])
  • connection to a plain PostgreSQL server → empty (the GUC is absent, so %o expands to nothing)

Verified end-to-end by building and connecting with the new psql against both an oracle- and a pg-mode cluster.

@123123213weqw 123123213weqw force-pushed the psql-ora-mode-prompt-1354 branch from 7f44f5c to d063058 Compare July 10, 2026 04:55
@bigplaice

Copy link
Copy Markdown
Collaborator

Hi @bigplaice, thanks for the review. Both points are addressed in the latest push.

1. Documentation

Added %o to the Prompting section of doc/src/sgml/ref/psql-ref.sgml, next to the other escapes, and updated the default-prompts note to reflect the new defaults ('%o%/%R%x%# ').

2. [ORA] shown by default for Oracle-mode databases

%o is now included in the default PROMPT1/PROMPT2, and it keys off ivorysql.database_mode (the db_mode == DB_ORACLE signal) rather than ivorysql.compatible_mode.

The reason for switching to database_mode: compatible_mode is the per-session parser setting and defaults to pg even in an initdb -m oracle database, so keying %o off it meant [ORA] never appeared unless the user changed the mode manually. database_mode is the stable, initdb-time structural mode, so it reliably reflects whether the cluster is an Oracle-mode database. To expose it to the client I added GUC_REPORT to ivorysql.database_mode — in both guc_parameters.dat (the codegen source) and the manual definition in ivy_guc.c — so that PQparameterStatus("ivorysql.database_mode") returns it.

Behavior of %o:

* `initdb -m oracle` cluster → `[ORA]postgres=# `

* `initdb -m pg` cluster → `postgres=# ` (no `[ORA]`)

* connection to a plain PostgreSQL server → empty (the GUC is absent, so `%o` expands to nothing)

Verified end-to-end by building and connecting with the new psql against both an oracle- and a pg-mode cluster.

When database is initialized with -m oracle, the ivory_ora extension is loaded automaticlly and thus user can switch compatible_mode between pg and oracle. While with -m pg, the database will be initialized without ivorysql_ora extension, and user can not switch to oracle mode.

The database_mode==oracle (in code: db_mode == DB_ORACLE) means that it is possible to switch to oracle mode(in code: compatible_db == ORA_PARSER).

User can switch to oracle mode either by connecting 1521 port, or running "set ivorysql.compatibel_mode=oracle;".

This's why I suggest to use compatible_mode instead of database_mode.

BTW, if you are using AI, please refer to https://github.com/IvorySQL/IvorySQL/blob/master/coding-assistants_CN.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

psql: show whether the session is in Oracle compatibility mode in the prompt

2 participants