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:
-
errposition(int cursorpos)is the primitive auxiliary routine defined inelog.c. Likeerrmsg(),errdetail(),errhint(),errcode(), etc., it is a function that sets a field on the currently-being-constructedErrorDatastruct inside anereport()expression. Specifically, it sets the cursor position (character offset into the query string) that will be reported to the client via theP(Position) field of the ErrorResponse protocol message. -
parser_errposition(ParseState *pstate, int location)is a wrapper living insrc/backend/parser/parse_node.c. It takes aParseStateand a parse-treelocationvalue (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 thep_sourcetextwithin the ParseState and potentially adjusting for nested query contexts), and then callserrposition()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:
- Extension authors writing custom parsers, PL handlers, or other code that produces parse-time errors outside
src/backend/parser/may legitimately need to callerrposition()directly without aParseState. The documentation must reflect the primitive they should use. - The
ErrorDataabstraction inelog.cis intentionally unaware of parser concepts. Keepingerrpositionas the documented primitive preserves the clean separation between error-reporting machinery and the subsystems that consume it. - Internal errors with cursor positions (e.g., errors detected deep in query rewriting or planning that want to point back into the source text) might call
errposition()directly after computing an offset through other means. The doc wording ("Currently it is only useful for errors detected in the lexical and syntactic analysis phases") describes typical usage, not a hard restriction.
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.