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

Commit d7f4f29

Browse files
author
Nikita Glukhov
committed
Use GUC sql_json in JSON() AND JSON_SCALAR()
1 parent 92c4ca5 commit d7f4f29

File tree

7 files changed

+223
-15
lines changed

7 files changed

+223
-15
lines changed

src/backend/parser/gram.y

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14816,21 +14816,24 @@ json_func_expr:
1481614816
;
1481714817

1481814818
json_parse_expr:
14819-
JSON '(' json_value_expr json_key_uniqueness_constraint_opt ')'
14819+
JSON '(' json_value_expr json_key_uniqueness_constraint_opt
14820+
json_returning_clause_opt ')'
1482014821
{
1482114822
JsonParseExpr *n = makeNode(JsonParseExpr);
1482214823
n->expr = (JsonValueExpr *) $3;
1482314824
n->unique_keys = $4;
14825+
n->output = (JsonOutput *) $5;
1482414826
n->location = @1;
1482514827
$$ = (Node *) n;
1482614828
}
1482714829
;
1482814830

1482914831
json_scalar_expr:
14830-
JSON_SCALAR '(' a_expr ')'
14832+
JSON_SCALAR '(' a_expr json_returning_clause_opt ')'
1483114833
{
1483214834
JsonScalarExpr *n = makeNode(JsonScalarExpr);
1483314835
n->expr = (Expr *) $3;
14836+
n->output = (JsonOutput *) $4;
1483414837
n->location = @1;
1483514838
$$ = (Node *) n;
1483614839
}

src/backend/parser/parse_expr.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "utils/builtins.h"
3838
#include "utils/date.h"
3939
#include "utils/fmgroids.h"
40+
#include "utils/jsonb.h"
4041
#include "utils/lsyscache.h"
4142
#include "utils/timestamp.h"
4243
#include "utils/xml.h"
@@ -4921,19 +4922,49 @@ transformJsonFuncExpr(ParseState *pstate, JsonFuncExpr *func)
49214922
return (Node *) jsexpr;
49224923
}
49234924

4925+
static JsonReturning *
4926+
transformJsonCtorRet(ParseState *pstate, JsonOutput *output, const char *fname)
4927+
{
4928+
JsonReturning *returning;
4929+
4930+
if (output)
4931+
{
4932+
returning = transformJsonOutput(pstate, output, false);
4933+
4934+
Assert(OidIsValid(returning->typid));
4935+
4936+
if (returning->typid != JSONOID && returning->typid != JSONBOID)
4937+
ereport(ERROR,
4938+
(errcode(ERRCODE_DATATYPE_MISMATCH),
4939+
errmsg("cannot use RETURNING type %s in %s",
4940+
format_type_be(returning->typid), fname),
4941+
parser_errposition(pstate, output->typeName->location)));
4942+
}
4943+
else
4944+
{
4945+
Oid targettype = SQLJSON_TYPE_OID();
4946+
JsonFormatType format =
4947+
SQLJSON_TYPE_IS_JSONB() ? JS_FORMAT_JSONB : JS_FORMAT_JSON;
4948+
4949+
returning = makeNode(JsonReturning);
4950+
returning->format = makeJsonFormat(format, JS_ENC_DEFAULT, -1);
4951+
returning->typid = targettype;
4952+
returning->typmod = -1;
4953+
}
4954+
4955+
return returning;
4956+
}
4957+
49244958
/*
49254959
* Transform a JSON() expression.
49264960
*/
49274961
static Node *
49284962
transformJsonParseExpr(ParseState *pstate, JsonParseExpr *jsexpr)
49294963
{
4930-
JsonReturning *returning = makeNode(JsonReturning);
4964+
JsonReturning *returning = transformJsonCtorRet(pstate, jsexpr->output,
4965+
"JSON()");
49314966
Node *arg;
49324967

4933-
returning->format = makeJsonFormat(JS_FORMAT_JSON, JS_ENC_DEFAULT, -1);
4934-
returning->typid = JSONOID;
4935-
returning->typmod = -1;
4936-
49374968
if (jsexpr->unique_keys)
49384969
{
49394970
/*
@@ -4973,12 +5004,9 @@ transformJsonParseExpr(ParseState *pstate, JsonParseExpr *jsexpr)
49735004
static Node *
49745005
transformJsonScalarExpr(ParseState *pstate, JsonScalarExpr *jsexpr)
49755006
{
4976-
JsonReturning *returning = makeNode(JsonReturning);
49775007
Node *arg = transformExprRecurse(pstate, (Node *) jsexpr->expr);
4978-
4979-
returning->format = makeJsonFormat(JS_FORMAT_JSON, JS_ENC_DEFAULT, -1);
4980-
returning->typid = JSONOID;
4981-
returning->typmod = -1;
5008+
JsonReturning *returning = transformJsonCtorRet(pstate, jsexpr->output,
5009+
"JSON_SCALAR()");
49825010

49835011
if (exprType(arg) == UNKNOWNOID)
49845012
arg = coerce_to_specific_type(pstate, arg, TEXTOID, "JSON_SCALAR");

src/backend/utils/adt/ruleutils.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "utils/fmgroids.h"
6666
#include "utils/guc.h"
6767
#include "utils/hsearch.h"
68+
#include "utils/jsonb.h"
6869
#include "utils/lsyscache.h"
6970
#include "utils/partcache.h"
7071
#include "utils/rel.h"
@@ -9590,8 +9591,9 @@ get_json_constructor_options(JsonConstructorExpr *ctor, StringInfo buf)
95909591
if (ctor->unique)
95919592
appendStringInfoString(buf, " WITH UNIQUE KEYS");
95929593

9593-
if (ctor->type != JSCTOR_JSON_PARSE &&
9594-
ctor->type != JSCTOR_JSON_SCALAR)
9594+
if (!((ctor->type == JSCTOR_JSON_PARSE ||
9595+
ctor->type == JSCTOR_JSON_SCALAR) &&
9596+
ctor->returning->typid == SQLJSON_TYPE_OID()))
95959597
get_json_returning(ctor->returning, buf, true);
95969598
}
95979599

src/include/nodes/parsenodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,7 @@ typedef struct JsonParseExpr
15781578
{
15791579
NodeTag type;
15801580
JsonValueExpr *expr; /* string expression */
1581+
JsonOutput *output; /* RETURNING clause, if specified */
15811582
bool unique_keys; /* WITH UNIQUE KEYS? */
15821583
int location; /* token location, or -1 if unknown */
15831584
} JsonParseExpr;
@@ -1590,6 +1591,7 @@ typedef struct JsonScalarExpr
15901591
{
15911592
NodeTag type;
15921593
Expr *expr; /* scalar expression */
1594+
JsonOutput *output; /* RETURNING clause, if specified */
15931595
int location; /* token location, or -1 if unknown */
15941596
} JsonScalarExpr;
15951597

src/test/regress/expected/jsonb.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5043,7 +5043,7 @@ create table test_json_as_json (js json, jb jsonb);
50435043

50445044
set sql_json = jsonb;
50455045
select json(' { "aa": 1, "b" : 2 }');
5046-
jsonb
5046+
json
50475047
-------------------
50485048
{"b": 2, "aa": 1}
50495049
(1 row)

src/test/regress/expected/sqljson.out

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,103 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITHOUT UNIQUE KEYS);
113113
Output: JSON('123'::json)
114114
(2 rows)
115115

