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

Commitf4fb45d

Browse files
committed
SQL/JSON constructors
This patch introduces the SQL/JSON standard constructors for JSON:JSON()JSON_ARRAY()JSON_ARRAYAGG()JSON_OBJECT()JSON_OBJECTAGG()For the most part these functions provide facilities that mimicexisting json/jsonb functions. However, they also offer some usefuladditional functionality. In addition to text input, the JSON() functionaccepts bytea input, which it will decode and constuct a json value from.The other functions provide useful options for handling duplicate keysand null values.This series of patches will be followed by a consolidated documentationpatch.Nikita GlukhovReviewers have included (in no particular order) Andres Freund, AlexanderKorotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu,Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby.Discussion:https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ru
1 parentf79b803 commitf4fb45d

37 files changed

+3615
-130
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,6 +2450,69 @@ ExecInitExprRec(Expr *node, ExprState *state,
24502450
break;
24512451
}
24522452

2453+
caseT_JsonConstructorExpr:
2454+
{
2455+
JsonConstructorExpr*ctor= (JsonConstructorExpr*)node;
2456+
List*args=ctor->args;
2457+
ListCell*lc;
2458+
intnargs=list_length(args);
2459+
intargno=0;
2460+
2461+
if (ctor->func)
2462+
{
2463+
ExecInitExprRec(ctor->func,state,resv,resnull);
2464+
}
2465+
else
2466+
{
2467+
scratch.opcode=EEOP_JSON_CONSTRUCTOR;
2468+
scratch.d.json_constructor.constructor=ctor;
2469+
scratch.d.json_constructor.arg_values=palloc(sizeof(Datum)*nargs);
2470+
scratch.d.json_constructor.arg_nulls=palloc(sizeof(bool)*nargs);
2471+
scratch.d.json_constructor.arg_types=palloc(sizeof(Oid)*nargs);
2472+
scratch.d.json_constructor.nargs=nargs;
2473+
2474+
foreach(lc,args)
2475+
{
2476+
Expr*arg= (Expr*)lfirst(lc);
2477+
2478+
scratch.d.json_constructor.arg_types[argno]=exprType((Node*)arg);
2479+
2480+
if (IsA(arg,Const))
2481+
{
2482+
/* Don't evaluate const arguments every round */
2483+
Const*con= (Const*)arg;
2484+
2485+
scratch.d.json_constructor.arg_values[argno]=con->constvalue;
2486+
scratch.d.json_constructor.arg_nulls[argno]=con->constisnull;
2487+
}
2488+
else
2489+
{
2490+
ExecInitExprRec(arg,state,
2491+
&scratch.d.json_constructor.arg_values[argno],
2492+
&scratch.d.json_constructor.arg_nulls[argno]);
2493+
}
2494+
argno++;
2495+
}
2496+
2497+
ExprEvalPushStep(state,&scratch);
2498+
}
2499+
2500+
if (ctor->coercion)
2501+
{
2502+
Datum*innermost_caseval=state->innermost_caseval;
2503+
bool*innermost_isnull=state->innermost_casenull;
2504+
2505+
state->innermost_caseval=resv;
2506+
state->innermost_casenull=resnull;
2507+
2508+
ExecInitExprRec(ctor->coercion,state,resv,resnull);
2509+
2510+
state->innermost_caseval=innermost_caseval;
2511+
state->innermost_casenull=innermost_isnull;
2512+
}
2513+
}
2514+
break;
2515+
24532516
default:
24542517
elog(ERROR,"unrecognized node type: %d",
24552518
(int)nodeTag(node));

‎src/backend/executor/execExprInterp.c

Lines changed: 48 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"
@@ -477,6 +479,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
477479
&&CASE_EEOP_GROUPING_FUNC,
478480
&&CASE_EEOP_WINDOW_FUNC,
479481
&&CASE_EEOP_SUBPLAN,
482+
&&CASE_EEOP_JSON_CONSTRUCTOR,
480483
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
481484
&&CASE_EEOP_AGG_DESERIALIZE,
482485
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
@@ -1786,7 +1789,13 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
17861789
{
17871790
/* too complex for an inline implementation */
17881791
ExecEvalAggOrderedTransTuple(state,op,econtext);
1792+
EEO_NEXT();
1793+
}
17891794

1795+
EEO_CASE(EEOP_JSON_CONSTRUCTOR)
1796+
{
1797+
/* too complex for an inline implementation */
1798+
ExecEvalJsonConstructor(state,op,econtext);
17901799
EEO_NEXT();
17911800
}
17921801

