Skip to content

feat(plugin-oracle): show DBMS_OUTPUT with the result of the statement that printed it - #2990

Merged
datlechin merged 1 commit into
mainfrom
feat/oracle-dbms-output
Sep 18, 2026
Merged

datlechin merged 1 commit into
mainfrom
feat/oracle-dbms-output

Conversation

@datlechin

Copy link
Copy Markdown
Member

Follow-up to #2988 (#2984). With PL/SQL blocks running, the block from the issue ran and showed nothing, because DBMS_OUTPUT.PUT_LINE writes to a session buffer only a client that asks ever reads.

What it does

  • The Oracle plugin enables DBMS_OUTPUT for every session at connect, and again after a reconnect, since the setting belongs to the session. No SET SERVEROUTPUT ON needed.
  • After each statement run from the editor (run at cursor, selection, Run All, gutter, parameterized), the app reads what that statement printed, on the same session, and attaches it to that statement's result. It reads after failed statements too, because the server hands the lines to whoever asks next: output left unread would be reported under the statement after it.
  • A statement with no rows shows its lines under the success message. A query that returned rows and printed gains an Output view mode (switcher and View > Result View), offered only when there is output. A tab left in Output mode goes back to Data when a later result printed nothing.
  • A failed statement lists the first 20 lines it printed before the error in the error banner, each clipped at 500 characters. The banner text is also what Fix with AI receives, and a loop can print 10,000 lines of 32,767 bytes before it fails.
  • At most 10,000 lines per statement. Past that the result says the output was cut short and the rest of the server buffer is discarded, so it cannot leak into the next statement.
  • A session that is already closed (query timeout, dropped transport) reads as no output. The drain never reconnects, so a statement's error is not held up behind a whole login.

How the lines are read

One round trip: a fixed PL/SQL block calls SYS.DBMS_OUTPUT.GET_LINES, splits every line into pieces a SQL VARCHAR2 can hold, and returns them through a REF CURSOR, which the core joins back together.

The split has to happen in PL/SQL. Measured on Oracle 23ai (MAX_STRING_SIZE=STANDARD): a DBMS_OUTPUT line can be 32767 bytes, any SQL over a longer-than-4000-byte element fails with ORA-00910 even through SUBSTR, and oracle-nio does not throw that error: a failure while the block opens its cursor ends the process in a fatalError inside the driver. Reading the lines as SYS.ODCIVARCHAR2LIST pieces of at most 999 characters keeps every SQL value under 4000 bytes in any character set.

Every package and type in the enable call and the drain block is named with its owner (SYS.DBMS_OUTPUT, SYS.DBMSOUTPUT_LINESARRAY, SYS.ODCIVARCHAR2LIST). A bare DBMS_OUTPUT resolves to an object of that name in the session's current schema before the public synonym. Measured on 23ai: with a DBMS_OUTPUT package created in the connecting user's schema, the bare-name version called that package's ENABLE and GET_LINES and the real line was never read; with owner-qualified names the same package received no calls and the line came back. Schema functions named SUBSTR, LENGTH, NVL and LEAST did not shadow the builtins the block uses. A unit test fails if any of the three names appears without SYS..

Measured through OracleCoreConnection against 23ai:

first: ["Hello from PL/SQL", "", "<5000 chars>", "<10000 multibyte chars>"] truncated: false
again: [] (consumed)
capped: ["row 1", "row 2", "row 3"] truncated: true
after cap: [] (rest discarded)
closed session drain: [] connected after: false
reconnected: ["after reconnect"]
after failure: ["before failure"]
shadow package in user schema: drained ["real line"], package calls: []

API

PluginDatabaseDriver.fetchServerOutput() with an empty default and a PluginServerOutput transfer struct: additive, verified with scripts/check-pluginkit-abi.sh against the merge base (no symbol removed), reusing the unreleased kit 33 (v0.75.0 shipped 32), so no bump. Every other driver returns nothing without a round trip.

Also carries the catalog entries for #2988's two compilation-error strings, whose follow-up commit reached the branch after it merged.

Known limit

Lines a trigger prints while a grid edit is saved are not read at save time and show with the next statement run from the editor. The docs say so. Reading them there would mean threading the capture through the change-save path, which reports no result to attach them to.

Tests

  • OracleServerOutputTests (package): piece reassembly, empty lines, truncation, the 4000-byte bound, owner-qualified names, bind order.
  • ServerOutputCaptureTests: output attached on success, read on failure for the error, nothing sent after a cancel, the bounded failure message.
  • TabDisplayOutputModeTests: Output mode leaves when the next result printed nothing.
  • QueryResultPresentationTests, ResultsModeAvailabilityTests, GridSelectionOwnerTests: the Output mode and the success view's output.

No UI automation: CI has no Oracle server to print anything.

@mintlify

mintlify Bot commented Sep 18, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
TablePro 🟢 Ready View Preview Sep 18, 2026, 6:10 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@datlechin
datlechin merged commit ff5d54d into main Sep 18, 2026
8 of 9 checks passed
@datlechin
datlechin deleted the feat/oracle-dbms-output branch September 18, 2026 18:29
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.

1 participant