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

Commit1e2c673

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

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
@@ -567,6 +567,8 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
567567
state=palloc(sizeof(OkeysState));
568568

569569
state->result_size=JB_ROOT_COUNT(jb);
570+
if (state->result_size<0)
571+
state->result_size=8;
570572
state->result_count=0;
571573
state->sent_count=0;
572574
state->result=palloc(state->result_size*sizeof(char*));
@@ -584,6 +586,12 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
584586
cstr=palloc(v.val.string.len+1*sizeof(char));
585587
memcpy(cstr,v.val.string.val,v.val.string.len);
586588
cstr[v.val.string.len]='\0';
589+
if (state->result_count >=state->result_size)
590+
{
591+
state->result_size *=2;
592+
state->result=repalloc(state->result,state->result_size*
593+
sizeof(char*));
594+
}
587595
state->result[state->result_count++]=cstr;
588596
}
589597
}
@@ -900,7 +908,9 @@ jsonb_array_element(PG_FUNCTION_ARGS)
900908
/* Handle negative subscript */
901909
if (element<0)
902910
{
903-
uint32nelements=JB_ROOT_COUNT(jb);
911+
intnelements=JB_ROOT_COUNT(jb);
912+
if (nelements<0)
913+
nelements=JsonGetArraySize(JsonRoot(jb));
904914

905915
if (-element>nelements)
906916
PG_RETURN_NULL();
@@ -944,6 +954,8 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
944954
if (element<0)
945955
{
946956
uint32nelements=JB_ROOT_COUNT(jb);
957+
if (nelements<0)
958+
nelements=JsonGetArraySize(JsonRoot(jb));
947959

948960
if (-element>nelements)
949961
PG_RETURN_NULL();
@@ -1827,7 +1839,8 @@ jsonb_array_length(PG_FUNCTION_ARGS)
18271839
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
18281840
errmsg("cannot get array length of a non-array")));
18291841

1830-
PG_RETURN_INT32(JB_ROOT_COUNT(jb));
1842+
PG_RETURN_INT32(JB_ROOT_COUNT(jb) >=0 ?JB_ROOT_COUNT(jb)
1843+
:JsonGetArraySize(JsonRoot(jb)));
18311844
}
18321845

18331846
/*
@@ -4536,16 +4549,19 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
45364549
Assert(r==WJB_BEGIN_ARRAY);
45374550
n=v.val.array.nElems;
45384551

4539-
if (idx<0)
4552+
if (v.val.array.nElems >=0)
45404553
{
4541-
if (-idx>n)
4542-
idx=n;
4543-
else
4544-
idx=n+idx;
4545-
}
4554+
if (idx<0)
4555+
{
4556+
if (-idx>n)
4557+
idx=n;
4558+
else
4559+
idx=n+idx;
4560+
}
45464561

4547-
if (idx >=n)
4548-
PG_RETURN_JSONB_P(in);
4562+
if (idx >=n)
4563+
PG_RETURN_JSONB_P(in);
4564+
}
45494565

45504566
pushJsonbValue(&state,r,NULL);
45514567

@@ -4562,6 +4578,15 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
45624578

45634579
Assert(res!=NULL);
45644580

4581+
if (idx<0&&-idx <=res->val.array.nElems)
4582+
{
4583+
idx=res->val.array.nElems+idx;
4584+
res->val.array.nElems--;
4585+
memmove(&res->val.array.elems[idx],
4586+
&res->val.array.elems[idx+1],
4587+
sizeof(JsonValue)* (res->val.array.nElems-idx));
4588+
}
4589+
45654590
PG_RETURN_JSONB_P(JsonbValueToJsonb(res));
45664591
}
45674592

@@ -4946,7 +4971,8 @@ setPath(JsonbIterator **it, Datum *path_elems,
49464971

49474972
(void)pushJsonbValue(st,r,NULL);
49484973
setPathArray(it,path_elems,path_nulls,path_len,st,level,
4949-
newval,v.val.array.nElems,op_type);
4974+
newval,v.val.array.nElems >=0 ?v.val.array.nElems :
4975+
JsonGetArraySize((*it)->container),op_type);
49504976
r=JsonbIteratorNext(it,&v, false);
49514977
Assert(r==WJB_END_ARRAY);
49524978
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