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

Commitfaa2b95

Browse files
committed
Refactor code used by jsonpath executor to fetch variables
Currently, getJsonPathVariable() directly extracts a namedvariable/key from the source Jsonb value. This commit puts thatlogic into a callback function called by getJsonPathVariable().Other implementations of the callback may accept different formsof the source value(s), for example, a List of values passed fromoutside jsonpath_exec.c.Extracted from a much larger patch to add SQL/JSON query functions.Author: Nikita Glukhov <n.gluhov@postgrespro.ru>Author: Teodor Sigaev <teodor@sigaev.ru>Author: Oleg Bartunov <obartunov@gmail.com>Author: Alexander Korotkov <aekorotkov@gmail.com>Author: Andrew Dunstan <andrew@dunslane.net>Author: Amit Langote <amitlangote09@gmail.com>Reviewers have included (in no particular order) Andres Freund,Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers,Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby,Álvaro Herrera, Jian He, Peter EisentrautDiscussion:https://postgr.es/m/cd0bb935-0158-78a7-08b5-904886deac4b@postgrespro.ruDiscussion:https://postgr.es/m/20220616233130.rparivafipt6doj3@alap3.anarazel.deDiscussion:https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.orgDiscussion:https://postgr.es/m/CA+HiwqHROpf9e644D8BRqYvaAPmgBZVup-xKMDPk-nd4EpgzHw@mail.gmail.comDiscussion:https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
1 parent1edb3b4 commitfaa2b95

File tree

1 file changed

+99
-37
lines changed

1 file changed

+99
-37
lines changed

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

Lines changed: 99 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,19 @@ typedef struct JsonBaseObjectInfo
8787
intid;
8888
}JsonBaseObjectInfo;
8989

90+
/* Callbacks for executeJsonPath() */
91+
typedefJsonbValue*(*JsonPathGetVarCallback) (void*vars,char*varName,intvarNameLen,
92+
JsonbValue*baseObject,int*baseObjectId);
93+
typedefint (*JsonPathCountVarsCallback) (void*vars);
94+
9095
/*
9196
* Context of jsonpath execution.
9297
*/
9398
typedefstructJsonPathExecContext
9499
{
95-
Jsonb*vars;/* variables to substitute into jsonpath */
100+
void*vars;/* variables to substitute into jsonpath */
101+
JsonPathGetVarCallbackgetVar;/* callback to extract a given variable
102+
* from 'vars' */
96103
JsonbValue*root;/* for $ evaluation */
97104
JsonbValue*current;/* for @ evaluation */
98105
JsonBaseObjectInfobaseObject;/* "base object" for .keyvalue()
@@ -174,7 +181,9 @@ typedef JsonPathBool (*JsonPathPredicateCallback) (JsonPathItem *jsp,
174181
void*param);
175182
typedefNumeric (*BinaryArithmFunc) (Numericnum1,Numericnum2,bool*error);
176183

177-
staticJsonPathExecResultexecuteJsonPath(JsonPath*path,Jsonb*vars,
184+
staticJsonPathExecResultexecuteJsonPath(JsonPath*path,void*vars,
185+
JsonPathGetVarCallbackgetVar,
186+
JsonPathCountVarsCallbackcountVars,
178187
Jsonb*json,boolthrowErrors,
179188
JsonValueList*result,booluseTz);
180189
staticJsonPathExecResultexecuteItem(JsonPathExecContext*cxt,
@@ -226,7 +235,12 @@ static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt,
226235
staticvoidgetJsonPathItem(JsonPathExecContext*cxt,JsonPathItem*item,
227236
JsonbValue*value);
228237
staticvoidgetJsonPathVariable(JsonPathExecContext*cxt,
229-
JsonPathItem*variable,Jsonb*vars,JsonbValue*value);
238+
JsonPathItem*variable,JsonbValue*value);
239+
staticintcountVariablesFromJsonb(void*varsJsonb);
240+
staticJsonbValue*getJsonPathVariableFromJsonb(void*varsJsonb,char*varName,
241+
intvarNameLen,
242+
JsonbValue*baseObject,
243+
int*baseObjectId);
230244
staticintJsonbArraySize(JsonbValue*jb);
231245
staticJsonPathBoolexecuteComparison(JsonPathItem*cmp,JsonbValue*lv,
232246
JsonbValue*rv,void*p);
@@ -284,7 +298,9 @@ jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)
284298
silent=PG_GETARG_BOOL(3);
285299
}
286300

287-
res=executeJsonPath(jp,vars,jb, !silent,NULL,tz);
301+
res=executeJsonPath(jp,vars,getJsonPathVariableFromJsonb,
302+
countVariablesFromJsonb,
303+
jb, !silent,NULL,tz);
288304

289305
PG_FREE_IF_COPY(jb,0);
290306
PG_FREE_IF_COPY(jp,1);
@@ -339,7 +355,9 @@ jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)
339355
silent=PG_GETARG_BOOL(3);
340356
}
341357

342-
(void)executeJsonPath(jp,vars,jb, !silent,&found,tz);
358+
(void)executeJsonPath(jp,vars,getJsonPathVariableFromJsonb,
359+
countVariablesFromJsonb,
360+
jb, !silent,&found,tz);
343361

344362
PG_FREE_IF_COPY(jb,0);
345363
PG_FREE_IF_COPY(jp,1);
@@ -417,7 +435,9 @@ jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)
417435
vars=PG_GETARG_JSONB_P_COPY(2);
418436
silent=PG_GETARG_BOOL(3);
419437

420-
(void)executeJsonPath(jp,vars,jb, !silent,&found,tz);
438+
(void)executeJsonPath(jp,vars,getJsonPathVariableFromJsonb,
439+
countVariablesFromJsonb,
440+
jb, !silent,&found,tz);
421441

422442
funcctx->user_fctx=JsonValueListGetList(&found);
423443

@@ -464,7 +484,9 @@ jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)
464484
Jsonb*vars=PG_GETARG_JSONB_P(2);
465485
boolsilent=PG_GETARG_BOOL(3);
466486

467-
(void)executeJsonPath(jp,vars,jb, !silent,&found,tz);
487+
(void)executeJsonPath(jp,vars,getJsonPathVariableFromJsonb,
488+
countVariablesFromJsonb,
489+
jb, !silent,&found,tz);
468490

469491
PG_RETURN_JSONB_P(JsonbValueToJsonb(wrapItemsInArray(&found)));
470492
}
@@ -495,7 +517,9 @@ jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)
495517
Jsonb*vars=PG_GETARG_JSONB_P(2);
496518
boolsilent=PG_GETARG_BOOL(3);
497519

498-
(void)executeJsonPath(jp,vars,jb, !silent,&found,tz);
520+
(void)executeJsonPath(jp,vars,getJsonPathVariableFromJsonb,
521+
countVariablesFromJsonb,
522+
jb, !silent,&found,tz);
499523

500524
if (JsonValueListLength(&found) >=1)
501525
PG_RETURN_JSONB_P(JsonbValueToJsonb(JsonValueListHead(&found)));
@@ -522,6 +546,9 @@ jsonb_path_query_first_tz(PG_FUNCTION_ARGS)
522546
*
523547
* 'path' - jsonpath to be executed
524548
* 'vars' - variables to be substituted to jsonpath
549+
* 'getVar' - callback used by getJsonPathVariable() to extract variables from
550+
*'vars'
551+
* 'countVars' - callback to count the number of jsonpath variables in 'vars'
525552
* 'json' - target document for jsonpath evaluation
526553
* 'throwErrors' - whether we should throw suppressible errors
527554
* 'result' - list to store result items into
@@ -537,8 +564,10 @@ jsonb_path_query_first_tz(PG_FUNCTION_ARGS)
537564
* In other case it tries to find all the satisfied result items.
538565
*/
539566
staticJsonPathExecResult
540-
executeJsonPath(JsonPath*path,Jsonb*vars,Jsonb*json,boolthrowErrors,
541-
JsonValueList*result,booluseTz)
567+
executeJsonPath(JsonPath*path,void*vars,JsonPathGetVarCallbackgetVar,
568+
JsonPathCountVarsCallbackcountVars,
569+
Jsonb*json,boolthrowErrors,JsonValueList*result,
570+
booluseTz)
542571
{
543572
JsonPathExecContextcxt;
544573
JsonPathExecResultres;
@@ -550,22 +579,16 @@ executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors,
550579
if (!JsonbExtractScalar(&json->root,&jbv))
551580
JsonbInitBinary(&jbv,json);
552581

553-
if (vars&& !JsonContainerIsObject(&vars->root))
554-
{
555-
ereport(ERROR,
556-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
557-
errmsg("\"vars\" argument is not an object"),
558-
errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object.")));
559-
}
560-
561582
cxt.vars=vars;
583+
cxt.getVar=getVar;
562584
cxt.laxMode= (path->header&JSONPATH_LAX)!=0;
563585
cxt.ignoreStructuralErrors=cxt.laxMode;
564586
cxt.root=&jbv;
565587
cxt.current=&jbv;
566588
cxt.baseObject.jbc=NULL;
567589
cxt.baseObject.id=0;
568-
cxt.lastGeneratedObjectId=vars ?2 :1;
590+
/* 1 + number of base objects in vars */
591+
cxt.lastGeneratedObjectId=1+countVars(vars);
569592
cxt.innermostArraySize=-1;
570593
cxt.throwErrors=throwErrors;
571594
cxt.useTz=useTz;
@@ -2108,7 +2131,7 @@ getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item,
21082131
&value->val.string.len);
21092132
break;
21102133
casejpiVariable:
2111-
getJsonPathVariable(cxt,item,cxt->vars,value);
2134+
getJsonPathVariable(cxt,item,value);
21122135
return;
21132136
default:
21142137
elog(ERROR,"unexpected jsonpath item type");
@@ -2120,42 +2143,81 @@ getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item,
21202143
*/
21212144
staticvoid
21222145
getJsonPathVariable(JsonPathExecContext*cxt,JsonPathItem*variable,
2123-
Jsonb*vars,JsonbValue*value)
2146+
JsonbValue*value)
21242147
{
21252148
char*varName;
21262149
intvarNameLength;
2127-
JsonbValuetmp;
2150+
JsonbValuebaseObject;
2151+
intbaseObjectId;
21282152
JsonbValue*v;
21292153

2130-
if (!vars)
2154+
Assert(variable->type==jpiVariable);
2155+
varName=jspGetString(variable,&varNameLength);
2156+
2157+
if (cxt->vars==NULL||
2158+
(v=cxt->getVar(cxt->vars,varName,varNameLength,
2159+
&baseObject,&baseObjectId))==NULL)
2160+
ereport(ERROR,
2161+
(errcode(ERRCODE_UNDEFINED_OBJECT),
2162+
errmsg("could not find jsonpath variable \"%s\"",
2163+
pnstrdup(varName,varNameLength))));
2164+
2165+
if (baseObjectId>0)
21312166
{
2132-
value->type=jbvNull;
2133-
return;
2167+
*value=*v;
2168+
setBaseObject(cxt,&baseObject,baseObjectId);
21342169
}
2170+
}
2171+
2172+
/*
2173+
* Definition of JsonPathGetVarCallback for when JsonPathExecContext.vars
2174+
* is specified as a jsonb value.
2175+
*/
2176+
staticJsonbValue*
2177+
getJsonPathVariableFromJsonb(void*varsJsonb,char*varName,intvarNameLength,
2178+
JsonbValue*baseObject,int*baseObjectId)
2179+
{
2180+
Jsonb*vars=varsJsonb;
2181+
JsonbValuetmp;
2182+
JsonbValue*result;
21352183

2136-
Assert(variable->type==jpiVariable);
2137-
varName=jspGetString(variable,&varNameLength);
21382184
tmp.type=jbvString;
21392185
tmp.val.string.val=varName;
21402186
tmp.val.string.len=varNameLength;
21412187

2142-
v=findJsonbValueFromContainer(&vars->root,JB_FOBJECT,&tmp);
2188+
result=findJsonbValueFromContainer(&vars->root,JB_FOBJECT,&tmp);
21432189

2144-
if (v)
2190+
if (result==NULL)
21452191
{
2146-
*value=*v;
2147-
pfree(v);
2192+
*baseObjectId=-1;
2193+
returnNULL;
21482194
}
2149-
else
2195+
2196+
*baseObjectId=1;
2197+
JsonbInitBinary(baseObject,vars);
2198+
2199+
returnresult;
2200+
}
2201+
2202+
/*
2203+
* Definition of JsonPathCountVarsCallback for when JsonPathExecContext.vars
2204+
* is specified as a jsonb value.
2205+
*/
2206+
staticint
2207+
countVariablesFromJsonb(void*varsJsonb)
2208+
{
2209+
Jsonb*vars=varsJsonb;
2210+
2211+
if (vars&& !JsonContainerIsObject(&vars->root))
21502212
{
21512213
ereport(ERROR,
2152-
(errcode(ERRCODE_UNDEFINED_OBJECT),
2153-
errmsg("could not find jsonpath variable \"%s\"",
2154-
pnstrdup(varName,varNameLength))));
2214+
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2215+
errmsg("\"vars\" argument is not an object"),
2216+
errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."));
21552217
}
21562218

2157-
JsonbInitBinary(&tmp,vars);
2158-
setBaseObject(cxt,&tmp,1);
2219+
/* count of base objects */
2220+
returnvars!=NULL ?1 :0;
21592221
}
21602222

21612223
/**************** Support functions for JsonPath execution *****************/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp