Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfe6eb36

Browse files
author
Nikita Glukhov
committed
Use nodes JsonFomat and JsonReturning in JsonCtorExpr transformation
1 parenta13e77d commitfe6eb36

File tree

8 files changed

+117
-55
lines changed

8 files changed

+117
-55
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,11 +2304,7 @@ _copyJsonCtorExpr(const JsonCtorExpr *from)
23042304

23052305
COPY_NODE_FIELD(func);
23062306
COPY_SCALAR_FIELD(type);
2307-
COPY_SCALAR_FIELD(returning.format.type);
2308-
COPY_SCALAR_FIELD(returning.format.encoding);
2309-
COPY_LOCATION_FIELD(returning.format.location);
2310-
COPY_SCALAR_FIELD(returning.typid);
2311-
COPY_SCALAR_FIELD(returning.typmod);
2307+
COPY_NODE_FIELD(returning);
23122308
COPY_SCALAR_FIELD(absent_on_null);
23132309
COPY_SCALAR_FIELD(unique);
23142310

@@ -2355,7 +2351,7 @@ _copyJsonOutput(const JsonOutput *from)
23552351
JsonOutput*newnode=makeNode(JsonOutput);
23562352

23572353
COPY_NODE_FIELD(typeName);
2358-
COPY_SCALAR_FIELD(returning);
2354+
COPY_NODE_FIELD(returning);
23592355

23602356
returnnewnode;
23612357
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -853,11 +853,7 @@ _equalJsonCtorExpr(const JsonCtorExpr *a, const JsonCtorExpr *b)
853853
{
854854
COMPARE_NODE_FIELD(func);
855855
COMPARE_SCALAR_FIELD(type);
856-
COMPARE_SCALAR_FIELD(returning.format.type);
857-
COMPARE_SCALAR_FIELD(returning.format.encoding);
858-
COMPARE_LOCATION_FIELD(returning.format.location);
859-
COMPARE_SCALAR_FIELD(returning.typid);
860-
COMPARE_SCALAR_FIELD(returning.typmod);
856+
COMPARE_NODE_FIELD(returning);
861857
COMPARE_SCALAR_FIELD(absent_on_null);
862858
COMPARE_SCALAR_FIELD(unique);
863859

‎src/backend/nodes/nodeFuncs.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,7 +2291,13 @@ expression_tree_walker(Node *node,
22912291
}
22922292
break;
22932293
caseT_JsonCtorExpr:
2294-
returnwalker(((JsonCtorExpr*)node)->func,context);
2294+
{
2295+
JsonCtorExpr*ctor= (JsonCtorExpr*)node;
2296+
2297+
if (walker(ctor->func,context))
2298+
return true;
2299+
}
2300+
break;
22952301
default:
22962302
elog(ERROR,"unrecognized node type: %d",
22972303
(int)nodeTag(node));
@@ -3245,6 +3251,7 @@ expression_tree_mutator(Node *node,
32453251

32463252
FLATCOPY(newnode,jve,JsonCtorExpr);
32473253
MUTATE(newnode->func,jve->func,FuncExpr*);
3254+
MUTATE(newnode->returning,jve->returning,JsonReturning*);
32483255

32493256
return (Node*)newnode;
32503257
}
@@ -3958,9 +3965,25 @@ raw_expression_tree_walker(Node *node,
39583965
}
39593966
break;
39603967
caseT_JsonCtorExpr:
3961-
returnwalker(((JsonCtorExpr*)node)->func,context);
3968+
{
3969+
JsonCtorExpr*ctor= (JsonCtorExpr*)node;
3970+
3971+
if (walker(ctor->func,context))
3972+
return true;
3973+
if (walker(ctor->returning,context))
3974+
return true;
3975+
}
3976+
break;
39623977
caseT_JsonOutput:
3963-
returnwalker(((JsonOutput*)node)->typeName,context);
3978+
{
3979+
JsonOutput*out= (JsonOutput*)node;
3980+
3981+
if (walker(out->typeName,context))
3982+
return true;
3983+
if (walker(out->returning,context))
3984+
return true;
3985+
}
3986+
break;
39643987
caseT_JsonKeyValue:
39653988
{
39663989
JsonKeyValue*jkv= (JsonKeyValue*)node;

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,11 +1746,7 @@ _outJsonCtorExpr(StringInfo str, const JsonCtorExpr *node)
17461746

17471747
WRITE_NODE_FIELD(func);
17481748
WRITE_INT_FIELD(type);
1749-
WRITE_ENUM_FIELD(returning.format.type,JsonFormatType);
1750-
WRITE_ENUM_FIELD(returning.format.encoding,JsonEncoding);
1751-
WRITE_LOCATION_FIELD(returning.format.location);
1752-
WRITE_OID_FIELD(returning.typid);
1753-
WRITE_INT_FIELD(returning.typmod);
1749+
WRITE_NODE_FIELD(returning);
17541750
WRITE_BOOL_FIELD(unique);
17551751
WRITE_BOOL_FIELD(absent_on_null);
17561752
}

‎src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,11 +1398,7 @@ _readJsonCtorExpr(void)
13981398

13991399
READ_NODE_FIELD(func);
14001400
READ_INT_FIELD(type);
1401-
READ_ENUM_FIELD(returning.format.type,JsonFormatType);
1402-
READ_ENUM_FIELD(returning.format.encoding,JsonEncoding);
1403-
READ_LOCATION_FIELD(returning.format.location);
1404-
READ_OID_FIELD(returning.typid);
1405-
READ_INT_FIELD(returning.typmod);
1401+
READ_NODE_FIELD(returning);
14061402
READ_BOOL_FIELD(unique);
14071403
READ_BOOL_FIELD(absent_on_null);
14081404

‎src/backend/parser/parse_expr.c

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3762,7 +3762,7 @@ checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format,
37623762
Oidtargettype,boolallow_format_for_non_strings)
37633763
{
37643764
if (!allow_format_for_non_strings&&
3765-
format->type!=JS_FORMAT_DEFAULT&&
3765+
format->format!=JS_FORMAT_DEFAULT&&
37663766
(targettype!=BYTEAOID&&
37673767
targettype!=JSONOID&&
37683768
targettype!=JSONBOID))
@@ -3779,7 +3779,7 @@ checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format,
37793779
errmsg("cannot use JSON format with non-string output types")));
37803780
}
37813781

3782-
if (format->type==JS_FORMAT_JSON)
3782+
if (format->format==JS_FORMAT_JSON)
37833783
{
37843784
JsonEncodingenc=format->encoding!=JS_ENC_DEFAULT ?
37853785
format->encoding :JS_ENC_UTF8;
@@ -3807,23 +3807,25 @@ checkJsonOutputFormat(ParseState *pstate, const JsonFormat *format,
38073807
* Assigns default format or checks specified format for its applicability to
38083808
* the target type.
38093809
*/
3810-
staticvoid
3810+
staticJsonReturning*
38113811
transformJsonOutput(ParseState*pstate,constJsonOutput*output,
3812-
boolallow_format,JsonReturning*ret)
3812+
boolallow_format)
38133813
{
3814+
JsonReturning*ret;
3815+
38143816
/* if output clause is not specified, make default clause value */
38153817
if (!output)
38163818
{
3817-
ret->format.type=JS_FORMAT_DEFAULT;
3818-
ret->format.encoding=JS_ENC_DEFAULT;
3819-
ret->format.location=-1;
3819+
ret=makeNode(JsonReturning);
3820+
3821+
ret->format=makeJsonFormat(JS_FORMAT_DEFAULT,JS_ENC_DEFAULT,-1);
38203822
ret->typid=InvalidOid;
38213823
ret->typmod=-1;
38223824

3823-
return;
3825+
returnret;
38243826
}
38253827

3826-
*ret=output->returning;
3828+
ret=copyObject(output->returning);
38273829

38283830
typenameTypeIdAndMod(pstate,output->typeName,&ret->typid,&ret->typmod);
38293831

@@ -3832,20 +3834,73 @@ transformJsonOutput(ParseState *pstate, const JsonOutput *output,
38323834
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
38333835
errmsg("returning SETOF types is not supported in SQL/JSON functions")));
38343836

3835-
if (ret->format.type==JS_FORMAT_DEFAULT)
3837+
if (ret->format->format==JS_FORMAT_DEFAULT)
38363838
/* assign JSONB format when returning jsonb, or JSON format otherwise */
3837-
ret->format.type=
3839+
ret->format->format=
38383840
ret->typid==JSONBOID ?JS_FORMAT_JSONB :JS_FORMAT_JSON;
38393841
else
3840-
checkJsonOutputFormat(pstate,&ret->format,ret->typid,allow_format);
3842+
checkJsonOutputFormat(pstate,ret->format,ret->typid,allow_format);
3843+
3844+
returnret;
3845+
}
3846+
3847+
/*
3848+
* Transform JSON output clause of JSON contructor functions.
3849+
*
3850+
* Derive RETURNING type, if not specified, from argument types.
3851+
*/
3852+
staticJsonReturning*
3853+
transformJsonCtorOutput(ParseState*pstate,JsonOutput*output,List*args)
3854+
{
3855+
JsonReturning*returning=transformJsonOutput(pstate,output, true);
3856+
3857+
if (!OidIsValid(returning->typid))
3858+
{
3859+
ListCell*lc;
3860+
boolhave_json= false;
3861+
boolhave_jsonb= false;
3862+
3863+
foreach(lc,args)
3864+
{
3865+
Node*expr=lfirst(lc);
3866+
Oidtypid=exprType(expr);
3867+
3868+
have_json |=typid==JSONOID;
3869+
have_jsonb |=typid==JSONBOID;
3870+
3871+
if (have_jsonb)
3872+
break;
3873+
}
3874+
3875+
if (have_jsonb)
3876+
{
3877+
returning->typid=JSONBOID;
3878+
returning->format->format=JS_FORMAT_JSONB;
3879+
}
3880+
elseif (have_json)
3881+
{
3882+
returning->typid=JSONOID;
3883+
returning->format->format=JS_FORMAT_JSON;
3884+
}
3885+
else
3886+
{
3887+
/* XXX TEXTOID is default by standard */
3888+
returning->typid=JSONOID;
3889+
returning->format->format=JS_FORMAT_JSON;
3890+
}
3891+
3892+
returning->typmod=-1;
3893+
}
3894+
3895+
returnreturning;
38413896
}
38423897