@@ -4380,3 +4389,42 @@ ExecAggPlainTransByRef(AggState *aggstate, AggStatePerTrans pertrans,
43804389

43814390
MemoryContextSwitchTo(oldContext);
43824391
}
4392+
4393+
/*
4394+
* Evaluate a JSON constructor expression.
4395+
*/
4396+
void
4397+
ExecEvalJsonConstructor(ExprState*state,ExprEvalStep*op,
4398+
ExprContext*econtext)
4399+
{
4400+
Datumres;
4401+
JsonConstructorExpr*ctor=op->d.json_constructor.constructor;
4402+
boolis_jsonb=ctor->returning->format->format_type==JS_FORMAT_JSONB;
4403+
boolisnull= false;
4404+
4405+
if (ctor->type==JSCTOR_JSON_ARRAY)
4406+
res= (is_jsonb ?
4407+
jsonb_build_array_worker :
4408+
json_build_array_worker)(op->d.json_constructor.nargs,
4409+
op->d.json_constructor.arg_values,
4410+
op->d.json_constructor.arg_nulls,
4411+
op->d.json_constructor.arg_types,
4412+
op->d.json_constructor.constructor->absent_on_null);
4413+
elseif (ctor->type==JSCTOR_JSON_OBJECT)
4414+
res= (is_jsonb ?
4415+
jsonb_build_object_worker :
4416+
json_build_object_worker)(op->d.json_constructor.nargs,
4417+
op->d.json_constructor.arg_values,
4418+
op->d.json_constructor.arg_nulls,
4419+
op->d.json_constructor.arg_types,
4420+
op->d.json_constructor.constructor->absent_on_null,
4421+
op->d.json_constructor.constructor->unique);
4422+
else
4423+
{
4424+
res= (Datum)0;
4425+
elog(ERROR,"invalid JsonConstructorExpr type %d",ctor->type);
4426+
}
4427+
4428+
*op->resvalue=res;
4429+
*op->resnull=isnull;
4430+
}

‎src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,12 @@ llvm_compile_expr(ExprState *state)
23482348
LLVMBuildBr(b,opblocks[opno+1]);
23492349
break;
23502350

2351+
caseEEOP_JSON_CONSTRUCTOR:
2352+
build_EvalXFunc(b,mod,"ExecEvalJsonConstructor",
2353+
v_state,op,v_econtext);
2354+
LLVMBuildBr(b,opblocks[opno+1]);
2355+
break;
2356+
23512357
caseEEOP_LAST:
23522358
Assert(false);
23532359
break;

‎src/backend/jit/llvm/llvmjit_types.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ void *referenced_functions[] =
131131
ExecEvalSysVar,
132132
ExecEvalWholeRowVar,
133133
ExecEvalXmlExpr,
134+
ExecEvalJsonConstructor,
134135
MakeExpandedObjectReadOnlyInternal,
135136
slot_getmissingattrs,
136137
slot_getsomeattrs_int,

‎src/backend/nodes/copyfuncs.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,6 +2344,152 @@ _copyJsonValueExpr(const JsonValueExpr *from)
23442344
returnnewnode;
23452345
}
23462346

