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

Commit 2cac48c

Browse files
author
Nikita Glukhov
committed
Add FORMAT jsonb
1 parent b6e5cc2 commit 2cac48c

File tree

10 files changed

+653
-214
lines changed

10 files changed

+653
-214
lines changed

src/backend/parser/gram.y

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

744744
JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG
745-
JSON_QUERY JSON_TABLE JSON_VALUE
745+
JSON_QUERY JSON_TABLE JSON_VALUE JSONB
746746

747747
KEY KEYS KEEP
748748

@@ -13136,9 +13136,6 @@ a_expr: c_expr { $$ = $1; }
1313613136
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1313713137
$$ = makeJsonIsPredicate($1, format, $4, $5);
1313813138
}
13139-
/*
13140-
* Required by standard, but it would conflict with expressions
13141-
* like: 'str' || format(...)
1314213139
| a_expr
1314313140
FORMAT json_representation
1314413141
IS JSON
@@ -13148,7 +13145,6 @@ a_expr: c_expr { $$ = $1; }
1314813145
$3.location = @2;
1314913146
$$ = makeJsonIsPredicate($1, $3, $6, $7);
1315013147
}
13151-
*/
1315213148
| a_expr
1315313149
IS NOT JSON
1315413150
json_predicate_type_constraint_opt
@@ -13157,9 +13153,6 @@ a_expr: c_expr { $$ = $1; }
1315713153
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1315813154
$$ = makeNotExpr(makeJsonIsPredicate($1, format, $5, $6), @1);
1315913155
}
13160-
/*
13161-
* Required by standard, but it would conflict with expressions
13162-
* like: 'str' || format(...)
1316313156
| a_expr
1316413157
FORMAT json_representation
1316513158
IS NOT JSON
@@ -13169,7 +13162,6 @@ a_expr: c_expr { $$ = $1; }
1316913162
$3.location = @2;
1317013163
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8), @1);
1317113164
}
13172-
*/
1317313165
| DEFAULT
1317413166
{
1317513167
/*
@@ -14586,6 +14578,11 @@ json_representation:
1458614578
$$.type = JS_FORMAT_JSON;
1458714579
$$.encoding = $2;
1458814580
}
14581+
| JSONB
14582+
{
14583+
$$.type = JS_FORMAT_JSONB;
14584+
$$.encoding = JS_ENC_DEFAULT;
14585+
}
1458914586
/* | implementation_defined_JSON_representation_option (BSON, AVRO etc) */
1459014587
;
1459114588

@@ -15706,6 +15703,7 @@ unreserved_keyword:
1570615703
| INVOKER
1570715704
| ISOLATION
1570815705
| JSON
15706+
| JSONB
1570915707
| KEEP
1571015708
| KEY
1571115709
| KEYS

src/backend/parser/parse_expr.c

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

3868+
if (returning->format.type == JS_FORMAT_JSONB &&
3869+
returning->typid == BYTEAOID &&
3870+
exprtype == JSONOID)
3871+
{
3872+
/* cast json to jsonb before encoding into bytea */
3873+
expr = coerce_to_specific_type(pstate, expr, JSONBOID, "JSON_FUNCTION");
3874+
exprtype = JSONBOID;
3875+
}
3876+
38683877
/* try to coerce expression to the output type */
38693878
res = coerce_to_target_type(pstate, expr, exprtype,
38703879
returning->typid, returning->typmod,
@@ -4273,9 +4282,12 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
42734282
/* prepare input document */
42744283
if (exprtype == BYTEAOID)
42754284
{
4276-
expr = makeJsonByteaToTextConversion(expr, &pred->format,
4277-
exprLocation(expr));
4278-
exprtype = TEXTOID;
4285+
if (pred->format.type != JS_FORMAT_JSONB)
4286+
{
4287+
expr = makeJsonByteaToTextConversion(expr, &pred->format,
4288+
exprLocation(expr));
4289+
exprtype = TEXTOID;
4290+
}
42794291
}
42804292
else
42814293
{
@@ -4293,6 +4305,12 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
42934305
exprtype = TEXTOID;
42944306
}
42954307

4308+
if (pred->format.type == JS_FORMAT_JSONB)
4309+
ereport(ERROR,
4310+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4311+
parser_errposition(pstate, pred->format.location),
4312+
errmsg("cannot use FORMAT JSONB for string input types")));
4313+
42964314
if (pred->format.encoding != JS_ENC_DEFAULT)
42974315
ereport(ERROR,
42984316
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -4313,7 +4331,7 @@ transformJsonIsPredicate(ParseState *pstate, JsonIsPredicate *pred)
43134331

43144332
fexpr->location = pred->location;
43154333
}
4316-
else if (exprtype == JSONBOID)
4334+
else if (exprtype == JSONBOID || exprtype == BYTEAOID)
43174335
{
43184336
/* XXX the following expressions also can be used here:
43194337
* 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
@@ -2166,17 +2166,22 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
21662166
}
21672167

21682168
/*
2169-
* jsonb_is_valid -- check jsonb value type
2169+
* jsonb_is_valid -- check bytea jsonb validity and its value type
21702170
*/
21712171
Datum
21722172
jsonb_is_valid(PG_FUNCTION_ARGS)
21732173
{
2174-
Jsonb *jb = PG_GETARG_JSONB_P(0);
2174+
bytea *ba = PG_GETARG_BYTEA_P(0);
21752175
text *type = PG_GETARG_TEXT_P(1);
2176+
Jsonb *jb = (Jsonb *) ba;
21762177

21772178
if (PG_ARGISNULL(0))
21782179
PG_RETURN_NULL();
21792180

2181+
if (get_fn_expr_argtype(fcinfo->flinfo, 0) != JSONBOID &&
2182+
!JsonbValidate(VARDATA(jb), VARSIZE(jb) - VARHDRSZ))
2183+
PG_RETURN_BOOL(false);
2184+
21802185
if (!PG_ARGISNULL(1) &&
21812186
strncmp("any", VARDATA(type), VARSIZE_ANY_EXHDR(type)))
21822187
{

src/include/parser/kwlist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD)
232232
PG_KEYWORD("json_query", JSON_QUERY, COL_NAME_KEYWORD)
233233
PG_KEYWORD("json_table", JSON_TABLE, COL_NAME_KEYWORD)
234234
PG_KEYWORD("json_value", JSON_VALUE, COL_NAME_KEYWORD)
235+
PG_KEYWORD("jsonb", JSONB, UNRESERVED_KEYWORD)
235236
PG_KEYWORD("keep", KEEP, UNRESERVED_KEYWORD)
236237
PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD)
237238
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
@@ -660,6 +660,12 @@ SELECT JSON_QUERY('"aaa"' FORMAT JSON, '$' RETURNING bytea FORMAT JSON OMIT QUOT
660660
\x616161
661661
(1 row)
662662

663+
SELECT JSON_QUERY('"aaa"' FORMAT JSON, '$' RETURNING bytea FORMAT JSONB OMIT QUOTES ERROR ON ERROR);
664+
?column?
665+
----------
666+
\x616161
667+
(1 row)
668+
663669
-- QUOTES behavior should not be specified when WITH WRAPPER used:
664670
-- Should fail
665671
SELECT JSON_QUERY(json '[1]', '$' WITH WRAPPER OMIT QUOTES);
@@ -797,6 +803,12 @@ SELECT JSON_QUERY(json '[1,2]', '$' RETURNING text FORMAT JSON);
797803
[1,2]
798804
(1 row)
799805

806+
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING text FORMAT JSONB);
807+
?column?
808+
----------
809+
[1,2]
810+
(1 row)
811+
800812
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea);
801813
?column?
802814
--------------
@@ -809,6 +821,12 @@ SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea FORMAT JSON);
809821
\x5b312c325d
810822
(1 row)
811823

