Commit 4a52b643 authored by StefanoPetrilli's avatar StefanoPetrilli Committed by Dave Gosselin

MDEV-34138: Implements the function MBRCoveredBy

Returns 1 or 0 to indicate whether the minimum bounding rectangle of g1
is covered by the minimum bounding rectangle of g2. The tests have been
cherry-picked from the MySQL implementation of this function to grant
compatibility among the two implementations.
Co-authored-by: default avatarErlend Dahl <erlend.dahl@oracle.com>
Co-authored-by: default avatarNorvald H. Ryeng <norvald.ryeng@oracle.com>
Co-authored-by: default avatarMartin Hansson  <martin.hansson@oracle.com>
Co-authored-by: default avatarErik Froseth <erik.froseth@oracle.com>
Co-authored-by: default avatarHans H Melby <hans.h.melby@oracle.com>
Co-authored-by: default avatarJens Even Berg Blomsøy <jens.even.blomosoy@oracle.com>
Co-authored-by: default avatarDavid Zhao <david.zhao@oracle.com>
Co-authored-by: default avatarBennyWang <benny.wang@oracle.com>
parent f21ee74e
...@@ -1032,6 +1032,7 @@ static COMMANDS commands[] = { ...@@ -1032,6 +1032,7 @@ static COMMANDS commands[] = {
{ "MASTER_POS_WAIT", 0, 0, 0, ""}, { "MASTER_POS_WAIT", 0, 0, 0, ""},
{ "MAX", 0, 0, 0, ""}, { "MAX", 0, 0, 0, ""},
{ "MBRCONTAINS", 0, 0, 0, ""}, { "MBRCONTAINS", 0, 0, 0, ""},
{ "MBRCOVEREDBY", 0, 0, 0, ""},
{ "MBRDISJOINT", 0, 0, 0, ""}, { "MBRDISJOINT", 0, 0, 0, ""},
{ "MBREQUAL", 0, 0, 0, ""}, { "MBREQUAL", 0, 0, 0, ""},
{ "MBRINTERSECTS", 0, 0, 0, ""}, { "MBRINTERSECTS", 0, 0, 0, ""},
......
This diff is collapsed.
This diff is collapsed.
...@@ -97,7 +97,7 @@ class Item_func :public Item_func_or_sum ...@@ -97,7 +97,7 @@ class Item_func :public Item_func_or_sum
INTERVAL_FUNC, ISNOTNULLTEST_FUNC, INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC, SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC, SP_CONTAINS_FUNC, SP_COVEREDBY_FUNC, SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING, SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC, SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC,
NOT_FUNC, NOT_ALL_FUNC, TEMPTABLE_ROWID, NOT_FUNC, NOT_ALL_FUNC, TEMPTABLE_ROWID,
......
...@@ -1135,10 +1135,12 @@ Item_func_spatial_rel::get_mm_leaf(RANGE_OPT_PARAM *param, ...@@ -1135,10 +1135,12 @@ Item_func_spatial_rel::get_mm_leaf(RANGE_OPT_PARAM *param,
LEX_CSTRING Item_func_spatial_mbr_rel::func_name_cstring() const LEX_CSTRING Item_func_spatial_mbr_rel::func_name_cstring() const
{ {
switch (spatial_rel) { switch (spatial_rel) {
case SP_CONTAINS_FUNC: case SP_CONTAINS_FUNC:
return { STRING_WITH_LEN("mbrcontains") }; return { STRING_WITH_LEN("mbrcontains") };
case SP_COVEREDBY_FUNC:
return { STRING_WITH_LEN("mbrcoveredby") };
case SP_WITHIN_FUNC: case SP_WITHIN_FUNC:
return { STRING_WITH_LEN("mbrwithin") } ; return { STRING_WITH_LEN("mbrwithin") } ;
case SP_EQUALS_FUNC: case SP_EQUALS_FUNC:
...@@ -1179,9 +1181,15 @@ longlong Item_func_spatial_mbr_rel::val_int() ...@@ -1179,9 +1181,15 @@ longlong Item_func_spatial_mbr_rel::val_int()
g2->get_mbr(&mbr2, &dummy) || !mbr2.valid()))) g2->get_mbr(&mbr2, &dummy) || !mbr2.valid())))
return 0; return 0;
uint32 srid1= uint4korr(res1->ptr()), srid2= uint4korr(res2->ptr());
if (srid1 != srid2)
my_error(ER_GIS_DIFFERENT_SRIDS, MYF(0), func_name(), srid1, srid2);
switch (spatial_rel) { switch (spatial_rel) {
case SP_CONTAINS_FUNC: case SP_CONTAINS_FUNC:
return mbr1.contains(&mbr2); return mbr1.contains(&mbr2);
case SP_COVEREDBY_FUNC:
return mbr1.coveredby(&mbr2);
case SP_WITHIN_FUNC: case SP_WITHIN_FUNC:
return mbr1.within(&mbr2); return mbr1.within(&mbr2);
case SP_EQUALS_FUNC: case SP_EQUALS_FUNC:
...@@ -1205,11 +1213,14 @@ longlong Item_func_spatial_mbr_rel::val_int() ...@@ -1205,11 +1213,14 @@ longlong Item_func_spatial_mbr_rel::val_int()
} }
LEX_CSTRING Item_func_spatial_precise_rel::func_name_cstring() const LEX_CSTRING Item_func_spatial_precise_rel::func_name_cstring() const
{ {
switch (spatial_rel) { switch (spatial_rel) {
case SP_CONTAINS_FUNC: case SP_CONTAINS_FUNC:
return { STRING_WITH_LEN("st_contains") }; return { STRING_WITH_LEN("st_contains") };
case SP_COVEREDBY_FUNC:
return { STRING_WITH_LEN("st_coveredby") };
case SP_WITHIN_FUNC: case SP_WITHIN_FUNC:
return { STRING_WITH_LEN("st_within") }; return { STRING_WITH_LEN("st_within") };
case SP_EQUALS_FUNC: case SP_EQUALS_FUNC:
...@@ -3080,6 +3091,38 @@ class Create_func_contains : public Create_func_arg2 ...@@ -3080,6 +3091,38 @@ class Create_func_contains : public Create_func_arg2
}; };
class Create_func_mbr_coveredby : public Create_func_arg2
{
public:
Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) override
{
return new (thd->mem_root) Item_func_spatial_mbr_rel(thd, arg1, arg2,
Item_func::SP_COVEREDBY_FUNC);
}
static Create_func_mbr_coveredby s_singleton;
protected:
Create_func_mbr_coveredby() = default;
~Create_func_mbr_coveredby() override = default;
};
class Create_func_coveredby : public Create_func_arg2
{
public:
Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) override
{
return new (thd->mem_root) Item_func_spatial_precise_rel(thd, arg1, arg2,
Item_func::SP_COVEREDBY_FUNC);
}
static Create_func_coveredby s_singleton;
protected:
Create_func_coveredby() = default;
~Create_func_coveredby() override = default;
};
class Create_func_crosses : public Create_func_arg2 class Create_func_crosses : public Create_func_arg2
{ {
public: public:
...@@ -4087,6 +4130,7 @@ Create_func_boundary Create_func_boundary::s_singleton; ...@@ -4087,6 +4130,7 @@ Create_func_boundary Create_func_boundary::s_singleton;
Create_func_buffer Create_func_buffer::s_singleton; Create_func_buffer Create_func_buffer::s_singleton;
Create_func_centroid Create_func_centroid::s_singleton; Create_func_centroid Create_func_centroid::s_singleton;
Create_func_contains Create_func_contains::s_singleton; Create_func_contains Create_func_contains::s_singleton;
Create_func_coveredby Create_func_coveredby::s_singleton;
Create_func_convexhull Create_func_convexhull::s_singleton; Create_func_convexhull Create_func_convexhull::s_singleton;
Create_func_crosses Create_func_crosses::s_singleton; Create_func_crosses Create_func_crosses::s_singleton;
Create_func_difference Create_func_difference::s_singleton; Create_func_difference Create_func_difference::s_singleton;
...@@ -4113,6 +4157,7 @@ Create_func_isempty Create_func_isempty::s_singleton; ...@@ -4113,6 +4157,7 @@ Create_func_isempty Create_func_isempty::s_singleton;
Create_func_isring Create_func_isring::s_singleton; Create_func_isring Create_func_isring::s_singleton;
Create_func_issimple Create_func_issimple::s_singleton; Create_func_issimple Create_func_issimple::s_singleton;
Create_func_mbr_contains Create_func_mbr_contains::s_singleton; Create_func_mbr_contains Create_func_mbr_contains::s_singleton;
Create_func_mbr_coveredby Create_func_mbr_coveredby::s_singleton;
Create_func_mbr_disjoint Create_func_mbr_disjoint::s_singleton; Create_func_mbr_disjoint Create_func_mbr_disjoint::s_singleton;
Create_func_mbr_equals Create_func_mbr_equals::s_singleton; Create_func_mbr_equals Create_func_mbr_equals::s_singleton;
Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton; Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton;
...@@ -4154,6 +4199,7 @@ static Native_func_registry func_array_geom[] = ...@@ -4154,6 +4199,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)}, { { STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
{ { STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)}, { { STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
{ { STRING_WITH_LEN("CONTAINS") }, GEOM_BUILDER(Create_func_contains)}, { { STRING_WITH_LEN("CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
{ { STRING_WITH_LEN("COVEREDBY") }, GEOM_BUILDER(Create_func_coveredby)},
{ { STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)}, { { STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
{ { STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)}, { { STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
{ { STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)}, { { STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
...@@ -4184,6 +4230,7 @@ static Native_func_registry func_array_geom[] = ...@@ -4184,6 +4230,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)}, { { STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)}, { { STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)}, { { STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)},
{ { STRING_WITH_LEN("MBRCOVEREDBY") }, GEOM_BUILDER(Create_func_mbr_coveredby)},
{ { STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)}, { { STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
{ { STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)}, { { STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)},
{ { STRING_WITH_LEN("MBREQUALS") }, GEOM_BUILDER(Create_func_mbr_equals)}, { { STRING_WITH_LEN("MBREQUALS") }, GEOM_BUILDER(Create_func_mbr_equals)},
...@@ -4228,6 +4275,7 @@ static Native_func_registry func_array_geom[] = ...@@ -4228,6 +4275,7 @@ static Native_func_registry func_array_geom[] =
{ { STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)}, { { STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
{ { STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)}, { { STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
{ { STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)}, { { STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
{ { STRING_WITH_LEN("ST_COVEREDBY") }, GEOM_BUILDER(Create_func_coveredby)},
{ { STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)}, { { STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
{ { STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)}, { { STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
{ { STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)}, { { STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},
......
...@@ -27,7 +27,7 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, ...@@ -27,7 +27,7 @@ double my_double_round(double value, longlong dec, bool dec_unsigned,
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
/* /*
exponential notation : exponential notation :
1 sign 1 sign
1 number before the decimal point 1 number before the decimal point
...@@ -142,6 +142,21 @@ int MBR::within(const MBR *mbr) ...@@ -142,6 +142,21 @@ int MBR::within(const MBR *mbr)
} }
int MBR::coveredby(const MBR *mbr)
{
int dim1= dimension();
int dim2= mbr->dimension();
if (dim1 > dim2)
return 0;
else if (dim1 == 0 && dim2 == 0)
return equals(mbr);
return ((xmin >= mbr->xmin) && (xmax <= mbr->xmax) &&
(ymin >= mbr->ymin) && (ymax <= mbr->ymax));
}
/***************************** Gis_class_info *******************************/ /***************************** Gis_class_info *******************************/
Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_last+1]= Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_last+1]=
......
...@@ -154,6 +154,8 @@ struct MBR ...@@ -154,6 +154,8 @@ struct MBR
(mbr->xmax <= xmax) && (mbr->ymax <= ymax)); (mbr->xmax <= xmax) && (mbr->ymax <= ymax));
} }
int coveredby(const MBR *mbr);
bool inner_point(double x, double y) const bool inner_point(double x, double y) const
{ {
/* The following should be safe, even if we compare doubles */ /* The following should be safe, even if we compare doubles */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment