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

Commitcddc819

Browse files
committed
Improve implementation of range-contains-element tests.
Implement these tests directly instead of constructing a singleton rangeand then applying range-contains. This saves a range serialize/deserializecycle as well as a couple of redundant bound-comparison steps, and addsvery little code on net.Remove elem_contained_by_range from the GiST opclass: it doesn't belongthere because there is no way to use it in an index clause (where theindexed column would have to be on the left). Its commutator is in theopclass, and that's what counts.
1 parentf1b4aa2 commitcddc819

File tree

5 files changed

+92
-84
lines changed

5 files changed

+92
-84
lines changed

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

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static char *range_deparse(char flags, const char *lbound_str,
6565
staticchar*range_bound_escape(constchar*value);
6666
staticboolrange_contains_internal(TypeCacheEntry*typcache,
6767
RangeType*r1,RangeType*r2);
68+
staticboolrange_contains_elem_internal(TypeCacheEntry*typcache,
69+
RangeType*r,Datumval);
6870
staticSizedatum_compute_size(Sizesz,Datumdatum,booltypbyval,
6971
chartypalign,int16typlen,chartypstorage);
7072
staticPointerdatum_write(Pointerptr,Datumdatum,booltypbyval,
@@ -555,36 +557,26 @@ range_upper_inf(PG_FUNCTION_ARGS)
555557
Datum
556558
range_contains_elem(PG_FUNCTION_ARGS)
557559
{
558-
RangeType*r1=PG_GETARG_RANGE(0);
560+
RangeType*r=PG_GETARG_RANGE(0);
559561
Datumval=PG_GETARG_DATUM(1);
560562
TypeCacheEntry*typcache;
561-
RangeType*r2;
562563

563-
typcache=range_get_typcache(fcinfo,RangeTypeGetOid(r1));
564-
565-
/* Construct a singleton range representing just "val" */
566-
r2=make_singleton_range(typcache,val);
564+
typcache=range_get_typcache(fcinfo,RangeTypeGetOid(r));
567565

568-
/* And use range_contains */
569-
PG_RETURN_BOOL(range_contains_internal(typcache,r1,r2));
566+
PG_RETURN_BOOL(range_contains_elem_internal(typcache,r,val));
570567
}
571568

572569
/* contained by? */
573570
Datum
574571
elem_contained_by_range(PG_FUNCTION_ARGS)
575572
{
576573
Datumval=PG_GETARG_DATUM(0);
577-
RangeType*r1=PG_GETARG_RANGE(1);
574+
RangeType*r=PG_GETARG_RANGE(1);
578575
TypeCacheEntry*typcache;
579-
RangeType*r2;
580-
581-
typcache=range_get_typcache(fcinfo,RangeTypeGetOid(r1));
582576

583-
/* Construct a singleton range representing just "val" */
584-
r2=make_singleton_range(typcache,val);
577+
typcache=range_get_typcache(fcinfo,RangeTypeGetOid(r));
585578

586-
/* And use range_contains */
587-
PG_RETURN_BOOL(range_contains_internal(typcache,r1,r2));
579+
PG_RETURN_BOOL(range_contains_elem_internal(typcache,r,val));
588580
}
589581

590582

@@ -2173,6 +2165,47 @@ range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
21732165
return true;
21742166
}
21752167

2168+
/*
2169+
* Test whether range r contains a specific element value.
2170+
*/
2171+
staticbool
2172+
range_contains_elem_internal(TypeCacheEntry*typcache,RangeType*r,Datumval)
2173+
{
2174+
RangeBoundlower;
2175+
RangeBoundupper;
2176+
boolempty;
2177+
int32cmp;
2178+
2179+
range_deserialize(typcache,r,&lower,&upper,&empty);
2180+
2181+
if (empty)
2182+
return false;
2183+
2184+
if (!lower.infinite)
2185+
{
2186+
cmp=DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
2187+
typcache->rng_collation,
2188+
lower.val,val));
2189+
if (cmp>0)
2190+
return false;
2191+
if (cmp==0&& !lower.inclusive)
2192+
return false;
2193+
}
2194+
2195+
if (!upper.infinite)
2196+
{
2197+
cmp=DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
2198+
typcache->rng_collation,
2199+
upper.val,val));
2200+
if (cmp<0)
2201+
return false;
2202+
if (cmp==0&& !upper.inclusive)
2203+
return false;
2204+
}
2205+
2206+
return true;
2207+
}
2208+
21762209

21772210
/*
21782211
* datum_compute_size() and datum_write() are used to insert the bound

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

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#defineRANGESTRAT_CONTAINS7
3232
#defineRANGESTRAT_CONTAINED_BY8
3333
#defineRANGESTRAT_CONTAINS_ELEM16
34-
#defineRANGESTRAT_ELEM_CONTAINED_BY17
3534
#defineRANGESTRAT_EQ18
3635
#defineRANGESTRAT_NE19
3736

@@ -48,11 +47,11 @@ typedef struct
4847
staticRangeType*range_super_union(TypeCacheEntry*typcache,RangeType*r1,
4948
RangeType*r2);
5049
staticboolrange_gist_consistent_int(FmgrInfo*flinfo,
51-
StrategyNumberstrategy,RangeType*key,
52-
RangeType*query);
50+
StrategyNumberstrategy,RangeType*key,
51+
Datumquery);
5352
staticboolrange_gist_consistent_leaf(FmgrInfo*flinfo,
54-
StrategyNumberstrategy,RangeType*key,
55-
RangeType*query);
53+
StrategyNumberstrategy,RangeType*key,
54+
Datumquery);
5655
staticintsort_item_cmp(constvoid*a,constvoid*b);
5756

5857

@@ -61,39 +60,15 @@ Datum
6160
range_gist_consistent(PG_FUNCTION_ARGS)
6261
{
6362
GISTENTRY*entry= (GISTENTRY*)PG_GETARG_POINTER(0);
64-
Datumdquery=PG_GETARG_DATUM(1);
63+
Datumquery=PG_GETARG_DATUM(1);
6564
StrategyNumberstrategy= (StrategyNumber)PG_GETARG_UINT16(2);
6665
/* Oid subtype = PG_GETARG_OID(3); */
6766
bool*recheck= (bool*)PG_GETARG_POINTER(4);
6867
RangeType*key=DatumGetRangeType(entry->key);
69-
TypeCacheEntry*typcache;
70-
RangeType*query;
7168

7269
/* All operators served by this function are exact */
7370
*recheck= false;
7471

75-
switch (strategy)
76-
{
77-
/*
78-
* For element contains and contained by operators, the other operand
79-
* is a "point" of the subtype. Construct a singleton range
80-
* containing just that value. (Since range_contains_elem and
81-
* elem_contained_by_range would do that anyway, it's actually more
82-
* efficient not less so to merge these cases into range containment
83-
* at this step. But revisit this if we ever change the implementation
84-
* of those functions.)
85-
*/
86-
caseRANGESTRAT_CONTAINS_ELEM:
87-
caseRANGESTRAT_ELEM_CONTAINED_BY:
88-
typcache=range_get_typcache(fcinfo,RangeTypeGetOid(key));
89-
query=make_singleton_range(typcache,dquery);
90-
break;
91-
92-
default:
93-
query=DatumGetRangeType(dquery);
94-
break;
95-
}
96-
9772
if (GIST_LEAF(entry))
9873
PG_RETURN_BOOL(range_gist_consistent_leaf(fcinfo->flinfo,strategy,
9974
key,query));
@@ -170,21 +145,23 @@ range_gist_penalty(PG_FUNCTION_ARGS)
170145

171146
subtype_diff=&typcache->rng_subdiff_finfo;
172147

173-
/* we want to compare the size of "orig" to size of "orig union new" */
148+
/*
149+
* We want to compare the size of "orig" to size of "orig union new".
150+
* The penalty will be the sum of the reduction in the lower bound plus
151+
* the increase in the upper bound.
152+
*/
174153
s_union=range_super_union(typcache,orig,new);
175154

176155
range_deserialize(typcache,orig,&lower1,&upper1,&empty1);
177156
range_deserialize(typcache,s_union,&lower2,&upper2,&empty2);
178157

179-
/* if orig isn't empty, s_union can't be either */
180-
Assert(empty1|| !empty2);
181-
158+
/* handle cases where orig is empty */
182159
if (empty1&&empty2)
183160
{
184161
*penalty=0;
185162
PG_RETURN_POINTER(penalty);
186163
}
187-
elseif (empty1&& !empty2)
164+
elseif (empty1)
188165
{
189166
if (lower2.infinite||upper2.infinite)
190167
{
@@ -199,6 +176,7 @@ range_gist_penalty(PG_FUNCTION_ARGS)
199176
typcache->rng_collation,
200177
upper2.val,
201178
lower2.val));
179+
/* upper2 must be >= lower2 */
202180
if (*penalty<0)
203181
*penalty=0;/* subtype_diff is broken */
204182
PG_RETURN_POINTER(penalty);
@@ -211,46 +189,53 @@ range_gist_penalty(PG_FUNCTION_ARGS)
211189
}
212190
}
213191

192+
/* if orig isn't empty, s_union can't be either */
193+
Assert(!empty2);
194+
195+
/* similarly, if orig's lower bound is infinite, s_union's must be too */
214196
Assert(lower2.infinite|| !lower1.infinite);
215197

216-
if (lower2.infinite&& !lower1.infinite)
217-
lower_diff=get_float8_infinity();
218-
elseif (lower2.infinite&&lower1.infinite)
198+
if (lower2.infinite&&lower1.infinite)
219199
lower_diff=0;
200+
elseif (lower2.infinite)
201+
lower_diff=get_float8_infinity();
220202
elseif (OidIsValid(subtype_diff->fn_oid))
221203
{
222204
lower_diff=DatumGetFloat8(FunctionCall2Coll(subtype_diff,
223205
typcache->rng_collation,
224206
lower1.val,
225207
lower2.val));
208+
/* orig's lower bound must be >= s_union's */
226209
if (lower_diff<0)
227210
lower_diff=0;/* subtype_diff is broken */
228211
}
229212
else
230213
{
231214
/* only know whether there is a difference or not */
232-
lower_diff=(float)range_cmp_bounds(typcache,&lower1,&lower2);
215+
lower_diff=range_cmp_bounds(typcache,&lower1,&lower2)>0 ?1 :0;
233216
}
234217

218+
/* similarly, if orig's upper bound is infinite, s_union's must be too */
235219
Assert(upper2.infinite|| !upper1.infinite);
236220

237-
if (upper2.infinite&& !upper1.infinite)
238-
upper_diff=get_float8_infinity();
239-
elseif (upper2.infinite&&upper1.infinite)
221+
if (upper2.infinite&&upper1.infinite)
240222
upper_diff=0;
223+
elseif (upper2.infinite)
224+
upper_diff=get_float8_infinity();
241225
elseif (OidIsValid(subtype_diff->fn_oid))
242226
{
243227
upper_diff=DatumGetFloat8(FunctionCall2Coll(subtype_diff,
244228
typcache->rng_collation,
245229
upper2.val,
246230
upper1.val));
231+
/* orig's upper bound must be <= s_union's */
247232
if (upper_diff<0)
248233
upper_diff=0;/* subtype_diff is broken */
249234
}
250235
else
251236
{
252237
/* only know whether there is a difference or not */
253-
upper_diff=(float)range_cmp_bounds(typcache,&upper2,&upper1);
238+
upper_diff=range_cmp_bounds(typcache,&upper2,&upper1)>0 ?1 :0;
254239
}
255240

256241
Assert(lower_diff >=0&&upper_diff >=0);
@@ -450,7 +435,7 @@ TrickFunctionCall2(PGFunction proc, FmgrInfo *flinfo, Datum arg1, Datum arg2)
450435
*/
451436
staticbool
452437
range_gist_consistent_int(FmgrInfo*flinfo,StrategyNumberstrategy,
453-
RangeType*key,RangeType*query)
438+
RangeType*key,Datumquery)
454439
{
455440
PGFunctionproc;
456441
boolnegate= false;
@@ -486,22 +471,23 @@ range_gist_consistent_int(FmgrInfo *flinfo, StrategyNumber strategy,
486471
negate= true;
487472
break;
488473
caseRANGESTRAT_ADJACENT:
489-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
474+
if (RangeIsEmpty(key)||RangeIsEmpty(DatumGetRangeType(query)))
490475
return false;
491476
if (DatumGetBool(TrickFunctionCall2(range_adjacent,flinfo,
492477
RangeTypeGetDatum(key),
493-
RangeTypeGetDatum(query))))
478+
query)))
494479
return true;
495480
proc=range_overlaps;
496481
break;
497482
caseRANGESTRAT_CONTAINS:
498-
caseRANGESTRAT_CONTAINS_ELEM:
499483
proc=range_contains;
500484
break;
501485
caseRANGESTRAT_CONTAINED_BY:
502-
caseRANGESTRAT_ELEM_CONTAINED_BY:
503486
return true;
504487
break;
488+
caseRANGESTRAT_CONTAINS_ELEM:
489+
proc=range_contains_elem;
490+
break;
505491
caseRANGESTRAT_EQ:
506492
proc=range_contains;
507493
break;
@@ -516,7 +502,7 @@ range_gist_consistent_int(FmgrInfo *flinfo, StrategyNumber strategy,
516502

517503
retval=DatumGetBool(TrickFunctionCall2(proc,flinfo,
518504
RangeTypeGetDatum(key),
519-
RangeTypeGetDatum(query)));
505+
query));
520506
if (negate)
521507
retval= !retval;
522508

@@ -528,48 +514,39 @@ range_gist_consistent_int(FmgrInfo *flinfo, StrategyNumber strategy,
528514
*/
529515
staticbool
530516
range_gist_consistent_leaf(FmgrInfo*flinfo,StrategyNumberstrategy,
531-
RangeType*key,RangeType*query)
517+
RangeType*key,Datumquery)
532518
{
533519
PGFunctionproc;
534520

535521
switch (strategy)
536522
{
537523
caseRANGESTRAT_BEFORE:
538-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
539-
return false;
540524
proc=range_before;
541525
break;
542526
caseRANGESTRAT_OVERLEFT:
543-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
544-
return false;
545527
proc=range_overleft;
546528
break;
547529
caseRANGESTRAT_OVERLAPS:
548530
proc=range_overlaps;
549531
break;
550532
caseRANGESTRAT_OVERRIGHT:
551-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
552-
return false;
553533
proc=range_overright;
554534
break;
555535
caseRANGESTRAT_AFTER:
556-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
557-
return false;
558536
proc=range_after;
559537
break;
560538
caseRANGESTRAT_ADJACENT:
561-
if (RangeIsEmpty(key)||RangeIsEmpty(query))
562-
return false;
563539
proc=range_adjacent;
564540
break;
565541
caseRANGESTRAT_CONTAINS:
566-
caseRANGESTRAT_CONTAINS_ELEM:
567542
proc=range_contains;
568543
break;
569544
caseRANGESTRAT_CONTAINED_BY:
570-
caseRANGESTRAT_ELEM_CONTAINED_BY:
571545
proc=range_contained_by;
572546
break;
547+
caseRANGESTRAT_CONTAINS_ELEM:
548+
proc=range_contains_elem;
549+
break;
573550
caseRANGESTRAT_EQ:
574551
proc=range_eq;
575552
break;
@@ -584,7 +561,7 @@ range_gist_consistent_leaf(FmgrInfo *flinfo, StrategyNumber strategy,
584561

585562
returnDatumGetBool(TrickFunctionCall2(proc,flinfo,
586563
RangeTypeGetDatum(key),
587-
RangeTypeGetDatum(query)));
564+
query));
588565
}
589566

590567
/*
@@ -649,7 +626,7 @@ sort_item_cmp(const void *a, const void *b)
649626
elseif (lower2.infinite)
650627
return1;
651628
elseif (upper1.infinite&&upper2.infinite)
652-
return-1*range_cmp_bounds(typcache,&lower1,&lower2);
629+
return-(range_cmp_bounds(typcache,&lower1,&lower2));
653630
elseif (upper1.infinite)
654631
return1;
655632
elseif (upper2.infinite)

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201111211
56+
#defineCATALOG_VERSION_NO201111221
5757

5858
#endif

‎src/include/catalog/pg_amop.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,6 @@ DATA(insert (3919 3831 3831 6 s3897 783 0 ));
735735
DATA(insert (3919383138317s38907830 ));
736736
DATA(insert (3919383138318s38927830 ));
737737
DATA(insert (39193831228316s38897830 ));
738-
DATA(insert (39192283383117s38917830 ));
739738
DATA(insert (39193831383118s38827830 ));
740739
DATA(insert (39193831383119s38837830 ));
741740

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp