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

Commit62f80ff

Browse files
author
Nikita Glukhov
committed
Add JSON_ARRAY() transformation
1 parenta4800a8 commit62f80ff

File tree

9 files changed

+332
-12
lines changed

9 files changed

+332
-12
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2358,6 +2358,22 @@ _copyJsonOutput(const JsonOutput *from)
23582358
returnnewnode;
23592359
}
23602360

2361+
/*
2362+
* _copyJsonArrayCtor
2363+
*/
2364+
staticJsonArrayCtor*
2365+
_copyJsonArrayCtor(constJsonArrayCtor*from)
2366+
{
2367+
JsonArrayCtor*newnode=makeNode(JsonArrayCtor);
2368+
2369+
COPY_NODE_FIELD(exprs);
2370+
COPY_NODE_FIELD(output);
2371+
COPY_SCALAR_FIELD(absent_on_null);
2372+
COPY_LOCATION_FIELD(location);
2373+
2374+
returnnewnode;
2375+
}
2376+
23612377
/* ****************************************************************
23622378
*pathnodes.h copy functions
23632379
*
@@ -5276,6 +5292,9 @@ copyObjectImpl(const void *from)
52765292
caseT_JsonOutput:
52775293
retval=_copyJsonOutput(from);
52785294
break;
5295+
caseT_JsonArrayCtor:
5296+
retval=_copyJsonArrayCtor(from);
5297+
break;
52795298

52805299
/*
52815300
* RELATION NODES

‎src/backend/nodes/nodeFuncs.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4010,6 +4010,16 @@ raw_expression_tree_walker(Node *node,
40104010
return true;
40114011
}
40124012
break;
4013+
caseT_JsonArrayCtor:
4014+
{
4015+
JsonArrayCtor*jac= (JsonArrayCtor*)node;
4016+
4017+
if (walker(jac->output,context))
4018+
return true;
4019+
if (walker(jac->exprs,context))
4020+
return true;
4021+
}
4022+
break;
40134023
default:
40144024
elog(ERROR,"unrecognized node type: %d",
40154025
(int)nodeTag(node));

‎src/backend/parser/parse_expr.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ static Node *transformIndirection(ParseState *pstate, A_Indirection *ind);
122122
staticNode*transformTypeCast(ParseState*pstate,TypeCast*tc);
123123
staticNode*transformCollateClause(ParseState*pstate,CollateClause*c);
124124
staticNode*transformJsonObjectCtor(ParseState*pstate,JsonObjectCtor*ctor);
125+
staticNode*transformJsonArrayCtor(ParseState*pstate,JsonArrayCtor*ctor);
125126
staticNode*make_row_comparison_op(ParseState*pstate,List*opname,
126127
List*largs,List*rargs,intlocation);
127128
staticNode*make_row_distinct_op(ParseState*pstate,List*opname,
@@ -374,6 +375,10 @@ transformExprRecurse(ParseState *pstate, Node *expr)
374375
result=transformJsonObjectCtor(pstate, (JsonObjectCtor*)expr);
375376
break;
376377

378+
caseT_JsonArrayCtor:
379+
result=transformJsonArrayCtor(pstate, (JsonArrayCtor*)expr);
380+
break;
381+
377382
default:
378383
/* should not reach here */
379384
elog(ERROR,"unrecognized node type: %d", (int)nodeTag(expr));
@@ -3995,3 +4000,68 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39954000

