2000-01-05 07:06:23 +01:00
|
|
|
--
|
|
|
|
-- BOX
|
|
|
|
--
|
|
|
|
--
|
|
|
|
-- box logic
|
|
|
|
-- o
|
|
|
|
-- 3 o--|X
|
|
|
|
-- | o|
|
|
|
|
-- 2 +-+-+ |
|
|
|
|
-- | | | |
|
|
|
|
-- 1 | o-+-o
|
|
|
|
-- | |
|
|
|
|
-- 0 +---+
|
|
|
|
--
|
|
|
|
-- 0 1 2 3
|
|
|
|
--
|
|
|
|
-- boxes are specified by two points, given by four floats x1,y1,x2,y2
|
|
|
|
CREATE TABLE BOX_TBL (f1 box);
|
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)');
|
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)');
|
2018-09-26 10:45:21 +02:00
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))');
|
2010-11-23 21:27:50 +01:00
|
|
|
-- degenerate cases where the box is a line or a point
|
|
|
|
-- note that lines and points boxes all have zero area
|
2000-01-05 07:06:23 +01:00
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)');
|
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)');
|
2010-11-23 21:27:50 +01:00
|
|
|
-- badly formatted box inputs
|
2000-01-05 07:06:23 +01:00
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: invalid input syntax for type box: "(2.3, 4.5)"
|
2008-09-01 22:42:46 +02:00
|
|
|
LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)');
|
|
|
|
^
|
2018-09-26 10:45:21 +02:00
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)');
|
|
|
|
ERROR: invalid input syntax for type box: "[1, 2, 3, 4)"
|
|
|
|
LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)');
|
|
|
|
^
|
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]');
|
|
|
|
ERROR: invalid input syntax for type box: "(1, 2, 3, 4]"
|
|
|
|
LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]');
|
|
|
|
^
|
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x');
|
|
|
|
ERROR: invalid input syntax for type box: "(1, 2, 3, 4) x"
|
|
|
|
LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x');
|
|
|
|
^
|
2000-01-05 07:06:23 +01:00
|
|
|
INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
|
2003-09-25 08:58:07 +02:00
|
|
|
ERROR: invalid input syntax for type box: "asdfasdf(ad"
|
2008-09-01 22:42:46 +02:00
|
|
|
LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad');
|
|
|
|
^
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT * FROM BOX_TBL;
|
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(-2,2),(-8,-10)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
|
|
|
(3,3),(3,3)
|
2018-09-26 10:45:21 +02:00
|
|
|
(5 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.*, area(b.f1) as barea
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b;
|
2020-12-15 21:54:06 +01:00
|
|
|
f1 | barea
|
|
|
|
---------------------+-------
|
|
|
|
(2,2),(0,0) | 4
|
|
|
|
(3,3),(1,1) | 4
|
|
|
|
(-2,2),(-8,-10) | 72
|
|
|
|
(2.5,3.5),(2.5,2.5) | 0
|
|
|
|
(3,3),(3,3) | 0
|
2018-09-26 10:45:21 +02:00
|
|
|
(5 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- overlap
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
2010-11-23 21:27:50 +01:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 && box '(2.5,2.5,1.0,1.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
1997-04-05 13:06:04 +02:00
|
|
|
(3 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- left-or-overlap (x only)
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b1.*
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b1
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(-2,2),(-8,-10)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
2018-09-26 10:45:21 +02:00
|
|
|
(3 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- right-or-overlap (x only)
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b1.*
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b1
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
|
|
|
(3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(2 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- left of
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 << box '(3.0,3.0,5.0,5.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(-2,2),(-8,-10)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
2018-09-26 10:45:21 +02:00
|
|
|
(3 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- area <=
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
|
|
|
(3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(4 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- area <
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 < box '(3.0,3.0,5.0,5.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
|
|
|
(3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(2 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- area =
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 = box '(3.0,3.0,5.0,5.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
-------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
1997-04-05 13:06:04 +02:00
|
|
|
(2 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- area >
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
2010-11-23 21:27:50 +01:00
|
|
|
FROM BOX_TBL b -- zero area
|
|
|
|
WHERE b.f1 > box '(3.5,3.0,4.5,3.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
-----------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(-2,2),(-8,-10)
|
2018-09-26 10:45:21 +02:00
|
|
|
(3 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- area >=
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
2010-11-23 21:27:50 +01:00
|
|
|
FROM BOX_TBL b -- zero area
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(-2,2),(-8,-10)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
|
|
|
(3,3),(3,3)
|
2018-09-26 10:45:21 +02:00
|
|
|
(5 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- right of
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1;
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
---------------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(-2,2),(-8,-10)
|
|
|
|
(2.5,3.5),(2.5,2.5)
|
2018-09-26 10:45:21 +02:00
|
|
|
(3 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- contained in
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2006-09-10 02:29:35 +02:00
|
|
|
WHERE b.f1 <@ box '(0,0,3,3)';
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
-------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(3 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- contains
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2006-09-10 02:29:35 +02:00
|
|
|
WHERE box '(0,0,3,3)' @> b.f1;
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
-------------
|
|
|
|
(2,2),(0,0)
|
|
|
|
(3,3),(1,1)
|
|
|
|
(3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(3 rows)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- box equality
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b.f1
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b
|
2000-01-05 07:06:23 +01:00
|
|
|
WHERE box '(1,1,3,3)' ~= b.f1;
|
2020-12-15 21:54:06 +01:00
|
|
|
f1
|
|
|
|
-------------
|
|
|
|
(3,3),(1,1)
|
1997-04-05 13:06:04 +02:00
|
|
|
(1 row)
|
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- center of box, left unary operator
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT @@(b1.f1) AS p
|
1997-04-05 13:06:04 +02:00
|
|
|
FROM BOX_TBL b1;
|
2020-12-15 21:54:06 +01:00
|
|
|
p
|
|
|
|
---------
|
|
|
|
(1,1)
|
|
|
|
(2,2)
|
|
|
|
(-5,-4)
|
|
|
|
(2.5,3)
|
|
|
|
(3,3)
|
2018-09-26 10:45:21 +02:00
|
|
|
(5 rows)
|
1997-04-05 13:06:04 +02:00
|
|
|
|
2010-11-23 21:27:50 +01:00
|
|
|
-- wholly-contained
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT b1.*, b2.*
|
2010-11-23 21:27:50 +01:00
|
|
|
FROM BOX_TBL b1, BOX_TBL b2
|
2006-09-10 02:29:35 +02:00
|
|
|
WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1;
|
2020-12-15 21:54:06 +01:00
|
|
|
f1 | f1
|
|
|
|
-------------+-------------
|
|
|
|
(3,3),(1,1) | (3,3),(3,3)
|
1997-04-05 13:06:04 +02:00
|
|
|
(1 row)
|
|
|
|
|
2020-12-15 21:54:06 +01:00
|
|
|
SELECT height(f1), width(f1) FROM BOX_TBL;
|
|
|
|
height | width
|
|
|
|
--------+-------
|
|
|
|
2 | 2
|
|
|
|
2 | 2
|
|
|
|
12 | 6
|
|
|
|
1 | 0
|
|
|
|
0 | 0
|
2018-09-26 10:45:21 +02:00
|
|
|
(5 rows)
|
1997-05-11 17:42:09 +02:00
|
|
|
|
2016-03-30 17:42:36 +02:00
|
|
|
--
|
|
|
|
-- Test the SP-GiST index
|
|
|
|
--
|
|
|
|
CREATE TEMPORARY TABLE box_temp (f1 box);
|
|
|
|
INSERT INTO box_temp
|
|
|
|
SELECT box(point(i, i), point(i * 2, i * 2))
|
|
|
|
FROM generate_series(1, 50) AS i;
|
|
|
|
CREATE INDEX box_spgist ON box_temp USING spgist (f1);
|
|
|
|
INSERT INTO box_temp
|
|
|
|
VALUES (NULL),
|
2016-04-01 18:25:17 +02:00
|
|
|
('(0,0)(0,100)'),
|
2016-03-30 17:42:36 +02:00
|
|
|
('(-3,4.3333333333)(40,1)'),
|
|
|
|
('(0,100)(0,infinity)'),
|
|
|
|
('(-infinity,0)(0,infinity)'),
|
|
|
|
('(-infinity,-infinity)(infinity,infinity)');
|
|
|
|
SET enable_seqscan = false;
|
|
|
|
SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
----------------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(2,2),(1,1)
|
|
|
|
(4,4),(2,2)
|
|
|
|
(6,6),(3,3)
|
|
|
|
(8,8),(4,4)
|
2016-04-01 18:25:17 +02:00
|
|
|
(0,100),(0,0)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(0,Infinity),(0,100)
|
|
|
|
(0,Infinity),(-Infinity,0)
|
2016-03-30 17:42:36 +02:00
|
|
|
(7 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 << '(30,40),(10,20)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
----------------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(2,2),(1,1)
|
|
|
|
(4,4),(2,2)
|
|
|
|
(6,6),(3,3)
|
|
|
|
(8,8),(4,4)
|
|
|
|
(10,10),(5,5)
|
2016-04-01 18:25:17 +02:00
|
|
|
(0,100),(0,0)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(0,Infinity),(0,100)
|
|
|
|
(0,Infinity),(-Infinity,0)
|
2016-03-30 17:42:36 +02:00
|
|
|
(8 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 &< '(10,100),(5,4.333334)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
-------------------------------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(20,20),(10,10)
|
|
|
|
(22,22),(11,11)
|
|
|
|
(24,24),(12,12)
|
|
|
|
(26,26),(13,13)
|
|
|
|
(28,28),(14,14)
|
|
|
|
(30,30),(15,15)
|
|
|
|
(32,32),(16,16)
|
|
|
|
(34,34),(17,17)
|
|
|
|
(36,36),(18,18)
|
|
|
|
(38,38),(19,19)
|
|
|
|
(40,40),(20,20)
|
|
|
|
(42,42),(21,21)
|
|
|
|
(44,44),(22,22)
|
|
|
|
(46,46),(23,23)
|
|
|
|
(48,48),(24,24)
|
|
|
|
(50,50),(25,25)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(Infinity,Infinity),(-Infinity,-Infinity)
|
2016-03-30 17:42:36 +02:00
|
|
|
(17 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 && '(25,30),(15,20)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
|
|
|
|
f1
|
|
|
|
-------------------
|
|
|
|
(80,80),(40,40)
|
|
|
|
(82,82),(41,41)
|
|
|
|
(84,84),(42,42)
|
|
|
|
(86,86),(43,43)
|
|
|
|
(88,88),(44,44)
|
|
|
|
(90,90),(45,45)
|
|
|
|
(92,92),(46,46)
|
|
|
|
(94,94),(47,47)
|
|
|
|
(96,96),(48,48)
|
|
|
|
(98,98),(49,49)
|
|
|
|
(100,100),(50,50)
|
|
|
|
(11 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 &> '(45,50),(40,30)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
|
|
|
|
f1
|
|
|
|
-------------------
|
|
|
|
(82,82),(41,41)
|
|
|
|
(84,84),(42,42)
|
|
|
|
(86,86),(43,43)
|
|
|
|
(88,88),(44,44)
|
|
|
|
(90,90),(45,45)
|
|
|
|
(92,92),(46,46)
|
|
|
|
(94,94),(47,47)
|
|
|
|
(96,96),(48,48)
|
|
|
|
(98,98),(49,49)
|
|
|
|
(100,100),(50,50)
|
|
|
|
(10 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 >> '(40,40),(30,30)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
|
|
|
|
f1
|
|
|
|
--------------------------
|
|
|
|
(2,2),(1,1)
|
|
|
|
(4,4),(2,2)
|
|
|
|
(40,4.3333333333),(-3,1)
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 <<| '(10,100),(5,4.33334)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
|
|
|
|
f1
|
|
|
|
--------------------------
|
|
|
|
(2,2),(1,1)
|
|
|
|
(4,4),(2,2)
|
|
|
|
(40,4.3333333333),(-3,1)
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 &<| '(10,4.3333334),(5,1)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
----------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(100,100),(50,50)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(0,Infinity),(0,100)
|
2016-03-30 17:42:36 +02:00
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)';
|
|
|
|
QUERY PLAN
|
|
|
|
-----------------------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 |&> '(49.99,49.99),(49.99,49.99)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
----------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(82,82),(41,41)
|
|
|
|
(84,84),(42,42)
|
|
|
|
(86,86),(43,43)
|
|
|
|
(88,88),(44,44)
|
|
|
|
(90,90),(45,45)
|
|
|
|
(92,92),(46,46)
|
|
|
|
(94,94),(47,47)
|
|
|
|
(96,96),(48,48)
|
|
|
|
(98,98),(49,49)
|
|
|
|
(100,100),(50,50)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(0,Infinity),(0,100)
|
2016-03-30 17:42:36 +02:00
|
|
|
(11 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)';
|
|
|
|
QUERY PLAN
|
|
|
|
-----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 |>> '(39,40),(37,38)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)';
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
f1
|
|
|
|
-------------------------------------------
|
2016-03-30 17:42:36 +02:00
|
|
|
(16,16),(8,8)
|
|
|
|
(18,18),(9,9)
|
|
|
|
(20,20),(10,10)
|
Improve portability of I/O behavior for the geometric types.
Formerly, the geometric I/O routines such as box_in and point_out relied
directly on strtod() and sprintf() for conversion of the float8 component
values of their data types. However, the behavior of those functions is
pretty platform-dependent, especially for edge-case values such as
infinities and NaNs. This was exposed by commit acdf2a8b372aec1d, which
added test cases involving boxes with infinity endpoints, and immediately
failed on Windows and AIX buildfarm members. We solved these problems
years ago in the main float8in and float8out functions, so let's fix it
by making the geometric types use that code instead of depending directly
on the platform-supplied functions.
To do this, refactor the float8in code so that it can be used to parse
just part of a string, and as a convenience make the guts of float8out
usable without going through DirectFunctionCall.
While at it, get rid of geo_ops.c's fairly shaky assumptions about the
maximum output string length for a double, by having it build results in
StringInfo buffers instead of fixed-length strings.
In passing, convert all the "invalid input syntax for type foo" messages
in this area of the code into "invalid input syntax for type %s" to reduce
the number of distinct translatable strings, per recent discussion.
We would have needed a fair number of the latter anyway for code-sharing
reasons, so we might as well just go whole hog.
Note: this patch is by no means intended to guarantee that the geometric
types uniformly behave sanely for infinity or NaN component values.
But any bugs we have in that line were there all along, they were just
harder to reach in a platform-independent way.
2016-03-30 23:25:03 +02:00
|
|
|
(Infinity,Infinity),(-Infinity,-Infinity)
|
2016-03-30 17:42:36 +02:00
|
|
|
(4 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 @> '(15,15),(10,11)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
|
|
|
|
f1
|
|
|
|
-----------------
|
|
|
|
(30,30),(15,15)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 <@ '(30,35),(10,15)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
|
|
|
|
f1
|
|
|
|
-----------------
|
|
|
|
(40,40),(20,20)
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)';
|
|
|
|
QUERY PLAN
|
|
|
|
----------------------------------------------
|
|
|
|
Index Only Scan using box_spgist on box_temp
|
|
|
|
Index Cond: (f1 ~= '(40,40),(20,20)'::box)
|
|
|
|
(2 rows)
|
|
|
|
|
|
|
|
RESET enable_seqscan;
|
|
|
|
DROP INDEX box_spgist;
|
2017-03-21 14:23:10 +01:00
|
|
|
--
|
|
|
|
-- Test the SP-GiST index on the larger volume of data
|
|
|
|
--
|
2019-07-14 13:57:53 +02:00
|
|
|
CREATE TABLE quad_box_tbl (id int, b box);
|
2017-03-21 14:23:10 +01:00
|
|
|
INSERT INTO quad_box_tbl
|
2019-07-14 13:57:53 +02:00
|
|
|
SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5))
|
|
|
|
FROM generate_series(1, 100) x,
|
|
|
|
generate_series(1, 100) y;
|
2017-03-21 14:23:10 +01:00
|
|
|
-- insert repeating data to test allTheSame
|
|
|
|
INSERT INTO quad_box_tbl
|
2019-07-14 13:57:53 +02:00
|
|
|
SELECT i, '((200, 300),(210, 310))'
|
|
|
|
FROM generate_series(10001, 11000) AS i;
|
2017-03-21 14:23:10 +01:00
|
|
|
INSERT INTO quad_box_tbl
|
2019-07-14 13:57:53 +02:00
|
|
|
VALUES
|
|
|
|
(11001, NULL),
|
|
|
|
(11002, NULL),
|
|
|
|
(11003, '((-infinity,-infinity),(infinity,infinity))'),
|
|
|
|
(11004, '((-infinity,100),(-infinity,500))'),
|
|
|
|
(11005, '((-infinity,-infinity),(700,infinity))');
|
2017-03-21 14:23:10 +01:00
|
|
|
CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b);
|
2019-07-14 13:57:53 +02:00
|
|
|
-- get reference results for ORDER BY distance from seq scan
|
|
|
|
SET enable_seqscan = ON;
|
|
|
|
SET enable_indexscan = OFF;
|
|
|
|
SET enable_bitmapscan = OFF;
|
|
|
|
CREATE TABLE quad_box_tbl_ord_seq1 AS
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl;
|
|
|
|
CREATE TABLE quad_box_tbl_ord_seq2 AS
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))';
|
2017-03-21 14:23:10 +01:00
|
|
|
SET enable_seqscan = OFF;
|
|
|
|
SET enable_indexscan = ON;
|
|
|
|
SET enable_bitmapscan = ON;
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b << box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
901
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b &< box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
3901
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b && box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1653
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b &> box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
10100
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
7000
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
7000
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b <<| box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1900
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b &<| box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
5901
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b |&> box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
9100
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b |>> box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
5000
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1003
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1600
|
|
|
|
(1 row)
|
|
|
|
|
|
|
|
SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))';
|
|
|
|
count
|
|
|
|
-------
|
|
|
|
1
|
|
|
|
(1 row)
|
|
|
|
|
2019-07-14 13:57:53 +02:00
|
|
|
-- test ORDER BY distance
|
|
|
|
SET enable_indexscan = ON;
|
|
|
|
SET enable_bitmapscan = OFF;
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl;
|
|
|
|
QUERY PLAN
|
|
|
|
---------------------------------------------------------
|
|
|
|
WindowAgg
|
|
|
|
-> Index Scan using quad_box_tbl_idx on quad_box_tbl
|
|
|
|
Order By: (b <-> '(123,456)'::point)
|
|
|
|
(3 rows)
|
|
|
|
|
|
|
|
CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl;
|
|
|
|
SELECT *
|
|
|
|
FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 idx
|
|
|
|
ON seq.n = idx.n AND seq.id = idx.id AND
|
|
|
|
(seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL)
|
|
|
|
WHERE seq.id IS NULL OR idx.id IS NULL;
|
|
|
|
n | dist | id | n | dist | id
|
|
|
|
---+------+----+---+------+----
|
|
|
|
(0 rows)
|
|
|
|
|
|
|
|
EXPLAIN (COSTS OFF)
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))';
|
|
|
|
QUERY PLAN
|
|
|
|
---------------------------------------------------------
|
|
|
|
WindowAgg
|
|
|
|
-> Index Scan using quad_box_tbl_idx on quad_box_tbl
|
|
|
|
Index Cond: (b <@ '(500,600),(200,300)'::box)
|
|
|
|
Order By: (b <-> '(123,456)'::point)
|
|
|
|
(4 rows)
|
|
|
|
|
|
|
|
CREATE TEMP TABLE quad_box_tbl_ord_idx2 AS
|
|
|
|
SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id
|
|
|
|
FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))';
|
|
|
|
SELECT *
|
|
|
|
FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx
|
|
|
|
ON seq.n = idx.n AND seq.id = idx.id AND
|
|
|
|
(seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL)
|
|
|
|
WHERE seq.id IS NULL OR idx.id IS NULL;
|
|
|
|
n | dist | id | n | dist | id
|
|
|
|
---+------+----+---+------+----
|
|
|
|
(0 rows)
|
|
|
|
|
2017-03-21 14:23:10 +01:00
|
|
|
RESET enable_seqscan;
|
|
|
|
RESET enable_indexscan;
|
|
|
|
RESET enable_bitmapscan;
|