Skip to content

Commit 178ec46

Browse files
committed
Fixes for multirange selectivity estimation
* Fix enumeration of the multirange operators in calc_multirangesel() and calc_multirangesel() switches. * Add more regression tests for matching to empty ranges/multiranges. Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/c5269c65-f967-77c5-ff7c-15e621c47f6a%40gmail.com Author: Alexander Korotkov Backpatch-through: 14, where multiranges were introduced
1 parent b71a9cb commit 178ec46

File tree

3 files changed

+272
-13
lines changed

3 files changed

+272
-13
lines changed

src/backend/utils/adt/multirangetypes_selfuncs.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -347,16 +347,15 @@ calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
347347
switch (operator)
348348
{
349349
/* these return false if either argument is empty */
350-
case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
351350
case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
352351
case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
353-
case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
354352
case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
355353
case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
356-
case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
357354
case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
358355
case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
356+
case OID_MULTIRANGE_LEFT_RANGE_OP:
359357
case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
358+
case OID_MULTIRANGE_RIGHT_RANGE_OP:
360359
case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
361360
/* nothing is less than an empty multirange */
362361
case OID_MULTIRANGE_LESS_OP:
@@ -367,7 +366,7 @@ calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
367366
* only empty multiranges can be contained by an empty
368367
* multirange
369368
*/
370-
case OID_MULTIRANGE_RANGE_CONTAINED_OP:
369+
case OID_RANGE_MULTIRANGE_CONTAINED_OP:
371370
case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
372371
/* only empty ranges are <= an empty multirange */
373372
case OID_MULTIRANGE_LESS_EQUAL_OP:
@@ -388,8 +387,18 @@ calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
388387
break;
389388

390389
/* an element cannot be empty */
391-
case OID_MULTIRANGE_ELEM_CONTAINED_OP:
392390
case OID_MULTIRANGE_CONTAINS_ELEM_OP:
391+
392+
/* filtered out by multirangesel() */
393+
case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
394+
case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
395+
case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
396+
case OID_RANGE_LEFT_MULTIRANGE_OP:
397+
case OID_RANGE_RIGHT_MULTIRANGE_OP:
398+
case OID_RANGE_CONTAINS_MULTIRANGE_OP:
399+
case OID_MULTIRANGE_ELEM_CONTAINED_OP:
400+
case OID_MULTIRANGE_RANGE_CONTAINED_OP:
401+
393402
default:
394403
elog(ERROR, "unexpected operator %u", operator);
395404
selec = 0.0; /* keep compiler quiet */
@@ -416,8 +425,7 @@ calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
416425
* calculations, realizing that the histogram covers only the
417426
* non-null, non-empty values.
418427
*/
419-
if (operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
420-
operator == OID_MULTIRANGE_RANGE_CONTAINED_OP ||
428+
if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
421429
operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP)
422430
{
423431
/* empty is contained by anything non-empty */
@@ -575,7 +583,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
575583
hist_lower, nhist, true);
576584
break;
577585

578-
case OID_RANGE_LEFT_MULTIRANGE_OP:
579586
case OID_MULTIRANGE_LEFT_RANGE_OP:
580587
case OID_MULTIRANGE_LEFT_MULTIRANGE_OP:
581588
/* var << const when upper(var) < lower(const) */
@@ -584,7 +591,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
584591
hist_upper, nhist, false);
585592
break;
586593

587-
case OID_RANGE_RIGHT_MULTIRANGE_OP:
588594
case OID_MULTIRANGE_RIGHT_RANGE_OP:
589595
case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP:
590596
/* var >> const when lower(var) > upper(const) */
@@ -593,7 +599,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
593599
hist_lower, nhist, true);
594600
break;
595601

596-
case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
597602
case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP:
598603
case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
599604
/* compare lower bounds */
@@ -602,7 +607,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
602607
hist_lower, nhist, false);
603608
break;
604609

