目次

MySQL 8のGIS機能(ST_Contains)のバグ

検証環境

2023-05-21:

2023-12-23:

検証方法

SQLファイルmysql8bug.sqlをMySQLで実行する。以下は、このファイルを説明するために、一部を抜粋して表示したものである。

# 国土数値情報 行政区域(2022)岐阜県美濃市
SET @wkt='POLYGON((136.881404111811 35.6522255863419,136.881898274886 35.6520964140184,
(中略)
,136.880985227387 35.652280026802,136.881404111811 35.6522255863419))';
SET @area=ST_GeomFromText(@wkt,4326/*!80003 ,'axis-order=long-lat' */);
# 天王山(岐阜県美濃市、標高537.6m)
SET @p0=ST_GeomFromText('POINT(136.866944 35.561111)',4326/*!80003 ,'axis-order=long-lat' */);
# 経度 -1/3600 付近
SET @p1=ST_GeomFromText('POINT(136.866666 35.561111)',4326/*!80003 ,'axis-order=long-lat' */);
SET @p2=ST_GeomFromText('POINT(136.866667 35.561111)',4326/*!80003 ,'axis-order=long-lat' */);
SET @p3=ST_GeomFromText('POINT(136.866668 35.561111)',4326/*!80003 ,'axis-order=long-lat' */);
# 期待される結果は全て 1
SELECT ST_Contains(@area,@p0),ST_Contains(@area,@p1),ST_Contains(@area,@p2),ST_Contains(@area,@p3);

このSQLファイルでは、1つのPolygon @areaと4つのPoint @p0@p1@p2@p3を定義している。@areaは国土数値情報の行政区域(2022年版)から抜粋した岐阜県美濃市のPolygonデータ、@p0は美濃市内の天王山(標高537.6m)の山頂を表すPointデータ、@p1@p2@p3は山頂から西へ約1秒の地点で、経度(単位:度)の小数点以下6桁目のみが異なる。この4点は明らかに美濃市内にある。実際に、Leafletを用いて地理院地図上に表示した結果を下記に示す。左上の[⌖]ボタンを押すと、@area@p2辺りの位置が表示される。 mysql8bug.sqlを実行した結果は、下の表のようになる。なお、比較のため、MySQL 5.7とMariaDB 10で実行した結果も示す。

実行結果のまとめ:太字が誤答で、バグの存在を示している。

正答 MySQL 8.0.35 MySQL 5.7.40 MariaDB 10.11.2
ST_Contains(@area,@p0) 1 1 1 1
ST_Contains(@area,@p1) 1 1 1 1
ST_Contains(@area,@p2) 1 0 1 1
ST_Contains(@area,@p3) 1 1 1 1

なお、経度を136.866667に固定し、緯度を連続的に振ってやると、かなりの広範囲で同じバグが発生する。