aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonb.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-10-15 13:46:09 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2015-10-15 13:46:09 -0400
commit3587cbc34fe87e1bde6c202daba791b68e44cb3a (patch)
treef546d6b084272868e13f9af75f61b6b4004181f5 /src/backend/utils/adt/jsonb.c
parent08fbad0afd62690cc82990c0504529ef238ac24d (diff)
downloadpostgresql-3587cbc34fe87e1bde6c202daba791b68e44cb3a.tar.gz
postgresql-3587cbc34fe87e1bde6c202daba791b68e44cb3a.zip
Fix NULL handling in datum_to_jsonb().
The function failed to adhere to its specification that the "tcategory" argument should not be examined when the input value is NULL. This resulted in a crash in some cases. Per bug #13680 from Boyko Yordanov. In passing, re-pgindent some recent changes in jsonb.c, and fix a rather ungrammatical comment. Diagnosis and patch by Michael Paquier, cosmetic changes by me
Diffstat (limited to 'src/backend/utils/adt/jsonb.c')
-rw-r--r--src/backend/utils/adt/jsonb.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index 8b1cab488bb..aa156c432c6 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -61,11 +61,11 @@ typedef enum /* type categories for datum_to_jsonb */
typedef struct JsonbAggState
{
- JsonbInState *res;
- JsonbTypeCategory key_category;
- Oid key_output_func;
- JsonbTypeCategory val_category;
- Oid val_output_func;
+ JsonbInState *res;
+ JsonbTypeCategory key_category;
+ Oid key_output_func;
+ JsonbTypeCategory val_category;
+ Oid val_output_func;
} JsonbAggState;
static inline Datum jsonb_from_cstring(char *json, int len);
@@ -714,6 +714,7 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
check_stack_depth();
+ /* Convert val to a JsonbValue in jb (in most cases) */
if (is_null)
{
Assert(!key_scalar);
@@ -936,8 +937,10 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result,
break;
}
}
- if (tcategory >= JSONBTYPE_JSON && tcategory <= JSONBTYPE_JSONCAST &&
- !scalar_jsonb)
+
+ /* Now insert jb into result, unless we did it recursively */
+ if (!is_null && !scalar_jsonb &&
+ tcategory >= JSONBTYPE_JSON && tcategory <= JSONBTYPE_JSONCAST)
{
/* work has been done recursively */
return;
@@ -1607,8 +1610,7 @@ jsonb_agg_transfn(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0))
{
-
- Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
+ Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
if (arg_type == InvalidOid)
ereport(ERROR,
@@ -1762,7 +1764,7 @@ jsonb_object_agg_transfn(PG_FUNCTION_ARGS)
if (PG_ARGISNULL(0))
{
- Oid arg_type;
+ Oid arg_type;
oldcontext = MemoryContextSwitchTo(aggcontext);
state = palloc(sizeof(JsonbAggState));
@@ -1950,8 +1952,9 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
/*
* We need to do a shallow clone of the argument's res field in case the
* final function is called more than once, so we avoid changing the
- * it. A shallow clone is sufficient as we aren't going to change any of
- * the values, just add the final object end marker.
+ * aggregate state value. A shallow clone is sufficient as we aren't
+ * going to change any of the values, just add the final object end
+ * marker.
*/
result.parseState = clone_parse_state(arg->res->parseState);