605-
case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
606610
case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP:
607611
case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
608612
/* compare upper bounds */
@@ -611,7 +615,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
611615
hist_upper, nhist, true);
612616
break;
613617

614-
case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
615618
case OID_MULTIRANGE_OVERLAPS_RANGE_OP:
616619
case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP:
617620
case OID_MULTIRANGE_CONTAINS_ELEM_OP:
@@ -647,7 +650,6 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
647650
lslot.values, lslot.nvalues);
648651
break;
649652

650-
case OID_MULTIRANGE_RANGE_CONTAINED_OP:
651653
case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP:
652654
case OID_RANGE_MULTIRANGE_CONTAINED_OP:
653655
if (const_lower.infinite)
@@ -675,6 +677,16 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
675677
}
676678
break;
677679

680+
/* filtered out by multirangesel() */
681+
case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
682+
case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP:
683+
case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP:
684+
case OID_RANGE_LEFT_MULTIRANGE_OP:
685+
case OID_RANGE_RIGHT_MULTIRANGE_OP:
686+
case OID_RANGE_CONTAINS_MULTIRANGE_OP:
687+
case OID_MULTIRANGE_ELEM_CONTAINED_OP:
688+
case OID_MULTIRANGE_RANGE_CONTAINED_OP:
689+
678690
default:
679691
elog(ERROR, "unknown multirange operator %u", operator);
680692
hist_selec = -1.0; /* keep compiler quiet */

src/test/regress/expected/multirangetypes.out

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,12 +2241,114 @@ analyze test_multirange_gist;
22412241
SET enable_seqscan = t;
22422242
SET enable_indexscan = f;
22432243
SET enable_bitmapscan = f;
2244+
select count(*) from test_multirange_gist where mr = '{}'::int4multirange;
2245+
count
2246+
-------
2247+
500
2248+
(1 row)
2249+
22442250
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
22452251
count
22462252
-------
22472253
3700
22482254
(1 row)
22492255

2256+
select count(*) from test_multirange_gist where mr && 'empty'::int4range;
2257+
count
2258+
-------
2259+
0
2260+
(1 row)
2261+
2262+
select count(*) from test_multirange_gist where mr <@ 'empty'::int4range;
2263+
count
2264+
-------
2265+
500
2266+
(1 row)
2267+
2268+
select count(*) from test_multirange_gist where mr << 'empty'::int4range;
2269+
count
2270+
-------
2271+
0
2272+
(1 row)
2273+
2274+
select count(*) from test_multirange_gist where mr >> 'empty'::int4range;
2275+
count
2276+
-------
2277+
0
2278+
(1 row)
2279+
2280+
select count(*) from test_multirange_gist where mr &< 'empty'::int4range;
2281+
count
2282+
-------
2283+
0
2284+
(1 row)
2285+
2286+
select count(*) from test_multirange_gist where mr &> 'empty'::int4range;
2287+
count
2288+
-------
2289+
0
2290+
(1 row)
2291+
2292+
select count(*) from test_multirange_gist where mr -|- 'empty'::int4range;
2293+
count
2294+
-------
2295+
0
2296+
(1 row)
2297+
2298+
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
2299+
count
2300+
-------
2301+
3700
2302+
(1 row)
2303+
2304+
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
2305+
count
2306+
-------
2307+
3700
2308+
(1 row)
2309+
2310+
select count(*) from test_multirange_gist where mr && '{}'::int4multirange;
2311+
count
2312+
-------
2313+
0
2314+
(1 row)
2315+
2316+
select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange;
2317+
count
2318+
-------
2319+
500
2320+
(1 row)
2321+
2322+
select count(*) from test_multirange_gist where mr << '{}'::int4multirange;
2323+
count
2324+
-------
2325+
0
2326+
(1 row)
2327+
2328+
select count(*) from test_multirange_gist where mr >> '{}'::int4multirange;
2329+
count
2330+
-------
2331+
0
2332+
(1 row)
2333+
2334+
select count(*) from test_multirange_gist where mr &< '{}'::int4multirange;
2335+
count
2336+
-------
2337+
0
2338+
(1 row)
2339+
2340+
select count(*) from test_multirange_gist where mr &> '{}'::int4multirange;
2341+
count
2342+
-------
2343+
0
2344+
(1 row)
2345+
2346+
select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange;
2347+
count
2348+
-------
2349+
0
2350+
(1 row)
2351+
22502352
select count(*) from test_multirange_gist where mr = int4multirange(int4range(10,20), int4range(30,40), int4range(50,60));
22512353
count
22522354
-------
@@ -2365,6 +2467,114 @@ select count(*) from test_multirange_gist where mr -|- int4multirange(int4range(
23652467
SET enable_seqscan = f;
23662468
SET enable_indexscan = t;
23672469
SET enable_bitmapscan = f;
2470+
select count(*) from test_multirange_gist where mr = '{}'::int4multirange;
2471+
count
2472+
-------
2473+
500
2474+
(1 row)
2475+
2476+
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
2477+
count
2478+
-------
2479+
3700
2480+
(1 row)
2481+
2482+
select count(*) from test_multirange_gist where mr && 'empty'::int4range;
2483+
count
2484+
-------
2485+
0
2486+
(1 row)
2487+
2488+
select count(*) from test_multirange_gist where mr <@ 'empty'::int4range;
2489+
count
2490+
-------
2491+
500
2492+
(1 row)
2493+
2494+
select count(*) from test_multirange_gist where mr << 'empty'::int4range;
2495+
count
2496+
-------
2497+
0
2498+
(1 row)
2499+
2500+
select count(*) from test_multirange_gist where mr >> 'empty'::int4range;
2501+
count
2502+
-------
2503+
0
2504+
(1 row)
2505+
2506+
select count(*) from test_multirange_gist where mr &< 'empty'::int4range;
2507+
count
2508+
-------
2509+
0
2510+
(1 row)
2511+
2512+
select count(*) from test_multirange_gist where mr &> 'empty'::int4range;
2513+
count
2514+
-------
2515+
0
2516+
(1 row)
2517+
2518+
select count(*) from test_multirange_gist where mr -|- 'empty'::int4range;
2519+
count
2520+
-------
2521+
0
2522+
(1 row)
2523+
2524+
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
2525+
count
2526+
-------
2527+
3700
2528+
(1 row)
2529+
2530+
select count(*) from test_multirange_gist where mr @> '{}'::int4multirange;
2531+
count
2532+
-------
2533+
3700
2534+
(1 row)
2535+
2536+
select count(*) from test_multirange_gist where mr && '{}'::int4multirange;
2537+
count
2538+
-------
2539+
0
2540+
(1 row)
2541+
2542+
select count(*) from test_multirange_gist where mr <@ '{}'::int4multirange;
2543+
count
2544+
-------
2545+
500
2546+
(1 row)
2547+
2548+
select count(*) from test_multirange_gist where mr << '{}'::int4multirange;
2549+
count
2550+
-------
2551+
0
2552+
(1 row)
2553+
2554+
select count(*) from test_multirange_gist where mr >> '{}'::int4multirange;
2555+
count
2556+
-------
2557+
0
2558+
(1 row)
2559+
2560+
select count(*) from test_multirange_gist where mr &< '{}'::int4multirange;
2561+
count
2562+
-------
2563+
0
2564+
(1 row)
2565+
2566+
select count(*) from test_multirange_gist where mr &> '{}'::int4multirange;
2567+
count
2568+
-------
2569+
0
2570+
(1 row)
2571+
2572+
select count(*) from test_multirange_gist where mr -|- '{}'::int4multirange;
2573+
count
2574+
-------
2575+
0
2576+
(1 row)
2577+
23682578
select count(*) from test_multirange_gist where mr @> 'empty'::int4range;
23692579
count
23702580
-------

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy