Commit 662c51ba authored by Alexey Botchkov's avatar Alexey Botchkov

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.
parent f50e4219
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment