Skip to content

42809 — Wrong object type

PostgreSQL SQLSTATE 42809: Wrong object type (wrong_object_type), source-backed diagnosis and recovery guidance.

42809 — Wrong object type

At a glance

42809 is wrong_object_type: a command is valid in general but not for the selected object kind. The case tries a row-level BEFORE trigger on a view.

Field Value
SQLSTATE 42809
Condition wrong_object_type
Status active
Known present by 7.4
Locked snapshots 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
Macros ERRCODE_WRONG_OBJECT_TYPE
Aliases

Meaning

The view-specific guard reports "%s" is a view, with DETAIL Views cannot have row-level BEFORE or AFTER triggers. Inspect pg_class.relkind, event, level, and timing. This is distinct from a missing relation and from a trigger-body error; the selected autocommit connection is IDLE after the failed definition.

Diagnosis

Inspect pg_class.relkind and the trigger event, level, and timing. Confirm whether the target is a view or table; a trigger-body error is a later stage and has a different diagnostic.

Response

Use the trigger form supported by the object: an INSTEAD OF row trigger on the view. If the business rule needs BEFORE/AFTER row timing, put it on a base table and keep view write semantics explicit. The selected run checks trigger definition success, not actual view DML behavior. In an explicit transaction, the rejected trigger definition leaves INERROR; roll back or return to a suitable savepoint before retrying. The selected autocommit path returns to IDLE.

Observed diagnostics

The source group is explicit ERROR with primary "%s" is a view and detail Views cannot have row-level BEFORE or AFTER triggers.

Representative case

The runner creates a view and function, attempts the forbidden trigger, then creates an INSTEAD OF trigger and verifies its catalog row.

CREATE VIEW syntax_schema.trigger_view AS SELECT 1 AS value;
CREATE FUNCTION syntax_schema.trigger_function() RETURNS trigger LANGUAGE plpgsql AS 'BEGIN RETURN NEW; END';
CREATE TRIGGER row_trigger BEFORE INSERT ON syntax_schema.trigger_view FOR EACH ROW EXECUTE PROCEDURE syntax_schema.trigger_function();
CREATE TRIGGER instead_trigger INSTEAD OF INSERT ON syntax_schema.trigger_view FOR EACH ROW EXECUTE PROCEDURE syntax_schema.trigger_function();
SELECT count(*) FROM pg_trigger t JOIN pg_class c ON c.oid = t.tgrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'syntax_schema_name' AND c.relname = 'trigger_view' AND t.tgname = 'instead_trigger' AND NOT t.tgisinternal;

The selected 18.6 and 10.21 runs passed SQLSTATE, severity, state/recovery, repair, cleanup, and isolated-target stop assertions. See case JSON and authored evidence; private manifest and registry hashes are recorded there.

Versions

The locked catalogue contains this condition from the 7.4 presence bound through the listed snapshots. The selected natural case passed on PostgreSQL 18.6 and 10.21; that bounded result does not infer every intermediate release or every source branch.

Sources

  • src.errcodes.REL_18_6 — fixed definition at 724edf9bde9d356724ad384a2e196edc3c9f80f7; SHA-256 6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba (source).
  • src.view-row-trigger.18.6src/backend/commands/trigger.c lines 274–278 at 724edf9bde9d356724ad384a2e196edc3c9f80f7; blob SHA-256 0a539af85b0de1a04779f92202e7bfc77d85ae6da1747ea32527c67f39084fbd (source).
  • src.view-row-trigger.10.23src/backend/commands/trigger.c lines 208–212 at 02991e79f8f58bc208f05dcc8af0c62dbe0a6ea4; blob SHA-256 dac7cdcbe2df1a1bbc77daa23e808b0c81ba8891c9895f10e8b270a15316e225 (source).
  • src.calls.REL_18_6 / src.calls.REL_10_23 — fixed call scans, SHA-256 9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf / 00d16d3eb01b71ccf1b245c8f3102f9d0ec9f36fb02777b8dd1b99fcb263040c.
  • manifest.42809 / snippet-registry.42809 — hashes are recorded in evidence/42809.json and each runtime record.