2347+
/*
2348+
* _copyJsonConstructorExpr
2349+
*/
2350+
staticJsonConstructorExpr*
2351+
_copyJsonConstructorExpr(constJsonConstructorExpr*from)
2352+
{
2353+
JsonConstructorExpr*newnode=makeNode(JsonConstructorExpr);
2354+
2355+
COPY_SCALAR_FIELD(type);
2356+
COPY_NODE_FIELD(args);
2357+
COPY_NODE_FIELD(func);
2358+
COPY_NODE_FIELD(coercion);
2359+
COPY_NODE_FIELD(returning);
2360+
COPY_SCALAR_FIELD(absent_on_null);
2361+
COPY_SCALAR_FIELD(unique);
2362+
COPY_LOCATION_FIELD(location);
2363+
2364+
returnnewnode;
2365+
}
2366+
2367+
/*
2368+
* _copyJsonKeyValue
2369+
*/
2370+
staticJsonKeyValue*
2371+
_copyJsonKeyValue(constJsonKeyValue*from)
2372+
{
2373+
JsonKeyValue*newnode=makeNode(JsonKeyValue);
2374+
2375+
COPY_NODE_FIELD(key);
2376+
COPY_NODE_FIELD(value);
2377+
2378+
returnnewnode;
2379+
}
2380+
2381+
/*
2382+
* _copyJsonObjectConstructor
2383+
*/
2384+
staticJsonObjectConstructor*
2385+
_copyJsonObjectConstructor(constJsonObjectConstructor*from)
2386+
{
2387+
JsonObjectConstructor*newnode=makeNode(JsonObjectConstructor);
2388+
2389+
COPY_NODE_FIELD(exprs);
2390+
COPY_NODE_FIELD(output);
2391+
COPY_SCALAR_FIELD(absent_on_null);
2392+
COPY_SCALAR_FIELD(unique);
2393+
COPY_LOCATION_FIELD(location);
2394+
2395+
returnnewnode;
2396+
}
2397+
2398+
/*
2399+
* _copyJsonAggConstructor
2400+
*/
2401+
staticJsonAggConstructor*
2402+
_copyJsonAggConstructor(constJsonAggConstructor*from)
2403+
{
2404+
JsonAggConstructor*newnode=makeNode(JsonAggConstructor);
2405+
2406+
COPY_NODE_FIELD(output);
2407+
COPY_NODE_FIELD(agg_filter);
2408+
COPY_NODE_FIELD(agg_order);
2409+
COPY_NODE_FIELD(over);
2410+
COPY_LOCATION_FIELD(location);
2411+
2412+
returnnewnode;
2413+
}
2414+
2415+
/*
2416+
* _copyJsonObjectAgg
2417+
*/
2418+
staticJsonObjectAgg*
2419+
_copyJsonObjectAgg(constJsonObjectAgg*from)
2420+
{
2421+
JsonObjectAgg*newnode=makeNode(JsonObjectAgg);
2422+
2423+
COPY_NODE_FIELD(constructor);
2424+
COPY_NODE_FIELD(arg);
2425+
COPY_SCALAR_FIELD(absent_on_null);
2426+
COPY_SCALAR_FIELD(unique);
2427+
2428+
returnnewnode;
2429+
}
2430+
2431+
/*
2432+
* _copyJsonOutput
2433+
*/
2434+
staticJsonOutput*
2435+
_copyJsonOutput(constJsonOutput*from)
2436+
{
2437+
JsonOutput*newnode=makeNode(JsonOutput);
2438+
2439+
COPY_NODE_FIELD(typeName);
2440+
COPY_NODE_FIELD(returning);
2441+
2442+
returnnewnode;
2443+
}
2444+
2445+
/*
2446+
* _copyJsonArrayConstructor
2447+
*/
2448+
staticJsonArrayConstructor*
2449+
_copyJsonArrayConstructor(constJsonArrayConstructor*from)
2450+
{
2451+
JsonArrayConstructor*newnode=makeNode(JsonArrayConstructor);
2452+
2453+
COPY_NODE_FIELD(exprs);
2454+
COPY_NODE_FIELD(output);
2455+
COPY_SCALAR_FIELD(absent_on_null);
2456+
COPY_LOCATION_FIELD(location);
2457+
2458+
returnnewnode;
2459+
}
2460+
2461+
/*
2462+
* _copyJsonArrayAgg
2463+
*/
2464+
staticJsonArrayAgg*
2465+
_copyJsonArrayAgg(constJsonArrayAgg*from)
2466+
{
2467+
JsonArrayAgg*newnode=makeNode(JsonArrayAgg);
2468+
2469+
COPY_NODE_FIELD(constructor);
2470+
COPY_NODE_FIELD(arg);
2471+
COPY_SCALAR_FIELD(absent_on_null);
2472+
2473+
returnnewnode;
2474+
}
2475+
2476+
/*
2477+
* _copyJsonArrayQueryConstructor
2478+
*/
2479+
staticJsonArrayQueryConstructor*
2480+
_copyJsonArrayQueryConstructor(constJsonArrayQueryConstructor*from)
2481+
{
2482+
JsonArrayQueryConstructor*newnode=makeNode(JsonArrayQueryConstructor);
2483+
2484+
COPY_NODE_FIELD(query);
2485+
COPY_NODE_FIELD(output);
2486+
COPY_NODE_FIELD(format);
2487+
COPY_SCALAR_FIELD(absent_on_null);
2488+
COPY_LOCATION_FIELD(location);
2489+
2490+
returnnewnode;
2491+
}
2492+
23472493
/* ****************************************************************
23482494
*pathnodes.h copy functions
23492495
*
@@ -5406,6 +5552,33 @@ copyObjectImpl(const void *from)
54065552
caseT_JsonValueExpr:
54075553
retval=_copyJsonValueExpr(from);
54085554
break;
5555+
caseT_JsonKeyValue:
5556+
retval=_copyJsonKeyValue(from);
5557+
break;
5558+
caseT_JsonConstructorExpr:
5559+
retval=_copyJsonConstructorExpr(from);
5560+
break;
5561+
caseT_JsonObjectConstructor:
5562+
retval=_copyJsonObjectConstructor(from);
5563+
break;
5564+
caseT_JsonAggConstructor:
5565+
retval=_copyJsonAggConstructor(from);
5566+
break;
5567+
caseT_JsonObjectAgg:
5568+
retval=_copyJsonObjectAgg(from);
5569+
break;
5570+
caseT_JsonOutput:
5571+
retval=_copyJsonOutput(from);
5572+
break;
5573+
caseT_JsonArrayConstructor:
5574+
retval=_copyJsonArrayConstructor(from);
5575+
break;
5576+
caseT_JsonArrayQueryConstructor:
5577+
retval=_copyJsonArrayQueryConstructor(from);
5578+
break;
5579+
caseT_JsonArrayAgg:
5580+
retval=_copyJsonArrayAgg(from);
5581+
break;
54095582

54105583
/*
54115584
* RELATION NODES

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp