Add support for <-> (box, point) operator to SP-GiST box_ops
Opclass support functions already can handle this operator, just catalog adjustment appears to be required. Discussion: https://postgr.es/m/f71ba19d-d989-63b6-f04a-abf02ad9345d%40postgrespro.ru Author: Nikita Glukhov Reviewed-by: Tom Lane, Alexander Korotkov
This commit is contained in:
parent
c085e1c1cb
commit
075f0a880f
|
@ -139,6 +139,7 @@
|
|||
<literal>|&></literal>
|
||||
</entry>
|
||||
<entry>
|
||||
<literal><-></literal>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
|
|
|
@ -1546,6 +1546,10 @@
|
|||
amopstrategy => '11', amopopr => '|>>(box,box)', amopmethod => 'spgist' },
|
||||
{ amopfamily => 'spgist/box_ops', amoplefttype => 'box', amoprighttype => 'box',
|
||||
amopstrategy => '12', amopopr => '|&>(box,box)', amopmethod => 'spgist' },
|
||||
{ amopfamily => 'spgist/box_ops', amoplefttype => 'box',
|
||||
amoprighttype => 'point', amopstrategy => '15', amoppurpose => 'o',
|
||||
amopopr => '<->(box,point)', amopmethod => 'spgist',
|
||||
amopsortfamily => 'btree/float_ops' },
|
||||
|
||||
# SP-GiST poly_ops (supports polygons)
|
||||
{ amopfamily => 'spgist/poly_ops', amoplefttype => 'polygon',
|
||||
|
|
|
@ -480,23 +480,33 @@ DROP INDEX box_spgist;
|
|||
--
|
||||
-- Test the SP-GiST index on the larger volume of data
|
||||
--
|
||||
CREATE TABLE quad_box_tbl (b box);
|
||||
CREATE TABLE quad_box_tbl (id int, b box);
|
||||
INSERT INTO quad_box_tbl
|
||||
SELECT box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5))
|
||||
FROM generate_series(1, 100) x,
|
||||
generate_series(1, 100) y;
|
||||
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;
|
||||
-- insert repeating data to test allTheSame
|
||||
INSERT INTO quad_box_tbl
|
||||
SELECT '((200, 300),(210, 310))'
|
||||
FROM generate_series(1, 1000);
|
||||
SELECT i, '((200, 300),(210, 310))'
|
||||
FROM generate_series(10001, 11000) AS i;
|
||||
INSERT INTO quad_box_tbl
|
||||
VALUES
|
||||
(NULL),
|
||||
(NULL),
|
||||
('((-infinity,-infinity),(infinity,infinity))'),
|
||||
('((-infinity,100),(-infinity,500))'),
|
||||
('((-infinity,-infinity),(700,infinity))');
|
||||
VALUES
|
||||
(11001, NULL),
|
||||
(11002, NULL),
|
||||
(11003, '((-infinity,-infinity),(infinity,infinity))'),
|
||||
(11004, '((-infinity,100),(-infinity,500))'),
|
||||
(11005, '((-infinity,-infinity),(700,infinity))');
|
||||
CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b);
|
||||
-- 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))';
|
||||
SET enable_seqscan = OFF;
|
||||
SET enable_indexscan = ON;
|
||||
SET enable_bitmapscan = ON;
|
||||
|
@ -578,6 +588,54 @@ SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))';
|
|||
1
|
||||
(1 row)
|
||||
|
||||
-- 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)
|
||||
|
||||
RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
RESET enable_bitmapscan;
|
||||
|
|
|
@ -165,6 +165,8 @@ pg_user_mapping|t
|
|||
point_tbl|t
|
||||
polygon_tbl|t
|
||||
quad_box_tbl|t
|
||||
quad_box_tbl_ord_seq1|f
|
||||
quad_box_tbl_ord_seq2|f
|
||||
quad_point_tbl|t
|
||||
quad_poly_tbl|t
|
||||
radix_text_tbl|t
|
||||
|
|
|
@ -192,28 +192,41 @@ DROP INDEX box_spgist;
|
|||
--
|
||||
-- Test the SP-GiST index on the larger volume of data
|
||||
--
|
||||
CREATE TABLE quad_box_tbl (b box);
|
||||
CREATE TABLE quad_box_tbl (id int, b box);
|
||||
|
||||
INSERT INTO quad_box_tbl
|
||||
SELECT box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5))
|
||||
FROM generate_series(1, 100) x,
|
||||
generate_series(1, 100) y;
|
||||
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;
|
||||
|
||||
-- insert repeating data to test allTheSame
|
||||
INSERT INTO quad_box_tbl
|
||||
SELECT '((200, 300),(210, 310))'
|
||||
FROM generate_series(1, 1000);
|
||||
SELECT i, '((200, 300),(210, 310))'
|
||||
FROM generate_series(10001, 11000) AS i;
|
||||
|
||||
INSERT INTO quad_box_tbl
|
||||
VALUES
|
||||
(NULL),
|
||||
(NULL),
|
||||
('((-infinity,-infinity),(infinity,infinity))'),
|
||||
('((-infinity,100),(-infinity,500))'),
|
||||
('((-infinity,-infinity),(700,infinity))');
|
||||
VALUES
|
||||
(11001, NULL),
|
||||
(11002, NULL),
|
||||
(11003, '((-infinity,-infinity),(infinity,infinity))'),
|
||||
(11004, '((-infinity,100),(-infinity,500))'),
|
||||
(11005, '((-infinity,-infinity),(700,infinity))');
|
||||
|
||||
CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b);
|
||||
|
||||
-- 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))';
|
||||
|
||||
SET enable_seqscan = OFF;
|
||||
SET enable_indexscan = ON;
|
||||
SET enable_bitmapscan = ON;
|
||||
|
@ -232,6 +245,39 @@ SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))';
|
|||
SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))';
|
||||
SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))';
|
||||
|
||||
-- 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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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))';
|
||||
|
||||
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;
|
||||
|
||||
RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
RESET enable_bitmapscan;
|
||||
|
|
Loading…
Reference in New Issue