Bug #11529 crash server after use stored procedure
Submitted: 23 Jun 2005 12:54 Modified: 30 Jun 2005 17:10
Reporter: Valentin Komissarov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:5.0.7/5.0.8 BK OS:Windows (win32/Linux)
Assigned to: Bugs System CPU Architecture:Any

[23 Jun 2005 12:54] Valentin Komissarov
Description:
Server crash after commit transaction after run stored procedure in this example.
In other procedures crash server because in cursor i use constriction FIELD IN(), but base Has the very large structure.

I give a very simple example.

MySQL 5.0.7 (nt)
OS: WinXP SP2, Win2k SP2,3,4

How to repeat:
SET FOREIGN_KEY_CHECKS=0;

USE `test`;

#
# Structure for the `t1` table : 
#

DROP TABLE IF EXISTS `t1`;

CREATE TABLE `t1` (
  `ID` int(11) unsigned NOT NULL auto_increment,
  `Key2` int(11) unsigned default NULL,
  `Name` varchar(50) default NULL,
  `Name2` varchar(50) default NULL,
  PRIMARY KEY  (`ID`),
  UNIQUE KEY `idx_Key2` (`Key2`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1251;

#
# Definition for the `gp_InsUpd_T1` procedure : 
#

DROP PROCEDURE `gp_InsUpd_T1`;

CREATE PROCEDURE `gp_InsUpd_T1`()
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  START TRANSACTION;
  CALL lp_InsUpd_T1();
  COMMIT;
END;

#
# Definition for the `lp_InsUpd_T1` procedure : 
#

DROP PROCEDURE `lp_InsUpd_T1`;

CREATE PROCEDURE `lp_InsUpd_T1`()
    NOT DETERMINISTIC
    SQL SECURITY DEFINER
    COMMENT '#Visor:23.06.05'
BEGIN
  DECLARE xName VARCHAR(50);
  DECLARE xID INTEGER;
  DECLARE xDone INTEGER DEFAULT 0;
  DECLARE curT CURSOR FOR
          SELECT t1.ID, t1.Name
          FROM t1
          WHERE t1.Key2 IN(10,13);
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET xDone=1;
  
  UPDATE t1 SET
    Name2=NULL
  WHERE Name2 IS NOT NULL;

  OPEN CurT;
  FETCH CurT
  INTO xID, xName;
  
  WHILE NOT xDone DO
    UPDATE t1 SET
      Name2=xName
    WHERE t1.ID=xID;
    
    FETCH CurT
    INTO xID, xName;
  END WHILE;

END;

#
# Data for the `t1` table  (LIMIT 0,500)
#

INSERT INTO `t1` (`ID`, `Key2`, `Name`, `Name2`) VALUES 
  (1,10,'Name1','Name1'),
  (2,11,'Name2',NULL),
  (3,12,'Name3',NULL),
  (4,13,'Name4','Name4'),
  (5,14,'Name5',NULL);

COMMIT;

#RUN

CALL `gp_InsUpd_T1`();
SELECT *
FROM t1;
COMMIT;
CALL `gp_InsUpd_T1`();

#Best regards
[23 Jun 2005 12:55] Valentin Komissarov
p.s. InnoDB ENGINE in table necessarily
[23 Jun 2005 13:47] MySQL Verification Team
Thank you for the bug report I was able to repeat:

item_cmpfunc.h
--834--

 void cleanup()
  {
    DBUG_ENTER("Item_func_in::cleanup");
    Item_int_func::cleanup();
    delete array;
^^^^^^^^^^^^^^^^
    delete in_item;
    array= 0;
    in_item= 0;
    DBUG_VOID_RETURN;
  }^

>	mysqld-debug.exe!Item_func_in::cleanup()  Line 838 + 0x1f	C++
 	mysqld-debug.exe!cleanup_items(Item * item=0x030e2a68)  Line 1287 + 0xb	C++
 	mysqld-debug.exe!sp_head::execute(THD * thd=0x00ffba58)  Line 655 + 0xf	C++
 	mysqld-debug.exe!sp_head::execute_procedure(THD * thd=0x00ffba58, List<Item> * args=0x030d35a0)  Line 917 + 0xf	C++
 	mysqld-debug.exe!mysql_execute_command(THD * thd=0x00ffba58)  Line 4207 + 0x19	C++
 	mysqld-debug.exe!sp_instr_stmt::exec_core(THD * thd=0x00ffba58, unsigned int * nextp=0x03fae5c4)  Line 1553 + 0x9	C++
 	mysqld-debug.exe!sp_lex_keeper::reset_lex_and_exec_core(THD * thd=0x00ffba58, unsigned int * nextp=0x03fae5c4, int open_tables=0, sp_instr * instr=0x030c6bc8)  Line 1472 + 0x13	C++
 	mysqld-debug.exe!sp_instr_stmt::execute(THD * thd=0x00ffba58, unsigned int * nextp=0x03fae5c4)  Line 1530 + 0x19	C++
 	mysqld-debug.exe!sp_head::execute(THD * thd=0x00ffba58)  Line 650 + 0x19	C++
 	mysqld-debug.exe!sp_head::execute_procedure(THD * thd=0x00ffba58, List<Item> * args=0x00ffbf28)  Line 917 + 0xf	C++
 	mysqld-debug.exe!mysql_execute_command(THD * thd=0x00ffba58)  Line 4207 + 0x19	C++
 	mysqld-debug.exe!mysql_parse(THD * thd=0x00ffba58, char * inBuf=0x030a46a0, unsigned int length=21)  Line 5364 + 0x9	C++
 	mysqld-debug.exe!dispatch_command(enum_server_command command=COM_QUERY, THD * thd=0x00ffba58, char * packet=0x030b6e69, unsigned int packet_length=22)  Line 1674 + 0x1d	C++
 	mysqld-debug.exe!do_command(THD * thd=0x00ffba58)  Line 1477 + 0x31	C++
 	mysqld-debug.exe!handle_one_connection(void * arg=0x00ffba58)  Line 1126 + 0x9	C++
 	mysqld-debug.exe!pthread_start(void * param=0x030b2758)  Line 63 + 0x7	C
 	mysqld-debug.exe!_threadstart(void * ptd=0x00ffff48)  Line 173 + 0xd	C
 	kernel32.dll!7c80b50b() 	
 	kernel32.dll!7c8399f3()
[23 Jun 2005 14:12] MySQL Verification Team
Backtrace on Linux:

050623 11:07:12 [Note] /home/miguel/dbs/5.0/libexec/mysqld: ready for connections.
Version: '5.0.8-beta-debug'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
[New Thread 163851 (LWP 1916)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 163851 (LWP 1916)]
0x0817d9cb in Item_func_in::cleanup (this=0x8e57128) at item_cmpfunc.h:838
838         delete array;
(gdb) backtrace full
#0  0x0817d9cb in Item_func_in::cleanup (this=0x8e57128) at item_cmpfunc.h:838
        _db_func_ = 0x85c4fd7 "sql_parse.cc"
        _db_file_ = 0x85c54e8 "cleanup_items"
        _db_level_ = 136176969
        _db_framep_ = (char **) 0xbe5fe7cc
#1  0x081de566 in cleanup_items (item=0x8e57128) at sql_parse.cc:1287
        _db_func_ = 0x8e386a0 "èßX\b"
        _db_file_ = 0x0
        _db_level_ = 137490378
        _db_framep_ = (char **) 0x1
#2  0x0831f16f in sp_head::execute (this=0x8e567e0, thd=0x8e127d0) at sp_head.cc:641
        i = (sp_instr *) 0x8e57220
        hip = 3193956380
        _db_func_ = 0x831f863 "\203Ä \203=TIz\b"
        _db_file_ = 0x5 <Address 0x5 out of bounds>
        _db_level_ = 142114080
        _db_framep_ = (char **) 0x8e386d8
        olddb = "qïf\b\022ïf\b¼è_¾¿lT\bÜ\000\000\000¬è_¾¨è_¾¤è_¾û\003\031@ô_\031@\234è_¾P\002\031@ \206ã\bàû_¾¼è_¾êØ\024\b\001\000\000\000ô_\031@Üè_¾\202\017\024\bØ\206ã\b }x\bÜè_¾¾\017\024\bdé_¾@\000\000\000üè_¾\000\000\000\000Ð'á\b \206ã\büè_¾Æ÷\024\b"
        dbchanged = false
        ctx = (sp_rcontext *) 0x8e385b0
        ret = 0
        ip = 2
        old_arena = (class Query_arena *) 0x8e3c540
        old_query_id = 26
        old_derived_tables = (TABLE *) 0x0
        old_lex = (LEX *) 0x8e2bc08
        old_change_list = {<base_ilist> = {first = 0x8e14154, last = {_vptr.ilink = 0x85b4a08, prev = 0x8e14150, 
      next = 0x0}}, <No data fields>}
        old_packet = {Ptr = 0x0, str_length = 0, Alloced_length = 0, alloced = false, str_charset = 0x8787d20}
#3  0x0831fc14 in sp_head::execute_procedure (this=0x8e567e0, thd=0x8e127d0, args=0x8e2c02c) at sp_head.cc:903
        _db_func_ = 0x81e58d0 "\203Ä \204Àt\024\213U\b\212\205oûÿÿ\210\202¾\a"
        _db_file_ = 0xbe5fef1c "<ï_¾×\0252\bÐ'á\b\v\200\002"
        _db_level_ = 148979284
        _db_framep_ = (char **) 0x8e58380
        ret = 0
        csize = 6
        params = 0
        hmax = 1
---Type <return> to continue, or q <return> to quit---
        cmax = 2
        octx = (sp_rcontext *) 0x8e38628
        nctx = (sp_rcontext *) 0x8e385b0
        tmp_octx = 1 '\001'
        old_mem_root = (MEM_ROOT *) 0xbe5ff154
        call_mem_root = {free = 0x8e385a0, used = 0x0, pre_alloc = 0x0, min_malloc = 32, block_size = 8136, block_num = 5, 
  first_block_usage = 0, error_handler = 0}
        old_free_list = (class Item *) 0x0
        call_free_list = (class Item *) 0x0
#4  0x081e59f4 in mysql_execute_command (thd=0x8e127d0) at sql_parse.cc:4207
        select_limit = 18446744073709551615
        save_options = 2224048640
        save_ctx = {changed = false, master_access = 3193958176, db_access = 3193958172, 
  priv_user = 0xbe5fef18 "Ð'á\b<ï_¾×\0252\bÐ'á\b\v\200\002", 
  priv_host = "\000\000\000\000\000\000\000\000\210æà\b¥ÿÿÿâá\206\000\000\000\000\000\000\000\000\000¸eã\bÈ\r{\b@\215x\bÔö_¾\020(á\b\f\000\000\000 æâ\b\021\000\000\000\f", user = 0x358 <Address 0x358 out of bounds>, host = 0xbe5ffbe0 "àû_¾", 
  ip = 0xbe5ff70c "<÷_¾\230\207\036\bÐ'á\bÐ'á\bhåâ\b\025"}
        bits_to_be_cleared = 0
        nsok = 1 '\001'
        sp = (class sp_head *) 0x8e567e0
        res = false
        result = 0
        lex = (LEX *) 0x8e2bc08
        select_lex = (SELECT_LEX *) 0x8e2bdfc
        slave_fake_lock = false
        fake_prev_lock = (MYSQL_LOCK *) 0x0
        first_table = (TABLE_LIST *) 0x0
        all_tables = (TABLE_LIST *) 0x0
        unit = (SELECT_LEX_UNIT *) 0x8e2bc18
        _db_func_ = 0x40191031 "\201ÃÃO"
        _db_file_ = 0x866ef12 "my_alloc.c"
        _db_level_ = 1075385358
        _db_framep_ = (char **) 0x8546a7e
#5  0x083215d7 in sp_instr_stmt::exec_core (this=0x8e3c8d0, thd=0x8e127d0, nextp=0xbe5ff044) at sp_head.cc:1539
        res = 148973520
#6  0x083213a8 in sp_lex_keeper::reset_lex_and_exec_core (this=0x8e3c8ec, thd=0x8e127d0, nextp=0xbe5ff044, open_tables=false, 
    instr=0x8e3c8d0) at sp_head.cc:1458
        res = 0
#7  0x0832151c in sp_instr_stmt::execute (this=0x8e3c8d0, thd=0x8e127d0, nextp=0xbe5ff044) at sp_head.cc:1516
---Type <return> to continue, or q <return> to quit---
        query = 0x8e2e568 "CALL `gp_InsUpd_T1`()"
        query_length = 21
        _db_func_ = 0x831efca "\203Ä \211\205\\ÿÿÿ\203½\\ÿÿÿ"
        _db_file_ = 0x1 <Address 0x1 out of bounds>
        _db_level_ = 3193958328
        _db_framep_ = (char **) 0x8e13f18
        res = 0
#8  0x0831f149 in sp_head::execute (this=0x8e3c540, thd=0x8e127d0) at sp_head.cc:639
        i = (sp_instr *) 0x8e3c8d0
        hip = 8
        _db_func_ = 0x831f863 "\203Ä \203=TIz\b"
        _db_file_ = 0xbe5ff1bc "\f÷_¾ôY\036\b@Åã\bÐ'á\b4,á\b"
        _db_level_ = 0
        _db_framep_ = (char **) 0x0
        olddb = '\0' <repeats 88 times>, "ìð_¾4hT\b\035ïf\b\022ïf\bìð_¾\035iT\bH\000\000\000àð_¾Üð_¾Øð_¾"
        dbchanged = false
        ctx = (sp_rcontext *) 0x0
        ret = 0
        ip = 1
        old_arena = (class Query_arena *) 0x8e127dc
        old_query_id = 24
        old_derived_tables = (TABLE *) 0x0
        old_lex = (LEX *) 0x8e12810
        old_change_list = {<base_ilist> = {first = 0x8e14154, last = {_vptr.ilink = 0x85b4a08, prev = 0x8e14150, 
      next = 0x0}}, <No data fields>}
        old_packet = {Ptr = 0x8e315b8 "\0015\00214\005Name5ûName4ame2\005Name2\f\b", str_length = 12, Alloced_length = 16384, 
  alloced = true, str_charset = 0x8787d20}
#9  0x0831fc14 in sp_head::execute_procedure (this=0x8e3c540, thd=0x8e127d0, args=0x8e12c34) at sp_head.cc:903
        _db_func_ = 0x81e58d0 "\203Ä \204Àt\024\213U\b\212\205oûÿÿ\210\202¾\a"
        _db_file_ = 0xbe5ff70c "<÷_¾\230\207\036\bÐ'á\bÐ'á\bhåâ\b\025"
        _db_level_ = 148979284
        _db_framep_ = (char **) 0x8e3ca38
        ret = 0
        csize = 0
        params = 0
        hmax = 0
        cmax = 0
        octx = (sp_rcontext *) 0x0
        nctx = (sp_rcontext *) 0x0
---Type <return> to continue, or q <return> to quit---
        tmp_octx = 0 '\0'
        old_mem_root = (MEM_ROOT *) 0x8e127e4
        call_mem_root = {free = 0x8e365b8, used = 0x0, pre_alloc = 0x0, min_malloc = 32, block_size = 8136, block_num = 5, 
  first_block_usage = 0, error_handler = 0}
        old_free_list = (class Item *) 0x0
        call_free_list = (class Item *) 0x0
#10 0x081e59f4 in mysql_execute_command (thd=0x8e127d0) at sql_parse.cc:4207
        select_limit = 18446744073709551615
        save_options = 2225359360
        save_ctx = {changed = false, master_access = 1919252000, db_access = 1852795251, 
  priv_user = 0x726f6620 <Address 0x726f6620 out of bounds>, priv_host = " the right syntax to use near '1,10,'Name1','Name1'),\n  (2,11", 
  user = 0x32656d61 <Address 0x32656d61 out of bounds>, host = 0x554e2c27 <Address 0x554e2c27 out of bounds>, 
  ip = 0x2c294c4c <Address 0x2c294c4c out of bounds>}
        bits_to_be_cleared = 0
        nsok = 0 '\0'
        sp = (class sp_head *) 0x8e3c540
        res = false
        result = 0
        lex = (LEX *) 0x8e12810
        select_lex = (SELECT_LEX *) 0x8e12a04
        slave_fake_lock = false
        fake_prev_lock = (MYSQL_LOCK *) 0x0
        first_table = (TABLE_LIST *) 0x0
        all_tables = (TABLE_LIST *) 0x0
        unit = (SELECT_LEX_UNIT *) 0x8e12820
        _db_func_ = 0x0
        _db_file_ = 0x0
        _db_level_ = 0
        _db_framep_ = (char **) 0xbe5ff6d0
#11 0x081e8798 in mysql_parse (thd=0x8e127d0, inBuf=0x8e2e568 "CALL `gp_InsUpd_T1`()", length=21) at sql_parse.cc:5364
        lex = (LEX *) 0x8e12810
        _db_func_ = 0x8794540 "(Ï_\b"
        _db_file_ = 0x81df332 "\203Ä \203=TIz\b"
        _db_level_ = 3193960892
        _db_framep_ = (char **) 0x2800b
#12 0x081df392 in dispatch_command (command=COM_QUERY, thd=0x8e127d0, packet=0x8e26509 "CALL `gp_InsUpd_T1`()", packet_length=22)
    at sql_parse.cc:1674
        packet_end = 0x8e2e57d ""
        net = (NET *) 0x8e12f3c
---Type <return> to continue, or q <return> to quit---
        error = false
        _db_func_ = 0x603ed8 <Address 0x603ed8 out of bounds>
        _db_file_ = 0x0
        _db_level_ = 136916366
        _db_framep_ = (char **) 0xbe5ff9dc
#13 0x081dec79 in do_command (thd=0x8e127d0) at sql_parse.cc:1477
        packet = 0x8e26508 "\003CALL `gp_InsUpd_T1`()"
        old_timeout = 30
        packet_length = 22
        net = (NET *) 0x8e12f3c
        command = COM_QUERY
        _db_func_ = 0x8e13f98 "ÿÿÿÿ\024"
        _db_file_ = 0x81b7fcb "\203Ä\020ÉÃU\211å\203ì\b\203ì\fÿu\bè\217"
        _db_level_ = 3193960956
        _db_framep_ = (char **) 0x1010
#14 0x081dde81 in handle_one_connection (arg=0x8e127d0) at sql_parse.cc:1126
        error = 0
        net = (NET *) 0x8e12f3c
        thd = (class THD *) 0x8e127d0
        launch_time = 0
        set = {__val = {0 <repeats 32 times>}}
#15 0x4018d54e in pthread_start_thread () from /lib/libpthread.so.0
No symbol table info available.
#16 0x4018d5df in pthread_start_thread_event () from /lib/libpthread.so.0
No symbol table info available.
#17 0x402fab8a in clone () from /lib/libc.so.6
No symbol table info available.
(gdb)
[27 Jun 2005 12:20] Per-Erik Martin
Didn't crash, but valgrind does complain (on something which might result in a crash on other systems).
[28 Jun 2005 9:57] Per-Erik Martin
InnoDB is not required to repeat, but using a cursor with the IN operator is. Here's a simpler test case:

create procedure bug11529()
begin
  declare c cursor for select ID, Name from t1 where Key2 in (10,13);

  open c;
  begin
    declare vid integer;
    declare vname varchar(50);
    declare exit handler for not found begin end;

    while true do
      fetch c into vid, vname;
    end while;
  end;
  close c;
end
[29 Jun 2005 6:39] Valentin Komissarov
Declare cursor???
What will give the cursor, if anything no and to leave a cycle it is not necessary?
I without problems can bypass this mistake, not using function IN (), but it not the decision of a mistake.
[30 Jun 2005 16:36] 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/internals/26560
[30 Jun 2005 17:05] Per-Erik Martin
Approved by email.
[30 Jun 2005 17:10] Per-Erik Martin
Pushed to bk 5.0.9