1-- 2-- BOX 3-- 4 5-- 6-- box logic 7-- o 8-- 3 o--|X 9-- | o| 10-- 2 +-+-+ | 11-- | | | | 12-- 1 | o-+-o 13-- | | 14-- 0 +---+ 15-- 16-- 0 1 2 3 17-- 18 19-- boxes are specified by two points, given by four floats x1,y1,x2,y2 20 21 22CREATE TABLE BOX_TBL (f1 box); 23 24INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)'); 25 26INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)'); 27 28INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))'); 29 30 31-- degenerate cases where the box is a line or a point 32-- note that lines and points boxes all have zero area 33INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)'); 34 35INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)'); 36 37-- badly formatted box inputs 38INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)'); 39 40INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)'); 41 42INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]'); 43 44INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x'); 45 46INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad'); 47 48 49SELECT '' AS four, * FROM BOX_TBL; 50 51SELECT '' AS four, b.*, area(b.f1) as barea 52 FROM BOX_TBL b; 53 54-- overlap 55SELECT '' AS three, b.f1 56 FROM BOX_TBL b 57 WHERE b.f1 && box '(2.5,2.5,1.0,1.0)'; 58 59-- left-or-overlap (x only) 60SELECT '' AS two, b1.* 61 FROM BOX_TBL b1 62 WHERE b1.f1 &< box '(2.0,2.0,2.5,2.5)'; 63 64-- right-or-overlap (x only) 65SELECT '' AS two, b1.* 66 FROM BOX_TBL b1 67 WHERE b1.f1 &> box '(2.0,2.0,2.5,2.5)'; 68 69-- left of 70SELECT '' AS two, b.f1 71 FROM BOX_TBL b 72 WHERE b.f1 << box '(3.0,3.0,5.0,5.0)'; 73 74-- area <= 75SELECT '' AS four, b.f1 76 FROM BOX_TBL b 77 WHERE b.f1 <= box '(3.0,3.0,5.0,5.0)'; 78 79-- area < 80SELECT '' AS two, b.f1 81 FROM BOX_TBL b 82 WHERE b.f1 < box '(3.0,3.0,5.0,5.0)'; 83 84-- area = 85SELECT '' AS two, b.f1 86 FROM BOX_TBL b 87 WHERE b.f1 = box '(3.0,3.0,5.0,5.0)'; 88 89-- area > 90SELECT '' AS two, b.f1 91 FROM BOX_TBL b -- zero area 92 WHERE b.f1 > box '(3.5,3.0,4.5,3.0)'; 93 94-- area >= 95SELECT '' AS four, b.f1 96 FROM BOX_TBL b -- zero area 97 WHERE b.f1 >= box '(3.5,3.0,4.5,3.0)'; 98 99-- right of 100SELECT '' AS two, b.f1 101 FROM BOX_TBL b 102 WHERE box '(3.0,3.0,5.0,5.0)' >> b.f1; 103 104-- contained in 105SELECT '' AS three, b.f1 106 FROM BOX_TBL b 107 WHERE b.f1 <@ box '(0,0,3,3)'; 108 109-- contains 110SELECT '' AS three, b.f1 111 FROM BOX_TBL b 112 WHERE box '(0,0,3,3)' @> b.f1; 113 114-- box equality 115SELECT '' AS one, b.f1 116 FROM BOX_TBL b 117 WHERE box '(1,1,3,3)' ~= b.f1; 118 119-- center of box, left unary operator 120SELECT '' AS four, @@(b1.f1) AS p 121 FROM BOX_TBL b1; 122 123-- wholly-contained 124SELECT '' AS one, b1.*, b2.* 125 FROM BOX_TBL b1, BOX_TBL b2 126 WHERE b1.f1 @> b2.f1 and not b1.f1 ~= b2.f1; 127 128SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL; 129 130-- 131-- Test the SP-GiST index 132-- 133 134CREATE TEMPORARY TABLE box_temp (f1 box); 135 136INSERT INTO box_temp 137 SELECT box(point(i, i), point(i * 2, i * 2)) 138 FROM generate_series(1, 50) AS i; 139 140CREATE INDEX box_spgist ON box_temp USING spgist (f1); 141 142INSERT INTO box_temp 143 VALUES (NULL), 144 ('(0,0)(0,100)'), 145 ('(-3,4.3333333333)(40,1)'), 146 ('(0,100)(0,infinity)'), 147 ('(-infinity,0)(0,infinity)'), 148 ('(-infinity,-infinity)(infinity,infinity)'); 149 150SET enable_seqscan = false; 151 152SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'; 153EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 << '(10,20),(30,40)'; 154 155SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'; 156EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &< '(10,4.333334),(5,100)'; 157 158SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'; 159EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 && '(15,20),(25,30)'; 160 161SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'; 162EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &> '(40,30),(45,50)'; 163 164SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'; 165EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 >> '(30,40),(40,30)'; 166 167SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'; 168EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <<| '(10,4.33334),(5,100)'; 169 170SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'; 171EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 &<| '(10,4.3333334),(5,1)'; 172 173SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'; 174EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |&> '(49.99,49.99),(49.99,49.99)'; 175 176SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'; 177EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 |>> '(37,38),(39,40)'; 178 179SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,16)'; 180EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 @> '(10,11),(15,15)'; 181 182SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'; 183EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 <@ '(10,15),(30,35)'; 184 185SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'; 186EXPLAIN (COSTS OFF) SELECT * FROM box_temp WHERE f1 ~= '(20,20),(40,40)'; 187 188RESET enable_seqscan; 189 190DROP INDEX box_spgist; 191 192-- 193-- Test the SP-GiST index on the larger volume of data 194-- 195CREATE TABLE quad_box_tbl (b box); 196 197INSERT INTO quad_box_tbl 198 SELECT box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) 199 FROM generate_series(1, 100) x, 200 generate_series(1, 100) y; 201 202-- insert repeating data to test allTheSame 203INSERT INTO quad_box_tbl 204 SELECT '((200, 300),(210, 310))' 205 FROM generate_series(1, 1000); 206 207INSERT INTO quad_box_tbl 208 VALUES 209 (NULL), 210 (NULL), 211 ('((-infinity,-infinity),(infinity,infinity))'), 212 ('((-infinity,100),(-infinity,500))'), 213 ('((-infinity,-infinity),(700,infinity))'); 214 215CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b); 216 217SET enable_seqscan = OFF; 218SET enable_indexscan = ON; 219SET enable_bitmapscan = ON; 220 221SELECT count(*) FROM quad_box_tbl WHERE b << box '((100,200),(300,500))'; 222SELECT count(*) FROM quad_box_tbl WHERE b &< box '((100,200),(300,500))'; 223SELECT count(*) FROM quad_box_tbl WHERE b && box '((100,200),(300,500))'; 224SELECT count(*) FROM quad_box_tbl WHERE b &> box '((100,200),(300,500))'; 225SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))'; 226SELECT count(*) FROM quad_box_tbl WHERE b >> box '((100,200),(300,500))'; 227SELECT count(*) FROM quad_box_tbl WHERE b <<| box '((100,200),(300,500))'; 228SELECT count(*) FROM quad_box_tbl WHERE b &<| box '((100,200),(300,500))'; 229SELECT count(*) FROM quad_box_tbl WHERE b |&> box '((100,200),(300,500))'; 230SELECT count(*) FROM quad_box_tbl WHERE b |>> box '((100,200),(300,500))'; 231SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))'; 232SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))'; 233SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))'; 234 235RESET enable_seqscan; 236RESET enable_indexscan; 237RESET enable_bitmapscan; 238