select open change scope Open full search

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

SQLSTATE / CLASS 42 · SYNTAX ERROR OR ACCESS RULE VIOLATION

invalid_recursion

SQLSTATE
42P19
Condition name
invalid_recursion
Class
Syntax Error or Access Rule Violation
Source macro
ERRCODE_INVALID_RECURSION
Evidence
Source path confirmed
Analysis & operational context

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

<h1>42P19 — Invalid recursion</h1>

At a glance

42P19 (invalid_recursion) Recursive query structure is checked before the recursive term can run.

Meaning

Recursive-query validation rejects a recursive term whose structure cannot be evaluated safely. Core 18.6 checks aggregate use in the recursive term, the required non-recursive UNION [ALL] recursive form, and recursive-reference context and multiplicity. The selected aggregate guard is about aggregates (p_hasAggs); it does not justify saying that every window function is forbidden.

Diagnosis

Read the query shape rather than only the CTE name. Separate the anchor term from the recursive term, count references to the recursive query, and inspect whether a reference appears in a forbidden recursive context such as a subquery or the nullable side of an outer join: for LEFT JOIN that is the right side, for RIGHT JOIN the left side, and for FULL JOIN both sides; the preserved side of a one-sided outer join is not covered by that guard. Also check INTERSECT/EXCEPT contexts. Identify actual aggregates in the recursive term; do not classify every window expression as this error. This distinguishes structural recursion errors from 42P18 type inference failures.

Response

Rewrite the CTE into one non-recursive anchor followed by one UNION or UNION ALL recursive term, keep one recursive reference in an allowed context, and move aggregation outside the recursive step when needed. Validate termination and result cardinality before retrying. If this ERROR occurs inside an explicit transaction, ROLLBACK or ROLLBACK TO a pre-error savepoint before sending the rewritten query.

Messages

Representative source messages include: message: aggregate functions are not allowed in a recursive query's recursive term; message: recursive query "%s" does not have the form non-recursive-term UNION [ALL] recursive-term; message: recursive reference to query "%s" must not appear more than once. Placeholders are filled by the actual object, column, or parameter.

Versions

The locked catalogue shows this condition by PostgreSQL 8.4.0; behavior here is fixed to PostgreSQL 18.6 source. Catalogue presence is a range boundary, not proof that every message or feature began in that release.

Sources

Source messages, line anchors, and evidence limits are recorded in authored evidence.

Source evidence

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

42P19 is the invalid_recursion condition in Class 42.

Method: Read fixed REL_18_6 errcodes.txt and locked facts.

Limits: Identity does not enumerate all source branches or client failures.

src.errcodes.42P19.18.6

Core 18.6 checks aggregate use in the recursive term, the required non-recursive UNION [ALL] recursive form, and recursive-reference context and multiplicity. The selected aggregate guard is p_hasAggs; it does not establish that every window function is forbidden. Outer-join context applies to the nullable side (LEFT right, RIGHT left, FULL both), while the preserved side of a one-sided join is not covered by that guard.

Method: Read selected resolved REL_18_6 report groups and message roles.

Limits: Representative confirmed core paths only; not exhaustive historical or extension coverage.

src.call.42P19.e59c077eba1a4a52a69a6d97 src.call.42P19.e6e0586856ee8989b006f7ae src.call.42P19.3b25492c51b06d773f237993 src.call.42P19.recursion-context

Locked catalogue snapshots show this condition by PostgreSQL 8.4.0; source behavior here is fixed at PostgreSQL 18.6.

Method: Read locked catalogue facts and definition snapshot.

Limits: First observed release is a lower bound, not precise behavioral introduction.

src.errcodes.42P19.18.6

Message templates

ERROR · message.variant-1

Primary

aggregate functions are not allowed in a recursive query's recursive term

Placeholders remain dynamic source fields; no concrete runtime value is claimed.

ERROR · message.variant-2

Primary

recursive query "%s" does not have the form non-recursive-term UNION [ALL] recursive-term

Placeholders remain dynamic source fields; no concrete runtime value is claimed.

ERROR · message.variant-3

Primary

recursive reference to query "%s" must not appear more than once

Placeholders remain dynamic source fields; no concrete runtime value is claimed.

Reproduction & repair cases

No reproduction case is attached to this condition.

Recorded runtime evidence

No runtime observation is attached to this entry.

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