mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 15:50:51 +03:00 
			
		
		
		
	cursor is interpreted latin1 character and Bug#9819 "Cursors: Mysql Server
Crash while fetching from table with 5 million records."
A fix for a possible memory leak when fetching into an SP cursor
in a long loop.
The patch uses a common implementation of cursors in the binary protocol and 
in stored procedures and implements materialized cursors.
For implementation details, see comments in sql_cursor.cc
include/my_sys.h:
  - declaration for multi_alloc_root
libmysqld/Makefile.am:
  - drop protocol_cursor.cc, add sql_cursor.cc (replaces the old
  implementation of cursors with a new one)
mysql-test/r/ctype_ujis.result:
  - test results fixed (a test case for Bug#6513)
mysql-test/r/sp-big.result:
  - test results fixed (a test case for Bug#9819)
mysql-test/t/ctype_ujis.test:
  Add a test case for Bug#6513 "Test Suite: Values inserted by using cursor is
   interpreted latin1 character"
mysql-test/t/sp-big.test:
  Add a restricted test case for Bug#9819 "Cursors: Mysql Server Crash
  while fetching from table with 5 million records."
mysys/my_alloc.c:
  - an implementation of multi_alloc_root; this is largely a copy-paste
    from mulalloc.c, but the function is small and there is no easy way
    to reuse the existing C function.
sql/Makefile.am:
  - add sql_cursor.h, sql_cursor.cc (a new implementation of stored procedure
  cursors) and drop protocol_cursor.cc (the old one)
sql/handler.cc:
  - now TABLE object has its mem_root always initialized.
    Adjust the implementation handler::ha_open
sql/item_subselect.cc:
  - adjust to the changed declaration of st_select_lex_unit::prepare
sql/protocol.h:
  - drop Protocol_cursor
sql/sp_head.cc:
  - move juggling with Query_arena::free_list and Item::next to
    sp_eval_func_item, as this is needed in 3 places already.
sql/sp_head.h:
  - declare a no-op implementation for cleanup_stmt in sp_instr_cpush.
    This method is needed for non-materializing cursors, which are yet not 
    used in stored procedures.
  - declaration for sp_eval_func_item
sql/sp_rcontext.cc:
  - reimplement sp_cursor using the new implementation of server side cursors.
  - use sp_eval_func_item to assign values of SP variables from the
    row fetched from a cursor. This should fix a possible memory leak in 
    the old implementation of sp_cursor::fetch
sql/sp_rcontext.h:
  - reimplement sp_cursor using the new implementation of server side cursors.
sql/sql_class.cc:
  - disable the functionality that closes transient cursors at commit/rollback;
    transient cursors are not used in 5.0, instead we use materialized ones.
    To be enabled in a later version.
sql/sql_class.h:
  - adjust to the rename Cursor -> Server_side_cursor
  - additional declarations of select_union used in materialized cursors
sql/sql_derived.cc:
  - reuse bits of tmp table code in UNION, derived tables, and materialized
    cursors
  - cleanup comments
sql/sql_lex.h:
  - declarations of auxiliary methods used by materialized cursors
  - a cleanup in st_select_lex_unit interface
sql/sql_list.h:
  - add an array operator new[] to class Sql_alloc
sql/sql_prepare.cc:
  - split the tight coupling of cursors and prepared statements to reuse 
    the same implementation in stored procedures
  - cleanups of error processing in Prepared_statement::{prepare,execute}
sql/sql_select.cc:
  - move the implementation of sensitive (non-materializing) cursors to 
    sql_cursor.cc
  - make temporary tables self-contained: the table, its record and fields
    are allocated in TABLE::mem_root. This implementation is not clean
    and resets thd->mem_root several times because of the way create_tmp_table 
    works (many additional things are done inside it).
  - adjust to the changed declaration of st_select_lex_unit::prepare
sql/sql_select.h:
  - move the declaration of sensitive (non-materializing) cursors to 
    sql_cursor.cc
sql/sql_union.cc:
  - move pieces of st_select_unit::prepare to select_union and st_table
    methods to be able to reuse code in the implementation of materialized
    cursors
sql/sql_view.cc:
  - adjust to the changed signature of st_select_lex_unit::prepare
sql/table.cc:
  - implement auxiliary st_table methods for use with temporary tables
sql/table.h:
  - add declarations for auxiliary methods of st_table used to work with 
   temporary tables
tests/mysql_client_test.c:
  - if cursors are materialized, a parallel update of the table used
    in the cursor may go through: update the test.
sql/sql_cursor.cc:
  New BitKeeper file ``sql/sql_cursor.cc'' -- implementation of server side
  cursors
sql/sql_cursor.h:
  New BitKeeper file ``sql/sql_cursor.h'' - declarations for
  server side cursors.
		
	
		
			
				
	
	
		
			83 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #
 | |
| # Bug #11602: SP with very large body not handled well
 | |
| #
 | |
| 
 | |
| --disable_warnings
 | |
| drop procedure if exists test.longprocedure;
 | |
| drop table if exists t1;
 | |
| --enable_warnings
 | |
| 
 | |
| create table t1 (a int);
 | |
| insert into t1 values (1),(2),(3);
 | |
| 
 | |
| let $body=`select repeat('select count(*) into out1 from t1;\n', 3072)`;
 | |
| 
 | |
| delimiter //;
 | |
| --disable_query_log
 | |
| eval select length('$body') as length//
 | |
| eval create procedure test.longprocedure (out out1 int) deterministic
 | |
| begin
 | |
|   $body
 | |
| end//
 | |
| --enable_query_log
 | |
| 
 | |
| delimiter ;//
 | |
| 
 | |
| # this is larger than the length above, because it includes the 'begin' and
 | |
| # 'end' bits and some whitespace
 | |
| select length(routine_definition) from information_schema.routines where routine_schema = 'test' and routine_name = 'longprocedure';
 | |
| 
 | |
| call test.longprocedure(@value); select @value;
 | |
| 
 | |
| drop procedure test.longprocedure;
 | |
| drop table t1;
 | |
| #
 | |
| # Bug #9819 "Cursors: Mysql Server Crash while fetching from table with 5
 | |
| # million records.": 
 | |
| # To really test the bug, increase the number of loop iterations ($1).
 | |
| # For 4 millions set $1 to 22.
 | |
| create table t1 (f1 char(100) , f2 mediumint , f3 int , f4 real, f5 numeric);
 | |
| insert into t1 (f1, f2, f3, f4, f5) values
 | |
| ("This is a test case for for Bug#9819", 1, 2, 3.0, 4.598);
 | |
| create table t2 like t1;
 | |
| let $1=8;
 | |
| --disable_query_log
 | |
| --disable_result_log
 | |
| while ($1)
 | |
| {
 | |
|   eval insert into t1 select * from t1;
 | |
|   dec $1;
 | |
| }
 | |
| --enable_result_log
 | |
| --enable_query_log
 | |
| select count(*) from t1;
 | |
| select count(*) from t2;
 | |
| delimiter |;
 | |
| create procedure p1()
 | |
| begin
 | |
|   declare done integer default 0;
 | |
|   declare vf1 char(100) ;
 | |
|   declare vf2 mediumint;
 | |
|   declare vf3 int ;
 | |
|   declare vf4 real ;
 | |
|   declare vf5 numeric ;
 | |
|   declare cur1 cursor for select f1,f2,f3,f4,f5 from t1;  
 | |
|   declare continue handler for sqlstate '02000' set done = 1; 
 | |
|   open cur1;
 | |
|   while done <> 1 do
 | |
|     fetch cur1 into vf1, vf2, vf3, vf4, vf5;
 | |
|     if not done then
 | |
|       insert into t2 values (vf1, vf2, vf3, vf4, vf5);
 | |
|     end if;
 | |
|   end while;
 | |
|   close cur1;
 | |
| end|
 | |
| delimiter ;|
 | |
| call p1();
 | |
| select count(*) from t1;
 | |
| select count(*) from t2;
 | |
| select f1 from t1 limit 1;
 | |
| select f1 from t2 limit 1;
 | |
| drop procedure p1;
 | |
| drop table t1, t2;
 |