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

Commit8da3440

Browse files
author
Nikita Glukhov
committed
Add support of json object/arrays with unknown size
1 parent2d41de0 commit8da3440

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ gin_extract_jsonb(PG_FUNCTION_ARGS)
244244
PG_RETURN_POINTER(NULL);
245245
}
246246

247+
if (total<0)
248+
total=8;
249+
247250
/* Otherwise, use 2 * root count as initial estimate of result size */
248251
init_gin_entries(&entries,2*total);
249252

@@ -1108,6 +1111,9 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS)
11081111
PG_RETURN_POINTER(NULL);
11091112
}
11101113

1114+
if (total<0)
1115+
total=8;
1116+
11111117
/* Otherwise, use 2 * root count as initial estimate of result size */
11121118
init_gin_entries(&entries,2*total);
11131119

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

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
562562
state=palloc(sizeof(OkeysState));
563563

564564
state->result_size=JB_ROOT_COUNT(jb);
565+
if (state->result_size<0)
566+
state->result_size=8;
565567
state->result_count=0;
566568
state->sent_count=0;
567569
state->result=palloc(state->result_size*sizeof(char*));
@@ -579,6 +581,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
579581
cstr=palloc(v.val.string.len+1*sizeof(char));
580582
memcpy(cstr,v.val.string.val,v.val.string.len);
581583
cstr[v.val.string.len]='\0';
584+
if (state->result_count >=state->result_size)
585+
{
586+
state->result_size *=2;
587+
state->result=repalloc(state->result,state->result_size*
588+
sizeof(char*));
589+
}
582590
state->result[state->result_count++]=cstr;
583591
}
584592
}
@@ -906,7 +914,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
906914
/* Handle negative subscript */
907915
if (element<0)
908916
{
909-
uint32nelements=JB_ROOT_COUNT(jb);
917+
intnelements=JB_ROOT_COUNT(jb);
918+
if (nelements<0)
919+
nelements=JsonGetArraySize(JsonRoot(jb));
910920

911921
if (-element>nelements)
912922
PG_RETURN_NULL();
@@ -950,6 +960,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
950960
if (element<0)
951961
{
952962
uint32nelements=JB_ROOT_COUNT(jb);
963+
if (nelements<0)
964+
nelements=JsonGetArraySize(JsonRoot(jb));
953965

954966
if (-element>nelements)
955967
PG_RETURN_NULL();
@@ -1685,7 +1697,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
16851697
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
16861698
errmsg("cannot get array length of a non-array")));
16871699

1688-
PG_RETURN_INT32(JB_ROOT_COUNT(jb));
1700+
PG_RETURN_INT32(JB_ROOT_COUNT(jb) >=0 ?JB_ROOT_COUNT(jb)
1701+
:JsonGetArraySize(JsonRoot(jb)));
16891702
}
16901703

16911704
/*
@@ -4437,16 +4450,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44374450
Assert(r==WJB_BEGIN_ARRAY);
44384451
n=v.val.array.nElems;
44394452

4440-
if (idx<0)
4453+
if (v.val.array.nElems >=0)
44414454
{
4442-
if (-idx>n)
4443-
idx=n;
4444-
else
4445-
idx=n+idx;
4446-
}
4455+
if (idx<0)
4456+
{
4457+
if (-idx>n)
4458+
idx=n;
4459+
else
4460+
idx=n+idx;
4461+
}
44474462

4448-
if (idx >=n)
4449-
PG_RETURN_JSONB_P(in);
4463+
if (idx >=n)
4464+
PG_RETURN_JSONB_P(in);
4465+
}
44504466

44514467
pushJsonbValue(&state,r,NULL);
44524468

@@ -4463,6 +4479,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
44634479

44644480
Assert(res!=NULL);
44654481

4482+
if (idx<0&&-idx <=res->val.array.nElems)
4483+
{
4484+
idx=res->val.array.nElems+idx;
4485+
res->val.array.nElems--;
4486+
memmove(&res->val.array.elems[idx],
4487+
&res->val.array.elems[idx+1],
4488+
sizeof(JsonValue)* (res->val.array.nElems-idx));
4489+
}
4490+
44664491
PG_RETURN_JSONB_P(JsonbValueToJsonb(res));
44674492
}
44684493

@@ -4814,7 +4839,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
48144839
caseWJB_BEGIN_ARRAY:
48154840
(void)pushJsonbValue(st,r,NULL);
48164841
setPathArray(it,path_elems,path_nulls,path_len,st,level,
4817-
newval,v.val.array.nElems,op_type);
4842+
newval,v.val.array.nElems >=0 ?v.val.array.nElems :
4843+
JsonGetArraySize((*it)->container),op_type);
48184844
r=JsonbIteratorNext(it,&v, false);
48194845
Assert(r==WJB_END_ARRAY);
48204846
res=pushJsonbValue(st,r,NULL);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,11 @@ JsonbArraySize(JsonbValue *jb)
21582158
JsonbContainer*jbc=jb->val.binary.data;
21592159

21602160
if (JsonContainerIsArray(jbc)&& !JsonContainerIsScalar(jbc))
2161-
returnJsonContainerSize(jbc);
2161+
{
2162+
intsize=JsonContainerSize(jbc);
2163+
2164+
returnsize >=0 ?size :JsonGetArraySize(jbc);
2165+
}
21622166
}
21632167

21642168
return-1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp