P0001
Read PG 18 manual ↗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
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'usesP0001by default.RAISE EXCEPTION condition_nameuses the condition's SQLSTATE, so it need not beP0001.RAISE EXCEPTION SQLSTATE '5-character-code'orRAISE ... USING ERRCODE = ...lets a procedure expose a domain-specific contract. PostgreSQL permits user-chosen five-character codes other than00000.- A lower level such as
RAISE WARNING 'message'emits a message at that priority. It is not the same transaction event asRAISE 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.
src.errcodes.18.6—errcodes.txtsrc.pl-exec.18.6—pl_exec.cdoc.plpgsql.18— Errors and Messages and Error Trappingdoc.protocol.18— Error and Notice Message Fieldsdoc.transactions.18— Transactions
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.
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.
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.
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.
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.
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.
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.
- src/backend/utils/errcodes.txt · REL_18_6 · lines 487-494
724edf9bde9d356724ad384a2e196edc3c9f80f7 - src/pl/plpgsql/src/pl_exec.c · REL_18_6 · lines 3889-3923, exec_stmt_raise default and ereport
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/plpgsql.sgml · PG18-docs · lines 2815-2860, 2957-2968, 3768-3775, 3836-3858, 4008-4013
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/protocol.sgml · PG18-docs · lines 6254-6290, severity and diagnostic fields
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/xact.sgml · PG18-docs · transaction rollback and savepoint behavior
724edf9bde9d356724ad384a2e196edc3c9f80f7 - doc/src/sgml/errcodes.sgml · · REL8_1_4 table rows 1303-1308
313a720f95a3f41b59f853786b184f38f82172d9 - sources/manifest.lock.json · · snapshots and definition_blobs entries for the P0001 definition
- verify/cases/P0001/cases.json · · plpgsql_raise_exception
- verify/cases/P0001/snippets.json · · plpgsql_raise_exception ordered function, call, and followup
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