mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Allow json{b}_strip_nulls to remove null array elements
An additional paramater ("strip_in_arrays") is added to these functions.
It defaults to false. If true, then null array elements are removed as
well as null valued object fields. JSON that just consists of a single
null is not affected.
Author: Florents Tselai <florents.tselai@gmail.com>
Discussion: https://postgr.es/m/4BCECCD5-4F40-4313-9E98-9E16BEB0B01D@gmail.com
This commit is contained in:
@@ -286,6 +286,7 @@ typedef struct StripnullState
|
||||
JsonLexContext *lex;
|
||||
StringInfo strval;
|
||||
bool skip_next_null;
|
||||
bool strip_in_arrays;
|
||||
} StripnullState;
|
||||
|
||||
/* structure for generalized json/jsonb value passing */
|
||||
@@ -4460,8 +4461,19 @@ sn_array_element_start(void *state, bool isnull)
|
||||
{
|
||||
StripnullState *_state = (StripnullState *) state;
|
||||
|
||||
if (_state->strval->data[_state->strval->len - 1] != '[')
|
||||
/* If strip_in_arrays is enabled and this is a null, mark it for skipping */
|
||||
if (isnull && _state->strip_in_arrays)
|
||||
{
|
||||
_state->skip_next_null = true;
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
|
||||
/* Only add a comma if this is not the first valid element */
|
||||
if (_state->strval->len > 0 &&
|
||||
_state->strval->data[_state->strval->len - 1] != '[')
|
||||
{
|
||||
appendStringInfoCharMacro(_state->strval, ',');
|
||||
}
|
||||
|
||||
return JSON_SUCCESS;
|
||||
}
|
||||
@@ -4493,6 +4505,7 @@ Datum
|
||||
json_strip_nulls(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *json = PG_GETARG_TEXT_PP(0);
|
||||
bool strip_in_arrays = PG_NARGS() == 2 ? PG_GETARG_BOOL(1) : false;
|
||||
StripnullState *state;
|
||||
JsonLexContext lex;
|
||||
JsonSemAction *sem;
|
||||
@@ -4503,6 +4516,7 @@ json_strip_nulls(PG_FUNCTION_ARGS)
|
||||
state->lex = makeJsonLexContext(&lex, json, true);
|
||||
state->strval = makeStringInfo();
|
||||
state->skip_next_null = false;
|
||||
state->strip_in_arrays = strip_in_arrays;
|
||||
|
||||
sem->semstate = state;
|
||||
sem->object_start = sn_object_start;
|
||||
@@ -4520,12 +4534,13 @@ json_strip_nulls(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* SQL function jsonb_strip_nulls(jsonb) -> jsonb
|
||||
* SQL function jsonb_strip_nulls(jsonb, bool) -> jsonb
|
||||
*/
|
||||
Datum
|
||||
jsonb_strip_nulls(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Jsonb *jb = PG_GETARG_JSONB_P(0);
|
||||
bool strip_in_arrays = false;
|
||||
JsonbIterator *it;
|
||||
JsonbParseState *parseState = NULL;
|
||||
JsonbValue *res = NULL;
|
||||
@@ -4534,6 +4549,9 @@ jsonb_strip_nulls(PG_FUNCTION_ARGS)
|
||||
JsonbIteratorToken type;
|
||||
bool last_was_key = false;
|
||||
|
||||
if (PG_NARGS() == 2)
|
||||
strip_in_arrays = PG_GETARG_BOOL(1);
|
||||
|
||||
if (JB_ROOT_IS_SCALAR(jb))
|
||||
PG_RETURN_POINTER(jb);
|
||||
|
||||
@@ -4564,6 +4582,11 @@ jsonb_strip_nulls(PG_FUNCTION_ARGS)
|
||||
(void) pushJsonbValue(&parseState, WJB_KEY, &k);
|
||||
}
|
||||
|
||||
/* if strip_in_arrays is set, also skip null array elements */
|
||||
if (strip_in_arrays)
|
||||
if (type == WJB_ELEM && v.type == jbvNull)
|
||||
continue;
|
||||
|
||||
if (type == WJB_VALUE || type == WJB_ELEM)
|
||||
res = pushJsonbValue(&parseState, type, &v);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user