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

Commit364ddc3

Browse files
committed
Clean up jsonb code.
The main target of this cleanup is the convertJsonb() function, but I alsotouched a lot of other things that I spotted into in the process.The new convertToJsonb() function uses an output buffer that's resized ondemand, so the code to estimate of the size of JsonbValue is removed.The on-disk format was not changed, even though I refactored the structsused to handle it. The term "superheader" is replaced with "container".The jsonb_exists_any and jsonb_exists_all functions no longer sort the inputarray. That was a premature optimization, the idea being that if there areduplicates in the input array, you only need to check them once. Also,sorting the array saves some effort in the binary search used to find a keywithin an object. But there were drawbacks too: the sorting anddeduplicating obviously isn't free, and in the typical case there are noduplicates to remove, and the gain in the binary search was minimal. Removeall that, which makes the code simpler too.This includes a bug-fix; the total length of the elements in a jsonb arrayor object mustn't exceed 2^28. That is now checked.
1 parent4d155d8 commit364ddc3

File tree

6 files changed

+556
-776
lines changed

6 files changed

+556
-776
lines changed

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ static void jsonb_in_array_end(void *pstate);
3333
staticvoidjsonb_in_object_field_start(void*pstate,char*fname,boolisnull);
3434
staticvoidjsonb_put_escaped_value(StringInfoout,JsonbValue*scalarVal);
3535
staticvoidjsonb_in_scalar(void*pstate,char*token,JsonTokenTypetokentype);
36-
char*JsonbToCString(StringInfoout,char*in,intestimated_len);
3736

3837
/*
3938
* jsonb type input function
@@ -65,7 +64,7 @@ jsonb_recv(PG_FUNCTION_ARGS)
6564
if (version==1)
6665
str=pq_getmsgtext(buf,buf->len-buf->cursor,&nbytes);
6766
else
68-
elog(ERROR,"Unsupported jsonb version number %d",version);
67+
elog(ERROR,"unsupported jsonb version number %d",version);
6968

7069
returnjsonb_from_cstring(str,nbytes);
7170
}
@@ -79,7 +78,7 @@ jsonb_out(PG_FUNCTION_ARGS)
7978
Jsonb*jb=PG_GETARG_JSONB(0);
8079
char*out;
8180

82-
out=JsonbToCString(NULL,VARDATA(jb),VARSIZE(jb));
81+
out=JsonbToCString(NULL,&jb->root,VARSIZE(jb));
8382

8483
PG_RETURN_CSTRING(out);
8584
}
@@ -97,7 +96,7 @@ jsonb_send(PG_FUNCTION_ARGS)
9796
StringInfojtext=makeStringInfo();
9897
intversion=1;
9998

100-
(void)JsonbToCString(jtext,VARDATA(jb),VARSIZE(jb));
99+
(void)JsonbToCString(jtext,&jb->root,VARSIZE(jb));
101100

102101
pq_begintypsend(&buf);
103102
pq_sendint(&buf,version,1);
@@ -130,7 +129,7 @@ jsonb_typeof(PG_FUNCTION_ARGS)
130129
{
131130
Assert(JB_ROOT_IS_SCALAR(in));
132131

133-
it=JsonbIteratorInit(VARDATA_ANY(in));
132+
it=JsonbIteratorInit(&in->root);
134133

135134
/*
136135
* A root scalar is stored as an array of one element, so we get the
@@ -249,7 +248,6 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
249248
v.type=jbvString;
250249
v.val.string.len=checkStringLen(strlen(fname));
251250
v.val.string.val=pnstrdup(fname,v.val.string.len);
252-
v.estSize=sizeof(JEntry)+v.val.string.len;
253251

254252
_state->res=pushJsonbValue(&_state->parseState,WJB_KEY,&v);
255253
}
@@ -290,8 +288,6 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
290288
JsonbInState*_state= (JsonbInState*)pstate;
291289
JsonbValuev;
292290

293-
v.estSize=sizeof(JEntry);
294-
295291
switch (tokentype)
296292
{
297293

@@ -300,7 +296,6 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
300296
v.type=jbvString;
301297
v.val.string.len=checkStringLen(strlen(token));
302298
v.val.string.val=pnstrdup(token,v.val.string.len);
303-
v.estSize+=v.val.string.len;
304299
break;
305300
caseJSON_TOKEN_NUMBER:
306301

@@ -312,7 +307,6 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
312307
v.type=jbvNumeric;
313308
v.val.numeric=DatumGetNumeric(DirectFunctionCall3(numeric_in,CStringGetDatum(token),0,-1));
314309

315-
v.estSize+=VARSIZE_ANY(v.val.numeric)+sizeof(JEntry)/* alignment */ ;
316310
break;
317311
caseJSON_TOKEN_TRUE:
318312
v.type=jbvBool;
@@ -374,7 +368,7 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
374368
* if they are converting it to a text* object.
375369
*/
376370
char*
377-
JsonbToCString(StringInfoout,JsonbSuperHeaderin,intestimated_len)
371+
JsonbToCString(StringInfoout,JsonbContainer*in,intestimated_len)
378372
{
379373
boolfirst= true;
380374
JsonbIterator*it;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ gin_extract_jsonb(PG_FUNCTION_ARGS)
8080

8181
entries= (Datum*)palloc(sizeof(Datum)*total);
8282

83-
it=JsonbIteratorInit(VARDATA(jb));
83+
it=JsonbIteratorInit(&jb->root);
8484

8585
while ((r=JsonbIteratorNext(&it,&v, false))!=WJB_DONE)
8686
{
@@ -487,7 +487,7 @@ gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
487487

488488
entries= (Datum*)palloc(sizeof(Datum)*total);
489489

490-
it=JsonbIteratorInit(VARDATA(jb));
490+
it=JsonbIteratorInit(&jb->root);
491491

492492
tail.parent=NULL;
493493
tail.hash=0;

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

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*/
1414
#include"postgres.h"
1515

16+
#include"catalog/pg_type.h"
1617
#include"miscadmin.h"
1718
#include"utils/jsonb.h"
1819

@@ -34,10 +35,9 @@ jsonb_exists(PG_FUNCTION_ARGS)
3435
kval.val.string.val=VARDATA_ANY(key);
3536
kval.val.string.len=VARSIZE_ANY_EXHDR(key);
3637

37-
v=findJsonbValueFromSuperHeader(VARDATA(jb),
38-
JB_FOBJECT |JB_FARRAY,
39-
NULL,
40-
&kval);
38+
v=findJsonbValueFromContainer(&jb->root,
39+
JB_FOBJECT |JB_FARRAY,
40+
&kval);
4141

4242
PG_RETURN_BOOL(v!=NULL);
4343
}
@@ -47,29 +47,28 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
4747
{
4848
Jsonb*jb=PG_GETARG_JSONB(0);
4949
ArrayType*keys=PG_GETARG_ARRAYTYPE_P(1);
50-
JsonbValue*arrKey=arrayToJsonbSortedArray(keys);
51-
uint32*plowbound=NULL,
52-
lowbound=0;
5350
inti;
51+
Datum*key_datums;
52+
bool*key_nulls;
53+
intelem_count;
5454

55-
if (arrKey==NULL||arrKey->val.object.nPairs==0)
56-
PG_RETURN_BOOL(false);
57-
58-
if (JB_ROOT_IS_OBJECT(jb))
59-
plowbound=&lowbound;
55+
deconstruct_array(keys,TEXTOID,-1, false,'i',&key_datums,&key_nulls,
56+
&elem_count);
6057

61-
/*
62-
* We exploit the fact that the pairs list is already sorted into strictly
63-
* increasing order to narrow the findJsonbValueFromSuperHeader search;
64-
* each search can start one entry past the previous "found" entry, or at
65-
* the lower bound of the last search.
66-
*/
67-
for (i=0;i<arrKey->val.array.nElems;i++)
58+
for (i=0;i<elem_count;i++)
6859
{
69-
if (findJsonbValueFromSuperHeader(VARDATA(jb),
70-
JB_FOBJECT |JB_FARRAY,
71-
plowbound,
72-
arrKey->val.array.elems+i)!=NULL)
60+
JsonbValuestrVal;
61+
62+
if (key_nulls[i])
63+
continue;
64+
65+
strVal.type=jbvString;
66+
strVal.val.string.val=VARDATA(key_datums[i]);
67+
strVal.val.string.len=VARSIZE(key_datums[i])-VARHDRSZ;
68+
69+
if (findJsonbValueFromContainer(&jb->root,
70+
JB_FOBJECT |JB_FARRAY,
71+
&strVal)!=NULL)
7372
PG_RETURN_BOOL(true);
7473
}
7574

@@ -81,29 +80,28 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
8180
{
8281
Jsonb*jb=PG_GETARG_JSONB(0);
8382
ArrayType*keys=PG_GETARG_ARRAYTYPE_P(1);
84-
JsonbValue*arrKey=arrayToJsonbSortedArray(keys);
85-
uint32*plowbound=NULL;
86-
uint32lowbound=0;
8783
inti;
84+
Datum*key_datums;
85+
bool*key_nulls;
86+
intelem_count;
8887

89-
if (arrKey==NULL||arrKey->val.array.nElems==0)
90-
PG_RETURN_BOOL(true);
88+
deconstruct_array(keys,TEXTOID,-1, false,'i',&key_datums,&key_nulls,
89+
&elem_count);
9190

92-
if (JB_ROOT_IS_OBJECT(jb))
93-
plowbound=&lowbound;
94-
95-
/*
96-
* We exploit the fact that the pairs list is already sorted into strictly
97-
* increasing order to narrow the findJsonbValueFromSuperHeader search;
98-
* each search can start one entry past the previous "found" entry, or at
99-
* the lower bound of the last search.
100-
*/
101-
for (i=0;i<arrKey->val.array.nElems;i++)
91+
for (i=0;i<elem_count;i++)
10292
{
103-
if (findJsonbValueFromSuperHeader(VARDATA(jb),
104-
JB_FOBJECT |JB_FARRAY,
105-
plowbound,
106-
arrKey->val.array.elems+i)==NULL)
93+
JsonbValuestrVal;
94+
95+
if (key_nulls[i])
96+
continue;
97+
98+
strVal.type=jbvString;
99+
strVal.val.string.val=VARDATA(key_datums[i]);
100+
strVal.val.string.len=VARSIZE(key_datums[i])-VARHDRSZ;
101+
102+
if (findJsonbValueFromContainer(&jb->root,
103+
JB_FOBJECT |JB_FARRAY,
104+
&strVal)==NULL)
107105
PG_RETURN_BOOL(false);
108106
}
109107

@@ -123,8 +121,8 @@ jsonb_contains(PG_FUNCTION_ARGS)
123121
JB_ROOT_IS_OBJECT(val)!=JB_ROOT_IS_OBJECT(tmpl))
124122
PG_RETURN_BOOL(false);
125123

126-
it1=JsonbIteratorInit(VARDATA(val));
127-
it2=JsonbIteratorInit(VARDATA(tmpl));
124+
it1=JsonbIteratorInit(&val->root);
125+
it2=JsonbIteratorInit(&tmpl->root);
128126

129127
PG_RETURN_BOOL(JsonbDeepContains(&it1,&it2));
130128
}
@@ -143,8 +141,8 @@ jsonb_contained(PG_FUNCTION_ARGS)
143141
JB_ROOT_IS_OBJECT(val)!=JB_ROOT_IS_OBJECT(tmpl))
144142
PG_RETURN_BOOL(false);
145143

146-
it1=JsonbIteratorInit(VARDATA(val));
147-
it2=JsonbIteratorInit(VARDATA(tmpl));
144+
it1=JsonbIteratorInit(&val->root);
145+
it2=JsonbIteratorInit(&tmpl->root);
148146

149147
PG_RETURN_BOOL(JsonbDeepContains(&it1,&it2));
150148
}
@@ -156,7 +154,7 @@ jsonb_ne(PG_FUNCTION_ARGS)
156154
Jsonb*jbb=PG_GETARG_JSONB(1);
157155
boolres;
158156

159-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb))!=0);
157+
res= (compareJsonbContainers(&jba->root,&jbb->root)!=0);
160158

161159
PG_FREE_IF_COPY(jba,0);
162160
PG_FREE_IF_COPY(jbb,1);
@@ -173,7 +171,7 @@ jsonb_lt(PG_FUNCTION_ARGS)
173171
Jsonb*jbb=PG_GETARG_JSONB(1);
174172
boolres;
175173

176-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb))<0);
174+
res= (compareJsonbContainers(&jba->root,&jbb->root)<0);
177175

178176
PG_FREE_IF_COPY(jba,0);
179177
PG_FREE_IF_COPY(jbb,1);
@@ -187,7 +185,7 @@ jsonb_gt(PG_FUNCTION_ARGS)
187185
Jsonb*jbb=PG_GETARG_JSONB(1);
188186
boolres;
189187

190-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb))>0);
188+
res= (compareJsonbContainers(&jba->root,&jbb->root)>0);
191189

192190
PG_FREE_IF_COPY(jba,0);
193191
PG_FREE_IF_COPY(jbb,1);
@@ -201,7 +199,7 @@ jsonb_le(PG_FUNCTION_ARGS)
201199
Jsonb*jbb=PG_GETARG_JSONB(1);
202200
boolres;
203201

204-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb)) <=0);
202+
res= (compareJsonbContainers(&jba->root,&jbb->root) <=0);
205203

206204
PG_FREE_IF_COPY(jba,0);
207205
PG_FREE_IF_COPY(jbb,1);
@@ -215,7 +213,7 @@ jsonb_ge(PG_FUNCTION_ARGS)
215213
Jsonb*jbb=PG_GETARG_JSONB(1);
216214
boolres;
217215

218-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb)) >=0);
216+
res= (compareJsonbContainers(&jba->root,&jbb->root) >=0);
219217

220218
PG_FREE_IF_COPY(jba,0);
221219
PG_FREE_IF_COPY(jbb,1);
@@ -229,7 +227,7 @@ jsonb_eq(PG_FUNCTION_ARGS)
229227
Jsonb*jbb=PG_GETARG_JSONB(1);
230228
boolres;
231229

232-
res= (compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb))==0);
230+
res= (compareJsonbContainers(&jba->root,&jbb->root)==0);
233231

234232
PG_FREE_IF_COPY(jba,0);
235233
PG_FREE_IF_COPY(jbb,1);
@@ -243,7 +241,7 @@ jsonb_cmp(PG_FUNCTION_ARGS)
243241
Jsonb*jbb=PG_GETARG_JSONB(1);
244242
intres;
245243

246-
res=compareJsonbSuperHeaderValue(VARDATA(jba),VARDATA(jbb));
244+
res=compareJsonbContainers(&jba->root,&jbb->root);
247245

248246
PG_FREE_IF_COPY(jba,0);
249247
PG_FREE_IF_COPY(jbb,1);
@@ -265,7 +263,7 @@ jsonb_hash(PG_FUNCTION_ARGS)
265263
if (JB_ROOT_COUNT(jb)==0)
266264
PG_RETURN_INT32(0);
267265

268-
it=JsonbIteratorInit(VARDATA(jb));
266+
it=JsonbIteratorInit(&jb->root);
269267

270268
while ((r=JsonbIteratorNext(&it,&v, false))!=WJB_DONE)
271269
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp