select open change scope Open full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

SQLSTATE / CLASS P0 · PL/PGSQL ERROR

raise_exception

SQLSTATE
P0001
Condition name
raise_exception
Class
PL/pgSQL Error
Source macro
ERRCODE_RAISE_EXCEPTION
Evidence
Observed at runtime in the source evidence
Analysis & operational context

English SQLSTATE atlas: authored explanations and source/runtime evidence are separate from the manual definitions. View source ↗

At a glance

P0001 is the raise_exception condition in PostgreSQL's PL/pgSQL-specific Class P0. A RAISE EXCEPTION statement with no condition name and no explicit SQLSTATE defaults to this code. The message is supplied by the function author, so P0001 is usually an application or procedure control signal rather than a diagnosis of one server subsystem.

The level and code are separate choices. EXCEPTION is the default RAISE level and normally aborts the current transaction. NOTICE, WARNING, INFO, LOG, and DEBUG generate messages without that exception behavior; an explicit ERRCODE can also choose a different SQLSTATE. Always capture the severity and SQLSTATE together.

The representative case plpgsql_raise_exception creates a function containing RAISE EXCEPTION 'calibration exception', calls it, and then runs SELECT 1 on the same autocommit connection. PostgreSQL 18.6 and 10.21 both returned P0001, preserved the message, left the connection IDLE, and accepted the follow-up query. The SQL excerpt below is the complete ordered function, call, and follow-up from the shared snippet registry; the runner owns the schema-qualified name and cleanup.

Meaning and trigger paths

The 18.6 directory places P0001 in Class P0, PL/pgSQL Error, and names it raise_exception. The class is PostgreSQL-specific. In the PL/pgSQL executor, the default code is assigned only when no code was supplied and the level is at least ERROR; the executor then reports the caller's message and optional detail, hint, and object fields.

The syntax supports several distinct paths:

  • RAISE EXCEPTION 'message' uses P0001 by default.
  • RAISE EXCEPTION condition_name uses the condition's SQLSTATE, so it need not be P0001.
  • RAISE EXCEPTION SQLSTATE '5-character-code' or RAISE ... USING ERRCODE = ... lets a procedure expose a domain-specific contract. PostgreSQL permits user-chosen five-character codes other than 00000.
  • A lower level such as RAISE WARNING 'message' emits a message at that priority. It is not the same transaction event as RAISE EXCEPTION, even if the caller chooses an explicit error code.

The no-argument RAISE; form is re-raise control inside an active exception handler. Its behavior and SQLSTATE are determined by the exception being re-raised; it is not a new default P0001 event.

Messages and diagnostics

The representative registry operation is:

CREATE FUNCTION raise_exception_case() RETURNS void
LANGUAGE plpgsql AS $$
BEGIN
    RAISE EXCEPTION 'calibration exception';
END
$$;
SELECT raise_exception_case();
SELECT 1;

The function name is schema-qualified and generated by the test executor in the actual run. The observed 18.6 diagnostic was:

SQLSTATE: P0001
severity: ERROR
message_primary: calibration exception
context: PL/pgSQL function ...raise_exception_case() line 3 at RAISE
source: pl_exec.c / exec_stmt_raise / line 3923

There is no universal English primary message for P0001; the function supplies it. USING MESSAGE, DETAIL, HINT, COLUMN, CONSTRAINT, DATATYPE, TABLE, and SCHEMA can add structured diagnostics. Localized message text can change while SQLSTATE remains stable, so branch on P0001 and inspect the structured fields rather than parsing the primary string.

Diagnosis

First determine whether the code came from an intentional RAISE EXCEPTION or from a different domain condition that the function explicitly selected. Record SQLSTATE, localized and nonlocalized severity, primary message, detail, hint, context, source location, and the statement that called the function. In a PL/pgSQL handler, SQLSTATE and SQLERRM identify the active exception, while GET STACKED DIAGNOSTICS retrieves its fields.

Then locate the function branch and its transaction context. A failed call in autocommit ends that statement and leaves the connection ready for another command, as the representative case shows. A call inside an explicit transaction normally leaves the transaction aborted until the client issues ROLLBACK or rolls back to a savepoint. The server connection is not necessarily terminated.