824+
SELECT JSON_QUERY(json '[1,2]', '$' RETURNING bytea FORMAT JSONB);
825+
?column?
826+
------------------------------------------------------------
827+
\x02000040080000900800001020000000008001002000000000800200
828+
(1 row)
829+
812830
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea EMPTY OBJECT ON ERROR);
813831
?column?
814832
----------
@@ -821,6 +839,12 @@ SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea FORMAT JSON EMPTY OBJECT
821839
\x7b7d
822840
(1 row)
823841

842+
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING bytea FORMAT JSONB EMPTY OBJECT ON ERROR);
843+
?column?
844+
------------
845+
\x00000020
846+
(1 row)
847+
824848
SELECT JSON_QUERY(json '[1,2]', '$[*]' RETURNING json EMPTY OBJECT ON ERROR);
825849
?column?
826850
----------
@@ -1066,7 +1090,7 @@ FROM
10661090
jst text FORMAT JSON PATH '$',
10671091
jsc char(4) FORMAT JSON PATH '$',
10681092
jsv varchar(4) FORMAT JSON PATH '$',
1069-
jsb jsonb FORMAT JSON PATH '$',
1093+
jsb jsonb FORMAT JSONB PATH '$',
10701094
aaa int, -- implicit path '$."aaa"',
10711095
aaa1 int PATH '$.aaa'
10721096
)
@@ -1108,7 +1132,7 @@ SELECT * FROM
11081132
jst text FORMAT JSON PATH '$',
11091133
jsc char(4) FORMAT JSON PATH '$',
11101134
jsv varchar(4) FORMAT JSON PATH '$',
1111-
jsb jsonb FORMAT JSON PATH '$',
1135+
jsb jsonb FORMAT JSONB PATH '$',
11121136
aaa int, -- implicit path '$."aaa"',
11131137
aaa1 int PATH '$.aaa',
11141138
NESTED PATH '$[1]' AS p1 COLUMNS (

0 commit comments

Comments
 (0)