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_17_STABLE Details ------- https://git.postgresql.org/pg/commitdiff/775e03191fa663b523363e6fa1eb7c3f1d565350 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(-)
