diff options
-rw-r--r-- | include/my_global.h | 6 | ||||
-rw-r--r-- | mysql-test/r/sp-error.result | 52 | ||||
-rw-r--r-- | mysql-test/r/sp.result | 165 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 135 | ||||
-rw-r--r-- | sql/field.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 |
6 files changed, 364 insertions, 6 deletions
diff --git a/include/my_global.h b/include/my_global.h index c41ac8f915f..5661f77f9c2 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1486,4 +1486,10 @@ do { doubleget_union _tmp; \ #include <new> #endif +/* Length of decimal number represented by INT32. */ +#define MY_INT32_NUM_DECIMAL_DIGITS 11 + +/* Length of decimal number represented by INT64. */ +#define MY_INT64_NUM_DECIMAL_DIGITS 21 + #endif /* my_global_h */ diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index a66bdfd2862..3dcdc46de2b 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1414,3 +1414,55 @@ ERROR 42000: This version of MySQL doesn't yet support 'return value collation' create function bug20701() returns varchar(25) return "test"; drop function bug20701; End of 5.1 tests +create procedure proc_26503_error_1() +begin +retry: +repeat +begin +declare continue handler for sqlexception +begin +iterate retry; +end +select "do something"; +end +until true end repeat retry; +end// +ERROR 42000: ITERATE with no matching label: retry +create procedure proc_26503_error_2() +begin +retry: +repeat +begin +declare continue handler for sqlexception +iterate retry; +select "do something"; +end +until true end repeat retry; +end// +ERROR 42000: ITERATE with no matching label: retry +create procedure proc_26503_error_3() +begin +retry: +repeat +begin +declare continue handler for sqlexception +begin +leave retry; +end +select "do something"; +end +until true end repeat retry; +end// +ERROR 42000: LEAVE with no matching label: retry +create procedure proc_26503_error_4() +begin +retry: +repeat +begin +declare continue handler for sqlexception +leave retry; +select "do something"; +end +until true end repeat retry; +end// +ERROR 42000: LEAVE with no matching label: retry diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 6c39b708e46..ce555b987cd 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5896,4 +5896,169 @@ func_8407_b() 1500 drop function func_8407_a| drop function func_8407_b| +drop table if exists table_26503| +drop procedure if exists proc_26503_ok_1| +drop procedure if exists proc_26503_ok_2| +drop procedure if exists proc_26503_ok_3| +drop procedure if exists proc_26503_ok_4| +create table table_26503(a int unique)| +create procedure proc_26503_ok_1(v int) +begin +declare i int default 5; +declare continue handler for sqlexception +begin +select 'caught something'; +retry: +while i > 0 do +begin +set i = i - 1; +select 'looping', i; +iterate retry; +select 'dead code'; +end; +end while retry; +select 'leaving handler'; +end; +select 'do something'; +insert into table_26503 values (v); +select 'do something again'; +insert into table_26503 values (v); +end| +create procedure proc_26503_ok_2(v int) +begin +declare i int default 5; +declare continue handler for sqlexception +begin +select 'caught something'; +retry: +while i > 0 do +begin +set i = i - 1; +select 'looping', i; +leave retry; +select 'dead code'; +end; +end while; +select 'leaving handler'; +end; +select 'do something'; +insert into table_26503 values (v); +select 'do something again'; +insert into table_26503 values (v); +end| +create procedure proc_26503_ok_3(v int) +begin +declare i int default 5; +retry: +begin +declare continue handler for sqlexception +begin +select 'caught something'; +retry: +while i > 0 do +begin +set i = i - 1; +select 'looping', i; +iterate retry; +select 'dead code'; +end; +end while retry; +select 'leaving handler'; +end; +select 'do something'; +insert into table_26503 values (v); +select 'do something again'; +insert into table_26503 values (v); +end; +end| +create procedure proc_26503_ok_4(v int) +begin +declare i int default 5; +retry: +begin +declare continue handler for sqlexception +begin +select 'caught something'; +retry: +while i > 0 do +begin +set i = i - 1; +select 'looping', i; +leave retry; +select 'dead code'; +end; +end while; +select 'leaving handler'; +end; +select 'do something'; +insert into table_26503 values (v); +select 'do something again'; +insert into table_26503 values (v); +end; +end| +call proc_26503_ok_1(1)| +do something +do something +do something again +do something again +caught something +caught something +looping i +looping 4 +looping i +looping 3 +looping i +looping 2 +looping i +looping 1 +looping i +looping 0 +leaving handler +leaving handler +call proc_26503_ok_2(2)| +do something +do something +do something again +do something again +caught something +caught something +looping i +looping 4 +leaving handler +leaving handler +call proc_26503_ok_3(3)| +do something +do something +do something again +do something again +caught something +caught something +looping i +looping 4 +looping i +looping 3 +looping i +looping 2 +looping i +looping 1 +looping i +looping 0 +leaving handler +leaving handler +call proc_26503_ok_4(4)| +do something +do something +do something again +do something again +caught something +caught something +looping i +looping 4 +leaving handler +leaving handler +drop table table_26503| +drop procedure proc_26503_ok_1| +drop procedure proc_26503_ok_2| +drop procedure proc_26503_ok_3| +drop procedure proc_26503_ok_4| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0ca1df8ff2b..d65bec48cc4 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6888,6 +6888,141 @@ drop function func_8407_a| drop function func_8407_b| # +# Bug#26503 (Illegal SQL exception handler code causes the server to crash) +# + +--disable_warnings +drop table if exists table_26503| +drop procedure if exists proc_26503_ok_1| +drop procedure if exists proc_26503_ok_2| +drop procedure if exists proc_26503_ok_3| +drop procedure if exists proc_26503_ok_4| +--enable_warnings + +create table table_26503(a int unique)| + +create procedure proc_26503_ok_1(v int) +begin + declare i int default 5; + + declare continue handler for sqlexception + begin + select 'caught something'; + retry: + while i > 0 do + begin + set i = i - 1; + select 'looping', i; + iterate retry; + select 'dead code'; + end; + end while retry; + select 'leaving handler'; + end; + + select 'do something'; + insert into table_26503 values (v); + select 'do something again'; + insert into table_26503 values (v); +end| + +create procedure proc_26503_ok_2(v int) +begin + declare i int default 5; + + declare continue handler for sqlexception + begin + select 'caught something'; + retry: + while i > 0 do + begin + set i = i - 1; + select 'looping', i; + leave retry; + select 'dead code'; + end; + end while; + select 'leaving handler'; + end; + + select 'do something'; + insert into table_26503 values (v); + select 'do something again'; + insert into table_26503 values (v); +end| + +## The outer retry label should not prevent using the inner label. + +create procedure proc_26503_ok_3(v int) +begin + declare i int default 5; + +retry: + begin + declare continue handler for sqlexception + begin + select 'caught something'; + retry: + while i > 0 do + begin + set i = i - 1; + select 'looping', i; + iterate retry; + select 'dead code'; + end; + end while retry; + select 'leaving handler'; + end; + + select 'do something'; + insert into table_26503 values (v); + select 'do something again'; + insert into table_26503 values (v); + end; +end| + +## The outer retry label should not prevent using the inner label. + +create procedure proc_26503_ok_4(v int) +begin + declare i int default 5; + +retry: + begin + declare continue handler for sqlexception + begin + select 'caught something'; + retry: + while i > 0 do + begin + set i = i - 1; + select 'looping', i; + leave retry; + select 'dead code'; + end; + end while; + select 'leaving handler'; + end; + + select 'do something'; + insert into table_26503 values (v); + select 'do something again'; + insert into table_26503 values (v); + end; +end| + +call proc_26503_ok_1(1)| +call proc_26503_ok_2(2)| +call proc_26503_ok_3(3)| +call proc_26503_ok_4(4)| + +drop table table_26503| +drop procedure proc_26503_ok_1| +drop procedure proc_26503_ok_2| +drop procedure proc_26503_ok_3| +drop procedure proc_26503_ok_4| + +# # NOTE: The delimiter is `|`, and not `;`. It is changed to `;` # at the end of the file! # diff --git a/sql/field.cc b/sql/field.cc index d406459b6c7..1d36b984653 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1207,13 +1207,13 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val) { ASSERT_COLUMN_MARKED_FOR_READ; CHARSET_INFO *cs= &my_charset_bin; - uint length= 21; + uint length; longlong value= val_int(); - if (val_buffer->alloc(length)) + if (val_buffer->alloc(MY_INT64_NUM_DECIMAL_DIGITS)) return 0; length= (uint) (*cs->cset->longlong10_to_str)(cs, (char*) val_buffer->ptr(), - length, + MY_INT64_NUM_DECIMAL_DIGITS, unsigned_val ? 10 : -10, value); val_buffer->length(length); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2da2261d3e1..b07fa185939 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8675,7 +8675,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) if ((new_cond= new Item_func_eq(args[0], new Item_int("last_insert_id()", thd->read_first_successful_insert_id_in_prev_stmt(), - 21)))) + MY_INT64_NUM_DECIMAL_DIGITS)))) { cond=new_cond; /* @@ -8940,7 +8940,7 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, break; case INT_RESULT: /* Select an integer type with the minimal fit precision */ - if (item->max_length > 11) + if (item->max_length > MY_INT32_NUM_DECIMAL_DIGITS) new_field=new Field_longlong(item->max_length, maybe_null, item->name, item->unsigned_flag); else @@ -15255,7 +15255,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, examined_rows=(ha_rows)join->best_positions[i].records_read; item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows, - 21)); + MY_INT64_NUM_DECIMAL_DIGITS)); /* Add "filtered" field to item_list. */ if (join->thd->lex->describe & DESCRIBE_EXTENDED) |