diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 30c889f505f..175b3d3ee69 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -4956,20 +4956,17 @@ transformJsonBehavior(ParseState *pstate, JsonExpr *jsexpr, coerce_at_runtime = true; /* - * json_populate_type() expects to be passed a jsonb value, so gin - * up a Const containing the appropriate boolean value represented - * as jsonb, discarding the original Const containing a plain - * boolean. + * json_populate_type() only takes a jsonb value, so convert a + * boolean to jsonb by calling to_jsonb() on it. That way any + * boolean-valued expression -- whether a canned TRUE/FALSE + * constant or a user-supplied DEFAULT expression -- is converted + * according to the value it actually evaluates to. */ if (exprType(expr) == BOOLOID) - { - char *val = btype == JSON_BEHAVIOR_TRUE ? "true" : "false"; - - expr = (Node *) makeConst(JSONBOID, -1, InvalidOid, -1, - DirectFunctionCall1(jsonb_in, - CStringGetDatum(val)), - false, false); - } + expr = (Node *) makeFuncExpr(F_TO_JSONB, JSONBOID, + list_make1(expr), + InvalidOid, InvalidOid, + COERCE_EXPLICIT_CALL); } else { diff --git a/src/test/regress/expected/sqljson_queryfuncs.out b/src/test/regress/expected/sqljson_queryfuncs.out index ff64dce0c59..50d9d230420 100644 --- a/src/test/regress/expected/sqljson_queryfuncs.out +++ b/src/test/regress/expected/sqljson_queryfuncs.out @@ -554,6 +554,25 @@ select json_value('{"a": 1.234}', '$.a' returning int error on error); ERROR: invalid input syntax for type integer: "1.234" select json_value('{"a": "1.234"}', '$.a' returning int error on error); ERROR: invalid input syntax for type integer: "1.234" +-- Test JSON_VALUE DEFAULT ON ERROR boolean expressions +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT false ON ERROR); + json_value +------------ + false +(1 row) + +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT true ON ERROR); + json_value +------------ + true +(1 row) + +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT (1=1) ON ERROR); + json_value +------------ + true +(1 row) + -- JSON_QUERY SELECT JSON_VALUE(NULL::jsonb, '$'); json_value diff --git a/src/test/regress/sql/sqljson_queryfuncs.sql b/src/test/regress/sql/sqljson_queryfuncs.sql index a69ef253f66..d9b6f2bcca2 100644 --- a/src/test/regress/sql/sqljson_queryfuncs.sql +++ b/src/test/regress/sql/sqljson_queryfuncs.sql @@ -149,6 +149,11 @@ SELECT JSON_VALUE(jsonb 'null', '$ts' PASSING timestamptz '2018-02-21 12:34:56 + select json_value('{"a": 1.234}', '$.a' returning int error on error); select json_value('{"a": "1.234"}', '$.a' returning int error on error); +-- Test JSON_VALUE DEFAULT ON ERROR boolean expressions +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT false ON ERROR); +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT true ON ERROR); +SELECT JSON_VALUE('{"a":"abc"}', 'strict $.b' DEFAULT (1=1) ON ERROR); + -- JSON_QUERY SELECT JSON_VALUE(NULL::jsonb, '$');