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

Commitfcf30ec

Browse files
author
Nikita Glukhov
committed
Extract jsonbFindKeyInObject(), jsonbFindValueInArray(), JsonbArrayIterator
1 parentc1b6a48 commitfcf30ec

File tree

1 file changed

+133
-85
lines changed

1 file changed

+133
-85
lines changed

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

Lines changed: 133 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,131 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
325325
returnres;
326326
}
327327

328+
staticJsonbValue*
329+
jsonbFindKeyInObject(constJsonbContainer*container,constJsonbValue*key)
330+
{
331+
/* Since this is an object, account for *Pairs* of Jentrys */
332+
constJEntry*children=container->children;
333+
intcount= (container->header&JB_CMASK);
334+
char*base_addr= (char*) (children+count*2);
335+
uint32stopLow=0,
336+
stopHigh=count;
337+
338+
/* Object key passed by caller must be a string */
339+
Assert(key->type==jbvString);
340+
341+
/* Binary search on object/pair keys *only* */
342+
while (stopLow<stopHigh)
343+
{
344+
uint32stopMiddle;
345+
intdifference;
346+
JsonbValuecandidate;
347+
348+
stopMiddle=stopLow+ (stopHigh-stopLow) /2;
349+
350+
candidate.type=jbvString;
351+
candidate.val.string.val=
352+
base_addr+getJsonbOffset(container,stopMiddle);
353+
candidate.val.string.len=getJsonbLength(container,stopMiddle);
354+
355+
difference=lengthCompareJsonbStringValue(&candidate,key);
356+
357+
if (difference==0)
358+
{
359+
/* Found our key, return corresponding value */
360+
JsonbValue*result=palloc(sizeof(JsonbValue));
361+
intindex=stopMiddle+count;
362+
363+
fillJsonbValue(container,index,base_addr,
364+
getJsonbOffset(container,index),
365+
result);
366+
367+
returnresult;
368+
}
369+
else
370+
{
371+
if (difference<0)
372+
stopLow=stopMiddle+1;
373+
else
374+
stopHigh=stopMiddle;
375+
}
376+
}
377+
378+
returnNULL;
379+
}
380+
381+
typedefstructJsonbArrayIterator
382+
{
383+
constJsonbContainer*container;
384+
char*base_addr;
385+
intindex;
386+
intcount;
387+
uint32offset;
388+
}JsonbArrayIterator;
389+
390+
staticvoid
391+
JsonbArrayIteratorInit(JsonbArrayIterator*it,constJsonbContainer*container)
392+
{
393+
it->container=container;
394+
it->index=0;
395+
it->count= (container->header&JB_CMASK);
396+
it->offset=0;
397+
it->base_addr= (char*) (container->children+it->count);
398+
}
399+
400+
staticbool
401+
JsonbArrayIteratorNext(JsonbArrayIterator*it,JsonbValue*result)
402+
{
403+
if (it->index >=it->count)
404+
return false;
405+
406+
fillJsonbValue(it->container,it->index,it->base_addr,it->offset,result);
407+
408+
JBE_ADVANCE_OFFSET(it->offset,it->container->children[it->index]);
409+
410+
it->index++;
411+
412+
return true;
413+
}
414+
415+
staticJsonbValue*
416+
JsonbArrayIteratorGetIth(JsonbArrayIterator*it,uint32i)
417+
{
418+
JsonbValue*result;
419+
420+
if (i >=it->count)
421+
returnNULL;
422+
423+
result=palloc(sizeof(JsonbValue));
424+
425+
fillJsonbValue(it->container,i,it->base_addr,
426+
getJsonbOffset(it->container,i),
427+
result);
428+
429+
returnresult;
430+
}
431+
432+
staticJsonbValue*
433+
jsonbFindValueInArray(constJsonbContainer*container,constJsonbValue*key)
434+
{
435+
JsonbArrayIteratorit;
436+
JsonbValue*result=palloc(sizeof(JsonbValue));
437+
438+
JsonbArrayIteratorInit(&it,container);
439+
440+
while (JsonbArrayIteratorNext(&it,result))
441+
{
442+
if (key->type==result->type)
443+
{
444+
if (equalsJsonbScalarValue(key,result))
445+
returnresult;
446+
}
447+
}
448+
449+
pfree(result);
450+
returnNULL;
451+
}
452+
328453
/*
329454
* Find value in object (i.e. the "value" part of some key/value pair in an
330455
* object), or find a matching element if we're looking through an array. Do
@@ -352,89 +477,24 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
352477
* return NULL. Otherwise, return palloc()'d copy of value.
353478
*/
354479
JsonbValue*
355-
findJsonbValueFromContainer(JsonbContainer*container,uint32flags,
480+
findJsonbValueFromContainer(constJsonbContainer*container,uint32flags,
356481
JsonbValue*key)
357482
{
358-
JEntry*children=container->children;
359483
intcount=JsonContainerSize(container);
360-
JsonbValue*result;
361484

362485
Assert((flags& ~(JB_FARRAY |JB_FOBJECT))==0);
363486

364487
/* Quick out without a palloc cycle if object/array is empty */
365488
if (count <=0)
366489
returnNULL;
367490

368-
result=palloc(sizeof(JsonbValue));
369-
370491
if ((flags&JB_FARRAY)&&JsonContainerIsArray(container))
371-
{
372-
char*base_addr= (char*) (children+count);
373-
uint32offset=0;
374-
inti;
375-
376-
for (i=0;i<count;i++)
377-
{
378-
fillJsonbValue(container,i,base_addr,offset,result);
379-
380-
if (key->type==result->type)
381-
{
382-
if (equalsJsonbScalarValue(key,result))
383-
returnresult;
384-
}
385-
386-
JBE_ADVANCE_OFFSET(offset,children[i]);
387-
}
388-
}
389-
elseif ((flags&JB_FOBJECT)&&JsonContainerIsObject(container))
390-
{
391-
/* Since this is an object, account for *Pairs* of Jentrys */
392-
char*base_addr= (char*) (children+count*2);
393-
uint32stopLow=0,
394-
stopHigh=count;
395-
396-
/* Object key passed by caller must be a string */
397-
Assert(key->type==jbvString);
398-
399-
/* Binary search on object/pair keys *only* */
400-
while (stopLow<stopHigh)
401-
{
402-
uint32stopMiddle;
403-
intdifference;
404-
JsonbValuecandidate;
405-
406-
stopMiddle=stopLow+ (stopHigh-stopLow) /2;
407-
408-
candidate.type=jbvString;
409-
candidate.val.string.val=
410-
base_addr+getJsonbOffset(container,stopMiddle);
411-
candidate.val.string.len=getJsonbLength(container,stopMiddle);
412-
413-
difference=lengthCompareJsonbStringValue(&candidate,key);
414-
415-
if (difference==0)
416-
{
417-
/* Found our key, return corresponding value */
418-
intindex=stopMiddle+count;
419-
420-
fillJsonbValue(container,index,base_addr,
421-
getJsonbOffset(container,index),
422-
result);
492+
returnjsonbFindValueInArray(container,key);
423493

424-
returnresult;
425-
}
426-
else
427-
{
428-
if (difference<0)
429-
stopLow=stopMiddle+1;
430-
else
431-
stopHigh=stopMiddle;
432-
}
433-
}
434-
}
494+
if ((flags&JB_FOBJECT)&&JsonContainerIsObject(container))
495+
returnjsonbFindKeyInObject(container,key);
435496

436497
/* Not found */
437-
pfree(result);
438498
returnNULL;
439499
}
440500

@@ -446,26 +506,14 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
446506
JsonbValue*
447507
getIthJsonbValueFromContainer(JsonbContainer*container,uint32i)
448508
{
449-
JsonbValue*result;
450-
char*base_addr;
451-
uint32nelements;
509+
JsonbArrayIteratorit;
452510

453511
if (!JsonContainerIsArray(container))
454512
elog(ERROR,"not a jsonb array");
455513

456-
nelements=JsonContainerSize(container);
457-
base_addr= (char*)&container->children[nelements];
514+
JsonbArrayIteratorInit(&it,container);
458515

459-
if (i >=nelements)
460-
returnNULL;
461-
462-
result=palloc(sizeof(JsonbValue));
463-
464-
fillJsonbValue(container,i,base_addr,
465-
getJsonbOffset(container,i),
466-
result);
467-
468-
returnresult;
516+
returnJsonbArrayIteratorGetIth(&it,i);
469517
}
470518

471519
/*
@@ -596,7 +644,7 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq,
596644
* Do the actual pushing, with only scalar or pseudo-scalar-array values
597645
* accepted.
598646
*/
599-
staticJsonbValue*
647+
JsonbValue*
600648
pushJsonbValueScalar(JsonbParseState**pstate,JsonbIteratorTokenseq,
601649
constJsonbValue*scalarVal)
602650
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp