Bug #27154 Server crash on statement using 3-dimensional row constructor
Submitted: 14 Mar 2007 20:41 Modified: 3 Apr 2007 22:37
Reporter: Aurel Pekarcik Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.37-community-nt/5.0BK OS:Windows (WinXP/Vista)
Assigned to: Igor Babaev CPU Architecture:Any
Tags: regression, row constructor

[14 Mar 2007 20:41] Aurel Pekarcik
Description:
Server crash on statement using 3-dimensional row constructor.
This statement works properly on 5.0.27 under the same conditions.

How to repeat:
drop table if exists test.T1;
create table test.T1(A int, B int, c int, D int,
 primary key (A,B,C) ) engine = myisam;

insert test.T1 (A,B,C,D) values (1,1,1,99);

set @X:=(select D from test.T1 where (A,B,C)=(1,1,1));

-- or

select D into @X from test.T1 where (A,B,C)=(1,1,1);

Suggested fix:
The right functionality.
[14 Mar 2007 22:26] MySQL Verification Team
Thank you for the bug report. This regression bugs only affects the
Windows version:

Microsoft Windows [versão 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. Todos os direitos reservados.

c:\>cd mysql-5.0.27-win32

c:\mysql-5.0.27-win32>bin\mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.0.27-community-nt

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> drop table if exists test.T1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table test.T1(A int, B int, c int, D int,
    ->  primary key (A,B,C) ) engine = myisam;
Query OK, 0 rows affected (0.05 sec)

mysql>
mysql> insert test.T1 (A,B,C,D) values (1,1,1,99);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> set @X:=(select D from test.T1 where (A,B,C)=(1,1,1));
Query OK, 0 rows affected (0.00 sec)

mysql>

c:\build\5.0>bin\mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.38 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> drop table if exists test.T1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create table test.T1(A int, B int, c int, D int,
    ->  primary key (A,B,C) ) engine = myisam;
Query OK, 0 rows affected (0.13 sec)

mysql>
mysql> insert test.T1 (A,B,C,D) values (1,1,1,99);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> set @X:=(select D from test.T1 where (A,B,C)=(1,1,1));
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>

>	mysqld-nt.exe!make_join_statistics(JOIN * join=0x0203cf98, st_table_list * tables=0x00000000, Item * conds=0x020396b0, st_dynamic_array * keyuse_array=0x0203dcd0)  Line 2549	C++
 	mysqld-nt.exe!JOIN::optimize()  Line 849 + 0x21 bytes	C++
 	mysqld-nt.exe!subselect_single_select_engine::exec()  Line 1769 + 0x8 bytes	C++
 	mysqld-nt.exe!Item_subselect::exec()  Line 214	C++
 	mysqld-nt.exe!Item_singlerow_subselect::val_int()  Line 506 + 0xa bytes	C++
 	mysqld-nt.exe!Item_func_set_user_var::check(int use_result_field=0)  Line 3900	C++
 	mysqld-nt.exe!set_var_user::check(THD * thd=0x01ff9618)  Line 3282 + 0x21 bytes	C++
 	mysqld-nt.exe!sql_set_variables(THD * thd=0x01ff9618, List<set_var_base> * var_list=0x01ffa80c)  Line 3141 + 0x8 bytes	C++
 	mysqld-nt.exe!mysql_execute_command(THD * thd=0x01ff9618)  Line 3791 + 0x7 bytes	C++
 	mysqld-nt.exe!mysql_parse(THD * thd=0x01ff9618, char * inBuf=0x020380b0, unsigned int length=53)  Line 5929	C++
 	mysqld-nt.exe!dispatch_command(enum_server_command command=COM_QUERY, THD * thd=0x01ff9618, char * packet=0x0202fe61, unsigned int packet_length=54)  Line 1797	C++
 	mysqld-nt.exe!do_command(THD * thd=0x00000036)  Line 1577 + 0x10 bytes	C++
 	mysqld-nt.exe!handle_one_connection(void * arg=0x01ff9618)  Line 1191 + 0xa bytes	C++
 	mysqld-nt.exe!_pthread_start()  + 0x3b bytes	C
 	mysqld-nt.exe!_callthreadstart()  Line 293 + 0x6 bytes	C
 	mysqld-nt.exe!_threadstart(void * ptd=0x02033e70)  Line 275 + 0x5 bytes	C
 	kernel32.dll!776a3833() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
 	ntdll.dll!7753a9bd() 	

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.38-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> drop table if exists test.T1;
Query OK, 0 rows affected, 1 warning (0.02 sec)

mysql> create table test.T1(A int, B int, c int, D int,
    ->  primary key (A,B,C) ) engine = myisam;
Query OK, 0 rows affected (0.03 sec)

mysql> 
mysql> insert test.T1 (A,B,C,D) values (1,1,1,99);
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> set @X:=(select D from test.T1 where (A,B,C)=(1,1,1));
Query OK, 0 rows affected (0.00 sec)

mysql>
[31 Mar 2007 4:51] Igor Babaev
With slightly more complicated example I succeded in causing memory corruption
on Linux (SuSE 10.1) as well:

mysql> SELECT VERSION();
+--------------+
| VERSION()    |
+--------------+
| 5.0.40-debug |
+--------------+
1 row in set (0.00 sec)

mysql> CREATE TABLE t1(
    ->  a int, b int, c int, d int, e int, f int, g int, h int,
    ->  PRIMARY KEY (a,b,c,d,e,f,g)
    -> );
Query OK, 0 rows affected (0.50 sec)

mysql> INSERT INTO t1 VALUES (1,2,3,4,5,6,7,99);
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> SELECT d FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7);
+---+
| d |
+---+
| 4 |
+---+
1 row in set (0.00 sec)

mysql>
mysql> SET @x:= (SELECT h FROM t1 WHERE (a,b,c,d,e,f,g)=(1,2,3,4,5,6,7));

After this I had on the server side:

Error: Memory allocated at (^Y) discovered at sql_select.cc:6149
Error: Memory allocated at (^Y) discovered at 'sql_select.cc:6149'
Error: Memory allocated at (null):0 was underrun, discovered at sql_select.cc:6149
Error: Memory allocated at (null):0 was overrun, discovered at 'sql_select.cc:6149'
Error: Safemalloc link list destroyed, discovered at 'sql_select.cc:6149'
root=0x8d441d0,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at array.c:231
Error: Memory allocated at (null):0 was overrun, discovered at 'array.c:231'
Error: Safemalloc link list destroyed, discovered at 'array.c:231'
root=0x8d441d0,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at sql_lex.cc:198
Error: Memory allocated at (null):0 was overrun, discovered at 'sql_lex.cc:198'
Error: Safemalloc link list destroyed, discovered at 'sql_lex.cc:198'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at sql_lex.cc:199
Error: Memory allocated at (null):0 was overrun, discovered at 'sql_lex.cc:199'
Error: Safemalloc link list destroyed, discovered at 'sql_lex.cc:199'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at lock.cc:269
Error: Memory allocated at (null):0 was overrun, discovered at 'lock.cc:269'
Error: Safemalloc link list destroyed, discovered at 'lock.cc:269'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at my_alloc.c:353
Error: Memory allocated at (null):0 was overrun, discovered at 'my_alloc.c:353'
Error: Safemalloc link list destroyed, discovered at 'my_alloc.c:353'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at my_alloc.c:64
Error: Memory allocated at (null):0 was overrun, discovered at 'my_alloc.c:64'
Error: Safemalloc link list destroyed, discovered at 'my_alloc.c:64'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at my_alloc.c:353
Error: Memory allocated at (null):0 was overrun, discovered at 'my_alloc.c:353'
Error: Safemalloc link list destroyed, discovered at 'my_alloc.c:353'
root=0x8d441d0,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at sql_lex.cc:198
Error: Memory allocated at (null):0 was overrun, discovered at 'sql_lex.cc:198'
Error: Safemalloc link list destroyed, discovered at 'sql_lex.cc:198'
root=0x8d48140,count=52,irem=(nil)
Error: Memory allocated at ()
Error: Memory allocated at ()
Error: Memory allocated at (null):0 was underrun, discovered at sql_lex.cc:199
Error: Memory allocated at (null):0 was overrun, discovered at 'sql_lex.cc:199'
Error: Safemalloc link list destroyed, discovered at 'sql_lex.cc:199'
root=0x8d48140,count=52,irem=(nil)

When running the test case within mysql test suite I got:
mysqltest: At line 155: query 'SET @x:= (SELECT d FROM t1 WHERE (a,b,c,d,e,f,g)=(1,1,1,1,1,1,1))' failed: 2013: Lost connection to MySQL server during query
[31 Mar 2007 7:23] 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/23452

ChangeSet@1.2427, 2007-03-31 00:23:03-07:00, igor@olga.mysql.com +3 -0
  Fixed bug #27154: memory corruption when using row equalities in where
  conditions.
  When allocating memory for KEY_FIELD/SARGABLE_PARAM structures the
  function update_ref_and_keys did not take into account the fact that
  a single row equality could be replaced by several simple equalities.
  Fixed by adjusting the counter cond_count accordingly for each subquery
  when performing substitution of a row equality for simple equalities.
[2 Apr 2007 8:18] Bugs System
Pushed into 5.1.18-beta
[2 Apr 2007 8:21] Bugs System
Pushed into 5.0.40
[3 Apr 2007 22:37] Paul DuBois
Noted in 5.0.40, 5.1.18 changelogs.

Row equalities in WHERE clauses could cause memory corruption.