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

Commitd9c6f23

Browse files
committed
Fixes and more query support.
1 parent314abc3 commitd9c6f23

File tree

1 file changed

+153
-30
lines changed

1 file changed

+153
-30
lines changed

‎jsonb_ops.c

Lines changed: 153 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ typedef struct ExtractedNode ExtractedNode;
5353
structExtractedNode
5454
{
5555
ExtractedNodeTypetype;
56+
boolindirect;
5657
union
5758
{
5859
struct
@@ -76,15 +77,19 @@ typedef struct
7677
{
7778
ExtractedNode*root;
7879
uint32hash;
80+
boollossy;
81+
boolinequality,leftInclusive,rightInclusive;
82+
GINKey*rightBound;
7983
}KeyExtra;
8084

8185
staticuint32get_bloom_value(uint32hash);
8286
staticuint32get_path_bloom(PathHashStack*stack);
8387
staticGINKey*make_gin_key(JsonbValue*v,uint32hash);
8488
staticGINKey*make_gin_query_key(char*jqBase,int32jqPos,int32type,uint32hash);
89+
staticGINKey*make_gin_query_key_minus_inf(uint32hash);
8590
staticint32compare_gin_key_value(GINKey*arg1,GINKey*arg2);
8691
staticintaddEntry(Entries*e,Datumkey,Pointerextra,boolpmatch);
87-
staticExtractedNode*recursiveExtract(char*jqBase,int32jqPos,uint32hash,Entries*e,boollossy);
92+
staticExtractedNode*recursiveExtract(char*jqBase,int32jqPos,uint32hash,Entries*e,boollossy,boolindirect);
8893

8994
PG_FUNCTION_INFO_V1(gin_compare_jsonb_bloom_value);
9095
PG_FUNCTION_INFO_V1(gin_compare_partial_jsonb_bloom_value);
@@ -127,13 +132,13 @@ addEntry(Entries *e, Datum key, Pointer extra, bool pmatch)
127132
}
128133

129134
staticExtractedNode*
130-
recursiveExtract(char*jqBase,int32jqPos,uint32hash,Entries*e,boollossy)
135+
recursiveExtract(char*jqBase,int32jqPos,uint32hash,Entries*e,boollossy,boolindirect)
131136
{
132-
int32type;
137+
int32type,childType;
133138
int32nextPos;
134139
int32left,right,arg;
135140
ExtractedNode*leftNode,*rightNode,*result;
136-
int32len;
141+
int32len,*arrayPos,nelems,i;
137142
KeyExtra*extra;
138143

139144
check_stack_depth();
@@ -146,8 +151,8 @@ recursiveExtract(char *jqBase, int32 jqPos, uint32 hash, Entries *e, bool lossy)
146151
read_int32(left,jqBase,jqPos);
147152
read_int32(right,jqBase,jqPos);
148153
Assert(nextPos==0);
149-
leftNode=recursiveExtract(jqBase,left,hash,e,lossy);
150-
rightNode=recursiveExtract(jqBase,right,hash,e,lossy);
154+
leftNode=recursiveExtract(jqBase,left,hash,e,lossy, false);
155+
rightNode=recursiveExtract(jqBase,right,hash,e,lossy, false);
151156
if (leftNode)
152157
{
153158
if (rightNode)
@@ -157,6 +162,7 @@ recursiveExtract(char *jqBase, int32 jqPos, uint32 hash, Entries *e, bool lossy)
157162
result->type=eAnd;
158163
elseif (type==jqiOr)
159164
result->type=eOr;
165+
result->indirect=indirect;
160166
result->args.items= (ExtractedNode**)palloc(2*sizeof(ExtractedNode*));
161167
result->args.items[0]=leftNode;
162168
result->args.items[1]=rightNode;
@@ -178,11 +184,12 @@ recursiveExtract(char *jqBase, int32 jqPos, uint32 hash, Entries *e, bool lossy)
178184
casejqiNot:
179185
read_int32(arg,jqBase,jqPos);
180186
Assert(nextPos==0);
181-
leftNode=recursiveExtract(jqBase,arg,hash,e,lossy);
187+
leftNode=recursiveExtract(jqBase,arg,hash,e,lossy, false);
182188
if (leftNode)
183189
{
184190
result= (ExtractedNode*)palloc(sizeof(ExtractedNode));
185191
result->type=eNot;
192+
result->indirect=indirect;
186193
result->args.items= (ExtractedNode**)palloc(sizeof(ExtractedNode*));
187194
result->args.items[0]=leftNode;
188195
result->args.count=1;
@@ -195,32 +202,88 @@ recursiveExtract(char *jqBase, int32 jqPos, uint32 hash, Entries *e, bool lossy)
195202
casejqiKey:
196203
read_int32(len,jqBase,jqPos);
197204
returnrecursiveExtract(jqBase,nextPos,
198-
hash |get_bloom_value(hash_any((unsignedchar*)jqBase+jqPos,len)),e,lossy);
205+
hash |get_bloom_value(hash_any((unsignedchar*)jqBase+jqPos,len)),e,lossy,indirect);
199206
casejqiAny:
200207
Assert(nextPos!=0);
201-
returnrecursiveExtract(jqBase,nextPos,hash,e, true);
208+
returnrecursiveExtract(jqBase,nextPos,hash,e, true, true);
202209
casejqiAnyArray:
203210
Assert(nextPos!=0);
204-
returnrecursiveExtract(jqBase,nextPos,hash,e,lossy);
211+
returnrecursiveExtract(jqBase,nextPos,hash,e,lossy, true);
205212
casejqiEqual:
206213
read_int32(arg,jqBase,jqPos);
207214
result= (ExtractedNode*)palloc(sizeof(ExtractedNode));
208-
extra= (KeyExtra*)palloc(sizeof(KeyExtra));
215+
extra= (KeyExtra*)palloc0(sizeof(KeyExtra));
209216
extra->hash=hash;
210217
result->type=eScalar;
211-
arg=readJsQueryHeader(jqBase,arg,&type,&nextPos);
218+
arg=readJsQueryHeader(jqBase,arg,&childType,&nextPos);
212219
result->entryNum=addEntry(e,
213-
PointerGetDatum(make_gin_query_key(jqBase,arg,type,lossy ?0 :hash)),
220+
PointerGetDatum(make_gin_query_key(jqBase,arg,childType,lossy ?0 :hash)),
214221
(Pointer)extra,lossy);
215222
returnresult;
216223
casejqiIn:
224+
casejqiOverlap:
225+
casejqiContains:
226+
read_int32(arg,jqBase,jqPos);
227+
arg=readJsQueryHeader(jqBase,arg,&childType,&nextPos);
228+
229+
read_int32(nelems,jqBase,arg);
230+
arrayPos= (int32*)(jqBase+arg);
231+
232+
extra= (KeyExtra*)palloc0(sizeof(KeyExtra));
233+
extra->hash=hash;
234+
result= (ExtractedNode*)palloc(sizeof(ExtractedNode));
235+
if (type==jqiContains)
236+
result->type=eAnd;
237+
else
238+
result->type=eOr;
239+
result->indirect=indirect;
240+
result->args.items= (ExtractedNode**)palloc(nelems*sizeof(ExtractedNode*));
241+
result->args.count=0;
242+
for (i=0;i<nelems;i++)
243+
{
244+
ExtractedNode*item;
245+
item= (ExtractedNode*)palloc(sizeof(ExtractedNode));
246+
item->indirect= false;
247+
item->type=eScalar;
248+
arg=readJsQueryHeader(jqBase,arrayPos[i],&childType,&nextPos);
249+
item->entryNum=addEntry(e,
250+
PointerGetDatum(make_gin_query_key(jqBase,arg,childType,lossy ?0 :hash)),
251+
(Pointer)extra,lossy);
252+
result->args.items[result->args.count]=item;
253+
result->args.count++;
254+
}
255+
returnresult;
217256
casejqiLess:
218257
casejqiGreater:
219258
casejqiLessOrEqual:
220259
casejqiGreaterOrEqual:
221-
casejqiContains:
260+
read_int32(arg,jqBase,jqPos);
261+
result= (ExtractedNode*)palloc(sizeof(ExtractedNode));
262+
extra= (KeyExtra*)palloc0(sizeof(KeyExtra));
263+
extra->hash=hash;
264+
extra->inequality= true;
265+
extra->lossy=lossy;
266+
result->type=eScalar;
267+
arg=readJsQueryHeader(jqBase,arg,&childType,&nextPos);
268+
if (type==jqiGreater||type==jqiGreaterOrEqual)
269+
{
270+
if (type==jqiGreaterOrEqual)
271+
extra->leftInclusive= true;
272+
result->entryNum=addEntry(e,
273+
PointerGetDatum(make_gin_query_key(jqBase,arg,childType,lossy ?0 :hash)),
274+
(Pointer)extra, true);
275+
}
276+
else
277+
{
278+
if (type==jqiLessOrEqual)
279+
extra->rightInclusive= true;
280+
result->entryNum=addEntry(e,
281+
PointerGetDatum(make_gin_query_key_minus_inf(lossy ?0 :hash)),
282+
(Pointer)extra, true);
283+
extra->rightBound=make_gin_query_key(jqBase,arg,childType,lossy ?0 :hash);
284+
}
285+
returnresult;
222286
casejqiContained:
223-
casejqiOverlap:
224287
returnNULL;
225288
default:
226289
elog(ERROR,"Wrong state: %d",type);
@@ -354,16 +417,27 @@ make_gin_query_key(char *jqBase, int32 jqPos, int32 type, uint32 hash)
354417
returnkey;
355418
}
356419

420+
staticGINKey*
421+
make_gin_query_key_minus_inf(uint32hash)
422+
{
423+
GINKey*key;
424+
425+
key= (GINKey*)palloc(GINKEYLEN);
426+
key->type=jbvNumeric |GINKeyTrue;
427+
SET_VARSIZE(key,GINKEYLEN);
428+
returnkey;
429+
}
430+
357431
staticint32
358432
compare_gin_key_value(GINKey*arg1,GINKey*arg2)
359433
{
360-
if (arg1->type!=arg2->type)
434+
if (GINKeyType(arg1)!=GINKeyType(arg2))
361435
{
362-
return (arg1->type>arg2->type) ?1 :-1;
436+
return (GINKeyType(arg1)>GINKeyType(arg2)) ?1 :-1;
363437
}
364438
else
365439
{
366-
switch(arg1->type)
440+
switch(GINKeyType(arg1))
367441
{
368442
casejbvNull:
369443
return0;
@@ -375,6 +449,18 @@ compare_gin_key_value(GINKey *arg1, GINKey *arg2)
375449
else
376450
return-1;
377451
casejbvNumeric:
452+
if (GINKeyIsTrue(arg1))
453+
{
454+
if (GINKeyIsTrue(arg2))
455+
return0;
456+
else
457+
return-1;
458+
}
459+
else
460+
{
461+
if (GINKeyIsTrue(arg2))
462+
return1;
463+
}
378464
returnDatumGetInt32(DirectFunctionCall2(numeric_cmp,
379465
PointerGetDatum(GINKeyDataNumeric(arg1)),
380466
PointerGetDatum(GINKeyDataNumeric(arg2))));
@@ -400,6 +486,8 @@ gin_compare_jsonb_bloom_value(PG_FUNCTION_ARGS)
400486
{
401487
result= (arg1->hash>arg2->hash) ?1 :-1;
402488
}
489+
PG_FREE_IF_COPY(arg1,0);
490+
PG_FREE_IF_COPY(arg2,1);
403491
PG_RETURN_INT32(result);
404492
}
405493

@@ -410,27 +498,58 @@ gin_compare_partial_jsonb_bloom_value(PG_FUNCTION_ARGS)
410498
GINKey*key= (GINKey*)PG_GETARG_VARLENA_P(1);
411499
StrategyNumberstrategy=PG_GETARG_UINT16(2);
412500
int32result;
413-
uint32bloom;
414501

415502
if (strategy==JsQueryMatchStrategyNumber)
416503
{
417-
GINKey*extra_data= (GINKey*)PG_GETARG_POINTER(3);
418-
bloom=extra_data->hash;
504+
KeyExtra*extra_data= (KeyExtra*)PG_GETARG_POINTER(3);
505+
506+
if (extra_data->inequality)
507+
{
508+
result=0;
509+
if (!extra_data->leftInclusive&&compare_gin_key_value(key,partial_key) <=0)
510+
{
511+
result=-1;
512+
}
513+
if (result==0&&extra_data->rightBound)
514+
{
515+
result=compare_gin_key_value(key,extra_data->rightBound);
516+
if ((extra_data->rightInclusive&&result <=0)||result<0)
517+
result=0;
518+
else
519+
result=1;
520+
}
521+
if (result==0)
522+
{
523+
if ((key->hash&extra_data->hash)!=extra_data->hash)
524+
result=-1;
525+
}
526+
}
527+
else
528+
{
529+
result=compare_gin_key_value(key,partial_key);
530+
if (result==0)
531+
{
532+
if ((key->hash&extra_data->hash)!=extra_data->hash)
533+
result=-1;
534+
}
535+
}
419536
}
420537
else
421538
{
422539
uint32*extra_data= (uint32*)PG_GETARG_POINTER(3);
423-
bloom=*extra_data;
424-
}
540+
uint32bloom=*extra_data;
425541

426-
result=compare_gin_key_value(key,partial_key);
542+
result=compare_gin_key_value(key,partial_key);
427543

428-
if (result==0)
429-
{
430-
if ((key->hash&bloom)!=bloom)
431-
result=-1;
544+
if (result==0)
545+
{
546+
if ((key->hash&bloom)!=bloom)
547+
result=-1;
548+
}
432549
}
433550

551+
PG_FREE_IF_COPY(partial_key,0);
552+
PG_FREE_IF_COPY(key,1);
434553
PG_RETURN_INT32(result);
435554
}
436555

@@ -563,7 +682,7 @@ gin_extract_jsonb_query_bloom_value(PG_FUNCTION_ARGS)
563682

564683
caseJsQueryMatchStrategyNumber:
565684
jq=PG_GETARG_JSQUERY(0);
566-
root=recursiveExtract(VARDATA(jq),0,0,&e, false);
685+
root=recursiveExtract(VARDATA(jq),0,0,&e, false, false);
567686

568687
*nentries=e.count;
569688
entries=e.entries;
@@ -741,9 +860,13 @@ gin_triconsistent_jsonb_bloom_value(PG_FUNCTION_ARGS)
741860

742861
caseJsQueryMatchStrategyNumber:
743862
if (nkeys==0)
744-
res=GIN_TRUE;
863+
res=GIN_MAYBE;
745864
else
746865
res=execRecursiveTristate(((KeyExtra*)extra_data[0])->root,check);
866+
867+
if (res==GIN_TRUE)
868+
res=GIN_MAYBE;
869+
747870
break;
748871

749872
default:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp