errposition

First seen: 2026-05-08 04:24:02+00:00 · Messages: 2 · Participants: 2

Latest Update

2026-05-09 · opus 4.7

Thread Overview: Documentation vs. API Layering for errposition

This is a short but instructive thread about the distinction between a low-level ereport auxiliary routine and its context-specific wrapper in PostgreSQL's error reporting infrastructure. The discussion clarifies a subtle but important point of API design that almost led to an incorrect documentation "fix."

The Core Issue

John Naylor observed an apparent documentation inconsistency in doc/src/sgml/sources.sgml. The section describing auxiliary routines available for use with ereport() documents errposition(int cursorpos) as specifying a textual location within a query string for lexer/parser errors. However, when grepping the tree, one finds that actual call sites in the parser use parser_errposition() rather than errposition() directly. Naylor's natural inference was that the documentation named the wrong function and proposed to change the docs to reference parser_errposition.

Why the Documentation Is Actually Correct

Tom Lane's response clarifies the architectural layering that makes the current documentation correct:

  1. errposition(int cursorpos) is the primitive auxiliary routine defined in elog.c. Like errmsg(), errdetail(), errhint(), errcode(), etc., it is a function that sets a field on the currently-being-constructed ErrorData struct inside an ereport() expression. Specifically, it sets the cursor position (character offset into the query string) that will be reported to the client via the P (Position) field of the ErrorResponse protocol message.

  2. parser_errposition(ParseState *pstate, int location) is a wrapper living in src/backend/parser/parse_node.c. It takes a ParseState and a parse-tree location value (byte offset as stored in parse nodes by the grammar), translates that to a cursor position appropriate for the current query text (handling things like the p_sourcetext within the ParseState and potentially adjusting for nested query contexts), and then calls errposition() with the translated value.

The documentation in sources.sgml is a reference for the ereport auxiliary routine family — the building blocks exposed by elog.h. parser_errposition is a parser-subsystem convenience, not a member of that family, so documenting it there would be a layering violation. Tom's key phrasing — "happenstance not a reason to contort the documentation" — captures this precisely: even if every current in-tree caller happens to go through the wrapper, the primitive remains the documented API surface.

Technical Implications

This distinction matters for several reasons:

Resolution

Naylor's proposed change is withdrawn implicitly by Tom's explanation. No patch is needed; the documentation stands as written. This is a classic example of the value of asking on the list before committing a seemingly-obvious cleanup — the "happenstance" of current call sites could have masked the layered API design.

Weight of Opinions

Tom Lane is the de facto authority on elog.c/ereport() infrastructure, having authored much of it and maintained it for decades. His explanation here is definitive. John Naylor (a committer in his own right, active in parser, vacuum, and radix tree work) appropriately raised the question before acting and accepted the clarification.