diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2020-03-18 13:55:21 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2020-03-18 13:55:21 +0400 |
commit | a0ce62f804dc1a0073688bea46dc2e6728cf55e3 (patch) | |
tree | be748f27c54e196a65e719a6299046b3b9e32478 /sql/spatial.cc | |
parent | 09e8707d90a8a73887fd4f22b64df43ff4669556 (diff) | |
download | mariadb-git-a0ce62f804dc1a0073688bea46dc2e6728cf55e3.tar.gz |
MDEV-14057 InnoDB GIS tests fail.
Tests fixed.
MBR::Within() function fixed.
Diffstat (limited to 'sql/spatial.cc')
-rw-r--r-- | sql/spatial.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/sql/spatial.cc b/sql/spatial.cc index 7c78b0dcb71..83905fc9f3d 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -50,6 +50,98 @@ double my_double_round(double value, longlong dec, bool dec_unsigned, #define MAX_DIGITS_IN_DOUBLE MY_GCVT_MAX_FIELD_WIDTH +int MBR::within(const MBR *mbr) +{ + /* + We have to take into account the 'dimension' of + the MBR, where the dimension of a single point is 0, + the dimesion of an vertical or horizontal line is 1, + and finally the dimension of the solid rectangle is 2. + */ + + int dim1= dimension(); + int dim2= mbr->dimension(); + + DBUG_ASSERT(dim1 >= 0 && dim1 <= 2 && dim2 >= 0 && dim2 <= 2); + + /* + Either/both of the two operands can degrade to a point or a + horizontal/vertical line segment, and we have to treat such cases + separately. + */ + switch (dim1) + { + case 0: + DBUG_ASSERT(xmin == xmax && ymin == ymax); + switch (dim2) + { + case 0: + DBUG_ASSERT(mbr->xmin == mbr->xmax && mbr->ymin == mbr->ymax); + return equals(mbr); + break; + case 1: + DBUG_ASSERT((mbr->xmin == mbr->xmax && mbr->ymin != mbr->ymax) || + (mbr->ymin == mbr->ymax && mbr->xmin != mbr->xmax)); + return ((xmin > mbr->xmin && xmin < mbr->xmax && ymin == mbr->ymin) || + (ymin > mbr->ymin && ymin < mbr->ymax && xmin == mbr->xmin)); + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return (xmin > mbr->xmin && xmax < mbr->xmax && + ymin > mbr->ymin && ymax < mbr->ymax); + break; + } + break; + case 1: + DBUG_ASSERT((xmin == xmax && ymin != ymax) || + (ymin == ymax && xmin != xmax)); + switch (dim2) + { + case 0: + DBUG_ASSERT(mbr->xmin == mbr->xmax && mbr->ymin == mbr->ymax); + return 0; + break; + case 1: + DBUG_ASSERT((mbr->xmin == mbr->xmax && mbr->ymin != mbr->ymax) || + (mbr->ymin == mbr->ymax && mbr->xmin != mbr->xmax)); + return ((xmin == xmax && mbr->xmin == mbr->xmax && mbr->xmin == xmin && + mbr->ymin <= ymin && mbr->ymax >= ymax) || + (ymin == ymax && mbr->ymin == mbr->ymax && mbr->ymin == ymin && + mbr->xmin <= xmin && mbr->xmax >= xmax)); + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return ((xmin == xmax && xmin > mbr->xmin && xmax < mbr->xmax && + ymin >= mbr->ymin && ymax <= mbr->ymax) || + (ymin == ymax && ymin > mbr->ymin && ymax < mbr->ymax && + xmin >= mbr->xmin && xmax <= mbr->xmax)); + break; + } + break; + case 2: + DBUG_ASSERT(xmin != xmax && ymin != ymax); + switch (dim2) + { + case 0: + case 1: + return 0; + break; + case 2: + DBUG_ASSERT(mbr->xmin != mbr->xmax && mbr->ymin != mbr->ymax); + return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && + (mbr->xmax >= xmax) && (mbr->ymax >= ymax)); + break; + + } + break; + } + + // Never reached. + DBUG_ASSERT(false); + return 0; +} + + /***************************** Gis_class_info *******************************/ String Geometry::bad_geometry_data("Bad object", &my_charset_bin); |