Skip to content

Commit a4800a8

Browse files
author
Nikita Glukhov
committed
Remove json[b]_build_object_ext()
1 parent 76b4760 commit a4800a8

File tree

17 files changed

+142
-108
lines changed

17 files changed

+142
-108
lines changed

src/backend/executor/execExpr.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,8 +2131,45 @@ ExecInitExprRec(Expr *node, ExprState *state,
21312131
}
21322132

21332133
case T_JsonCtorExpr:
2134-
ExecInitExprRec(&((JsonCtorExpr *) node)->func->xpr, state, resv,
2135-
resnull);
2134+
{
2135+
JsonCtorExpr *ctor = (JsonCtorExpr *) node;
2136+
List *args = ctor->args;
2137+
ListCell *lc;
2138+
int nargs = list_length(args);
2139+
int argno = 0;
2140+
2141+
scratch.opcode = EEOP_JSON_CTOR;
2142+
scratch.d.json_ctor.ctor = ctor;
2143+
scratch.d.json_ctor.arg_values = palloc(sizeof(Datum) * nargs);
2144+
scratch.d.json_ctor.arg_nulls = palloc(sizeof(bool) * nargs);
2145+
scratch.d.json_ctor.arg_types = palloc(sizeof(Oid) * nargs);
2146+
scratch.d.json_ctor.nargs = nargs;
2147+
2148+
foreach(lc, args)
2149+
{
2150+
Expr *arg = (Expr *) lfirst(lc);
2151+
2152+
scratch.d.json_ctor.arg_types[argno] = exprType((Node *) arg);
2153+
2154+
if (IsA(arg, Const))
2155+
{
2156+
/* Don't evaluate const arguments every round */
2157+
Const *con = (Const *) arg;
2158+
2159+
scratch.d.json_ctor.arg_values[argno] = con->constvalue;
2160+
scratch.d.json_ctor.arg_nulls[argno] = con->constisnull;
2161+
}
2162+
else
2163+
{
2164+
ExecInitExprRec(arg, state,
2165+
&scratch.d.json_ctor.arg_values[argno],
2166+
&scratch.d.json_ctor.arg_nulls[argno]);
2167+
}
2168+
argno++;
2169+
}
2170+
2171+
ExprEvalPushStep(state, &scratch);
2172+
}
21362173
break;
21372174

21382175
default:

src/backend/executor/execExprInterp.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
#include "utils/date.h"
7272
#include "utils/datum.h"
7373
#include "utils/expandedrecord.h"
74+
#include "utils/json.h"
75+
#include "utils/jsonb.h"
7476
#include "utils/lsyscache.h"
7577
#include "utils/memutils.h"
7678
#include "utils/timestamp.h"
@@ -432,6 +434,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
432434
&&CASE_EEOP_WINDOW_FUNC,
433435
&&CASE_EEOP_SUBPLAN,
434436
&&CASE_EEOP_ALTERNATIVE_SUBPLAN,
437+
&&CASE_EEOP_JSON_CTOR,
435438
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
436439
&&CASE_EEOP_AGG_DESERIALIZE,
437440
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
@@ -1544,6 +1547,26 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
15441547
EEO_NEXT();
15451548
}
15461549

