| Bug #34620 | item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed | ||
|---|---|---|---|
| Submitted: | 16 Feb 2008 17:16 | Modified: | 15 Mar 2008 8:41 |
| Reporter: | Gleb Shchepa | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: DML | Severity: | S3 (Non-critical) |
| Version: | 5.0+, 5.0.58-BK | OS: | Any |
| Assigned to: | Gleb Shchepa | CPU Architecture: | Any |
[16 Feb 2008 19:36]
Valeriy Kravchuk
Thank you for a bug report. Verified just as described with latest 5.0.58-BK on Linux.
[22 Feb 2008 17:21]
Gleb Shchepa
If ROW item is a part of an expression that also has
aggregate function calls (COUNT/SUM/AVG...), a
"splitting" with a Item::split_sum_func2 function
is applied to that ROW item.
Current implementation of Item::split_sum_func2
a. calls Item_row::split_sum_func on this ROW item
if its "columns" contain aggregate fuctions, otherwise
b. replaces this Item_row with a newly created
Item_aggregate_ref reference to it.
(a) is ok, but (b) is an error, because Item_aggregate_ref
is not suited for referencing multicolumn objects like
ROW or multicolumn subselect.
This error leads to several problems:
1. wrong result:
SELECT ROW(a, 1) = (SELECT SUM(b), 10) FROM t1 GROUP BY a;
This query returns 1 if t1 consists of the (1, 1) row,
because Item_aggregate_ref::cols() always return 1 and
comparison of 2nd "columns" (1 = 10) is always skipped;
2. failed assertion in debugging build:
SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
This query fails in the Item_row::illegal_method_call
method after unexpected try to call Item_row::val_int (or
another val_* method).
It is because the IN expression evaluates with the aid of
row cache, and row cache stores ROW item elements for
further comparison reasons via sequential calls to the
element_index method. This method is not overloaded for
the Item_aggregate_ref class and it always returns 'this'
pointer. So, instead of storing scalar values of ROW
elements, row cache trying to obtain and store scalar
value of a whole ROW.
IMO replacement of ROW item with a Item_aggregate_ref reference
item is unnecessary, and instead of overloading of
Item_aggregate_ref::cols and Item_aggregate_ref::::element_index
methods to route those calls to real item, I prefer to deal with
ROW items like with [multicolumn] subselect items it the
Item::split_sum_func2 method.
[27 Feb 2008 11:16]
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/43041 ChangeSet@1.2607, 2008-02-27 15:15:09+04:00, gshchepa@host.loc +3 -0 Fixed bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed If ROW item is a part of an expression that also has aggregate function calls (COUNT/SUM/AVG...), a "splitting" with an Item::split_sum_func2 function is applied to that ROW item. Current implementation of Item::split_sum_func2 replaces this Item_row with a newly created Item_aggregate_ref reference to it. Then the row cache tries to work with the Item_aggregate_ref object as with the Item_row object: row cache calls row-emulation methods such as cols and element_index. Item_aggregate_ref (like it's parent Item_ref) inherits dummy implementations of those methods from the hierarchy root Item, and call to them leads to failed assertions and wrong data output. Row-emulation virtual functions (cols, element_index, addr, check_cols, null_inside and bring_value) of Item_ref have been overloaded to forward calls to an underlying item reference.
[27 Feb 2008 17:52]
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/43094 ChangeSet@1.2607, 2008-02-27 21:51:23+04:00, gshchepa@host.loc +3 -0 Fixed bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed If ROW item is a part of an expression that also has aggregate function calls (COUNT/SUM/AVG...), a "splitting" with an Item::split_sum_func2 function is applied to that ROW item. Current implementation of Item::split_sum_func2 replaces this Item_row with a newly created Item_aggregate_ref reference to it. Then the row cache tries to work with the Item_aggregate_ref object as with the Item_row object: row cache calls row-emulation methods such as cols and element_index. Item_aggregate_ref (like it's parent Item_ref) inherits dummy implementations of those methods from the hierarchy root Item, and call to them leads to failed assertions and wrong data output. Row-emulation virtual functions (cols, element_index, addr, check_cols, null_inside and bring_value) of Item_ref have been overloaded to forward calls to an underlying item reference.
[27 Feb 2008 21:59]
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/43116 ChangeSet@1.2607, 2008-02-28 01:58:06+04:00, gshchepa@host.loc +3 -0 Fixed bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed If ROW item is a part of an expression that also has aggregate function calls (COUNT/SUM/AVG...), a "splitting" with an Item::split_sum_func2 function is applied to that ROW item. Current implementation of Item::split_sum_func2 replaces this Item_row with a newly created Item_aggregate_ref reference to it. Then the row cache tries to work with the Item_aggregate_ref object as with the Item_row object: row cache calls row-emulation methods such as cols and element_index. Item_aggregate_ref (like it's parent Item_ref) inherits dummy implementations of those methods from the hierarchy root Item, and call to them leads to failed assertions and wrong data output. Row-emulation virtual functions (cols, element_index, addr, check_cols, null_inside and bring_value) of Item_ref have been overloaded to forward calls to an underlying item reference.
[28 Feb 2008 17:55]
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/43165 ChangeSet@1.2607, 2008-02-28 21:52:16+04:00, gshchepa@host.loc +3 -0 Fixed bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed If ROW item is a part of an expression that also has aggregate function calls (COUNT/SUM/AVG...), a "splitting" with an Item::split_sum_func2 function is applied to that ROW item. Current implementation of Item::split_sum_func2 replaces this Item_row with a newly created Item_aggregate_ref reference to it. Then the row cache tries to work with the Item_aggregate_ref object as with the Item_row object: row cache calls row-emulation methods such as cols and element_index. Item_aggregate_ref (like it's parent Item_ref) inherits dummy implementations of those methods from the hierarchy root Item, and call to them leads to failed assertions and wrong data output. Row-emulation virtual functions (cols, element_index, addr, check_cols, null_inside and bring_value) of Item_ref have been overloaded to forward calls to an underlying item reference.
[28 Feb 2008 18:56]
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/43171 ChangeSet@1.2607, 2008-02-28 22:53:31+04:00, gshchepa@host.loc +3 -0 Fixed bug #34620: item_row.cc:50: Item_row::illegal_method_call(const char*): Assertion `0' failed If ROW item is a part of an expression that also has aggregate function calls (COUNT/SUM/AVG...), a "splitting" with an Item::split_sum_func2 function is applied to that ROW item. Current implementation of Item::split_sum_func2 replaces this Item_row with a newly created Item_aggregate_ref reference to it. Then the row cache tries to work with the Item_aggregate_ref object as with the Item_row object: row cache calls row-emulation methods such as cols and element_index. Item_aggregate_ref (like it's parent Item_ref) inherits dummy implementations of those methods from the hierarchy root Item, and call to them leads to failed assertions and wrong data output. Row-emulation virtual functions (cols, element_index, addr, check_cols, null_inside and bring_value) of Item_ref have been overloaded to forward calls to an underlying item reference.
[13 Mar 2008 19:26]
Bugs System
Pushed into 6.0.5-alpha
[13 Mar 2008 19:34]
Bugs System
Pushed into 5.1.24-rc
[13 Mar 2008 19:42]
Bugs System
Pushed into 5.0.60
[15 Mar 2008 8:41]
Jon Stephens
Documented bugfix in the 5.0.60, 5.1.24, and 6.0.5 changelogs as follows:
Some subqueries using an expression that included an aggregate
function could fail or in some cases lead to a crash of the server.
[2 Apr 2008 20:00]
Jon Stephens
Also noted in the 5.1.23-ndb-6.3.11 changelog.

Description: On debug build: Query: ------ Server version: 5.0.56-debug Source distribution mysql> CREATE TABLE t1 (a INT, b INT); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t1 VALUES (1,1); Query OK, 1 row affected (0.00 sec) mysql> SELECT t1.a FROM t1 GROUP BY t1.a HAVING ROW(t1.a, 1) IN (SELECT SUM(t1.b), 1); ERROR 2013 (HY000): Lost connection to MySQL server during query var/log/master.trace: --------------------- T@-1219708: | | | | | | | | >Item_row::illegal_method_call T@-1219708: | | | | | | | | | error: !!! val_int method was called for row item Stack trace: ------------ #2 0xb7da88e8 in abort () from /lib/libc.so.6 #3 0xb7da07a5 in __assert_fail () from /lib/libc.so.6 #4 0x081a122a in Item_row::illegal_method_call (this=0x873d020, method=0x84f1860 "val_int") at item_row.cc:50 #5 0x081a1523 in Item_row::val_int (this=0x873d020) at item_row.h:48 #6 0x0813f812 in Item::val_int_result (this=0x873d020) at item.h:650 #7 0x0812fe6f in Item_ref::val_int (this=0x8744400) at item.cc:5593 #8 0x0812e8de in Item_ref::val_int_result (this=0x8744400) at item.cc:5523 #9 0x0812efdc in Item_cache_int::store (this=0x87442d8, item=0x8744400) at item.cc:6350 #10 0x0812f15c in Item_cache_row::store (this=0x873e7d0, item=0x8744400) at item.cc:6544 #11 0x0816d82b in Item_in_optimizer::val_int (this=0x873e750) at item_cmpfunc.cc:1467 #12 0x0823bfff in end_send_group (join=0x873d7f0, join_tab=0x8744920, end_of_records=true) at sql_select.cc:11599 #13 0x082449bf in do_select (join=0x873d7f0, fields=0x873e578, table=0x0, procedure=0x0) at sql_select.cc:10414 #14 0x0825b3ee in JOIN::exec (this=0x873d7f0) at sql_select.cc:2118 #15 0x08257327 in mysql_select (thd=0x87042e0, rref_pointer_array=0x87053a0, tables=0x873cc88, wild_num=0, fields=@0x8705310, conds=0x0, og_num=1, order=0x0, group=0x873ced8, having=0x873d6a0, proc_param=0x0, select_options=2156153344, result=0x873d7d8, unit=0x8705044, select_lex=0x870527c) at sql_select.cc:2296 #16 0x0825b702 in handle_select (thd=0x87042e0, lex=0x8704fec, result=0x873d7d8, setup_tables_done_option=0) at sql_select.cc:257 #17 0x081ef6d5 in mysql_execute_command (thd=0x87042e0) at sql_parse.cc:2736 #18 0x081f7afc in mysql_parse (thd=0x87042e0, inBuf=0x873cb20 "SELECT t1.a FROM t1 GROUP BY t1.a HAVING ROW(t1.a, 1) IN (SELECT SUM(t1.b), 1)", length=78, found_semicolon=0xb745b1b0) at sql_parse.cc:6174 #19 0x081fa346 in dispatch_command (command=COM_QUERY, thd=0x87042e0, packet=0x8734ac1 "", packet_length=79) at sql_parse.cc:1889 #20 0x081fb89f in do_command (thd=0x87042e0) at sql_parse.cc:1595 #21 0x081fc89b in handle_one_connection (arg=0x87042e0) at sql_parse.cc:1201 #22 0xb7f1f18b in start_thread () from /lib/libpthread.so.0 #23 0xb7e3f09e in clone () from /lib/libc.so.6 On non-debugging build (wrong result): -------------------------------------- Server version: 5.0.56 Source distribution mysql> CREATE TABLE t1 (a INT, b INT); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t1 VALUES (1,1); Query OK, 1 row affected (0.00 sec) mysql> SELECT t1.a FROM t1 GROUP BY t1.a HAVING ROW(t1.a, 1) IN (SELECT SUM(t1.b), 1); ERROR 1241 (21000): Operand should contain 1 column(s) How to repeat: --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 VALUES (1,1); SELECT t1.a FROM t1 GROUP BY t1.a HAVING ROW(t1.a, 1) IN (SELECT SUM(t1.b), 1); DROP TABLE t1;