aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonpath_exec.c
diff options
context:
space:
mode:
authorAmit Langote <amitlan@postgresql.org>2024-09-12 09:36:31 +0900
committerAmit Langote <amitlan@postgresql.org>2024-09-12 09:39:56 +0900
commite6c45d85dc168fb05b5ee5596a4de5167c9fe01f (patch)
treeacf249d689ab6800d4a23939b6d3b473f821fa8d /src/backend/utils/adt/jsonpath_exec.c
parent77761ee5dddc0518235a51c533893e81e5f375b9 (diff)
downloadpostgresql-e6c45d85dc168fb05b5ee5596a4de5167c9fe01f.tar.gz
postgresql-e6c45d85dc168fb05b5ee5596a4de5167c9fe01f.zip
SQL/JSON: Fix JSON_QUERY(... WITH CONDITIONAL WRAPPER)
Currently, when WITH CONDITIONAL WRAPPER is specified, array wrappers are applied even to a single SQL/JSON item if it is a scalar JSON value, but this behavior does not comply with the standard. To fix, apply wrappers only when there are multiple SQL/JSON items in the result. Reported-by: Peter Eisentraut <peter@eisentraut.org> Author: Peter Eisentraut <peter@eisentraut.org> Author: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Andrew Dunstan <andrew@dunslane.net> Discussion: https://postgr.es/m/8022e067-818b-45d3-8fab-6e0d94d03626%40eisentraut.org Backpatch-through: 17
Diffstat (limited to 'src/backend/utils/adt/jsonpath_exec.c')
-rw-r--r--src/backend/utils/adt/jsonpath_exec.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c
index e3ee0093d4d..e569c7efb83 100644
--- a/src/backend/utils/adt/jsonpath_exec.c
+++ b/src/backend/utils/adt/jsonpath_exec.c
@@ -3947,7 +3947,24 @@ JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty,
return (Datum) 0;
}
- /* WRAP or not? */
+ /*
+ * Determine whether to wrap the result in a JSON array or not.
+ *
+ * First, count the number of SQL/JSON items in the returned
+ * JsonValueList. If the list is empty (singleton == NULL), no wrapping is
+ * necessary.
+ *
+ * If the wrapper mode is JSW_NONE or JSW_UNSPEC, wrapping is explicitly
+ * disabled. This enforces a WITHOUT WRAPPER clause, which is also the
+ * default when no WRAPPER clause is specified.
+ *
+ * If the mode is JSW_UNCONDITIONAL, wrapping is enforced regardless of
+ * the number of SQL/JSON items, enforcing a WITH WRAPPER or WITH
+ * UNCONDITIONAL WRAPPER clause.
+ *
+ * For JSW_CONDITIONAL, wrapping occurs only if there is more than one
+ * SQL/JSON item in the list, enforcing a WITH CONDITIONAL WRAPPER clause.
+ */
count = JsonValueListLength(&found);
singleton = count > 0 ? JsonValueListHead(&found) : NULL;
if (singleton == NULL)
@@ -3957,10 +3974,7 @@ JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty,
else if (wrapper == JSW_UNCONDITIONAL)
wrap = true;
else if (wrapper == JSW_CONDITIONAL)
- wrap = count > 1 ||
- IsAJsonbScalar(singleton) ||
- (singleton->type == jbvBinary &&
- JsonContainerIsScalar(singleton->val.binary.data));
+ wrap = count > 1;
else
{
elog(ERROR, "unrecognized json wrapper %d", (int) wrapper);