aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/jsonfuncs.c')
-rw-r--r--src/backend/utils/adt/jsonfuncs.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index 71179f65518..f303860fdbb 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -2075,8 +2075,10 @@ populate_record_worker(FunctionCallInfo fcinfo, bool have_record_arg)
* with domain nulls.
*/
if (hash_get_num_entries(json_hash) == 0 && rec)
+ {
+ hash_destroy(json_hash);
PG_RETURN_POINTER(rec);
-
+ }
}
else
{
@@ -2250,6 +2252,9 @@ populate_record_worker(FunctionCallInfo fcinfo, bool have_record_arg)
ReleaseTupleDesc(tupdesc);
+ if (json_hash)
+ hash_destroy(json_hash);
+
PG_RETURN_DATUM(HeapTupleGetDatum(rettuple));
}
@@ -2735,16 +2740,23 @@ populate_recordset_object_start(void *state)
int lex_level = _state->lex->lex_level;
HASHCTL ctl;
+ /* Reject object at top level: we must have an array at level 0 */
if (lex_level == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot call json_populate_recordset on an object")));
- else if (lex_level > 1 && !_state->use_json_as_text)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("cannot call json_populate_recordset with nested objects")));
- /* set up a new hash for this entry */
+ /* Nested objects, if allowed, require no special processing */
+ if (lex_level > 1)
+ {
+ if (!_state->use_json_as_text)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("cannot call json_populate_recordset with nested objects")));
+ return;
+ }
+
+ /* Object at level 1: set up a new hash table for this object */
memset(&ctl, 0, sizeof(ctl));
ctl.keysize = NAMEDATALEN;
ctl.entrysize = sizeof(JsonHashEntry);
@@ -2771,9 +2783,11 @@ populate_recordset_object_end(void *state)
HeapTupleHeader rec = _state->rec;
HeapTuple rettuple;
+ /* Nested objects require no special processing */
if (_state->lex->lex_level > 1)
return;
+ /* Otherwise, construct and return a tuple based on this level-1 object */
values = (Datum *) palloc(ncolumns * sizeof(Datum));
nulls = (bool *) palloc(ncolumns * sizeof(bool));
@@ -2865,7 +2879,9 @@ populate_recordset_object_end(void *state)
tuplestore_puttuple(_state->tuple_store, rettuple);
+ /* Done with hash for this object */
hash_destroy(json_hash);
+ _state->json_hash = NULL;
}
static void