Commit 60985e53 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan

parent 9d884fd3
...@@ -1618,5 +1618,29 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1618,5 +1618,29 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 34 NULL 1 Using where 1 SIMPLE t1 range a a 34 NULL 1 Using where
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan
#
CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (Point(1,1)),(Point(2,2)),(Point(3,3));
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1.0);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1e0);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIME'00:00:00');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,DATE'2001-01-01');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIMESTAMP'2001-01-01 00:00:00');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1;
#
# End of 10.1 tests # End of 10.1 tests
# #
...@@ -993,6 +993,20 @@ EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(Point(1,2),a); ...@@ -993,6 +993,20 @@ EXPLAIN SELECT * FROM t1 WHERE MBRINTERSECTS(Point(1,2),a);
EXPLAIN SELECT * FROM t1 WHERE ST_INTERSECTS(Point(1,2),a); EXPLAIN SELECT * FROM t1 WHERE ST_INTERSECTS(Point(1,2),a);
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-8610 "WHERE CONTAINS(indexed_geometry_column,1)" causes full table scan
--echo #
CREATE TABLE t1 (a GEOMETRY NOT NULL, SPATIAL KEY(a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (Point(1,1)),(Point(2,2)),(Point(3,3));
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1);
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1.0);
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,1e0);
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIME'00:00:00');
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,DATE'2001-01-01');
EXPLAIN SELECT * FROM t1 WHERE CONTAINS(a,TIMESTAMP'2001-01-01 00:00:00');
DROP TABLE t1;
--echo # --echo #
--echo # End of 10.1 tests --echo # End of 10.1 tests
--echo # --echo #
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "set_var.h" #include "set_var.h"
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
#include <m_ctype.h> #include <m_ctype.h>
#include "opt_range.h"
Field *Item_geometry_func::tmp_table_field(TABLE *t_arg) Field *Item_geometry_func::tmp_table_field(TABLE *t_arg)
...@@ -929,6 +930,78 @@ err: ...@@ -929,6 +930,78 @@ err:
Functions for spatial relations Functions for spatial relations
*/ */
static SEL_ARG sel_arg_impossible(SEL_ARG::IMPOSSIBLE);
SEL_ARG *
Item_func_spatial_rel::get_mm_leaf(RANGE_OPT_PARAM *param,
Field *field, KEY_PART *key_part,
Item_func::Functype type, Item *value)
{
DBUG_ENTER("Item_func_spatial_rel::get_mm_leaf");
if (key_part->image_type != Field::itMBR)
DBUG_RETURN(0);
if (value->cmp_type() != STRING_RESULT)
DBUG_RETURN(&sel_arg_impossible);
if (param->using_real_indexes &&
!field->optimize_range(param->real_keynr[key_part->key],
key_part->part))
DBUG_RETURN(0);
if (value->save_in_field_no_warnings(field, 1))
DBUG_RETURN(&sel_arg_impossible); // Bad GEOMETRY value
DBUG_ASSERT(!field->real_maybe_null()); // SPATIAL keys do not support NULL
uchar *str= (uchar*) alloc_root(param->mem_root, key_part->store_length + 1);
if (!str)
DBUG_RETURN(0); // out of memory
field->get_key_image(str, key_part->length, key_part->image_type);
SEL_ARG *tree;
if (!(tree= new (param->mem_root) SEL_ARG(field, str, str)))
DBUG_RETURN(0); // out of memory
switch (type) {
case SP_EQUALS_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_EQUAL;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_DISJOINT_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_DISJOINT;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_INTERSECTS_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_TOUCHES_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_CROSSES_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_WITHIN_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_WITHIN;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_CONTAINS_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_CONTAIN;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
case SP_OVERLAPS_FUNC:
tree->min_flag= GEOM_FLAG | HA_READ_MBR_INTERSECT;// NEAR_MIN;//512;
tree->max_flag= NO_MAX_RANGE;
break;
default:
DBUG_ASSERT(0);
break;
}
DBUG_RETURN(tree);
}
const char *Item_func_spatial_mbr_rel::func_name() const const char *Item_func_spatial_mbr_rel::func_name() const
{ {
switch (spatial_rel) { switch (spatial_rel) {
......
...@@ -277,6 +277,9 @@ class Item_func_spatial_rel: public Item_bool_func2 ...@@ -277,6 +277,9 @@ class Item_func_spatial_rel: public Item_bool_func2
protected: protected:
enum Functype spatial_rel; enum Functype spatial_rel;
String tmp_value1, tmp_value2; String tmp_value1, tmp_value2;
SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, Field *field,
KEY_PART *key_part,
Item_func::Functype type, Item *value);
public: public:
Item_func_spatial_rel(Item *a, Item *b, enum Functype sp_rel) Item_func_spatial_rel(Item *a, Item *b, enum Functype sp_rel)
:Item_bool_func2(a, b), spatial_rel(sp_rel) :Item_bool_func2(a, b), spatial_rel(sp_rel)
......
This diff is collapsed.
This diff is collapsed.
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