Commit 0536bd66 authored by jimw@mysql.com's avatar jimw@mysql.com

Increase allowed size of stored procedure bodies to 4GB, and

produce a sensible error when that limit is exceeded. (Bug #11602)
parent d5032838
...@@ -66,7 +66,8 @@ ...@@ -66,7 +66,8 @@
#ifndef WEXITSTATUS #ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif #endif
#define MAX_QUERY 131072 /* MAX_QUERY is 256K -- there is a test in sp-big that is >128K */
#define MAX_QUERY (256*1024)
#define MAX_VAR_NAME 256 #define MAX_VAR_NAME 256
#define MAX_COLUMNS 256 #define MAX_COLUMNS 256
#define PAD_SIZE 128 #define PAD_SIZE 128
......
drop procedure if exists test.longprocedure;
drop table if exists t1;
create table t1 (a int);
insert into t1 values (1),(2),(3);
length
107520
select length(routine_definition) from information_schema.routines where routine_schema = 'test' and routine_name = 'longprocedure';
length(routine_definition)
107530
call test.longprocedure(@value);
select @value;
@value
3
drop procedure test.longprocedure;
drop table t1;
...@@ -172,7 +172,7 @@ proc CREATE TABLE `proc` ( ...@@ -172,7 +172,7 @@ proc CREATE TABLE `proc` (
`security_type` enum('INVOKER','DEFINER') NOT NULL default 'DEFINER', `security_type` enum('INVOKER','DEFINER') NOT NULL default 'DEFINER',
`param_list` blob NOT NULL, `param_list` blob NOT NULL,
`returns` char(64) NOT NULL default '', `returns` char(64) NOT NULL default '',
`body` blob NOT NULL, `body` longblob NOT NULL,
`definer` char(77) character set utf8 collate utf8_bin NOT NULL default '', `definer` char(77) character set utf8 collate utf8_bin NOT NULL default '',
`created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `created` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL default '0000-00-00 00:00:00', `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
......
#
# 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;
...@@ -683,7 +683,7 @@ then ...@@ -683,7 +683,7 @@ then
c_p="$c_p security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL," c_p="$c_p security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,"
c_p="$c_p param_list blob DEFAULT '' NOT NULL," c_p="$c_p param_list blob DEFAULT '' NOT NULL,"
c_p="$c_p returns char(64) DEFAULT '' NOT NULL," c_p="$c_p returns char(64) DEFAULT '' NOT NULL,"
c_p="$c_p body blob DEFAULT '' NOT NULL," c_p="$c_p body longblob DEFAULT '' NOT NULL,"
c_p="$c_p definer char(77) collate utf8_bin DEFAULT '' NOT NULL," c_p="$c_p definer char(77) collate utf8_bin DEFAULT '' NOT NULL,"
c_p="$c_p created timestamp," c_p="$c_p created timestamp,"
c_p="$c_p modified timestamp," c_p="$c_p modified timestamp,"
......
...@@ -426,7 +426,7 @@ CREATE TABLE IF NOT EXISTS proc ( ...@@ -426,7 +426,7 @@ CREATE TABLE IF NOT EXISTS proc (
security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,
param_list blob DEFAULT '' NOT NULL, param_list blob DEFAULT '' NOT NULL,
returns char(64) DEFAULT '' NOT NULL, returns char(64) DEFAULT '' NOT NULL,
body blob DEFAULT '' NOT NULL, body longblob DEFAULT '' NOT NULL,
definer char(77) collate utf8_bin DEFAULT '' NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL,
created timestamp, created timestamp,
modified timestamp, modified timestamp,
...@@ -477,6 +477,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL, ...@@ -477,6 +477,7 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
'READS_SQL_DATA', 'READS_SQL_DATA',
'MODIFIES_SQL_DATA' 'MODIFIES_SQL_DATA'
) DEFAULT 'CONTAINS_SQL' NOT NULL, ) DEFAULT 'CONTAINS_SQL' NOT NULL,
MODIFY body longblob DEFAULT '' NOT NULL,
MODIFY sql_mode MODIFY sql_mode
set('REAL_AS_FLOAT', set('REAL_AS_FLOAT',
'PIPES_AS_CONCAT', 'PIPES_AS_CONCAT',
......
...@@ -5370,3 +5370,5 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009 ...@@ -5370,3 +5370,5 @@ ER_SCALE_BIGGER_THAN_PRECISION 42000 S1009
eng "Scale may not be larger than the precision (column '%-.64s')." eng "Scale may not be larger than the precision (column '%-.64s')."
ER_WRONG_LOCK_OF_SYSTEM_TABLE ER_WRONG_LOCK_OF_SYSTEM_TABLE
eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables" eng "You can't combine write-locking of system '%-.64s.%-.64s' table with other tables"
ER_TOO_LONG_BODY 42000 S1009
eng "Routine body for '%-.100s' is too long"
...@@ -503,6 +503,11 @@ db_create_routine(THD *thd, int type, sp_head *sp) ...@@ -503,6 +503,11 @@ db_create_routine(THD *thd, int type, sp_head *sp)
ret= SP_BAD_IDENTIFIER; ret= SP_BAD_IDENTIFIER;
goto done; goto done;
} }
if (sp->m_body.length > table->field[MYSQL_PROC_FIELD_BODY]->field_length)
{
ret= SP_BODY_TOO_LONG;
goto done;
}
table->field[MYSQL_PROC_FIELD_DB]-> table->field[MYSQL_PROC_FIELD_DB]->
store(sp->m_db.str, sp->m_db.length, system_charset_info); store(sp->m_db.str, sp->m_db.length, system_charset_info);
table->field[MYSQL_PROC_FIELD_NAME]-> table->field[MYSQL_PROC_FIELD_NAME]->
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define SP_INTERNAL_ERROR -7 #define SP_INTERNAL_ERROR -7
#define SP_NO_DB_ERROR -8 #define SP_NO_DB_ERROR -8
#define SP_BAD_IDENTIFIER -9 #define SP_BAD_IDENTIFIER -9
#define SP_BODY_TOO_LONG -10
/* Drop all routines in database 'db' */ /* Drop all routines in database 'db' */
int int
......
...@@ -4112,6 +4112,12 @@ mysql_execute_command(THD *thd) ...@@ -4112,6 +4112,12 @@ mysql_execute_command(THD *thd)
delete lex->sphead; delete lex->sphead;
lex->sphead= 0; lex->sphead= 0;
goto error; goto error;
case SP_BODY_TOO_LONG:
my_error(ER_TOO_LONG_BODY, MYF(0), name);
lex->unit.cleanup();
delete lex->sphead;
lex->sphead= 0;
goto error;
default: default:
my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
lex->unit.cleanup(); lex->unit.cleanup();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment