Loading mysql-test/r/sp.result +43 −0 Original line number Diff line number Diff line Loading @@ -2967,4 +2967,47 @@ begin end; goto label1; end| drop procedure bug6898| drop function if exists bug9102| create function bug9102() returns blob return 'a'| select bug9102()| bug9102() a drop function bug9102| drop function if exists bug7648| create function bug7648() returns bit(8) return 'a'| select bug7648()| bug7648() a drop function bug7648| drop function if exists bug9775| create function bug9775(v1 char(1)) returns enum('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('c')| bug9775('a') bug9775('b') bug9775('c') a b drop function bug9775| create function bug9775(v1 int) returns enum('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3)| bug9775(1) bug9775(2) bug9775(3) a b drop function bug9775| create function bug9775(v1 char(1)) returns set('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')| bug9775('a') bug9775('b') bug9775('a,b') bug9775('c') a b a,b drop function bug9775| create function bug9775(v1 int) returns set('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3),bug9775(4)| bug9775(1) bug9775(2) bug9775(3) bug9775(4) a b a,b drop function bug9775| drop function if exists bug8861| create function bug8861(v1 int) returns year return v1| select bug8861(05)| bug8861(05) 2005 set @x = bug8861(05)| select @x| @x 2005 drop function bug8861| drop table t1,t2; mysql-test/t/sp.test +56 −0 Original line number Diff line number Diff line Loading @@ -3644,6 +3644,62 @@ end| drop procedure bug6898| # # BUG#9102: Stored proccedures: function which returns blob causes crash # --disable_warnings drop function if exists bug9102| --enable_warnings create function bug9102() returns blob return 'a'| select bug9102()| drop function bug9102| # # BUG#7648: Stored procedure crash when invoking a function that returns a bit # --disable_warnings drop function if exists bug7648| --enable_warnings create function bug7648() returns bit(8) return 'a'| select bug7648()| drop function bug7648| # # BUG#9775: crash if create function that returns enum or set # --disable_warnings drop function if exists bug9775| --enable_warnings create function bug9775(v1 char(1)) returns enum('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('c')| drop function bug9775| create function bug9775(v1 int) returns enum('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3)| drop function bug9775| create function bug9775(v1 char(1)) returns set('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')| drop function bug9775| create function bug9775(v1 int) returns set('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3),bug9775(4)| drop function bug9775| # # BUG#8861: If Return is a YEAR data type, value is not shown in year format # --disable_warnings drop function if exists bug8861| --enable_warnings create function bug8861(v1 int) returns year return v1| select bug8861(05)| set @x = bug8861(05)| select @x| drop function bug8861| # # BUG#NNNN: New bug synopsis # Loading sql/item_func.cc +48 −14 Original line number Diff line number Diff line Loading @@ -4461,7 +4461,7 @@ longlong Item_func_row_count::val_int() Item_func_sp::Item_func_sp(sp_name *name) :Item_func(), m_name(name), m_sp(NULL) :Item_func(), m_name(name), m_sp(NULL), result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); Loading @@ -4470,7 +4470,7 @@ Item_func_sp::Item_func_sp(sp_name *name) Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list) :Item_func(list), m_name(name), m_sp(NULL) :Item_func(list), m_name(name), m_sp(NULL), result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); Loading Loading @@ -4526,6 +4526,29 @@ Item_func_sp::sp_result_field(void) const } int Item_func_sp::execute(Field **flp) { Item *it; Field *f; if (execute(&it)) { null_value= 1; return 1; } if (!(f= *flp)) { *flp= f= sp_result_field(); f->move_field((f->pack_length() > sizeof(result_buf)) ? sql_alloc(f->pack_length()) : result_buf); f->null_ptr= (uchar *)&null_value; f->null_bit= 1; } it->save_in_field(f, 1); return f->is_null(); } int Item_func_sp::execute(Item **itp) { Loading Loading @@ -4601,6 +4624,8 @@ Item_func_sp::field_type() const Field *field= 0; DBUG_ENTER("Item_func_sp::field_type"); if (result_field) DBUG_RETURN(result_field->type()); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if ((field= sp_result_field())) Loading @@ -4621,6 +4646,8 @@ Item_func_sp::result_type() const DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); if (result_field) DBUG_RETURN(result_field->result_type()); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if ((field= sp_result_field())) Loading @@ -4636,8 +4663,16 @@ Item_func_sp::result_type() const void Item_func_sp::fix_length_and_dec() { Field *field= result_field; DBUG_ENTER("Item_func_sp::fix_length_and_dec"); if (result_field) { decimals= result_field->decimals(); max_length= result_field->representation_length(); DBUG_VOID_RETURN; } if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if (! m_sp) Loading @@ -4646,29 +4681,28 @@ Item_func_sp::fix_length_and_dec() } else { switch (result_type()) { if (!field) field= sp_result_field(); decimals= field->decimals(); max_length= field->representation_length(); switch (field->result_type()) { case STRING_RESULT: maybe_null= 1; max_length= MAX_BLOB_WIDTH; break; case REAL_RESULT: decimals= NOT_FIXED_DEC; max_length= float_length(decimals); break; case INT_RESULT: decimals= 0; max_length= 21; break; case DECIMAL_RESULT: // TODO: where to find real precision and scale? decimals= min(DECIMAL_MAX_LENGTH / 2, NOT_FIXED_DEC - 1); max_length= DECIMAL_MAX_LENGTH; break; case ROW_RESULT: default: // This case should never be chosen DBUG_ASSERT(0); break; } if (field != result_field) delete field; } DBUG_VOID_RETURN; } Loading sql/item_func.h +18 −32 Original line number Diff line number Diff line Loading @@ -1283,8 +1283,11 @@ class Item_func_sp :public Item_func sp_name *m_name; mutable sp_head *m_sp; TABLE *dummy_table; Field *result_field; char result_buf[64]; int execute(Item **itp); int execute(Field **flp); Field *sp_result_field(void) const; public: Loading @@ -1296,6 +1299,12 @@ class Item_func_sp :public Item_func virtual ~Item_func_sp() {} void cleanup() { Item_func::cleanup(); result_field= NULL; } const char *func_name() const; enum enum_field_types field_type() const; Loading @@ -1308,53 +1317,30 @@ class Item_func_sp :public Item_func longlong val_int() { return (longlong)Item_func_sp::val_real(); if (execute(&result_field)) return 0LL; return result_field->val_int(); } double val_real() { Item *it; double d; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return 0.0; } d= it->val_real(); null_value= it->null_value; return d; return result_field->val_real(); } my_decimal *val_decimal(my_decimal *dec_buf) { Item *it; my_decimal *result; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return NULL; return result_field->val_decimal(dec_buf); } result= it->val_decimal(dec_buf); null_value= it->null_value; return result; } String *val_str(String *str) { Item *it; String *s; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return NULL; } s= it->val_str(str); null_value= it->null_value; return s; return result_field->val_str(str); } void fix_length_and_dec(); Loading sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group, bool modify_item, uint convert_blob_length); void sp_prepare_create_field(THD *thd, create_field *sql_field); int prepare_create_field(create_field *sql_field, uint *blob_columns, int *timestamps, int *timestamps_with_niladic, Loading Loading
mysql-test/r/sp.result +43 −0 Original line number Diff line number Diff line Loading @@ -2967,4 +2967,47 @@ begin end; goto label1; end| drop procedure bug6898| drop function if exists bug9102| create function bug9102() returns blob return 'a'| select bug9102()| bug9102() a drop function bug9102| drop function if exists bug7648| create function bug7648() returns bit(8) return 'a'| select bug7648()| bug7648() a drop function bug7648| drop function if exists bug9775| create function bug9775(v1 char(1)) returns enum('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('c')| bug9775('a') bug9775('b') bug9775('c') a b drop function bug9775| create function bug9775(v1 int) returns enum('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3)| bug9775(1) bug9775(2) bug9775(3) a b drop function bug9775| create function bug9775(v1 char(1)) returns set('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')| bug9775('a') bug9775('b') bug9775('a,b') bug9775('c') a b a,b drop function bug9775| create function bug9775(v1 int) returns set('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3),bug9775(4)| bug9775(1) bug9775(2) bug9775(3) bug9775(4) a b a,b drop function bug9775| drop function if exists bug8861| create function bug8861(v1 int) returns year return v1| select bug8861(05)| bug8861(05) 2005 set @x = bug8861(05)| select @x| @x 2005 drop function bug8861| drop table t1,t2;
mysql-test/t/sp.test +56 −0 Original line number Diff line number Diff line Loading @@ -3644,6 +3644,62 @@ end| drop procedure bug6898| # # BUG#9102: Stored proccedures: function which returns blob causes crash # --disable_warnings drop function if exists bug9102| --enable_warnings create function bug9102() returns blob return 'a'| select bug9102()| drop function bug9102| # # BUG#7648: Stored procedure crash when invoking a function that returns a bit # --disable_warnings drop function if exists bug7648| --enable_warnings create function bug7648() returns bit(8) return 'a'| select bug7648()| drop function bug7648| # # BUG#9775: crash if create function that returns enum or set # --disable_warnings drop function if exists bug9775| --enable_warnings create function bug9775(v1 char(1)) returns enum('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('c')| drop function bug9775| create function bug9775(v1 int) returns enum('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3)| drop function bug9775| create function bug9775(v1 char(1)) returns set('a','b') return v1| select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')| drop function bug9775| create function bug9775(v1 int) returns set('a','b') return v1| select bug9775(1),bug9775(2),bug9775(3),bug9775(4)| drop function bug9775| # # BUG#8861: If Return is a YEAR data type, value is not shown in year format # --disable_warnings drop function if exists bug8861| --enable_warnings create function bug8861(v1 int) returns year return v1| select bug8861(05)| set @x = bug8861(05)| select @x| drop function bug8861| # # BUG#NNNN: New bug synopsis # Loading
sql/item_func.cc +48 −14 Original line number Diff line number Diff line Loading @@ -4461,7 +4461,7 @@ longlong Item_func_row_count::val_int() Item_func_sp::Item_func_sp(sp_name *name) :Item_func(), m_name(name), m_sp(NULL) :Item_func(), m_name(name), m_sp(NULL), result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); Loading @@ -4470,7 +4470,7 @@ Item_func_sp::Item_func_sp(sp_name *name) Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list) :Item_func(list), m_name(name), m_sp(NULL) :Item_func(list), m_name(name), m_sp(NULL), result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); Loading Loading @@ -4526,6 +4526,29 @@ Item_func_sp::sp_result_field(void) const } int Item_func_sp::execute(Field **flp) { Item *it; Field *f; if (execute(&it)) { null_value= 1; return 1; } if (!(f= *flp)) { *flp= f= sp_result_field(); f->move_field((f->pack_length() > sizeof(result_buf)) ? sql_alloc(f->pack_length()) : result_buf); f->null_ptr= (uchar *)&null_value; f->null_bit= 1; } it->save_in_field(f, 1); return f->is_null(); } int Item_func_sp::execute(Item **itp) { Loading Loading @@ -4601,6 +4624,8 @@ Item_func_sp::field_type() const Field *field= 0; DBUG_ENTER("Item_func_sp::field_type"); if (result_field) DBUG_RETURN(result_field->type()); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if ((field= sp_result_field())) Loading @@ -4621,6 +4646,8 @@ Item_func_sp::result_type() const DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); if (result_field) DBUG_RETURN(result_field->result_type()); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if ((field= sp_result_field())) Loading @@ -4636,8 +4663,16 @@ Item_func_sp::result_type() const void Item_func_sp::fix_length_and_dec() { Field *field= result_field; DBUG_ENTER("Item_func_sp::fix_length_and_dec"); if (result_field) { decimals= result_field->decimals(); max_length= result_field->representation_length(); DBUG_VOID_RETURN; } if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only if (! m_sp) Loading @@ -4646,29 +4681,28 @@ Item_func_sp::fix_length_and_dec() } else { switch (result_type()) { if (!field) field= sp_result_field(); decimals= field->decimals(); max_length= field->representation_length(); switch (field->result_type()) { case STRING_RESULT: maybe_null= 1; max_length= MAX_BLOB_WIDTH; break; case REAL_RESULT: decimals= NOT_FIXED_DEC; max_length= float_length(decimals); break; case INT_RESULT: decimals= 0; max_length= 21; break; case DECIMAL_RESULT: // TODO: where to find real precision and scale? decimals= min(DECIMAL_MAX_LENGTH / 2, NOT_FIXED_DEC - 1); max_length= DECIMAL_MAX_LENGTH; break; case ROW_RESULT: default: // This case should never be chosen DBUG_ASSERT(0); break; } if (field != result_field) delete field; } DBUG_VOID_RETURN; } Loading
sql/item_func.h +18 −32 Original line number Diff line number Diff line Loading @@ -1283,8 +1283,11 @@ class Item_func_sp :public Item_func sp_name *m_name; mutable sp_head *m_sp; TABLE *dummy_table; Field *result_field; char result_buf[64]; int execute(Item **itp); int execute(Field **flp); Field *sp_result_field(void) const; public: Loading @@ -1296,6 +1299,12 @@ class Item_func_sp :public Item_func virtual ~Item_func_sp() {} void cleanup() { Item_func::cleanup(); result_field= NULL; } const char *func_name() const; enum enum_field_types field_type() const; Loading @@ -1308,53 +1317,30 @@ class Item_func_sp :public Item_func longlong val_int() { return (longlong)Item_func_sp::val_real(); if (execute(&result_field)) return 0LL; return result_field->val_int(); } double val_real() { Item *it; double d; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return 0.0; } d= it->val_real(); null_value= it->null_value; return d; return result_field->val_real(); } my_decimal *val_decimal(my_decimal *dec_buf) { Item *it; my_decimal *result; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return NULL; return result_field->val_decimal(dec_buf); } result= it->val_decimal(dec_buf); null_value= it->null_value; return result; } String *val_str(String *str) { Item *it; String *s; if (execute(&it)) { null_value= 1; if (execute(&result_field)) return NULL; } s= it->val_str(str); null_value= it->null_value; return s; return result_field->val_str(str); } void fix_length_and_dec(); Loading
sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -647,6 +647,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, bool group, bool modify_item, uint convert_blob_length); void sp_prepare_create_field(THD *thd, create_field *sql_field); int prepare_create_field(create_field *sql_field, uint *blob_columns, int *timestamps, int *timestamps_with_niladic, Loading