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

Commit95d6f4d

Browse files
committed
implement ELEMENT OF jsonb AS e WITH INDEX AS i SATISFIES
1 parent1e81b00 commit95d6f4d

File tree

4 files changed

+72
-11
lines changed

4 files changed

+72
-11
lines changed

‎src/backend/parser/gram.y

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
177177
bool *no_inherit,core_yyscan_t yyscanner);
178178
static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
179179
static SelectStmt *makeElementSubselect(int any_or_each,int kind,bool recursive, Node *of,
180-
constchar *aliasname, Node *clause,int location);
180+
constchar *aliasname,constchar *indexname,
181+
Node *clause,int location);
181182

182183
%}
183184

@@ -292,6 +293,7 @@ static SelectStmt * makeElementSubselect(int any_or_each, int kind, bool recursi
292293
opt_grant_grant_optionopt_grant_admin_option
293294
opt_nowaitopt_if_existsopt_with_data
294295
opt_anywhere
296+
%type<str>opt_with_index
295297
%type<ival>opt_nowait_or_skip
296298

297299
%type<list>OptRoleListAlterOptRoleList
@@ -12060,6 +12062,18 @@ c_expr:columnref{ $$ = $1; }
1206012062
g->location =@1;
1206112063
$$ = (Node *)g;
1206212064
}
12065+
|any_or_eachELEMENTopt_anywhereOFb_exprASColIdopt_with_indexSATISFIES'('a_expr')'
12066+
{
12067+
SubLink*n = makeNode(SubLink);
12068+
12069+
n->subLinkType = EXPR_SUBLINK;
12070+
n->subLinkId =0;
12071+
n->testexpr =NULL;
12072+
n->operName = NIL;
12073+
n->subselect = (Node*)makeElementSubselect($1, ELEMENT,$3,$5,$7,$8,$11,@1);
12074+
n->location =@1;
12075+
$$ = (Node *)n;
12076+
}
1206312077
|any_or_eachany_or_each_kindopt_anywhereOFb_exprASColIdSATISFIES'('a_expr')'
1206412078
{
1206512079
SubLink*n = makeNode(SubLink);
@@ -12068,7 +12082,7 @@ c_expr:columnref{ $$ = $1; }
1206812082
n->subLinkId =0;
1206912083
n->testexpr =NULL;
1207012084
n->operName = NIL;
12071-
n->subselect = (Node*)makeElementSubselect($1,$2,$3,$5,$7,$10,@1);
12085+
n->subselect = (Node*)makeElementSubselect($1,$2,$3,$5,$7,NULL,$10,@1);
1207212086
n->location =@1;
1207312087
$$ = (Node *)n;
1207412088
}
@@ -12080,11 +12094,15 @@ any_or_each:
1208012094
;
1208112095

1208212096
any_or_each_kind:
12083-
ELEMENT{$$ = ELEMENT; }
12084-
|KEY{$$ = KEY; }
12097+
KEY{$$ = KEY; }
1208512098
|VALUE_P{$$ = VALUE_P; }
1208612099
;
1208712100

12101+
opt_with_index:
12102+
WITHINDEXASColId {$$ =$4; }
12103+
|/* empty*/{$$ =NULL; }
12104+
;
12105+
1208812106
opt_anywhere:
1208912107
ANYWHERE{$$ =true; }
1209012108
|/* empty*/{$$ =false; }
@@ -14866,7 +14884,8 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query)
1486614884

1486714885
static SelectStmt *
1486814886
makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
14869-
const char *aliasname, Node *clause, int location)
14887+
const char *aliasname, const char *indexname,
14888+
Node *clause, int location)
1487014889
{
1487114890
ResTarget *target = makeNode(ResTarget);
1487214891
FuncCall*unnest_call, *agg_call, *count_call;
@@ -14930,7 +14949,7 @@ makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
1493014949
switch(kind)
1493114950
{
1493214951
case ELEMENT:
14933-
unnest_name = "unnest_element";
14952+
unnest_name =indexname ? "unnest_element_index" :"unnest_element";
1493414953
break;
1493514954
case KEY:
1493614955
unnest_name = "unnest_key";
@@ -14948,6 +14967,8 @@ makeElementSubselect(int any_or_each, int kind, bool recursive, Node *of,
1494814967

1494914968
table_ref->functions = list_make1(list_make2(unnest_call, NIL));
1495014969
table_ref->alias = makeAlias(aliasname, NIL);
14970+
if (indexname)
14971+
table_ref->alias->colnames = list_make2(makeString(pstrdup(aliasname)), makeString(pstrdup(indexname)));
1495114972
subselect->fromClause = list_make1(table_ref);
1495214973

1495314974
return subselect;

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

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3900,14 +3900,16 @@ typedef struct UnnestState
39003900
JsonbIterator*it;
39013901
boolskipNested;
39023902
JsonbIteratorTokentype;
3903+
int32counter;
3904+
TupleDesctupdesc;
39033905
}
39043906
UnnestState;
39053907

39063908
staticvoidfiniUnnest(UnnestState*state);
39073909

39083910
staticvoid
39093911
initUnnest(FuncCallContext*funcctx,Datumjsonb,boolrecursive,
3910-
JsonbIteratorTokentype)
3912+
JsonbIteratorTokentype,FunctionCallInfofcinfo)
39113913
{
39123914
MemoryContextoldcontext;
39133915
UnnestState*state;
@@ -3932,6 +3934,10 @@ initUnnest(FuncCallContext *funcctx, Datum jsonb, bool recursive,
39323934
Assert(r==WJB_DONE);
39333935
}
39343936

3937+
if (r!=WJB_DONE&&fcinfo&&
3938+
get_call_result_type(fcinfo,NULL,&state->tupdesc)!=TYPEFUNC_COMPOSITE)
3939+
elog(ERROR,"return type must be a row type");
3940+
39353941
MemoryContextSwitchTo(oldcontext);
39363942

39373943
if (r==WJB_DONE)
@@ -3940,6 +3946,7 @@ initUnnest(FuncCallContext *funcctx, Datum jsonb, bool recursive,
39403946
state=NULL;
39413947
}
39423948

3949+
39433950
funcctx->user_fctx= (void*)state;
39443951
}
39453952

@@ -3963,6 +3970,8 @@ nextUnnest(UnnestState *state)
39633970

39643971
MemoryContextSwitchTo(oldcontext);
39653972

3973+
state->counter++;
3974+
39663975
return (r==state->type) ?JsonbValueToJsonb(&v) :NULL;
39673976
}
39683977

@@ -4008,7 +4017,7 @@ jsonb_unnest_element(PG_FUNCTION_ARGS)
40084017

40094018
if (SRF_IS_FIRSTCALL())
40104019
initUnnest(SRF_FIRSTCALL_INIT(),PG_GETARG_DATUM(0),
4011-
PG_GETARG_BOOL(1),WJB_ELEM);
4020+
PG_GETARG_BOOL(1),WJB_ELEM,NULL);
40124021

40134022
funcctx=SRF_PERCALL_SETUP();
40144023
state=funcctx->user_fctx;
@@ -4022,6 +4031,34 @@ jsonb_unnest_element(PG_FUNCTION_ARGS)
40224031
SRF_RETURN_NEXT(funcctx,JsonbGetDatum(r));
40234032
}
40244033

4034+
Datum
4035+
jsonb_unnest_element_index(PG_FUNCTION_ARGS)
4036+
{
4037+
FuncCallContext*funcctx;
4038+
UnnestState*state;
4039+
Jsonb*r;
4040+
Datumvals[2];
4041+
boolnulls[2]= {false, false};
4042+
4043+
if (SRF_IS_FIRSTCALL())
4044+
initUnnest(SRF_FIRSTCALL_INIT(),PG_GETARG_DATUM(0),
4045+
PG_GETARG_BOOL(1),WJB_ELEM,fcinfo);
4046+
4047+
funcctx=SRF_PERCALL_SETUP();
4048+
state=funcctx->user_fctx;
4049+
4050+
if (state==NULL|| (r=nextUnnest(state))==NULL)
4051+
{
4052+
finiUnnest(state);
4053+
SRF_RETURN_DONE(funcctx);
4054+
}
4055+
4056+
vals[0]=JsonbGetDatum(r);
4057+
vals[1]=Int32GetDatum(state->counter-1);
4058+
4059+
SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(heap_form_tuple(state->tupdesc,vals,nulls)));
4060+
}
4061+
40254062
Datum
40264063
jsonb_unnest_value(PG_FUNCTION_ARGS)
40274064
{
@@ -4031,7 +4068,7 @@ jsonb_unnest_value(PG_FUNCTION_ARGS)
40314068

40324069
if (SRF_IS_FIRSTCALL())
40334070
initUnnest(SRF_FIRSTCALL_INIT(),PG_GETARG_DATUM(0),
4034-
PG_GETARG_BOOL(1),WJB_VALUE);
4071+
PG_GETARG_BOOL(1),WJB_VALUE,NULL);
40354072

40364073
funcctx=SRF_PERCALL_SETUP();
40374074
state=funcctx->user_fctx;
@@ -4050,11 +4087,11 @@ jsonb_unnest_key(PG_FUNCTION_ARGS)
40504087
{
40514088
FuncCallContext*funcctx;
40524089
UnnestState*state;
4053-
Jsonb*r;
4090+
text*r;
40544091

40554092
if (SRF_IS_FIRSTCALL())
40564093
initUnnest(SRF_FIRSTCALL_INIT(),PG_GETARG_DATUM(0),
4057-
PG_GETARG_BOOL(1),WJB_KEY);
4094+
PG_GETARG_BOOL(1),WJB_KEY,NULL);
40584095

40594096
funcctx=SRF_PERCALL_SETUP();
40604097
state=funcctx->user_fctx;

‎src/include/catalog/pg_proc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4876,6 +4876,8 @@ DATA(insert OID = 3306 ( jsonb_pretty PGNSP PGUID 12 1 0 0 0 f f f f t f i 1
48764876
DESCR("Indented text from jsonb");
48774877
DATA(insert OID = 7645 ( unnest_element PGNSP PGUID 12 1 100 0 0 f f f f t t i 2 0 3802 "3802 16" _null_ _null_ _null_ _null_ _null_ jsonb_unnest_element _null_ _null_ _null_ ));
48784878
DESCR("expand elements from jsonb");
4879+
DATA(insert OID = 7652 ( unnest_element_index PGNSP PGUID 12 1 100 0 0 f f f f t t i 2 0 2249 "3802 16" "{3802,16,3802,23}" "{i,i,o,o}" "{jsonb_in,recursive,element,index}" _null_ _null_ jsonb_unnest_element_index _null_ _null_ _null_ ));
4880+
DESCR("expand elements from jsonb");
48794881
DATA(insert OID = 7646 ( unnest_value PGNSP PGUID 12 1 100 0 0 f f f f t t i 2 0 3802 "3802 16" _null_ _null_ _null_ _null_ _null_ jsonb_unnest_value _null_ _null_ _null_ ));
48804882
DESCR("expand values from jsonb");
48814883
DATA(insert OID = 7647 ( unnest_key PGNSP PGUID 12 1 100 0 0 f f f f t t i 2 0 25 "3802 16" _null_ _null_ _null_ _null_ _null_ jsonb_unnest_key _null_ _null_ _null_ ));

‎src/include/utils/jsonb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ extern Datum jsonb_concat(PG_FUNCTION_ARGS);
404404

405405
/* unnesting function */
406406
externDatumjsonb_unnest_element(PG_FUNCTION_ARGS);
407+
externDatumjsonb_unnest_element_index(PG_FUNCTION_ARGS);
407408
externDatumjsonb_unnest_value(PG_FUNCTION_ARGS);
408409
externDatumjsonb_unnest_key(PG_FUNCTION_ARGS);
409410

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp