pgsql: SQL/JSON: Fix ON EMPTY/ERROR state leakage on NULL input

From: Amit Langote <amitlan(at)postgresql(dot)org>
To: pgsql-committers(at)lists(dot)postgresql(dot)org
Subject: pgsql: SQL/JSON: Fix ON EMPTY/ERROR state leakage on NULL input
Date: 2026-11-04 23:57:09
Message-ID: E1xOkqr-00000000EYo-1XrM@gemulon.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers

SQL/JSON: Fix ON EMPTY/ERROR state leakage on NULL input

ExecInitJsonExpr() emitted JUMP_IF_NULL steps to skip the
EEOP_JSONEXPR_PATH step when either the context item or the path
expression was NULL, landing on a CONST step that returned NULL.
However, ExecEvalJsonExprPath(), which implements EEOP_JSONEXPR_PATH,
was also the only place where JsonExprState's empty and error flags
got reset for a new row. Skipping it left the flags as the previous
row had set them, and since execution then fell through the
ON EMPTY / ON ERROR steps that check those flags, a NULL-input row
returned the previous row's ON EMPTY / ON ERROR expression instead of
NULL, making the result depend on the order of the input rows.

This could only happen when ExecInitJsonExpr() had emitted the
ON EMPTY / ON ERROR steps for the NULL-input row to fall through,
which it does unless the corresponding expression is a NULL constant
and the RETURNING type is not a domain. So JSON_VALUE and JSON_QUERY
with their default NULL ON EMPTY / NULL ON ERROR behaviors were not
affected, but JSON_EXISTS, whose default is FALSE ON ERROR, was.

Fix by pointing those JUMP_IF_NULL steps at EEOP_JSONEXPR_PATH itself
and dropping the CONST NULL step. ExecEvalJsonExprPath() now returns
NULL for NULL input after resetting the flags, skipping jsonpath
evaluation and the ON EMPTY / ON ERROR steps as before, but still
jumping to the coercion steps when RETURNING a domain type so that its
constraints are checked.

Oversight in commit 6185c9737cf, so back-patch to 17.

Bug: #19621
Reported-by: Suyang Zhong <syzhong16(at)gmail(dot)com>
Author: jian he <jian(dot)universality(at)gmail(dot)com>
Author: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
Reviewed-by: Srinath Reddy Sadipiralla <srinath2133(at)gmail(dot)com>
Tested-by: Manu <manuelreyesbravo(at)gmail(dot)com>
Discussion: https://postgr.es/m/19621-0a480d2dc74e6bd5@postgresql.org
Backpatch-through: 17

Branch
------
REL_18_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/52033b8871b8ff3c5fe34ffbdef1db38f46586b8

Modified Files
--------------
src/backend/executor/execExpr.c | 24 ++++----
src/backend/executor/execExprInterp.c | 34 +++++++++--
src/test/regress/expected/sqljson_queryfuncs.out | 73 ++++++++++++++++++++++++
src/test/regress/sql/sqljson_queryfuncs.sql | 29 ++++++++++
4 files changed, 141 insertions(+), 19 deletions(-)

Browse pgsql-committers by date

  From Date Subject
Next Message Amit Langote 2026-11-04 23:57:22 pgsql: SQL/JSON: Fix ON EMPTY/ERROR state leakage on NULL input
Previous Message Amit Langote 2026-11-04 23:56:55 pgsql: SQL/JSON: Fix ON EMPTY/ERROR state leakage on NULL input