Oracle新版本中SDO_RELATE的CONTAINS空间连接异常问题问询
Oracle 21.3/23.7 空间连接CONTAINS异常问题排查
为GeoTools升级Oracle CI栈,从18.4.XE升级至21.3 XE和23.7 Free时,出现多边形与点的空间连接测试用例异常:使用CONTAINS条件的查询未返回预期结果。
环境搭建SQL语句
CREATE TABLE ft1 ( id INT, geometry MDSYS.SDO_GEOMETRY, intProperty INT, doubleProperty FLOAT, stringProperty VARCHAR(255), PRIMARY KEY(id) ); INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) VALUES ('FT1','GEOMETRY',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-180,180,0.5), MDSYS.SDO_DIM_ELEMENT('Y',-90,90,0.5)), 4326); INSERT INTO ft1 VALUES (0,MDSYS.SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(0.0,0.0,NULL),NULL,NULL), 0, 0.0,'zero'); INSERT INTO ft1 VALUES (1,MDSYS.SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(1.0,1.0,NULL),NULL,NULL), 1, 1.1,'one'); INSERT INTO ft1 VALUES (2,MDSYS.SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(2.0,2.0,NULL),NULL,NULL), 2, 2.2,'two'); CREATE INDEX FT1_GEOMETRY_IDX ON ft1(GEOMETRY) INDEXTYPE IS MDSYS.SPATIAL_INDEX_V2 PARAMETERS ( 'layer_gtype=POINT' ); CREATE TABLE FTJOIN ( id INT PRIMARY KEY, name VARCHAR(255), geom MDSYS.SDO_GEOMETRY, join1intProperty INT ); INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) VALUES ('FTJOIN','GEOM',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-20,20,0.05), MDSYS.SDO_DIM_ELEMENT('Y',-20,20,0.05)), 4326); INSERT INTO FTJOIN VALUES (0, 'zero', MDSYS.SDO_GEOMETRY(2003, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1), MDSYS.SDO_ORDINATE_ARRAY(-0.1,-0.1, -0.1,0.1, 0.1,0.1, 0.1,-0.1, -0.1,-0.1)), 0); INSERT INTO FTJOIN VALUES (1, 'one', MDSYS.SDO_GEOMETRY(2003, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1), MDSYS.SDO_ORDINATE_ARRAY(-1.1,-1.1, -1.1,1.1, 1.1,1.1, 1.1,-1.1, -1.1,-1.1)), 1); INSERT INTO FTJOIN VALUES (2, 'two', MDSYS.SDO_GEOMETRY(2003, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1), MDSYS.SDO_ORDINATE_ARRAY(-10,-10, -10,10, 10,10, 10,-10, -10,-10)), 2); INSERT INTO FTJOIN VALUES (3, 'three', NULL, 3); CREATE INDEX FTJOIN_GEOMETRY_IDX ON FTJOIN(GEOM) INDEXTYPE IS MDSYS.SPATIAL_INDEX_V2 PARAMETERS ( 'layer_gtype=POLYGON' );
测试异常情况
预期返回6条记录的空间连接查询,在21.3和23.7版本中均返回0条:
SELECT COUNT(*) FROM GEOTOOLS.FT1 A INNER JOIN GEOTOOLS.FTJOIN B ON SDO_RELATE(b.GEOM, a.GEOMETRY, 'mask=contains querytype=WINDOW') = 'TRUE';
要素交互关系排查
执行以下查询分析空间要素交互矩阵,发现多边形CONTAINS点返回FALSE,但点INSIDE多边形返回TRUE的矛盾结果:
SELECT point.ID as point_id, polygon.ID as polygon_id, SDO_CONTAINS(polygon.GEOM, point.GEOMETRY) as polygon_contains_point, SDO_INSIDE(point.GEOMETRY, polygon.GEOM) as point_inside_polygon, SDO_GEOM.relate( polygon.GEOM, 'DETERMINE', point.GEOMETRY) as polygon_relates_to_point, SDO_GEOM.relate( point.GEOMETRY, 'DETERMINE', polygon.GEOM) as point_relates_to_polygon FROM FT1 point INNER JOIN FTJOIN polygon ON 'TRUE' ORDER BY polygon_id, point_id;
查询结果:
| POINT_ID | POLYGON_ID | POLYGON_CONTAINS_POINT | POINT_INSIDE_POLYGON | POLYGON_RELATES_TO_POINT | POINT_RELATES_TO_POLYGON |
|---|---|---|---|---|---|
| 0 | 0 | FALSE | TRUE | DISJOINT | INSIDE |
| 1 | 0 | FALSE | FALSE | DISJOINT | DISJOINT |
| 2 | 0 | FALSE | FALSE | DISJOINT | DISJOINT |
| 0 | 1 | FALSE | TRUE | DISJOINT | INSIDE |
| 1 | 1 | FALSE | TRUE | DISJOINT | INSIDE |
| 2 | 1 | FALSE | FALSE | DISJOINT | DISJOINT |
| 0 | 2 | FALSE | TRUE | DISJOINT | INSIDE |
| 1 | 2 | FALSE | TRUE | DISJOINT | INSIDE |
| 2 | 2 | FALSE | TRUE | DISJOINT | INSIDE |
| 0 | 3 | FALSE | FALSE | null | null |
| 1 | 3 | FALSE | FALSE | null | null |
| 2 | 3 | FALSE | FALSE | null | null |
已尝试的解决措施
- 调整
min_resolution参数 - 将
querytype从WINDOW改为JOIN(该参数已失效)
以上操作均未解决问题。
疑问
除Oracle软件自身bug外,是否存在其他导致该问题的原因?(18.4版本可正常运行,空间索引和主键配置均符合要求)
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