38433898
/*
38443899
* Coerce json[b]-valued function expression to the output type.
38453900
*/
38463901
staticNode*
3847-
coerceJsonFuncExpr(ParseState*pstate,Node*expr,JsonReturning*returning,
3848-
boolreport_error)
3902+
coerceJsonFuncExpr(ParseState*pstate,Node*expr,
3903+
constJsonReturning*returning,boolreport_error)
38493904
{
38503905
Node*res;
38513906
intlocation;
@@ -3858,16 +3913,16 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr, JsonReturning *returning,
38583913
location=exprLocation(expr);
38593914

38603915
if (location<0)
3861-
location=returning ?returning->format.location :-1;
3916+
location=returning ?returning->format->location :-1;
38623917

38633918
/* special case for RETURNING bytea FORMAT json */
3864-
if (returning->format.type==JS_FORMAT_JSON&&
3919+
if (returning->format->format==JS_FORMAT_JSON&&
38653920
returning->typid==BYTEAOID)
38663921
{
38673922
/* encode json text into bytea using pg_convert_to() */
38683923
Node*texpr=coerce_to_specific_type(pstate,expr,TEXTOID,
38693924
"JSON_FUNCTION");
3870-
Const*enc=getJsonEncodingConst(&returning->format);
3925+
Const*enc=getJsonEncodingConst(returning->format);
38713926
FuncExpr*fexpr=makeFuncExpr(F_PG_CONVERT_TO,BYTEAOID,
38723927
list_make2(texpr,enc),
38733928
InvalidOid,InvalidOid,
@@ -3908,7 +3963,7 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr, JsonReturning *returning,
39083963
staticNode*
39093964
transformJsonObjectCtor(ParseState*pstate,JsonObjectCtor*ctor)
39103965
{
3911-
JsonReturningreturning;
3966+
JsonReturning*returning;
39123967
JsonCtorExpr*jsctor;
39133968
FuncExpr*fexpr;
39143969
List*args=NIL;
@@ -3937,9 +3992,9 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39373992
}
39383993
}
39393994

3940-
transformJsonOutput(pstate,ctor->output,true,&returning);
3995+
returning=transformJsonCtorOutput(pstate,ctor->output,args);
39413996

3942-
if (returning.format.type==JS_FORMAT_JSONB)
3997+
if (returning->format->format==JS_FORMAT_JSONB)
39433998
{
39443999
funcid=args ?F_JSONB_BUILD_OBJECT_EXT :F_JSONB_BUILD_OBJECT_NOARGS;
39454000
funcrettype=JSONBOID;
@@ -3961,5 +4016,5 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39614016
jsctor->unique=ctor->unique;
39624017
jsctor->absent_on_null=ctor->absent_on_null;
39634018

3964-
returncoerceJsonFuncExpr(pstate, (Node*)jsctor,&returning, true);
4019+
returncoerceJsonFuncExpr(pstate, (Node*)jsctor,returning, true);
39654020
}

‎src/include/nodes/primnodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ typedef struct JsonCtorExpr
12651265
Exprxpr;
12661266
JsonCtorTypetype;/* constructor type */
12671267
FuncExpr*func;/* underlying json[b]_xxx() function call */
1268-
JsonReturningreturning;/* RETURNING clause */
1268+
JsonReturning*returning;/* RETURNING clause */
12691269
boolabsent_on_null;/* ABSENT ON NULL? */
12701270
boolunique;/* WITH UNIQUE KEYS? (JSON_OBJECT[AGG] only) */
12711271
}JsonCtorExpr;

‎src/test/regress/expected/sqljson.out

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON);
100100
WARNING: FORMAT JSON has no effect for json and jsonb types
101101
LINE 1: SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON);
102102
^
103-
json_object
104-
----------------
105-
{"foo": null}
103+
json_object
104+
---------------
105+
{"foo": null}
106106
(1 row)
107107

108108
SELECT JSON_OBJECT('foo': NULL::jsonb FORMAT JSON ENCODING UTF8);
@@ -176,9 +176,9 @@ SELECT JSON_OBJECT(
176176
'c': json '[ 1,true,{ } ]',
177177
'd': jsonb '{ "x" : 123.45 }'
178178
);
179-
json_object
180-
------------------------------------------------------------------------
181-
{"a": "123", "1.23" : 123, "c": [ 1,true,{ }], "d": {"x": 123.45}}
179+
json_object
180+
-------------------------------------------------------------------
181+
{"a": "123", "c": [1,true, {}], "d": {"x": 123.45}, "1.23": 123}
182182
(1 row)
183183

184184
SELECT JSON_OBJECT(
@@ -207,9 +207,9 @@ SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa'));
207207
(1 row)
208208

209209
SELECT JSON_OBJECT('a': '123', 'b': JSON_OBJECT('a': 111, 'b': 'aaa' RETURNING jsonb));
210-
json_object
211-
---------------------------------------------
212-
{"a": "123", "b": {"a": 111, "b": "aaa"}}
210+
json_object
211+
-------------------------------------------
212+
{"a": "123", "b": {"a": 111, "b": "aaa"}}
213213
(1 row)
214214

215215
SELECT JSON_OBJECT('a': JSON_OBJECT('b': 1 RETURNING text));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp