diff --git a/mysql-test/main/mdev-35765.result b/mysql-test/main/mdev-35765.result new file mode 100644 index 00000000000..9a3de115b83 --- /dev/null +++ b/mysql-test/main/mdev-35765.result @@ -0,0 +1,20 @@ +# +# MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +# +DROP table if EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' +DROP table if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +ST_OVERLAPS(t1.geom, t2.geom) +0 +DROP TABLE t1, t2; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/mdev-35765.test b/mysql-test/main/mdev-35765.test new file mode 100644 index 00000000000..f9d04cff1f4 --- /dev/null +++ b/mysql-test/main/mdev-35765.test @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +--echo # +DROP table if EXISTS t1; +DROP table if EXISTS t2; +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +DROP TABLE t1, t2; +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 662ca14a25b..957d7670c77 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1398,6 +1398,38 @@ exit: } +static void handle_sp_crosses_func_case(Gcalc_function &func, + Gcalc_operation_transporter &trn, + Geometry_ptr_with_buffer_and_mbr &g1, + Geometry_ptr_with_buffer_and_mbr &g2, + uint &shape_a, uint &shape_b, + bool &null_value) +{ + func.add_operation(Gcalc_function::op_intersection, 2); + if (func.reserve_op_buffer(3)) + return; + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_intersection, 2); + shape_a= func.get_next_expression_pos(); + if ((null_value= g1.store_shapes(&trn))) + return; + shape_b= func.get_next_expression_pos(); + if ((null_value= g2.store_shapes(&trn))) + return; + if (func.reserve_op_buffer(7)) + return; + func.add_operation(Gcalc_function::op_intersection, 2); + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_difference, 2); + func.repeat_expression(shape_a); + func.repeat_expression(shape_b); + func.add_operation(Gcalc_function::v_find_t | + Gcalc_function::op_difference, 2); + func.repeat_expression(shape_b); + func.repeat_expression(shape_a); +} + + bool Item_func_spatial_precise_rel::val_bool() { DBUG_ENTER("Item_func_spatial_precise_rel::val_int"); @@ -1459,29 +1491,21 @@ bool Item_func_spatial_precise_rel::val_bool() null_value= g1.store_shapes(&trn) || g2.store_shapes(&trn); break; case SP_OVERLAPS_FUNC: + { + // Both geometries must have the same number of dimensions. + uint32 g1_dim, g2_dim; + const char *dummy; + g1.geom->dimension(&g1_dim, &dummy); + g2.geom->dimension(&g2_dim, &dummy); + if (g1_dim != g2_dim) + DBUG_RETURN(0); + handle_sp_crosses_func_case(func, trn, g1, g2, + shape_a, shape_b, null_value); + break; + } case SP_CROSSES_FUNC: - func.add_operation(Gcalc_function::op_intersection, 2); - if (func.reserve_op_buffer(3)) - break; - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_intersection, 2); - shape_a= func.get_next_expression_pos(); - if ((null_value= g1.store_shapes(&trn))) - break; - shape_b= func.get_next_expression_pos(); - if ((null_value= g2.store_shapes(&trn))) - break; - if (func.reserve_op_buffer(7)) - break; - func.add_operation(Gcalc_function::op_intersection, 2); - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_difference, 2); - func.repeat_expression(shape_a); - func.repeat_expression(shape_b); - func.add_operation(Gcalc_function::v_find_t | - Gcalc_function::op_difference, 2); - func.repeat_expression(shape_b); - func.repeat_expression(shape_a); + handle_sp_crosses_func_case(func, trn, g1, g2, + shape_a, shape_b, null_value); break; case SP_TOUCHES_FUNC: if (func.reserve_op_buffer(5))