39964001
returncoerceJsonFuncExpr(pstate, (Node*)jsctor,jsctor->returning, true);
39974002
}
4003+
4004+
/*
4005+
* Transform JSON_ARRAY() constructor.
4006+
*
4007+
* JSON_ARRAY() is transformed into json[b]_build_array[_ext]() call
4008+
* depending on the output JSON format. The first argument of
4009+
* json[b]_build_array_ext() is absent_on_null.
4010+
*
4011+
* Then function call result is coerced to the target type.
4012+
*/
4013+
staticNode*
4014+
transformJsonArrayCtor(ParseState*pstate,JsonArrayCtor*ctor)
4015+
{
4016+
JsonReturningreturning;
4017+
JsonCtorExpr*jsctor;
4018+
FuncExpr*fexpr;
4019+
List*args=NIL;
4020+
Oidfuncid;
4021+
Oidfuncrettype;
4022+
4023+
/* transform element expressions, if any */
4024+
if (ctor->exprs)
4025+
{
4026+
ListCell*lc;
4027+
4028+
/* append the first absent_on_null argument */
4029+
args=lappend(args,makeBoolConst(ctor->absent_on_null, false));
4030+
4031+
/* transform and append element arguments */
4032+
foreach(lc,ctor->exprs)
4033+
{
4034+
JsonValueExpr*jsval=castNode(JsonValueExpr,lfirst(lc));
4035+
Node*val=transformJsonValueExpr(pstate,jsval,
4036+
JS_FORMAT_DEFAULT);
4037+
4038+
args=lappend(args,val);
4039+
}
4040+
}
4041+
4042+
transformJsonOutput(pstate,ctor->output, true,&returning);
4043+
4044+
if (returning.format.type==JS_FORMAT_JSONB)
4045+
{
4046+
funcid=args ?F_JSONB_BUILD_ARRAY_EXT :F_JSONB_BUILD_ARRAY_NOARGS;
4047+
funcrettype=JSONBOID;
4048+
}
4049+
else
4050+
{
4051+
funcid=args ?F_JSON_BUILD_ARRAY_EXT :F_JSON_BUILD_ARRAY_NOARGS;
4052+
funcrettype=JSONOID;
4053+
}
4054+
4055+
fexpr=makeFuncExpr(funcid,funcrettype,args,
4056+
InvalidOid,InvalidOid,COERCE_EXPLICIT_CALL);
4057+
fexpr->location=ctor->location;
4058+
4059+
jsctor=makeNode(JsonCtorExpr);
4060+
jsctor->func=fexpr;
4061+
jsctor->type=JSCTOR_JSON_ARRAY;
4062+
jsctor->returning=returning;
4063+
jsctor->unique= false;
4064+
jsctor->absent_on_null=ctor->absent_on_null;
4065+
4066+
returncoerceJsonFuncExpr(pstate, (Node*)jsctor,&returning, true);
4067+
}

‎src/backend/parser/parse_target.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,6 +1934,9 @@ FigureColnameInternal(Node *node, char **name)
19341934
caseT_JsonObjectCtor:
19351935
*name="json_object";
19361936
return2;
1937+
caseT_JsonArrayCtor:
1938+
*name="json_array";
1939+
return2;
19371940
default:
19381941
break;
19391942
}

‎src/backend/utils/adt/json.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,11 +1237,9 @@ json_build_object_noargs(PG_FUNCTION_ARGS)
12371237
PG_RETURN_TEXT_P(cstring_to_text_with_len("{}",2));
12381238
}
12391239

1240-
/*
1241-
* SQL function json_build_array(variadic "any")
1242-
*/
1243-
Datum
1244-
json_build_array(PG_FUNCTION_ARGS)
1240+
staticDatum
1241+
json_build_array_worker(FunctionCallInfofcinfo,intfirst_vararg,
1242+
boolabsent_on_null)
12451243
{
12461244
intnargs;
12471245
inti;
@@ -1252,7 +1250,8 @@ json_build_array(PG_FUNCTION_ARGS)
12521250
Oid*types;
12531251

12541252
/* fetch argument values to build the array */
1255-
nargs=extract_variadic_args(fcinfo,0, false,&args,&types,&nulls);
1253+
nargs=extract_variadic_args(fcinfo,first_vararg, false,
1254+
&args,&types,&nulls);
12561255

12571256
if (nargs<0)
12581257
PG_RETURN_NULL();
@@ -1263,6 +1262,9 @@ json_build_array(PG_FUNCTION_ARGS)
12631262

12641263
for (i=0;i<nargs;i++)
12651264
{
1265+
if (absent_on_null&&nulls[i])
1266+
continue;
1267+
12661268
appendStringInfoString(result,sep);
12671269
sep=", ";
12681270
add_json(args[i],nulls[i],result,types[i], false);
@@ -1273,6 +1275,24 @@ json_build_array(PG_FUNCTION_ARGS)
12731275
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data,result->len));
12741276
}
12751277

1278+
/*
1279+
* SQL function json_build_array(variadic "any")
1280+
*/
1281+
Datum
1282+
json_build_array(PG_FUNCTION_ARGS)
1283+
{
1284+
returnjson_build_array_worker(fcinfo,0, false);
1285+
}
1286+
1287+
/*
1288+
* SQL function json_build_array_ext(absent_on_null bool, variadic "any")
1289+
*/
1290+
Datum
1291+
json_build_array_ext(PG_FUNCTION_ARGS)
1292+
{
1293+
returnjson_build_array_worker(fcinfo,1,PG_GETARG_BOOL(0));
1294+
}
1295+
12761296
/*
12771297
* degenerate case of json_build_array where it gets 0 arguments.
12781298
*/

