Description:
Contains/Within queries on a table with a non-spatial, non-unique index on a POINT column with no NULL values returns zero results. If the key is removed or ignored, or a spatial index on the same column is forced, the correct results are returned for the same query.
The behavior was first observed using ST_Contains, but can be replicated with ST_Contains, ST_Within, MBRContains, MBRWithin, Contains, and Within.
The issue could not be reproduced using MySQL version 5.5.28 and Contains/Within.
How to repeat:
-- (spatial data shamelessly cribbed from http://bugs.mysql.com/bug.php?id=64533)
DROP TABLE IF EXISTS spatial_test;
CREATE TABLE spatial_test (
id INT UNSIGNED NOT NULL AUTO_INCREMENT
, shape_data POLYGON NOT NULL
, PRIMARY KEY (id)
, SPATIAL KEY s_idx_shape_data(shape_data)
) ENGINE=MyISAM;
-- Populate with two polygons, only ID: 2 should show up in any subsequent queries.
INSERT INTO spatial_test (shape_data)
VALUES
(GeomFromText('POLYGON((37.961911 23.731155,37.965159 23.752441,37.977068 23.753128,37.977068 23.728065,37.961911 23.731155))'))
, (GeomFromText('POLYGON((38.034195 23.840504,38.016413 23.845568,38.019186 23.873892,38.050524 23.875523,38.034195 23.840504))'))
;
DROP TABLE IF EXISTS point_test;
CREATE TABLE point_test (
id INT UNSIGNED NOT NULL AUTO_INCREMENT
, point_data POINT NOT NULL
, PRIMARY KEY (id)
, SPATIAL KEY s_idx_point_data(point_data)
, KEY idx_point_data(point_data)
) ENGINE=MyISAM;
-- Populate with two points, alternating to fill the table to a point where the query optimizer will not employ a full-table scan. Only even-numbered points should appear in subsequent queries.
INSERT INTO point_test (point_data)
VALUES
(GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
, (GeomFromText('Point(37.0248492 23.8512726)'))
, (GeomFromText('Point(38.0248492 23.8512726)'))
;
-- Returns ID: 2
SELECT id
FROM spatial_test
WHERE ST_Contains(shape_data, GeomFromText('Point(38.0248492 23.8512726)'))
;
-- Returns all even-numbered IDs.
SELECT id
FROM point_test
WHERE ST_Contains(point_data, GeomFromText('Point(38.0248492 23.8512726)'))
;
-- Should return all even-numbered IDs, returns empty set.
SELECT
point_test.id
, spatial_test.id
FROM spatial_test, point_test
WHERE (ST_Contains(shape_data, point_data))
;
-- Returns all even-numbered IDs
SELECT
point_test.id
, spatial_test.id
FROM spatial_test FORCE INDEX(s_idx_shape_data), point_test IGNORE INDEX(idx_point_data)
WHERE (ST_Contains(shape_data, point_data))
;
-- Should return all even-numbered IDs, returns empty set.
SELECT
point_test.id
, spatial_test.id
FROM spatial_test IGNORE INDEX(s_idx_shape_data), point_test USE INDEX(idx_point_data)
WHERE (ST_Contains(shape_data, point_data))
;