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 <[email protected]>
Author: jian he <[email protected]>
Author: Andrey Rachitskiy <[email protected]>
Reviewed-by: Srinath Reddy Sadipiralla <[email protected]>
Tested-by: Manu <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Backpatch-through: 17

Branch
------
REL_19_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/8e5c3d3db18dd875846970385a74b05d2d827217

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(-)

Reply via email to