1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Add a non-strict version of jsonb_set

jsonb_set_lax() is the same as jsonb_set, except that it takes and extra
argument that specifies what to do if the value argument is NULL. The
default is 'use_json_null'. Other possibilities are 'raise_exception',
'return_target' and 'delete_key', all these behaviours having been
suggested as reasonable by various users.

Discussion: https://postgr.es/m/375873e2-c957-3a8d-64f9-26c43c2b16e7@2ndQuadrant.com

Reviewed by: Pavel Stehule
This commit is contained in:
Andrew Dunstan
2020-01-17 11:41:35 +10:30
parent f7cd5896a6
commit a83586b554
6 changed files with 176 additions and 0 deletions

View File

@ -4395,6 +4395,70 @@ jsonb_set(PG_FUNCTION_ARGS)
}
/*
* SQL function jsonb_set_lax(jsonb, text[], jsonb, boolean, text)
*/
Datum
jsonb_set_lax(PG_FUNCTION_ARGS)
{
/* Jsonb *in = PG_GETARG_JSONB_P(0); */
/* ArrayType *path = PG_GETARG_ARRAYTYPE_P(1); */
/* Jsonb *newval = PG_GETARG_JSONB_P(2); */
/* bool create = PG_GETARG_BOOL(3); */
text *handle_null;
char *handle_val;
if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(3))
PG_RETURN_NULL();
/* could happen if they pass in an explicit NULL */
if (PG_ARGISNULL(4))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("need delete_key, return_target, use_json_null, or raise_exception")));
/* if the new value isn't an SQL NULL just call jsonb_set */
if (! PG_ARGISNULL(2))
return jsonb_set(fcinfo);
handle_null = PG_GETARG_TEXT_P(4);
handle_val = text_to_cstring(handle_null);
if (strcmp(handle_val,"raise_exception") == 0)
{
ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("NULL is not allowed"),
errdetail("exception raised due to \"null_value_treatment => 'raise_exception'\""),
errhint("to avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not used")));
}
else if (strcmp(handle_val, "use_json_null") == 0)
{
Datum newval;
newval = DirectFunctionCall1(jsonb_in, CStringGetDatum("null"));
fcinfo->args[2].value = newval;
fcinfo->args[2].isnull = false;
return jsonb_set(fcinfo);
}
else if (strcmp(handle_val, "delete_key") == 0)
{
return jsonb_delete_path(fcinfo);
}
else if (strcmp(handle_val, "return_target") == 0)
{
Jsonb *in = PG_GETARG_JSONB_P(0);
PG_RETURN_JSONB_P(in);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("need delete_key, return_target, use_json_null, or raise_exception")));
}
}
/*
* SQL function jsonb_delete_path(jsonb, text[])
*/