‎src/backend/utils/adt/jsonb.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,11 +1237,9 @@ jsonb_build_object_noargs(PG_FUNCTION_ARGS)
12371237
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
12381238
}
12391239

1240-
/*
1241-
* SQL function jsonb_build_array(variadic "any")
1242-
*/
1243-
Datum
1244-
jsonb_build_array(PG_FUNCTION_ARGS)
1240+
staticDatum
1241+
jsonb_build_array_worker(FunctionCallInfofcinfo,intfirst_vararg,
1242+
boolabsent_on_null)
12451243
{
12461244
intnargs;
12471245
inti;
@@ -1251,7 +1249,8 @@ jsonb_build_array(PG_FUNCTION_ARGS)
12511249
Oid*types;
12521250

12531251
/* build argument values to build the array */
1254-
nargs=extract_variadic_args(fcinfo,0, true,&args,&types,&nulls);
1252+
nargs=extract_variadic_args(fcinfo,first_vararg, true,
1253+
&args,&types,&nulls);
12551254

12561255
if (nargs<0)
12571256
PG_RETURN_NULL();
@@ -1261,13 +1260,36 @@ jsonb_build_array(PG_FUNCTION_ARGS)
12611260
result.res=pushJsonbValue(&result.parseState,WJB_BEGIN_ARRAY,NULL);
12621261

12631262
for (i=0;i<nargs;i++)
1263+
{
1264+
if (absent_on_null&&nulls[i])
1265+
continue;
1266+
12641267
add_jsonb(args[i],nulls[i],&result,types[i], false);
1268+
}
12651269

12661270
result.res=pushJsonbValue(&result.parseState,WJB_END_ARRAY,NULL);
12671271

12681272
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
12691273
}
12701274

1275+
/*
1276+
* SQL function jsonb_build_array(variadic "any")
1277+
*/
1278+
Datum
1279+
jsonb_build_array(PG_FUNCTION_ARGS)
1280+
{
1281+
returnjsonb_build_array_worker(fcinfo,0, false);
1282+
}
1283+
1284+
/*
1285+
* SQL function jsonb_build_array_ext(absent_on_null bool, variadic "any")
1286+
*/
1287+
Datum
1288+
jsonb_build_array_ext(PG_FUNCTION_ARGS)
1289+
{
1290+
returnjsonb_build_array_worker(fcinfo,1,PG_GETARG_BOOL(0));
1291+
}
1292+
12711293
/*
12721294
* degenerate case of jsonb_build_array where it gets 0 arguments.
12731295
*/

‎src/include/catalog/pg_proc.dat

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8397,6 +8397,11 @@
83978397
proname => 'json_build_array', proisstrict => 'f', provolatile => 's',
83988398
prorettype => 'json', proargtypes => '',
83998399
prosrc => 'json_build_array_noargs' },
8400+
{ oid => '2228', descr => 'build a json array from any inputs',
8401+
proname => 'json_build_array_ext', provariadic => 'any', proisstrict => 'f',
8402+
provolatile => 's', prorettype => 'json', proargtypes => 'bool any',
8403+
proallargtypes => '{bool,any}', proargmodes => '{i,v}',
8404+
prosrc => 'json_build_array_ext' },
84008405
{ oid => '3200',
84018406
descr => 'build a json object from pairwise key/value inputs',
84028407
proname => 'json_build_object', provariadic => 'any', proisstrict => 'f',
@@ -9272,6 +9277,11 @@
92729277
proname => 'jsonb_build_array', proisstrict => 'f', provolatile => 's',
92739278
prorettype => 'jsonb', proargtypes => '',
92749279
prosrc => 'jsonb_build_array_noargs' },
9280+
{ oid => '6068', descr => 'build a jsonb array from any inputs',
9281+
proname => 'jsonb_build_array_ext', provariadic => 'any', proisstrict => 'f',
9282+
provolatile => 's', prorettype => 'jsonb', proargtypes => 'bool any',
9283+
proallargtypes => '{bool,any}', proargmodes => '{i,v}',
9284+
prosrc => 'jsonb_build_array_ext' },
92759285
{ oid => '3273',
92769286
descr => 'build a jsonb object from pairwise key/value inputs',
92779287
proname => 'jsonb_build_object', provariadic => 'any', proisstrict => 'f',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp