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

Commit ab1f0da

Browse files
author
Nikita Glukhov
committed
Add FORMAT jsonb
1 parent 8ad78f6 commit ab1f0da

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
@@ -739,7 +739,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
739739
INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
740740

741741
JOIN JSON JSON_ARRAY JSON_ARRAYAGG JSON_EXISTS JSON_OBJECT JSON_OBJECTAGG
742-
JSON_QUERY JSON_TABLE JSON_VALUE
742+
JSON_QUERY JSON_TABLE JSON_VALUE JSONB
743743

744744
KEY KEYS KEEP
745745

@@ -13052,9 +13052,6 @@ a_expr: c_expr { $$ = $1; }
1305213052
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1305313053
$$ = makeJsonIsPredicate($1, format, $4, $5);
1305413054
}
13055-
/*
13056-
* Required by standard, but it would conflict with expressions
13057-
* like: 'str' || format(...)
1305813055
| a_expr
1305913056
FORMAT json_representation
1306013057
IS JSON
@@ -13064,7 +13061,6 @@ a_expr: c_expr { $$ = $1; }
1306413061
$3.location = @2;
1306513062
$$ = makeJsonIsPredicate($1, $3, $6, $7);
1306613063
}
13067-
*/
1306813064
| a_expr
1306913065
IS NOT JSON
1307013066
json_predicate_type_constraint_opt
@@ -13073,9 +13069,6 @@ a_expr: c_expr { $$ = $1; }
1307313069
JsonFormat format = { JS_FORMAT_DEFAULT, JS_ENC_DEFAULT, -1 };
1307413070
$$ = makeNotExpr(makeJsonIsPredicate($1, format, $5, $6), @1);
1307513071
}
13076-
/*
13077-
* Required by standard, but it would conflict with expressions
13078-
* like: 'str' || format(...)
1307913072
| a_expr
1308013073
FORMAT json_representation
1308113074
IS NOT JSON
@@ -13085,7 +13078,6 @@ a_expr: c_expr { $$ = $1; }
1308513078
$3.location = @2;
1308613079
$$ = makeNotExpr(makeJsonIsPredicate($1, $3, $7, $8), @1);
1308713080
}
13088-
*/
1308913081
| DEFAULT
1309013082
{
1309113083
/*
@@ -14502,6 +14494,11 @@ json_representation:
1450214494
$$.type = JS_FORMAT_JSON;
1450314495
$$.encoding = $2;
1450414496
}
14497+
| JSONB
14498+
{
14499+
$$.type = JS_FORMAT_JSONB;
14500+
$$.encoding = JS_ENC_DEFAULT;
14501+
}
1450514502
/* | implementation_defined_JSON_representation_option (BSON, AVRO etc) */
1450614503
;
1450714504

@@ -15622,6 +15619,7 @@ unreserved_keyword:
1562215619
| INVOKER
1562315620
| ISOLATION
1562415621
| JSON
15622+
| JSONB
1562515623
| KEEP
1562615624
| KEY
1562715625
| 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)