Skip to content

Commit

Permalink
MDEV-35765 ST_OVERLAPS wrong result when dim(geom1) <> dim(geom2)
Browse files Browse the repository at this point in the history
Validates that the two geometries passed to ST_OVERLAPS have the
same number of dimensions.
  • Loading branch information
DaveGosselin-MariaDB committed Jan 23, 2025
1 parent 2543be6 commit 34a9098
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 22 deletions.
20 changes: 20 additions & 0 deletions mysql-test/main/mdev-35765.result
Original file line number Diff line number Diff line change
@@ -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
#
14 changes: 14 additions & 0 deletions mysql-test/main/mdev-35765.test
Original file line number Diff line number Diff line change
@@ -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 #
68 changes: 46 additions & 22 deletions sql/item_geofunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,38 @@ bool Item_func_spatial_relate::val_bool()
}


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");
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 34a9098

Please sign in to comment.