Missing jsonb_ ... functions on DOCs

First seen: 2026-05-10 16:49:51+00:00 · Messages: 1 · Participants: 1

Latest Update

2026-05-11 · opus 4.7

Overview

This is a single-message documentation report on pgsql-hackers rather than a full design discussion. Marcos points out that a set of underlying SQL-callable functions backing the jsonb operators are undocumented, and asks whether this is intentional, and if not, suggests a couple of presentational options for fixing the docs.

The Core Issue

In PostgreSQL, every operator is implemented by an underlying strict SQL function registered in pg_proc, and the operator in pg_operator is effectively a syntactic shortcut that points at that function via oprcode. For the jsonb type, the operator table in doc/src/sgml/func.sgml documents the operators (?, ?|, ?&, @>, <@, ||, -, #-) but does not document the function forms:

All of them are callable from SQL (they are plain pg_proc entries with no prosecdef/visibility restriction), yet they do not appear in the JSON functions table in the documentation.

Why This Matters

There are two reasons this matters beyond mere completeness:

  1. Operators cannot always be used where functions can. The ? operator in particular is problematic in JDBC and other drivers that treat ? as a parameter placeholder. Users who need to query JSONB key existence through such drivers routinely fall back to calling jsonb_exists(...) directly. If the function form is undocumented, users either have to read pg_proc or rely on blog posts / source code to discover it. This is a real, recurring pain point in the community.

  2. Operators cannot be passed as first-class callables. Certain constructs — e.g. using a function in a functional index expression, in CREATE AGGREGATE, or as an argument to higher-order-ish SQL — work more naturally with the function name than the operator.

So the undocumented functions are not internal plumbing; they are part of the de facto public API.

Historical Context

This is a long-standing pattern in PostgreSQL documentation: for many types (arrays, ranges, geometric types, tsvector/tsquery), only the operators are listed in the operator table, while the underlying *_cmp, *_contains, etc. functions are omitted — some are genuinely internal (BTree/GiST support functions with internal arguments), while others are perfectly usable. The JSON/JSONB area inherited this convention when jsonb was introduced in 9.4 and extended in 9.5 (which added ||, -, #-, and the jsonb_delete/jsonb_concat functions).

The omission is almost certainly not intentional policy but rather an oversight: when the operators were added, the documentation patch only described the operator syntax. Because the functions are stable names in pg_proc, they are part of the ABI regardless of whether they appear in the SGML docs.

Proposed Presentation Options

Marcos floats two concrete documentation approaches:

  1. An additional table after the operators table — a standalone "JSONB functions corresponding to operators" table. This is cleanest structurally because it mirrors how the existing JSON functions table is laid out, and it keeps operator and function listings side-by-side for discoverability.

  2. Inline comments on each operator row — adding a "Function" column or note in the existing operator table. This has the advantage of co-locating the operator with its callable name, but it widens an already-dense table and breaks the pattern used elsewhere in the docs (where operator tables list only operators).

Option (1) is more consistent with how func.sgml is organized elsewhere and is easier to cross-reference. Option (2) is more compact but intrusive.

A third option not mentioned but commonly used in PostgreSQL docs is to simply add rows to the existing functions table (functions-json) for these entries, which is probably what a committer would actually do.

Technical Implications

Assessment of the Thread

This thread is essentially a bug report against the documentation with a constructive suggestion. It contains only the initial message in the provided corpus, so there is no visible committer response, no patch, and no resolution captured here. A typical outcome for such a report would be either (a) a small doc patch from a committer like Andrew Dunstan or Tom Lane who have historically maintained the JSON documentation, or (b) the report being filed and addressed when someone touches the JSON docs next.

Key Design Point

The only real design question is where to put these. The community convention is strongly in favor of listing them as regular rows in the JSON functions table with a short description that says "equivalent to the ? operator" (etc.), rather than creating a parallel "operator-equivalent functions" table. That keeps a single authoritative function reference and avoids users having to check two tables.