Skip to content

Commit 1233b33

Browse files
author
Nikita Glukhov
committed
Use nodes JsonFomat and JsonReturning in JSON_ARRAY
1 parent 62f80ff commit 1233b33

File tree

7 files changed

+62
-94
lines changed

7 files changed

+62
-94
lines changed

src/backend/executor/execExprInterp.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,19 +1550,35 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
15501550
EEO_CASE(EEOP_JSON_CTOR)
15511551
{
15521552
Datum res;
1553-
bool is_jsonb = op->d.json_ctor.ctor->returning->format->format == JS_FORMAT_JSONB;
1554-
1555-
res = (is_jsonb ?
1556-
jsonb_build_object_worker :
1557-
json_build_object_worker)(op->d.json_ctor.nargs,
1558-
op->d.json_ctor.arg_values,
1559-
op->d.json_ctor.arg_nulls,
1560-
op->d.json_ctor.arg_types,
1561-
op->d.json_ctor.ctor->absent_on_null,
1562-
op->d.json_ctor.ctor->unique);
1553+
JsonCtorExpr *ctor = op->d.json_ctor.ctor;
1554+
bool is_jsonb = ctor->returning->format->format == JS_FORMAT_JSONB;
1555+
bool isnull = false;
1556+
1557+
if (ctor->type == JSCTOR_JSON_ARRAY)
1558+
res = (is_jsonb ?
1559+
jsonb_build_array_worker :
1560+
json_build_array_worker)(op->d.json_ctor.nargs,
1561+
op->d.json_ctor.arg_values,
1562+
op->d.json_ctor.arg_nulls,
1563+
op->d.json_ctor.arg_types,
1564+
op->d.json_ctor.ctor->absent_on_null);
1565+
else if (ctor->type == JSCTOR_JSON_OBJECT)
1566+
res = (is_jsonb ?
1567+
jsonb_build_object_worker :
1568+
json_build_object_worker)(op->d.json_ctor.nargs,
1569+
op->d.json_ctor.arg_values,
1570+
op->d.json_ctor.arg_nulls,
1571+
op->d.json_ctor.arg_types,
1572+
op->d.json_ctor.ctor->absent_on_null,
1573+
op->d.json_ctor.ctor->unique);
1574+
else
1575+
{
1576+
res = (Datum) 0;
1577+
elog(ERROR, "invalid JsonCtorExpr type %d", ctor->type);
1578+
}
15631579

15641580
*op->resvalue = res;
1565-
*op->resnull = false;
1581+
*op->resnull = isnull;
15661582

15671583
EEO_NEXT();
15681584
}

src/backend/parser/parse_expr.c

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4013,21 +4013,14 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
40134013
static Node *
40144014
transformJsonArrayCtor(ParseState *pstate, JsonArrayCtor *ctor)
40154015
{
4016-
JsonReturning returning;
40174016
JsonCtorExpr *jsctor;
4018-
FuncExpr *fexpr;
40194017
List *args = NIL;
4020-
Oid funcid;
4021-
Oid funcrettype;
40224018

40234019
/* transform element expressions, if any */
40244020
if (ctor->exprs)
40254021
{
40264022
ListCell *lc;
40274023

4028-
/* append the first absent_on_null argument */
4029-
args = lappend(args, makeBoolConst(ctor->absent_on_null, false));
4030-
40314024
/* transform and append element arguments */
40324025
foreach(lc, ctor->exprs)
40334026
{
@@ -4039,29 +4032,13 @@ transformJsonArrayCtor(ParseState *pstate, JsonArrayCtor *ctor)
40394032
}
40404033
}
40414034

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-
40594035
jsctor = makeNode(JsonCtorExpr);
4060-
jsctor->func = fexpr;
4036+
jsctor->args = args;
40614037
jsctor->type = JSCTOR_JSON_ARRAY;
4062-
jsctor->returning = returning;
4038+
jsctor->returning = transformJsonOutput(pstate, ctor->output, true);
40634039
jsctor->unique = false;
40644040
jsctor->absent_on_null = ctor->absent_on_null;
4041+
jsctor->location = ctor->location;
40654042

4066-
return coerceJsonFuncExpr(pstate, (Node *) jsctor, &returning, true);
4043+
return coerceJsonFuncExpr(pstate, (Node *) jsctor, jsctor->returning, true);
40674044
}

src/backend/utils/adt/json.c

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

1240-
static Datum
1241-
json_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
1240+
Datum
1241+
json_build_array_worker(int nargs, Datum *args, bool *nulls, Oid *types,
12421242
bool absent_on_null)
12431243
{
1244-
int nargs;
12451244
int i;
12461245
const char *sep = "";
12471246
StringInfo result;
1248-
Datum *args;
1249-
bool *nulls;
1250-
Oid *types;
1251-
1252-
/* fetch argument values to build the array */
1253-
nargs = extract_variadic_args(fcinfo, first_vararg, false,
1254-
&args, &types, &nulls);
1255-
1256-
if (nargs < 0)
1257-
PG_RETURN_NULL();
12581247

12591248
result = makeStringInfo();
12601249

@@ -1272,7 +1261,7 @@ json_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
12721261

12731262
appendStringInfoChar(result, ']');
12741263

1275-
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1264+
return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
12761265
}
12771266

12781267
/*
@@ -1281,16 +1270,17 @@ json_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
12811270
Datum
12821271
json_build_array(PG_FUNCTION_ARGS)
12831272
{
1284-
return json_build_array_worker(fcinfo, 0, false);
1285-
}
1273+
Datum *args;
1274+
bool *nulls;
1275+
Oid *types;
1276+
/* build argument values to build the object */
1277+
int nargs = extract_variadic_args(fcinfo, 0, true,
1278+
&args, &types, &nulls);
12861279

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-
return json_build_array_worker(fcinfo, 1, PG_GETARG_BOOL(0));
1280+
if (nargs < 0)
1281+
PG_RETURN_NULL();
1282+
1283+
PG_RETURN_DATUM(json_build_array_worker(nargs, args, nulls, types, false));
12941284
}
12951285

12961286
/*

src/backend/utils/adt/jsonb.c

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

1240-
static Datum
1241-
jsonb_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
1240+
Datum
1241+
jsonb_build_array_worker(int nargs, Datum *args, bool *nulls, Oid *types,
12421242
bool absent_on_null)
12431243
{
1244-
int nargs;
12451244
int i;
12461245
JsonbInState result;
1247-
Datum *args;
1248-
bool *nulls;
1249-
Oid *types;
1250-
1251-
/* build argument values to build the array */
1252-
nargs = extract_variadic_args(fcinfo, first_vararg, true,
1253-
&args, &types, &nulls);
1254-
1255-
if (nargs < 0)
1256-
PG_RETURN_NULL();
12571246

12581247
memset(&result, 0, sizeof(JsonbInState));
12591248

@@ -1269,7 +1258,7 @@ jsonb_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
12691258

12701259
result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
12711260

1272-
PG_RETURN_POINTER(JsonbValueToJsonb(result.res));
1261+
return JsonbPGetDatum(JsonbValueToJsonb(result.res));
12731262
}
12741263

12751264
/*
@@ -1278,18 +1267,20 @@ jsonb_build_array_worker(FunctionCallInfo fcinfo, int first_vararg,
12781267
Datum
12791268
jsonb_build_array(PG_FUNCTION_ARGS)
12801269
{
1281-
return jsonb_build_array_worker(fcinfo, 0, false);
1282-
}
1270+
Datum *args;
1271+
bool *nulls;
1272+
Oid *types;
1273+
/* build argument values to build the object */
1274+
int nargs = extract_variadic_args(fcinfo, 0, true,
1275+
&args, &types, &nulls);
12831276

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-
return jsonb_build_array_worker(fcinfo, 1, PG_GETARG_BOOL(0));
1277+
if (nargs < 0)
1278+
PG_RETURN_NULL();
1279+
1280+
PG_RETURN_DATUM(jsonb_build_array_worker(nargs, args, nulls, types, false));
12911281
}
12921282

1283+
12931284
/*
12941285
* degenerate case of jsonb_build_array where it gets 0 arguments.
12951286
*/

src/include/catalog/pg_proc.dat

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8397,11 +8397,6 @@
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' },
84058400
{ oid => '3200',
84068401
descr => 'build a json object from pairwise key/value inputs',
84078402
proname => 'json_build_object', provariadic => 'any', proisstrict => 'f',
@@ -9277,11 +9272,6 @@
92779272
proname => 'jsonb_build_array', proisstrict => 'f', provolatile => 's',
92789273
prorettype => 'jsonb', proargtypes => '',
92799274
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' },
92859275
{ oid => '3273',
92869276
descr => 'build a jsonb object from pairwise key/value inputs',
92879277
proname => 'jsonb_build_object', provariadic => 'any', proisstrict => 'f',

src/include/utils/json.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid,
2323
extern Datum json_build_object_worker(int nargs, Datum *args, bool *nulls,
2424
Oid *types, bool absent_on_null,
2525
bool unique_keys);
26+
extern Datum json_build_array_worker(int nargs, Datum *args, bool *nulls,
27+
Oid *types, bool absent_on_null);
2628

2729
#endif /* JSON_H */

src/include/utils/jsonb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,5 +412,7 @@ extern const char *JsonbTypeName(JsonbValue *jb);
412412
extern Datum jsonb_build_object_worker(int nargs, Datum *args, bool *nulls,
413413
Oid *types, bool absent_on_null,
414414
bool unique_keys);
415+
extern Datum jsonb_build_array_worker(int nargs, Datum *args, bool *nulls,
416+
Oid *types, bool absent_on_null);
415417

416418
#endif /* __JSONB_H__ */

0 commit comments

Comments
 (0)