Bug #46386 Intersection() and Difference() make the server disconnect
Submitted: 26 Jul 2009 2:45 Modified: 7 Aug 2012 12:26
Reporter: Andi Kalsch Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: GIS Severity:S1 (Critical)
Version:5.1.35-snapshot20090630 Source distribution, mysql-5.1-wl1326 OS:Linux
Assigned to: Assigned Account CPU Architecture:Any
Tags: analysis, gis, spatial

[26 Jul 2009 2:45] Andi Kalsch
Description:
It seems that for complex or big geometries, Intersection() or Difference() (and probably some other geometry creation functions) will make the server go away with Code "HY000".

How to repeat:
I cannot reproduce this as a whole. I will just post two statements and you can try similar things with a bug dataset:

SET @geom := (
  SELECT geom FROM _area_surface WHERE class = ? AND id = ?
)

^ This geometry is a MULTIPOLYGON AND != NULL

SELECT 
	class,
	id,
	level
FROM _area_surface
WHERE 
	Intersects(@geom, geom)
	AND level < ?
	AND Area(Difference(@geom, geom)) / Area(@geom) < .1
/* AND Area(Intersection(@geom, geom)) / Area(@geom) > .9 */
ORDER BY level DESC
LIMIT 1
[26 Jul 2009 7:12] Valeriy Kravchuk
Thank you for the problem report. How big geometries should be, based on your experience? How many points/curves?
[26 Jul 2009 13:59] Andi Kalsch
The geometries are Multipolygons with many thousand nodes, like this: http://www.openstreetmap.org/browse/relation/62771

The current dataset contains all available German political areas of OpenStreetMap - 1700 Surfaces and 60000 Points.

Without Difference() or Intersection() all would work properly.
[26 Jul 2009 14:55] Andi Kalsch
From the error log:

key_buffer_size=67108864
read_buffer_size=131072
max_used_connections=3
max_threads=151
threads_connected=3
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 395065 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

thd: 0x85346b0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0xaf36b3a4 thread_stack 0x20000
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(my_print_stacktrace+0x22) [0x83a7e92]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(handle_segfault+0x39e) [0x81ba33e]
[0xb7f02420]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Gis_polygon::priv_init_from_opresult(String*, char const*, unsigned int, unsigned int*)+0x10d) [0x830233d]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Gis_multi_polygon::init_from_opresult(String*, char const*, unsigned int)+0x88) [0x8302468]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Geometry::create_from_opresult(Geometry_buffer*, String*, gcalc_result_receiver&)+0xa5) [0x8302cd5]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Item_func_spatial_operation::val_str(String*)+0x259) [0x817ac49]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Item_func_area::val_real()+0x2c) [0x817a69c]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Arg_comparator::compare_real()+0x16) [0x813d156]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Item_func_lt::val_int()+0x2a) [0x814612a]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Item::val_bool()+0x58) [0x8103ab8]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(Item_cond_and::val_int()+0x33) [0x8140c83]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld [0x82a98c9]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(filesort(THD*, st_table*, st_sort_field*, unsigned int, SQL_SELECT*, unsigned long, bool, unsigned long*)+0x80b) [0x82ab65b]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld [0x8231f85]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(JOIN::exec()+0xaf4) [0x823e084]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*)+0x158) [0x82404e8]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(handle_select(THD*, st_lex*, select_result*, unsigned long)+0x14a) [0x8240d9a]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld [0x81c662d]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(mysql_execute_command(THD*)+0x1d3b) [0x81cbdfb]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(mysql_parse(THD*, char const*, unsigned int, char const**)+0x211) [0x81d3c11]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(dispatch_command(enum_server_command, THD*, char*, unsigned int)+0x43a) [0x81d405a]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(do_command(THD*)+0xe0) [0x81d5230]
/home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld(handle_one_connection+0x5fe) [0x81c3cfe]
/lib/i686/cmov/libpthread.so.0 [0xb7ee44e5]
/lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7cda21e]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort...
thd->query at 0x8540678 = SELECT
        class,
        id,
        level
FROM _area_surface
WHERE
        Intersects(@geom, geom)
        AND level < '4'
        AND Area(Difference(@geom, geom)) < .1 * @area_geom
ORDER BY level DESC
LIMIT 1
thd->thread_id=6
thd->killed=NOT_KILLED
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
090726 16:38:01 mysqld_safe Number of processes running now: 0
090726 16:38:01 mysqld_safe mysqld restarted
090726 16:38:01 [Note] Event Scheduler: Loaded 0 events
090726 16:38:01 [Note] /home/andi/mysql-5.1-wl1326/5.1.35/libexec/mysqld: ready for connections.
Version: '5.1.35'  socket: '/tmp/mysql_sandbox5135.sock'  port: 3306  Source distribution
090726 16:43:41 - mysqld got signal 11 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help diagnose
the problem, but since we have already crashed, something is definitely wrong
and this may fail.
[28 Jul 2009 20:49] Sveta Smirnova
Thank you for the report.

Partially verified as described: get crash with Difference:

/users/ssmirnova//blade12/build/mysql-5.1-wl1326/libexec/mysqld[0x8618fc]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZNK11Gis_polygon4areaEPdPPKc+0x17d)[0x863ddd]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZNK17Gis_multi_polygon4areaEPdPPKc+0xfc)[0x866f5a]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN14Item_func_area8val_realEv+0xd6)[0x64c6f0]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN13Item_func_div7real_opEv+0x58)[0x5e58ca]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN19Item_func_numhybrid8val_realEv+0x16d)[0x5e3cb3]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN14Arg_comparator12compare_realEv+0x31)[0x5fd281]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN14Arg_comparator7compareEv+0x57)[0x60bb13]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN12Item_func_lt7val_intEv+0x43)[0x5fef45]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN4Item8val_boolEv+0x5a)[0x5b36f8]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN13Item_cond_and7val_intEv+0x6e)[0x607a44]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld[0x72e4a6]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z10sub_selectP4JOINP13st_join_tableb+0x179)[0x72e347]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld[0x72de6e]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_ZN4JOIN4execEv+0x24c2)[0x7173d0]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z12mysql_selectP3THDPPP4ItemP10TABLE_LISTjR4ListIS1_ES2_jP8st_orderSB_S2_SB_yP13select_resultP18st_select_lex_unitP13st_select_lex+0x323)[0x717a83]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z13handle_selectP3THDP6st_lexP13select_resultm+0x1ba)[0x710170]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld[0x6afcd7]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z21mysql_execute_commandP3THD+0x88f)[0x6a6dea]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z11mysql_parseP3THDPKcjPS2_+0x293)[0x6b1f9c]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcj+0xcff)[0x6a48f0]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(_Z10do_commandP3THD+0x272)[0x6a3976]
/users/ssmirnova/blade12/build/mysql-5.1-wl1326/libexec/mysqld(handle_one_connection+0x129)[0x6a1de2]
/lib64/libpthread.so.0[0x3429e061b5]
/lib64/libc.so.6(clone+0x6d)[0x34292cd39d]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort...
thd->query at 0x13159298 = SELECT fid, g FROM  gis_multi_polygon WHERE Intersects(@geom, g) and fid < 120 AND Area(Difference(@geom, g)) / Area(@geom) < .1 ORDER BY fid DESC LIMIT 1
[28 Jul 2009 20:50] Sveta Smirnova
Test used:

$cat t/bug46386_2.test 
DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
CREATE TABLE gis_multi_polygon  (fid INTEGER NOT NULL PRIMARY KEY, g MULTIPOLYGON);
SHOW FIELDS FROM gis_multi_polygon;
INSERT INTO gis_multi_polygon VALUES
(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
SELECT fid, AsText(g) FROM gis_multi_polygon;
SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
SELECT fid, Area(g) FROM gis_multi_polygon;
SELECT fid, NumGeometries(g) from gis_multi_polygon;
SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon;
SET @geom := (SELECT g FROM  gis_multi_polygon WHERE fid=118);
SELECT fid, g FROM  gis_multi_polygon WHERE Intersects(@geom, g) and fid < 120 AND Area(Difference(@geom, g)) / Area(@geom) < .1 ORDER BY fid DESC LIMIT 1;
SELECT fid, g FROM  gis_multi_polygon WHERE Intersects(@geom, g) and fid < 120 AND Area(Intersection(@geom, g)) / Area(@geom) > .9 ORDER BY fid DESC LIMIT 1;
DROP TABLE gis_multi_polygon;
[28 Jul 2009 20:53] Sveta Smirnova
Andi,

please provide example of row crash with Intersection is repeatable with.
[29 Jul 2009 17:34] Andi Kalsch
It is as simple as this. - MySQL GIS has no function to check validity of a geometry - so I don't guarantee for validity.

Attachment: geom (application/octet-stream, text), 108.33 KiB.

[29 Jul 2009 19:39] Andi Kalsch
The test I have posted does not work either in the latest "5.1.35-snapshot20090630 Source distribution" (provided as official MySQL GIS branch).
[29 Jul 2009 22:13] Sveta Smirnova
Thank you for the feedback.

Test you provided crashes mysqld for me.
[30 Jul 2009 22:55] Sveta Smirnova
Problem is only repeatable with  mysql-5.1-wl1326 tree
[2 Aug 2009 17:23] Andi Kalsch
So is the latest build of the branch, _which provides full OpenGIS functionality_, currently crashing?
[4 Aug 2009 9:10] Sveta Smirnova
Andi,

yes, build of latest update (update/build from July, 28) crashes.
[6 Dec 2009 9:29] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/92991

2664 Alexey Botchkov	2009-12-05
      Bug #46386      Intersection() and Difference() make the server disconnect
           there was a mistake in handling of 'holes' in the polygons.
           Fixed by adding the 'first_poly_node' pointer to the res_point
           structure to point to the first point of the surrounding polygon.
           Also a set of debugging functions was added. It doesn't affect the
           working fucntions, but greatly simplifies the debugging.
           This path fixes also bug#46498.
      
       per-file comments:
         sql/gcalc_slicescan.cc
      Bug #46386      Intersection() and Difference() make the server disconnect
         sql/gcalc_slicescan.h
      Bug #46386      Intersection() and Difference() make the server disconnect
         sql/gcalc_tools.cc
      Bug #46386      Intersection() and Difference() make the server disconnect
         sql/gcalc_tools.h
      Bug #46386      Intersection() and Difference() make the server disconnect
         sql/item_geofunc.cc
      Bug #46386      Intersection() and Difference() make the server disconnect
         sql/spatial.cc
      Bug #46386      Intersection() and Difference() make the server disconnect
[7 Aug 2012 12:26] Alexander Barkov
This bug was earlier fixed in mysql-gis tree (before mysql-5.6 release).