mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-294 SELECT WHERE ST_CONTAINS doesn't return all the records where ST_CONTAINS() is 1.
Optimizator fails using index with ST_Within(g, constant_poly). per-file comments: mysql-test/r/gis-rt-precise.result test result fixed. mysql-test/r/gis-rtree.result test result fixed. mysql-test/suite/maria/r/maria-gis-rtree-dynamic.result test result fixed. mysql-test/suite/maria/r/maria-gis-rtree-trans.result test result fixed. mysql-test/suite/maria/r/maria-gis-rtree.result test result fixed. storage/maria/ma_rt_index.c Use MBR_INTERSECT mode when optimizing the select WITH ST_Within. storage/myisam/rt_index.c Use MBR_INTERSECT mode when optimizing the select WITH ST_Within.
This commit is contained in:
parent
f50e4219eb
commit
662c51bad1
7 changed files with 84 additions and 8 deletions
|
@ -20,7 +20,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t1 range g g 34 NULL 8 Using where
|
||||
SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
|
||||
fid AsText(g)
|
||||
1 LINESTRING(150 150,150 150)
|
||||
3 LINESTRING(148 148,152 152)
|
||||
4 LINESTRING(147 147,153 153)
|
||||
5 LINESTRING(146 146,154 154)
|
||||
6 LINESTRING(145 145,155 155)
|
||||
7 LINESTRING(144 144,156 156)
|
||||
8 LINESTRING(143 143,157 157)
|
||||
9 LINESTRING(142 142,158 158)
|
||||
10 LINESTRING(141 141,159 159)
|
||||
11 LINESTRING(140 140,160 160)
|
||||
2 LINESTRING(149 149,151 151)
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (
|
||||
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
|
@ -45,5 +55,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
SELECT fid, AsText(g) FROM t1 WHERE ST_Within(g,
|
||||
GeomFromText('Polygon((40 40,60 40,60 60,40 40))'));
|
||||
fid AsText(g)
|
||||
46 LINESTRING(51 41,60 50)
|
||||
56 LINESTRING(41 41,50 50)
|
||||
45 LINESTRING(51 51,60 60)
|
||||
DROP TABLE t1;
|
||||
End of 5.5 tests.
|
||||
|
|
|
@ -170,7 +170,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t1 range g g 34 NULL 8 Using where
|
||||
SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))'));
|
||||
fid AsText(g)
|
||||
1 LINESTRING(150 150,150 150)
|
||||
3 LINESTRING(148 148,152 152)
|
||||
4 LINESTRING(147 147,153 153)
|
||||
5 LINESTRING(146 146,154 154)
|
||||
6 LINESTRING(145 145,155 155)
|
||||
7 LINESTRING(144 144,156 156)
|
||||
8 LINESTRING(143 143,157 157)
|
||||
9 LINESTRING(142 142,158 158)
|
||||
10 LINESTRING(141 141,159 159)
|
||||
11 LINESTRING(140 140,160 160)
|
||||
2 LINESTRING(149 149,151 151)
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t2 (
|
||||
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
|
@ -295,6 +305,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
|
||||
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
|
||||
fid AsText(g)
|
||||
46 LINESTRING(51 41,60 50)
|
||||
56 LINESTRING(41 41,50 50)
|
||||
45 LINESTRING(51 51,60 60)
|
||||
55 LINESTRING(41 51,50 60)
|
||||
DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))));
|
||||
SELECT count(*) FROM t2;
|
||||
count(*)
|
||||
|
|
|
@ -306,6 +306,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
|
||||
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
|
||||
fid AsText(g)
|
||||
45 LINESTRING(51 51,60 60)
|
||||
46 LINESTRING(51 41,60 50)
|
||||
55 LINESTRING(41 51,50 60)
|
||||
56 LINESTRING(41 41,50 50)
|
||||
DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))));
|
||||
SELECT count(*) FROM t2;
|
||||
count(*)
|
||||
|
|
|
@ -306,6 +306,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
|
||||
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
|
||||
fid AsText(g)
|
||||
45 LINESTRING(51 51,60 60)
|
||||
46 LINESTRING(51 41,60 50)
|
||||
55 LINESTRING(41 51,50 60)
|
||||
56 LINESTRING(41 41,50 50)
|
||||
DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))));
|
||||
SELECT count(*) FROM t2;
|
||||
count(*)
|
||||
|
|
|
@ -306,6 +306,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
SELECT fid, AsText(g) FROM t2 WHERE Within(g,
|
||||
GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))'));
|
||||
fid AsText(g)
|
||||
45 LINESTRING(51 51,60 60)
|
||||
46 LINESTRING(51 41,60 50)
|
||||
55 LINESTRING(41 51,50 60)
|
||||
56 LINESTRING(41 41,50 50)
|
||||
DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))));
|
||||
SELECT count(*) FROM t2;
|
||||
count(*)
|
||||
|
|
|
@ -196,6 +196,12 @@ int maria_rtree_find_first(MARIA_HA *info, MARIA_KEY *key, uint32 search_flag)
|
|||
uint nod_cmp_flag;
|
||||
MARIA_KEYDEF *keyinfo= key->keyinfo;
|
||||
|
||||
/*
|
||||
At the moment index can only properly handle the
|
||||
MBR_INTERSECT, so we use it for all sorts of queries.
|
||||
TODO: better searsh for CONTAINS/WITHIN.
|
||||
*/
|
||||
search_flag= nod_cmp_flag= MBR_INTERSECT;
|
||||
if ((root= info->s->state.key_root[keyinfo->key_nr]) == HA_OFFSET_ERROR)
|
||||
{
|
||||
my_errno= HA_ERR_END_OF_FILE;
|
||||
|
@ -213,8 +219,11 @@ int maria_rtree_find_first(MARIA_HA *info, MARIA_KEY *key, uint32 search_flag)
|
|||
info->maria_rtree_recursion_depth= -1;
|
||||
info->keyread_buff_used= 1;
|
||||
|
||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
/*
|
||||
TODO better search for CONTAINS/WITHIN.
|
||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
*/
|
||||
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root,
|
||||
0);
|
||||
}
|
||||
|
@ -241,6 +250,12 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag)
|
|||
uint32 nod_cmp_flag;
|
||||
MARIA_KEYDEF *keyinfo= info->s->keyinfo + keynr;
|
||||
DBUG_ASSERT(info->last_key.keyinfo == keyinfo);
|
||||
/*
|
||||
At the moment index can only properly handle the
|
||||
MBR_INTERSECT, so we use it for all sorts of queries.
|
||||
TODO: better searsh for CONTAINS/WITHIN.
|
||||
*/
|
||||
search_flag= nod_cmp_flag= MBR_INTERSECT;
|
||||
|
||||
if (info->update & HA_STATE_DELETED)
|
||||
return maria_rtree_find_first(info, &info->last_key, search_flag);
|
||||
|
@ -284,8 +299,11 @@ int maria_rtree_find_next(MARIA_HA *info, uint keynr, uint32 search_flag)
|
|||
return -1;
|
||||
}
|
||||
|
||||
nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT));
|
||||
/*
|
||||
TODO better search for CONTAINS/WITHIN.
|
||||
nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT));
|
||||
*/
|
||||
return maria_rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root,
|
||||
0);
|
||||
}
|
||||
|
|
|
@ -175,6 +175,13 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
|
|||
uint nod_cmp_flag;
|
||||
MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
|
||||
/*
|
||||
At the moment index can only properly handle the
|
||||
MBR_INTERSECT, so we use it for all sorts of queries.
|
||||
TODO: better searsh for CONTAINS/WITHIN.
|
||||
*/
|
||||
search_flag= nod_cmp_flag= MBR_INTERSECT;
|
||||
|
||||
if ((root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
|
||||
{
|
||||
my_errno= HA_ERR_END_OF_FILE;
|
||||
|
@ -192,8 +199,11 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
|
|||
info->rtree_recursion_depth = -1;
|
||||
info->buff_used = 1;
|
||||
|
||||
nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
/*
|
||||
TODO better search for CONTAINS/WITHIN.
|
||||
nod_cmp_flag= ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
*/
|
||||
return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
|
||||
}
|
||||
|
||||
|
@ -218,6 +228,12 @@ int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag)
|
|||
my_off_t root;
|
||||
uint nod_cmp_flag;
|
||||
MI_KEYDEF *keyinfo = info->s->keyinfo + keynr;
|
||||
/*
|
||||
At the moment index can only properly handle the
|
||||
MBR_INTERSECT, so we use it for all sorts of queries.
|
||||
TODO: better searsh for CONTAINS/WITHIN.
|
||||
*/
|
||||
search_flag= nod_cmp_flag= MBR_INTERSECT;
|
||||
|
||||
if (info->update & HA_STATE_DELETED)
|
||||
return rtree_find_first(info, keynr, info->lastkey, info->lastkey_length,
|
||||
|
@ -252,8 +268,11 @@ int rtree_find_next(MI_INFO *info, uint keynr, uint search_flag)
|
|||
return -1;
|
||||
}
|
||||
|
||||
nod_cmp_flag = ((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT);
|
||||
/*
|
||||
TODO better search for CONTAINS/WITHIN.
|
||||
nod_cmp_flag= (((search_flag & (MBR_EQUAL | MBR_WITHIN)) ?
|
||||
MBR_WITHIN : MBR_INTERSECT));
|
||||
*/
|
||||
return rtree_find_req(info, keyinfo, search_flag, nod_cmp_flag, root, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue