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

Commitbf4f96b

Browse files
committed
Fix range_cmp_bounds for the case of equal-valued exclusive bounds.
Also improve its comments and related regression tests.Jeff Davis, with some further adjustments by Tom
1 parentef27c81 commitbf4f96b

File tree

3 files changed

+126
-26
lines changed

3 files changed

+126
-26
lines changed

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

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,33 +1622,89 @@ make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper,
16221622
returnrange;
16231623
}
16241624

1625+
/*
1626+
* Compare two range boundary points, returning <0, 0, or >0 according to
1627+
* whether b1 is less than, equal to, or greater than b2.
1628+
*
1629+
* The boundaries can be any combination of upper and lower; so it's useful
1630+
* for a variety of operators.
1631+
*
1632+
* The simple case is when b1 and b2 are both finite and inclusive, in which
1633+
* case the result is just a comparison of the values held in b1 and b2.
1634+
*
1635+
* If a bound is exclusive, then we need to know whether it's a lower bound,
1636+
* in which case we treat the boundary point as "just greater than" the held
1637+
* value; or an upper bound, in which case we treat the boundary point as
1638+
* "just less than" the held value.
1639+
*
1640+
* If a bound is infinite, it represents minus infinity (less than every other
1641+
* point) if it's a lower bound; or plus infinity (greater than every other
1642+
* point) if it's an upper bound.
1643+
*
1644+
* There is only one case where two boundaries compare equal but are not
1645+
* identical: when both bounds are inclusive and hold the same finite value,
1646+
* but one is an upper bound and the other a lower bound.
1647+
*/
16251648
int
16261649
range_cmp_bounds(TypeCacheEntry*typcache,RangeBound*b1,RangeBound*b2)
16271650
{
16281651
int32result;
16291652

1653+
/*
1654+
* First, handle cases involving infinity, which don't require invoking
1655+
* the comparison proc.
1656+
*/
16301657
if (b1->infinite&&b2->infinite)
16311658
{
1659+
/*
1660+
* Both are infinity, so they are equal unless one is lower and the
1661+
* other not.
1662+
*/
16321663
if (b1->lower==b2->lower)
16331664
return0;
16341665
else
1635-
return(b1->lower) ?-1 :1;
1666+
returnb1->lower ?-1 :1;
16361667
}
1637-
elseif (b1->infinite&& !b2->infinite)
1638-
return(b1->lower) ?-1 :1;
1639-
elseif (!b1->infinite&&b2->infinite)
1640-
return(b2->lower) ?1 :-1;
1668+
elseif (b1->infinite)
1669+
returnb1->lower ?-1 :1;
1670+
elseif (b2->infinite)
1671+
returnb2->lower ?1 :-1;
16411672

1673+
/*
1674+
* Both boundaries are finite, so compare the held values.
1675+
*/
16421676
result=DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo,
16431677
typcache->rng_collation,
16441678
b1->val,b2->val));
16451679

1680+
/*
1681+
* If the comparison is anything other than equal, we're done. If they
1682+
* compare equal though, we still have to consider whether the boundaries
1683+
* are inclusive or exclusive.
1684+
*/
16461685
if (result==0)
16471686
{
1648-
if (b1->inclusive&& !b2->inclusive)
1649-
return (b2->lower) ?-1 :1;
1650-
elseif (!b1->inclusive&&b2->inclusive)
1651-
return (b1->lower) ?1 :-1;
1687+
if (!b1->inclusive&& !b2->inclusive)
1688+
{
1689+
/* both are exclusive */
1690+
if (b1->lower==b2->lower)
1691+
return0;
1692+
else
1693+
returnb1->lower ?1 :-1;
1694+
}
1695+
elseif (!b1->inclusive)
1696+
returnb1->lower ?1 :-1;
1697+
elseif (!b2->inclusive)
1698+
returnb2->lower ?-1 :1;
1699+
else
1700+
{
1701+
/*
1702+
* Both are inclusive and the values held are equal, so they are
1703+
* equal regardless of whether they are upper or lower boundaries,
1704+
* or a mix.
1705+
*/
1706+
return0;
1707+
}
16521708
}
16531709

16541710
returnresult;

‎src/test/regress/expected/rangetypes.out

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ ERROR: malformed range literal: "(a,])"
4848
LINE 1: select '(a,])'::textrange;
4949
^
5050
DETAIL: Junk after right parenthesis or bracket.
51+
select '( , )'::textrange;
52+
ERROR: range lower bound must be less than or equal to range upper bound
53+
LINE 1: select '( , )'::textrange;
54+
^
55+
select '("","")'::textrange;
56+
ERROR: range lower bound must be less than or equal to range upper bound
57+
LINE 1: select '("","")'::textrange;
58+
^
59+
select '(",",",")'::textrange;
60+
ERROR: range lower bound must be less than or equal to range upper bound
61+
LINE 1: select '(",",",")'::textrange;
62+
^
63+
select '("\\","\\")'::textrange;
64+
ERROR: range lower bound must be less than or equal to range upper bound
65+
LINE 1: select '("\\","\\")'::textrange;
66+
^
67+
select '[a,a)'::textrange;
68+
ERROR: range lower bound must be less than or equal to range upper bound
69+
LINE 1: select '[a,a)'::textrange;
70+
^
71+
select '(a,a]'::textrange;
72+
ERROR: range lower bound must be less than or equal to range upper bound
73+
LINE 1: select '(a,a]'::textrange;
74+
^
5175
-- should succeed
5276
select ' empty '::textrange;
5377
textrange
@@ -91,35 +115,36 @@ select '[a,]'::textrange;
91115
[a,)
92116
(1 row)
93117

94-
select '( ,)'::textrange;
118+
select '(,)'::textrange;
95119
textrange
96120
-----------
97-
(" "," ")
121+
(,)
98122
(1 row)
99123

100-
select '("","")'::textrange;
124+
select '["",""]'::textrange;
101125
textrange
102126
-----------
103-
("","")
127+
["",""]
104128
(1 row)
105129

106-
select '["",""]'::textrange;
130+
select '[",",","]'::textrange;
107131
textrange
108132
-----------
109-
["",""]
133+
[",",","]
110134
(1 row)
111135

112-
select '(",",",")'::textrange;
136+
select '["\\","\\"]'::textrange;
137+
textrange
138+
-------------
139+
["\\","\\"]
140+
(1 row)
141+
142+
select '(\\,a)'::textrange;
113143
textrange
114144
-----------
115-
(",",",")
145+
("\\",a)
116146
(1 row)
117147

118-
select '("\\","\\")'::textrange
119-
select '(\\,a)'::textrange;
120-
ERROR: syntax error at or near "select"
121-
LINE 2: select '(\\,a)'::textrange;
122-
^
123148
select '((,z)'::textrange;
124149
textrange
125150
-----------
@@ -307,6 +332,18 @@ select numrange(1.0, 2.0) << numrange(3.0, 4.0);
307332
t
308333
(1 row)
309334

335+
select numrange(1.0, 3.0,'[]') << numrange(3.0, 4.0,'[]');
336+
?column?
337+
----------
338+
f
339+
(1 row)
340+
341+
select numrange(1.0, 3.0,'()') << numrange(3.0, 4.0,'()');
342+
?column?
343+
----------
344+
t
345+
(1 row)
346+
310347
select numrange(1.0, 2.0) >> numrange(3.0, 4.0);
311348
?column?
312349
----------

‎src/test/regress/sql/rangetypes.sql

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ select '(),a)'::textrange;
1515
select'(a,))'::textrange;
1616
select'(],a)'::textrange;
1717
select'(a,])'::textrange;
18+
select'( , )'::textrange;
19+
select'("","")'::textrange;
20+
select'(",",",")'::textrange;
21+
select'("\\","\\")'::textrange;
22+
select'[a,a)'::textrange;
23+
select'(a,a]'::textrange;
1824

1925
-- should succeed
2026
select' empty'::textrange;
@@ -24,11 +30,10 @@ select '(,z)'::textrange;
2430
select'(a,)'::textrange;
2531
select'[,z]'::textrange;
2632
select'[a,]'::textrange;
27-
select'( , )'::textrange;
28-
select'("","")'::textrange;
33+
select'(,)'::textrange;
2934
select'["",""]'::textrange;
30-
select'(",",",")'::textrange;
31-
select'("\\","\\")'::textrange
35+
select'[",",","]'::textrange;
36+
select'["\\","\\"]'::textrange;
3237
select'(\\,a)'::textrange;
3338
select'((,z)'::textrange;
3439
select'([,z)'::textrange;
@@ -81,6 +86,8 @@ select range_minus(numrange(10.1,12.2,'[]'), numrange(0.0,120.2,'(]'));
8186

8287
select numrange(4.5,5.5,'[]') && numrange(5.5,6.5);
8388
select numrange(1.0,2.0)<< numrange(3.0,4.0);
89+
select numrange(1.0,3.0,'[]')<< numrange(3.0,4.0,'[]');
90+
select numrange(1.0,3.0,'()')<< numrange(3.0,4.0,'()');
8491
select numrange(1.0,2.0)>> numrange(3.0,4.0);
8592
select numrange(3.0,70.0) &< numrange(6.6,100.0);
8693

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp