Skip to content

Commit 1401d2f

Browse files
StefanoPetrillidahlerlendnryengMartin HanssonErik Froseth
authored andcommitted
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: Erlend Dahl <erlend.dahl@oracle.com> Co-authored-by: Norvald H. Ryeng <norvald.ryeng@oracle.com> Co-authored-by: Martin Hansson <martin.hansson@oracle.com> Co-authored-by: Erik Froseth <erik.froseth@oracle.com> Co-authored-by: Hans H Melby <hans.h.melby@oracle.com> Co-authored-by: Jens Even Berg Blomsøy <jens.even.blomosoy@oracle.com> Co-authored-by: David Zhao <david.zhao@oracle.com> Co-authored-by: BennyWang <benny.wang@oracle.com>
1 parent 47ed8c0 commit 1401d2f

File tree

7 files changed

+2220
-4
lines changed

7 files changed

+2220
-4
lines changed

client/mysql.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,7 @@ static COMMANDS commands[] = {
10331033
{ "MASTER_POS_WAIT", 0, 0, 0, ""},
10341034
{ "MAX", 0, 0, 0, ""},
10351035
{ "MBRCONTAINS", 0, 0, 0, ""},
1036+
{ "MBRCOVEREDBY", 0, 0, 0, ""},
10361037
{ "MBRDISJOINT", 0, 0, 0, ""},
10371038
{ "MBREQUAL", 0, 0, 0, ""},
10381039
{ "MBRINTERSECTS", 0, 0, 0, ""},

mysql-test/main/spatial_testing_functions_coveredby.result

Lines changed: 1184 additions & 0 deletions
Large diffs are not rendered by default.

mysql-test/main/spatial_testing_functions_coveredby.test

Lines changed: 966 additions & 0 deletions
Large diffs are not rendered by default.

sql/item_func.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class Item_func :public Item_func_or_sum
9696
INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
9797
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
9898
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
99-
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
99+
SP_CONTAINS_FUNC, SP_COVEREDBY_FUNC, SP_OVERLAPS_FUNC,
100100
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
101101
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC,
102102
NOT_FUNC, NOT_ALL_FUNC, TEMPTABLE_ROWID,

sql/item_geofunc.cc

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,10 +1139,12 @@ Item_func_spatial_rel::get_mm_leaf(RANGE_OPT_PARAM *param,
11391139

11401140

11411141
LEX_CSTRING Item_func_spatial_mbr_rel::func_name_cstring() const
1142-
{
1142+
{
11431143
switch (spatial_rel) {
11441144
case SP_CONTAINS_FUNC:
11451145
return { STRING_WITH_LEN("mbrcontains") };
1146+
case SP_COVEREDBY_FUNC:
1147+
return { STRING_WITH_LEN("mbrcoveredby") };
11461148
case SP_WITHIN_FUNC:
11471149
return { STRING_WITH_LEN("mbrwithin") } ;
11481150
case SP_EQUALS_FUNC:
@@ -1183,9 +1185,15 @@ bool Item_func_spatial_mbr_rel::val_bool()
11831185
g2->get_mbr(&mbr2, &dummy) || !mbr2.valid())))
11841186
return 0;
11851187

1188+
uint32 srid1= uint4korr(res1->ptr()), srid2= uint4korr(res2->ptr());
1189+
if (srid1 != srid2)
1190+
my_error(ER_GIS_DIFFERENT_SRIDS, MYF(0), func_name(), srid1, srid2);
1191+
11861192
switch (spatial_rel) {
11871193
case SP_CONTAINS_FUNC:
11881194
return mbr1.contains(&mbr2);
1195+
case SP_COVEREDBY_FUNC:
1196+
return mbr1.coveredby(&mbr2);
11891197
case SP_WITHIN_FUNC:
11901198
return mbr1.within(&mbr2);
11911199
case SP_EQUALS_FUNC:
@@ -1209,11 +1217,14 @@ bool Item_func_spatial_mbr_rel::val_bool()
12091217
}
12101218

12111219

1220+
12121221
LEX_CSTRING Item_func_spatial_precise_rel::func_name_cstring() const
1213-
{
1222+
{
12141223
switch (spatial_rel) {
12151224
case SP_CONTAINS_FUNC:
12161225
return { STRING_WITH_LEN("st_contains") };
1226+
case SP_COVEREDBY_FUNC:
1227+
return { STRING_WITH_LEN("st_coveredby") };
12171228
case SP_WITHIN_FUNC:
12181229
return { STRING_WITH_LEN("st_within") };
12191230
case SP_EQUALS_FUNC:
@@ -3085,6 +3096,38 @@ class Create_func_contains : public Create_func_arg2
30853096
};
30863097

30873098

3099+
class Create_func_mbr_coveredby : public Create_func_arg2
3100+
{
3101+
public:
3102+
Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) override
3103+
{
3104+
return new (thd->mem_root) Item_func_spatial_mbr_rel(thd, arg1, arg2,
3105+
Item_func::SP_COVEREDBY_FUNC);
3106+
}
3107+
3108+
static Create_func_mbr_coveredby s_singleton;
3109+
3110+
protected:
3111+
Create_func_mbr_coveredby() = default;
3112+
~Create_func_mbr_coveredby() override = default;
3113+
};
3114+
3115+
class Create_func_coveredby : public Create_func_arg2
3116+
{
3117+
public:
3118+
Item *create_2_arg(THD *thd, Item *arg1, Item *arg2) override
3119+
{
3120+
return new (thd->mem_root) Item_func_spatial_precise_rel(thd, arg1, arg2,
3121+
Item_func::SP_COVEREDBY_FUNC);
3122+
}
3123+
static Create_func_coveredby s_singleton;
3124+
3125+
protected:
3126+
Create_func_coveredby() = default;
3127+
~Create_func_coveredby() override = default;
3128+
};
3129+
3130+
30883131
class Create_func_crosses : public Create_func_arg2
30893132
{
30903133
public:
@@ -4092,6 +4135,7 @@ Create_func_boundary Create_func_boundary::s_singleton;
40924135
Create_func_buffer Create_func_buffer::s_singleton;
40934136
Create_func_centroid Create_func_centroid::s_singleton;
40944137
Create_func_contains Create_func_contains::s_singleton;
4138+
Create_func_coveredby Create_func_coveredby::s_singleton;
40954139
Create_func_convexhull Create_func_convexhull::s_singleton;
40964140
Create_func_crosses Create_func_crosses::s_singleton;
40974141
Create_func_difference Create_func_difference::s_singleton;
@@ -4118,6 +4162,7 @@ Create_func_isempty Create_func_isempty::s_singleton;
41184162
Create_func_isring Create_func_isring::s_singleton;
41194163
Create_func_issimple Create_func_issimple::s_singleton;
41204164
Create_func_mbr_contains Create_func_mbr_contains::s_singleton;
4165+
Create_func_mbr_coveredby Create_func_mbr_coveredby::s_singleton;
41214166
Create_func_mbr_disjoint Create_func_mbr_disjoint::s_singleton;
41224167
Create_func_mbr_equals Create_func_mbr_equals::s_singleton;
41234168
Create_func_mbr_intersects Create_func_mbr_intersects::s_singleton;
@@ -4159,6 +4204,7 @@ static Native_func_registry func_array_geom[] =
41594204
{ { STRING_WITH_LEN("BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
41604205
{ { STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
41614206
{ { STRING_WITH_LEN("CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
4207+
{ { STRING_WITH_LEN("COVEREDBY") }, GEOM_BUILDER(Create_func_coveredby)},
41624208
{ { STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
41634209
{ { STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
41644210
{ { STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)},
@@ -4189,6 +4235,7 @@ static Native_func_registry func_array_geom[] =
41894235
{ { STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
41904236
{ { STRING_WITH_LEN("LINESTRINGFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
41914237
{ { STRING_WITH_LEN("MBRCONTAINS") }, GEOM_BUILDER(Create_func_mbr_contains)},
4238+
{ { STRING_WITH_LEN("MBRCOVEREDBY") }, GEOM_BUILDER(Create_func_mbr_coveredby)},
41924239
{ { STRING_WITH_LEN("MBRDISJOINT") }, GEOM_BUILDER(Create_func_mbr_disjoint)},
41934240
{ { STRING_WITH_LEN("MBREQUAL") }, GEOM_BUILDER(Create_func_mbr_equals)},
41944241
{ { STRING_WITH_LEN("MBREQUALS") }, GEOM_BUILDER(Create_func_mbr_equals)},
@@ -4233,6 +4280,7 @@ static Native_func_registry func_array_geom[] =
42334280
{ { STRING_WITH_LEN("ST_BUFFER") }, GEOM_BUILDER(Create_func_buffer)},
42344281
{ { STRING_WITH_LEN("ST_CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
42354282
{ { STRING_WITH_LEN("ST_CONTAINS") }, GEOM_BUILDER(Create_func_contains)},
4283+
{ { STRING_WITH_LEN("ST_COVEREDBY") }, GEOM_BUILDER(Create_func_coveredby)},
42364284
{ { STRING_WITH_LEN("ST_CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
42374285
{ { STRING_WITH_LEN("ST_CROSSES") }, GEOM_BUILDER(Create_func_crosses)},
42384286
{ { STRING_WITH_LEN("ST_DIFFERENCE") }, GEOM_BUILDER(Create_func_difference)},

sql/spatial.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
double my_double_round(double value, longlong dec, bool dec_unsigned,
2626
bool truncate);
2727

28-
/*
28+
/*
2929
exponential notation :
3030
1 sign
3131
1 number before the decimal point
@@ -140,6 +140,21 @@ int MBR::within(const MBR *mbr)
140140
}
141141

142142

143+
int MBR::coveredby(const MBR *mbr)
144+
{
145+
int dim1= dimension();
146+
int dim2= mbr->dimension();
147+
148+
if (dim1 > dim2)
149+
return 0;
150+
else if (dim1 == 0 && dim2 == 0)
151+
return equals(mbr);
152+
153+
return ((xmin >= mbr->xmin) && (xmax <= mbr->xmax) &&
154+
(ymin >= mbr->ymin) && (ymax <= mbr->ymax));
155+
}
156+
157+
143158
/***************************** Gis_class_info *******************************/
144159

145160
Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_last+1]=

sql/spatial.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ struct MBR
152152
(mbr->xmax <= xmax) && (mbr->ymax <= ymax));
153153
}
154154

155+
int coveredby(const MBR *mbr);
156+
155157
bool inner_point(double x, double y) const
156158
{
157159
/* The following should be safe, even if we compare doubles */

0 commit comments

Comments
 (0)