Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f2cb085

Browse files
author
Nikita Glukhov
committed
Add FORMAT jsonb
1 parent a1d2662 commit f2cb085

File tree

10 files changed

+654
-214
lines changed

10 files changed

+654
-214
lines changed

src/backend/parser/gram.y

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
750750
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
751751

752752
JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG
753-
JSON_QUERY JSON_TABLE JSON_VALUE
753+
JSON_QUERY JSON_TABLE JSON_VALUE JSONB
754754

755755
KEY KEYS KEEP
756756

@@ -13477,9 +13477,6 @@ a_expr: c_expr { $$ = $1; }
1347713477
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1347813478
$$ = makeJsonIsPredicate($1, format, $4, $5);
1347913479
}
13480-
/*
13481-
* Required by standard, but it would conflict with expressions
13482-
* like: 'str' || format(...)
1348313480
| a_expr
1348413481
FORMAT json_representation
1348513482
IS JSON
@@ -13489,7 +13486,6 @@ a_expr: c_expr { $$ = $1; }
1348913486
$3.location = @2;
1349013487
$$ = makeJsonIsPredicate($1, $3, $6, $7);
1349113488
}
13492-
*/
1349313489
| a_expr
1349413490
IS NOT JSON
1349513491
json_predicate_type_constraint_opt
@@ -13498,9 +13494,6 @@ a_expr: c_expr { $$ = $1; }
1349813494
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1349913495
$$ = makeNotExpr(makeJsonIsPredicate($1, format, $5, $6), @1);
1350013496
}
13501-
/*
13502-
* Required by standard, but it would conflict with expressions
13503-
* like: 'str' || format(...)
1350413497
| a_expr
1350513498
FORMAT json_representation
1350613499
IS NOT JSON
@@ -13510,7 +13503,6 @@ a_expr: c_expr { $$ = $1; }
1351013503
$3.location = @2;
1351113504
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8), @1);
1351213505
}
13513-
*/
1351413506
| DEFAULT
1351513507
{
1351613508
/*
@@ -14935,6 +14927,12 @@ json_representation:
1493514927
$$.encoding = $2;
1493614928
$$.location = @1;
1493714929
}
14930+
| JSONB
14931+
{
14932+
$$.type = JS_FORMAT_JSONB;
14933+
$$.encoding = JS_ENC_DEFAULT;
14934+
$$.location = @1;
14935+
}
1493814936
/* | implementation_defined_JSON_representation_option (BSON, AVRO etc) */
1493914937
;
1494014938

@@ -16062,6 +16060,7 @@ unreserved_keyword:
1606216060
| INVOKER
1606316061
| ISOLATION
1606416062
| JSON
16063+
| JSONB
1606516064
| KEEP
1606616065
| KEY
1606716066
| KEYS

src/backend/parser/parse_expr.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3972,6 +3972,15 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr, JsonReturning *returning,
39723972
return (Node *) fexpr;
39733973
}
39743974

3975+
if (returning->format.type == JS_FORMAT_JSONB &&
3976+
returning->typid == BYTEAOID &&
3977+
exprtype == JSONOID)
3978+
{
3979+
/* cast json to jsonb before encoding into bytea */
3980+
expr = coerce_to_specific_type(pstate, expr, JSONBOID, "JSON_FUNCTION");
3981+
exprtype = JSONBOID;
3982+
}
3983+
39753984
/* try to coerce expression to the output type */
39763985
res = coerce_to_target_type(pstate, expr, exprtype,
39773986
returning->typid, returning->typmod,
@@ -4386,9 +4395,12 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
43864395
/* prepare input document */
43874396
if (exprtype == BYTEAOID)
43884397
{
4389-
expr = makeJsonByteaToTextConversion(expr, &pred->format,
4390-
exprLocation(expr));
4391-
exprtype = TEXTOID;
4398+
if (pred->format.type != JS_FORMAT_JSONB)
4399+
{
4400+
expr = makeJsonByteaToTextConversion(expr, &pred->format,
4401+
exprLocation(expr));
4402+
exprtype = TEXTOID;
4403+
}
43924404
}
43934405
else
43944406
{
@@ -4406,6 +4418,12 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
44064418
exprtype = TEXTOID;
44074419
}
44084420

4421+
if (pred->format.type == JS_FORMAT_JSONB)
4422+
ereport(ERROR,
4423+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4424+
parser_errposition(pstate, pred->format.location),
4425+
errmsg("cannot use FORMAT JSONB for string input types")));
4426+
44094427
if (pred->format.encoding != JS_ENC_DEFAULT)
44104428
ereport(ERROR,
44114429
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4426,7 +4444,7 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
44264444

44274445
fexpr->location = pred->location;
44284446
}
4429-
else if (exprtype == JSONBOID)
4447+
else if (exprtype == JSONBOID || exprtype == BYTEAOID)
44304448
{
44314449
/* XXX the following expressions also can be used here:
44324450
* jsonb_type(jsonb) = 'type' (for object and array checks)

src/backend/utils/adt/jsonb.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,17 +2138,22 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
21382138

21392139

21402140
/*
2141-
* jsonb_is_valid -- check jsonb value type
2141+
* jsonb_is_valid -- check bytea jsonb validity and its value type
21422142
*/
21432143
Datum
21442144
jsonb_is_valid(PG_FUNCTION_ARGS)
21452145
{
2146-
Jsonb *jb = PG_GETARG_JSONB_P(0);
2146+
bytea *ba = PG_GETARG_BYTEA_P(0);
21472147
text *type = PG_GETARG_TEXT_P(1);
2148+
Jsonb *jb = (Jsonb *) ba;
21482149

21492150
if (PG_ARGISNULL(0))
21502151
PG_RETURN_NULL();
21512152

2153+
if (get_fn_expr_argtype(fcinfo->flinfo, 0) != JSONBOID &&
2154+
!JsonbValidate(VARDATA(jb), VARSIZE(jb) - VARHDRSZ))
2155+
PG_RETURN_BOOL(false);
2156+
21522157
if (!PG_ARGISNULL(1) &&
21532158
strncmp("any", VARDATA(type), VARSIZE_ANY_EXHDR(type)))
21542159
{

src/include/parser/kwlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD)
234234
PG_KEYWORD("json_query", JSON_QUERY, COL_NAME_KEYWORD)
235235
PG_KEYWORD("json_table", JSON_TABLE, COL_NAME_KEYWORD)
236236
PG_KEYWORD("json_value", JSON_VALUE, COL_NAME_KEYWORD)
237+
PG_KEYWORD("jsonb", JSONB, UNRESERVED_KEYWORD)
237238
PG_KEYWORD("keep", KEEP, UNRESERVED_KEYWORD)
238239
PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD)
239240
PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD)

src/test/regress/expected/json_sqljson.out

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,12 @@ SELECT JSON_QUERY('"aaa"' FORMAT JSON, '$' RETURNING bytea FORMAT JSON OMIT QUOT
687687
\x616161
688688
(1 row)
689689

690+
SELECT JSON_QUERY('"aaa"' FORMAT JSON, '$' RETURNING bytea FORMAT JSONB OMIT QUOTES ERROR ON ERROR);
691+
json_query
692+
------------
693+
\x616161
694+
(1 row)
695+
690696
-- QUOTES behavior should not be specified when WITH WRAPPER used:
691697
-- Should fail
692698
SELECT JSON_QUERY(json '[1]', '$' WITH WRAPPER OMIT QUOTES);
@@ -825,6 +831,12 @@ SELECT JSON_QUERY(json '[1,2]', '$' RETURNING text FORMAT JSON);
825831
[1,2]
826832
(1 row)
827833

834+
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING text FORMAT JSONB);
835+
json_query
836+
------------
837+
[1,2]
838+
(1 row)
839+
828840
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea);
829841
json_query
830842
--------------
@@ -837,6 +849,12 @@ SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea FORMAT JSON);
837849
\x5b312c325d
838850
(1 row)
839851

852+
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea FORMAT JSONB);
853+
json_query
854+
------------------------------------------------------------
855+
\x02000040080000900800001020000000008001002000000000800200
856+
(1 row)
857+
840858
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR);
841859
json_query
842860
------------
@@ -849,6 +867,12 @@ SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT
849867
\x7b7d
850868
(1 row)
851869

870+
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea FORMAT JSONB EMPTY OBJECT ON ERROR);
871+
json_query
872+
------------
873+
\x00000020
874+
(1 row)
875+
852876
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING json EMPTY OBJECT ON ERROR);
853877
json_query
854878
------------
@@ -1113,7 +1137,7 @@ FROM
11131137
jst text FORMAT JSON PATH '$',
11141138
jsc char(4) FORMAT JSON PATH '$',
11151139
jsv varchar(4) FORMAT JSON PATH '$',
1116-
jsb jsonb FORMAT JSON PATH '$',
1140+
jsb jsonb FORMAT JSONB PATH '$',
11171141
aaa int, -- implicit path '$."aaa"',
11181142
aaa1 int PATH '$.aaa'
11191143
)
@@ -1155,7 +1179,7 @@ SELECT * FROM
11551179
jst text FORMAT JSON PATH '$',
11561180
jsc char(4) FORMAT JSON PATH '$',
11571181
jsv varchar(4) FORMAT JSON PATH '$',
1158-
jsb jsonb FORMAT JSON PATH '$',
1182+
jsb jsonb FORMAT JSONB PATH '$',
11591183
aaa int, -- implicit path '$."aaa"',
11601184
aaa1 int PATH '$.aaa',
11611185
NESTED PATH '$[1]' AS p1 COLUMNS (

0 commit comments

Comments
 (0)