116+
SELECT JSON('123' RETURNING text);
117+
ERROR: cannot use RETURNING type text in JSON()
118+
LINE 1: SELECT JSON('123' RETURNING text);
119+
^
120+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123');
121+
QUERY PLAN
122+
-----------------------------
123+
Result
124+
Output: JSON('123'::json)
125+
(2 rows)
126+
127+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json);
128+
QUERY PLAN
129+
-----------------------------
130+
Result
131+
Output: JSON('123'::json)
132+
(2 rows)
133+
134+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING jsonb);
135+
QUERY PLAN
136+
----------------------------------------------
137+
Result
138+
Output: JSON('123'::jsonb RETURNING jsonb)
139+
(2 rows)
140+
141+
SELECT pg_typeof(JSON('123'));
142+
pg_typeof
143+
-----------
144+
json
145+
(1 row)
146+
147+
SELECT pg_typeof(JSON('123' RETURNING json));
148+
pg_typeof
149+
-----------
150+
json
151+
(1 row)
152+
153+
SELECT pg_typeof(JSON('123' RETURNING jsonb));
154+
pg_typeof
155+
-----------
156+
jsonb
157+
(1 row)
158+
159+
SET sql_json = jsonb;
160+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123');
161+
QUERY PLAN
162+
-----------------------------
163+
Result
164+
Output: JSON('123'::json)
165+
(2 rows)
166+
167+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json);
168+
QUERY PLAN
169+
-----------------------------
170+
Result
171+
Output: JSON('123'::json)
172+
(2 rows)
173+
174+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING jsonb);
175+
QUERY PLAN
176+
-----------------------------
177+
Result
178+
Output: JSON('123'::json)
179+
(2 rows)
180+
181+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json text);
182+
QUERY PLAN
183+
------------------------------------------------------
184+
Result
185+
Output: JSON('123'::json text RETURNING json text)
186+
(2 rows)
187+
188+
SELECT pg_typeof(JSON('123'));
189+
pg_typeof
190+
-----------
191+
json
192+
(1 row)
193+
194+
SELECT pg_typeof(JSON('123' RETURNING json));
195+
pg_typeof
196+
-----------
197+
json
198+
(1 row)
199+
200+
SELECT pg_typeof(JSON('123' RETURNING jsonb));
201+
pg_typeof
202+
-----------
203+
json
204+
(1 row)
205+
206+
SELECT pg_typeof(JSON('123' RETURNING json text));
207+
pg_typeof
208+
-----------
209+
json text
210+
(1 row)
211+
212+
SET sql_json = json;
116213
-- JSON_SCALAR()
117214
SELECT JSON_SCALAR();
118215
ERROR: syntax error at or near ")"
@@ -204,6 +301,50 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR('123');
204301
Output: JSON_SCALAR('123'::text)
205302
(2 rows)
206303

304+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json);
305+
QUERY PLAN
306+
----------------------------
307+
Result
308+
Output: JSON_SCALAR(123)
309+
(2 rows)
310+
311+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING jsonb);
312+
QUERY PLAN
313+
--------------------------------------------
314+
Result
315+
Output: JSON_SCALAR(123 RETURNING jsonb)
316+
(2 rows)
317+
318+
SET sql_json = jsonb;
319+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123);
320+
QUERY PLAN
321+
----------------------------
322+
Result
323+
Output: JSON_SCALAR(123)
324+
(2 rows)
325+
326+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json);
327+
QUERY PLAN
328+
----------------------------
329+
Result
330+
Output: JSON_SCALAR(123)
331+
(2 rows)
332+
333+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING jsonb);
334+
QUERY PLAN
335+
----------------------------
336+
Result
337+
Output: JSON_SCALAR(123)
338+
(2 rows)
339+
340+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json text);
341+
QUERY PLAN
342+
------------------------------------------------
343+
Result
344+
Output: JSON_SCALAR(123 RETURNING json text)
345+
(2 rows)
346+
347+
SET sql_json = json;
207348
-- JSON_SERIALIZE()
208349
SELECT JSON_SERIALIZE();
209350
ERROR: syntax error at or near ")"

src/test/regress/sql/sqljson.sql

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123'::bytea FORMAT JSON ENCODING UTF8)
2323
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITH UNIQUE KEYS);
2424
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' WITHOUT UNIQUE KEYS);
2525

26+
SELECT JSON('123' RETURNING text);
27+
28+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123');
29+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json);
30+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING jsonb);
31+
SELECT pg_typeof(JSON('123'));
32+
SELECT pg_typeof(JSON('123' RETURNING json));
33+
SELECT pg_typeof(JSON('123' RETURNING jsonb));
34+
35+
SET sql_json = jsonb;
36+
37+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123');
38+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json);
39+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING jsonb);
40+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON('123' RETURNING json text);
41+
SELECT pg_typeof(JSON('123'));
42+
SELECT pg_typeof(JSON('123' RETURNING json));
43+
SELECT pg_typeof(JSON('123' RETURNING jsonb));
44+
SELECT pg_typeof(JSON('123' RETURNING json text));
45+
46+
SET sql_json = json;
2647

2748
-- JSON_SCALAR()
2849
SELECT JSON_SCALAR();
@@ -41,6 +62,17 @@ SELECT JSON_SCALAR('{}'::jsonb);
4162

4263
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123);
4364
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR('123');
65+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json);
66+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING jsonb);
67+
68+
SET sql_json = jsonb;
69+
70+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123);
71+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json);
72+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING jsonb);
73+
EXPLAIN (VERBOSE, COSTS OFF) SELECT JSON_SCALAR(123 RETURNING json text);
74+
75+
SET sql_json = json;
4476

4577
-- JSON_SERIALIZE()
4678
SELECT JSON_SERIALIZE();

0 commit comments

Comments
 (0)