An EXCEPTION clause changes the boundary. The protected body runs in a subtransaction; when it errors, persistent changes made by that body are rolled back before the first matching condition handler runs, while changes made outside it remain. WHEN OTHERS matches every error except QUERY_CANCELED and ASSERT_FAILURE; it is broad and should not be used as a substitute for identifying the intended P0001 path.

Response

Use P0001 when the procedure intentionally exposes the generic PL/pgSQL raise contract. If callers need to distinguish validation, conflict, quota, or another business outcome, choose and document an appropriate SQLSTATE and add DETAIL or HINT that helps the caller act. Do not turn unrelated server errors into P0001 merely to simplify application code.

At the client boundary, roll back an explicit transaction before issuing unrelated commands, or use a savepoint when the caller can safely isolate the function call. In PL/pgSQL, prefer a narrow handler such as WHEN raise_exception or WHEN SQLSTATE 'P0001' when the recovery is specific. If a broad handler is required, preserve RETURNED_SQLSTATE, MESSAGE_TEXT, PG_EXCEPTION_DETAIL, PG_EXCEPTION_HINT, and context before deciding whether to continue or re-raise.

The natural RAISE EXCEPTION case is safe to demonstrate because it exercises the intended PL/pgSQL mechanism. That does not make P0001 evidence of a server fault; it is an explicit exception raised by the function.

Versions

The catalogue records P0001 in the locked 8.0.0–8.4.22 pre-9.0 formal sources, every formal snapshot from 9.0.23 through 18.6, and the 19 Beta 3 preview. The same-tag REL8_1_4 errcodes.sgml table already lists P0001 as raise_exception, confirming that condition-name observation by 8.1.4. The class title is PL/pgSQL Error (PostgreSQL-specific error class) in the 9.0 header view and changes to PL/pgSQL Error in the 9.1 text definition. Candidate source gaps remain for 7.0–7.3; these are observed catalogue boundaries, not asserted implementation introduction dates.

The fixed 18.6 source commit is 724edf9bde9d356724ad384a2e196edc3c9f80f7. The default RAISE EXCEPTION rule is documented for PostgreSQL 18 and source-confirmed in the 18.6 executor. The representative case passed on PostgreSQL 18.6 and 10.21; it does not test every custom code, handler, or transaction mode.

Sources

The structured evidence is recorded in the public evidence JSON. Source records are pinned to PostgreSQL commit 724edf9bde9d356724ad384a2e196edc3c9f80f7; runtime records retain the shared snippet registry, both target summaries, and run P0001-snippet-registry-final-20260909.

Source evidence

Evidence belongs to the frozen source and runtime versions listed here. It is not a runtime verification of the selected manual version.

P0001 is the raise_exception condition in PostgreSQL-specific Class P0, PL/pgSQL Error.

Method: Read the Class P0 section and P0001 row in the frozen errcodes.txt snapshot.

Limits: The directory identifies the condition; it does not say that every application error should use P0001.

src.errcodes.18.6

A RAISE EXCEPTION with no condition name and no SQLSTATE defaults to raise_exception, P0001.

Method: Read the executor's default err_code branch and the official RAISE documentation.

Limits: An explicit condition, SQLSTATE, or ERRCODE selects another code; the default applies to an EXCEPTION-level raise.

src.pl-exec.18.6 doc.plpgsql.18

RAISE supports DEBUG, LOG, INFO, NOTICE, WARNING, and EXCEPTION levels; EXCEPTION normally aborts the current transaction, while lower levels generate messages, and USING can supply structured fields.

Method: Read the RAISE syntax, level behavior, USING options, and ereport construction.

Limits: Client and server visibility also depends on message configuration; an explicit SQLSTATE can accompany a lower level.

doc.plpgsql.18 src.pl-exec.18.6

A PL/pgSQL block with an EXCEPTION clause runs its protected body in a subtransaction; persistent changes made by the body are rolled back before the matching handler runs.

Method: Read the official error-trapping and subtransaction descriptions.

Limits: The handler's own errors propagate outward, and local variables follow PL/pgSQL's documented handler rules.

doc.plpgsql.18

OTHERS matches every error type except QUERY_CANCELED and ASSERT_FAILURE, and a new error raised by the selected handler is not caught by that same clause.

Method: Read the condition matching and handler propagation paragraphs.

Limits: OTHERS is a broad handler; this claim does not recommend swallowing all errors.

doc.plpgsql.18

Inside an exception handler, SQLSTATE and SQLERRM identify the active exception and GET STACKED DIAGNOSTICS can retrieve its fields.

Method: Read the PL/pgSQL exception diagnostics section and the protocol field reference.

Limits: The exact fields present depend on the raised condition and the client interface.

doc.plpgsql.18 doc.protocol.18

plpgsql_raise_exception returned P0001 with the caller-supplied calibration exception message on PostgreSQL 18.6 and 10.21; both autocommit connections remained IDLE and accepted SELECT 1.

Method: Read the stable case and ordered snippet registry, then compare the case_result diagnostics and follow-up status in both final target summaries and raw records.

Limits: This is an intentional PL/pgSQL exception case; it does not test custom SQLSTATEs, explicit transactions, or handler recovery.

case-manifest.P0001 snippet-registry.P0001.final runtime.P0001-snippet-registry-final-20260909.latest runtime.P0001-snippet-registry-final-20260909.pg10

An unhandled EXCEPTION in an explicit transaction normally requires rollback before unrelated commands, while the representative autocommit call leaves the connection usable.

Method: Read the transaction contract and compare it with the observed IDLE/follow-up result.

Limits: No explicit transaction was run in this P0001 case; handler blocks have the separate subtransaction contract above.

doc.transactions.18 runtime.P0001-snippet-registry-final-20260909.latest runtime.P0001-snippet-registry-final-20260909.pg10

The locked catalogue records P0001 in the 8.0.0–8.4.22 pre-9.0 formal sources, every listed formal snapshot from 9.0.23 through 18.6, and 19beta3. The same-tag REL8_1_4 errcodes.sgml row already lists P0001 as raise_exception, confirming that condition-name observation by 8.1.4. The class title changes between the 9.0 header and 9.1 text definitions; candidate source gaps remain for 7.0–7.3. These are presence boundaries, not asserted implementation introduction dates.

Method: Read the manifest snapshot and the same-tag REL8_1_4 errcodes.sgml row for the code; the generated per-code history is a derived view.

Limits: The pre-9.0 source set is locked through 8.4.22 but candidate source gaps remain for 7.0–7.3; the observed condition-name and class-title changes are not exact implementation introduction dates.

manifest.P0001 doc.errcodes.8.1.4

Message templates

default EXCEPTION level · message.raise-user

Primary

caller-supplied RAISE format, condition, or MESSAGE expression

There is no universal P0001 primary text; the default message when no text is supplied is the condition name or SQLSTATE.

EXCEPTION · message.runtime-calibration

Primary

calibration exception

This literal is specific to the representative function and is not a built-in P0001 message template.

Reproduction & repair cases

plpgsql_raise_exception · PG 10, 18

Preconditions

  • PL/pgSQL is available

Trigger: Execute a function containing RAISE EXCEPTION without an explicit SQLSTATE.

Expected assertions

  • SQLSTATE is P0001
  • The custom message is preserved
  • The failed call is isolated to its transaction

Repair: Use a domain-specific SQLSTATE only when the caller contract requires it; catch and handle the exception at the correct transaction boundary.

Cleanup: Drop the function and case schema.

Recorded runtime evidence

18.6 (Homebrew) · passed

Run: P0001-snippet-registry-final-20260909

{
  "followup": 1,
  "severity": "ERROR",
  "sqlstate": "P0001",
  "source_file": "pl_exec.c",
  "source_line": "3923",
  "message_primary": "calibration exception",
  "source_function": "exec_stmt_raise",
  "status_after_error": "IDLE"
}
10.21 (Debian 10.21-1.pgdg90+1) · passed

Run: P0001-snippet-registry-final-20260909

{
  "followup": 1,
  "severity": "ERROR",
  "sqlstate": "P0001",
  "source_file": "pl_exec.c",
  "source_line": "3337",
  "message_primary": "calibration exception",
  "source_function": "exec_stmt_raise",
  "status_after_error": "IDLE"
}

Definition snapshot: english-manuals:a12d2365231746adf360f231479… · English manual source