1550+
EEO_CASE(EEOP_JSON_CTOR)
1551+
{
1552+
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);
1563+
1564+
*op->resvalue = res;
1565+
*op->resnull = false;
1566+
1567+
EEO_NEXT();
1568+
}
1569+
15471570
/* evaluate a strict aggregate deserialization function */
15481571
EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE)
15491572
{

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,11 +2302,13 @@ _copyJsonCtorExpr(const JsonCtorExpr *from)
23022302
{
23032303
JsonCtorExpr *newnode = makeNode(JsonCtorExpr);
23042304

2305+
COPY_NODE_FIELD(args);
23052306
COPY_NODE_FIELD(func);
23062307
COPY_SCALAR_FIELD(type);
23072308
COPY_NODE_FIELD(returning);
23082309
COPY_SCALAR_FIELD(absent_on_null);
23092310
COPY_SCALAR_FIELD(unique);
2311+
COPY_LOCATION_FIELD(location);
23102312

23112313
return newnode;
23122314
}

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,11 +851,13 @@ _equalJsonValueExpr(const JsonValueExpr *a, const JsonValueExpr *b)
851851
static bool
852852
_equalJsonCtorExpr(const JsonCtorExpr *a, const JsonCtorExpr *b)
853853
{
854+
COMPARE_NODE_FIELD(args);
854855
COMPARE_NODE_FIELD(func);
855856
COMPARE_SCALAR_FIELD(type);
856857
COMPARE_NODE_FIELD(returning);
857858
COMPARE_SCALAR_FIELD(absent_on_null);
858859
COMPARE_SCALAR_FIELD(unique);
860+
COMPARE_LOCATION_FIELD(location);
859861

860862
return true;
861863
}

src/backend/nodes/nodeFuncs.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ exprType(const Node *expr)
266266
}
267267
break;
268268
case T_JsonCtorExpr:
269-
type = exprType((Node *) ((const JsonCtorExpr *) expr)->func);
269+
type = ((const JsonCtorExpr *) expr)->returning->format->format == JS_FORMAT_JSONB ? JSONBOID : JSONOID;
270270
break;
271271
default:
272272
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
@@ -504,7 +504,7 @@ exprTypmod(const Node *expr)
504504
case T_JsonValueExpr:
505505
return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
506506
case T_JsonCtorExpr:
507-
return exprTypmod((Node *) ((const JsonCtorExpr *) expr)->func);
507+
return -1; /* ((const JsonCtorExpr *) expr)->returning->typmod; */
508508
default:
509509
break;
510510
}
@@ -924,7 +924,8 @@ exprCollation(const Node *expr)
924924
coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
925925
break;
926926
case T_JsonCtorExpr:
927-
coll = exprCollation((Node *) ((const JsonCtorExpr *) expr)->func);
927+
/* coll = exprCollation((Node *) ((const JsonCtorExpr *) expr)->func); */
928+
coll = InvalidOid; /* keep compiler quiet */
928929
break;
929930
default:
930931
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
@@ -1134,8 +1135,8 @@ exprSetCollation(Node *expr, Oid collation)
11341135
collation);
11351136
break;
11361137
case T_JsonCtorExpr:
1137-
exprSetCollation((Node *) ((const JsonCtorExpr *) expr)->func,
1138-
collation);
1138+
/* exprSetCollation((Node *) ((const JsonCtorExpr *) expr)->func, collation); */
1139+
Assert(!OidIsValid(collation)); /* result is always an json[b] type */
11391140
break;
11401141
default:
11411142
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
@@ -1581,7 +1582,7 @@ exprLocation(const Node *expr)
15811582
loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
15821583
break;
15831584
case T_JsonCtorExpr:
1584-
loc = exprLocation((Node *) ((const JsonCtorExpr *) expr)->func);
1585+
loc = ((const JsonCtorExpr *) expr)->location;
15851586
break;
15861587
default:
15871588
/* for any other node type it's just unknown... */
@@ -2293,7 +2294,9 @@ expression_tree_walker(Node *node,
22932294
case T_JsonCtorExpr:
22942295
{
22952296
JsonCtorExpr *ctor = (JsonCtorExpr *) node;
2296-
2297+
2298+
if (walker(ctor->args, context))
2299+
return true;
22972300
if (walker(ctor->func, context))
22982301
return true;
22992302
}
@@ -3250,6 +3253,7 @@ expression_tree_mutator(Node *node,
32503253
JsonCtorExpr *newnode;
32513254

32523255
FLATCOPY(newnode, jve, JsonCtorExpr);
3256+
MUTATE(newnode->args, jve->args, List *);
32533257
MUTATE(newnode->func, jve->func, FuncExpr *);
32543258
MUTATE(newnode->returning, jve->returning, JsonReturning *);
32553259

@@ -3968,6 +3972,8 @@ raw_expression_tree_walker(Node *node,
39683972
{
39693973
JsonCtorExpr *ctor = (JsonCtorExpr *) node;
39703974

3975+
if (walker(ctor->args, context))
3976+
return true;
39713977
if (walker(ctor->func, context))
39723978
return true;
39733979
if (walker(ctor->returning, context))

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,11 +1744,13 @@ _outJsonCtorExpr(StringInfo str, const JsonCtorExpr *node)
17441744
{
17451745
WRITE_NODE_TYPE("JSONCTOREXPR");
17461746

1747+
WRITE_NODE_FIELD(args);
17471748
WRITE_NODE_FIELD(func);
17481749
WRITE_INT_FIELD(type);
17491750
WRITE_NODE_FIELD(returning);
17501751
WRITE_BOOL_FIELD(unique);
17511752
WRITE_BOOL_FIELD(absent_on_null);
1753+
WRITE_LOCATION_FIELD(location);
17521754
}
17531755

17541756
/*****************************************************************************

src/backend/nodes/readfuncs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,11 +1396,13 @@ _readJsonCtorExpr(void)
13961396
{
13971397
READ_LOCALS(JsonCtorExpr);
13981398

1399+
READ_NODE_FIELD(args);
13991400
READ_NODE_FIELD(func);
14001401
READ_INT_FIELD(type);
14011402
READ_NODE_FIELD(returning);
14021403
READ_BOOL_FIELD(unique);
14031404
READ_BOOL_FIELD(absent_on_null);
1405+
READ_LOCATION_FIELD(location);
14041406

14051407
READ_DONE();
14061408
}

src/backend/parser/parse_expr.c

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,22 +3963,14 @@ coerceJsonFuncExpr(ParseState *pstate, Node *expr,
39633963
static Node *
39643964
transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39653965
{
3966-
JsonReturning *returning;
39673966
JsonCtorExpr *jsctor;
3968-
FuncExpr *fexpr;
39693967
List *args = NIL;
3970-
Oid funcid;
3971-
Oid funcrettype;
39723968

39733969
/* transform key-value pairs, if any */
39743970
if (ctor->exprs)
39753971
{
39763972
ListCell *lc;
39773973

3978-
/* append the first two arguments */
3979-
args = lappend(args, makeBoolConst(ctor->absent_on_null, false));
3980-
args = lappend(args, makeBoolConst(ctor->unique, false));
3981-
39823974
/* transform and append key-value arguments */
39833975
foreach(lc, ctor->exprs)
39843976
{
@@ -3992,29 +3984,14 @@ transformJsonObjectCtor(ParseState *pstate, JsonObjectCtor *ctor)
39923984
}
39933985
}
39943986

3995-
returning = transformJsonCtorOutput(pstate, ctor->output, args);
3996-
3997-
if (returning->format->format == JS_FORMAT_JSONB)
3998-
{
3999-
funcid = args ? F_JSONB_BUILD_OBJECT_EXT : F_JSONB_BUILD_OBJECT_NOARGS;
4000-
funcrettype = JSONBOID;
4001-
}
4002-
else
4003-
{
4004-
funcid = args ? F_JSON_BUILD_OBJECT_EXT : F_JSON_BUILD_OBJECT_NOARGS;
4005-
funcrettype = JSONOID;
4006-
}
4007-
4008-
fexpr = makeFuncExpr(funcid, funcrettype, args,
4009-
InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL);
4010-
fexpr->location = ctor->location;
4011-
40123987
jsctor = makeNode(JsonCtorExpr);
4013-
jsctor->func = fexpr;
3988+
jsctor->args = args;
3989+
jsctor->func = NULL;
40143990
jsctor->type = JSCTOR_JSON_OBJECT;
4015-
jsctor->returning = returning;
3991+
jsctor->returning = transformJsonCtorOutput(pstate, ctor->output, args);
40163992
jsctor->unique = ctor->unique;
40173993
jsctor->absent_on_null = ctor->absent_on_null;
3994+
jsctor->location = ctor->location;
40183995

4019-
return coerceJsonFuncExpr(pstate, (Node *) jsctor, returning, true);
3996+
return coerceJsonFuncExpr(pstate, (Node *) jsctor, jsctor->returning, true);
40203997
}

src/backend/utils/adt/json.c

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,26 +1121,15 @@ catenate_stringinfo_string(StringInfo buffer, const char *addon)
11211121
return result;
11221122
}
11231123

1124-
static Datum
1125-
json_build_object_worker(FunctionCallInfo fcinfo, int first_vararg,
1124+
Datum
1125+
json_build_object_worker(int nargs, Datum *args, bool *nulls, Oid *types,
11261126
bool absent_on_null, bool unique_keys)
11271127
{
1128-
int nargs = PG_NARGS();
11291128
int i;
11301129
const char *sep = "";
11311130
StringInfo result;
1132-
Datum *args;
1133-
bool *nulls;
1134-
Oid *types;
11351131
JsonUniqueBuilderState unique_check;
11361132

1137-
/* fetch argument values to build the object */
1138-
nargs = extract_variadic_args(fcinfo, first_vararg, false,
1139-
&args, &types, &nulls);
1140-
1141-
if (nargs < 0)
1142-
PG_RETURN_NULL();
1143-
11441133
if (nargs % 2 != 0)
11451134
ereport(ERROR,
11461135
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1184,7 +1173,7 @@ json_build_object_worker(FunctionCallInfo fcinfo, int first_vararg,
11841173
if (nulls[i])
11851174
ereport(ERROR,
11861175
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1187-
errmsg("argument %d cannot be null", first_vararg + i + 1),
1176+
errmsg("argument %d cannot be null", i + 1),
11881177
errhint("Object keys should be text.")));
11891178

11901179
/* save key offset before key appending */
@@ -1217,7 +1206,7 @@ json_build_object_worker(FunctionCallInfo fcinfo, int first_vararg,
12171206
if (unique_keys)
12181207
json_unique_builder_free(&unique_check);
12191208

1220-
PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1209+
return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
12211210
}
12221211

12231212
/*
@@ -1226,17 +1215,17 @@ json_build_object_worker(FunctionCallInfo fcinfo, int first_vararg,
12261215
Datum
12271216
json_build_object(PG_FUNCTION_ARGS)
12281217
{
1229-
return json_build_object_worker(fcinfo, 0, false, false);
1230-
}
1218+
Datum *args;
1219+
bool *nulls;
1220+
Oid *types;
1221+
/* build argument values to build the object */
1222+
int nargs = extract_variadic_args(fcinfo, 0, true,
1223+
&args, &types, &nulls);
12311224

1232-
/*
1233-
* SQL function json_build_object_ext(absent_on_null bool, unique bool, variadic "any")
1234-
*/
1235-
Datum
1236-
json_build_object_ext(PG_FUNCTION_ARGS)
1237-
{
1238-
return json_build_object_worker(fcinfo, 2,
1239-
PG_GETARG_BOOL(0), PG_GETARG_BOOL(1));
1225+
if (nargs < 0)
1226+
PG_RETURN_NULL();
1227+
1228+
PG_RETURN_DATUM(json_build_object_worker(nargs, args, nulls, types, false, false));
12401229
}
12411230

12421231
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy