====== MySQL 8のGIS機能(ST_Contains)のバグ ====== ===== 検証環境 ===== * macOS Sonoma 14.2.1 * MySQL 8.0.35 2023-05-21: * 公開 2023-12-23: * 改訂 ===== 検証方法 ===== SQLファイル[[https://anineco.nyanta.jp/easy-rgeocode-jpn/mysql8bug.sql.txt|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''辺りの位置が表示される。 {{url>https://anineco.github.io/easy-rgeocode-jpn/example.html?lon=136.866667&lat=35.561111 100%,480}} ''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に固定し、緯度を連続的に振ってやると、かなりの広範囲で同じバグが発生する。