Below is the list of changes that have just been committed into a local
5.0 repository of acurtis. When acurtis does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1856 05/04/20 18:08:42 acurtis@stripped +5 -0
Bug#9775 - Stored procedures: crash if create function that returns enum or set
Fix bug and implement return type casting.
sql/sp_head.cc
1.128 05/04/20 18:08:28 acurtis@stripped +6 -2
Bug#9775
missing initialiation for type_lengths in sp_head::create_typelib()
sql/item_func.h
1.106 05/04/20 18:08:27 acurtis@stripped +17 -41
Bug#9775
results for Item_func_sp pass through a Field of the return type.
new method Item_func_sp::execute(Field **)
sql/item_func.cc
1.181 05/04/20 18:08:27 acurtis@stripped +48 -14
Bug#9775
new method Item_func_sp::execute(Field **)
some optimizations.
mysql-test/t/sp.test
1.111 05/04/20 18:08:27 acurtis@stripped +22 -1
Bug#9775
Test for bug + feature
Fix previous tests
mysql-test/r/sp.result
1.116 05/04/20 18:08:26 acurtis@stripped +24 -3
Bug#9775
Test for bug + feature
Fix previous tests
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: acurtis
# Host: ltantony.xiphis.org
# Root: /.amd_mnt/bk.anubis/host/work-acurtis/bug9102
--- 1.180/sql/item_func.cc 2005-03-28 10:15:07 +01:00
+++ 1.181/sql/item_func.cc 2005-04-20 18:08:27 +01:00
@@ -4461,7 +4461,7 @@
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);
@@ -4470,7 +4470,7 @@
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);
@@ -4527,6 +4527,29 @@
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)
{
DBUG_ENTER("Item_func_sp::execute");
@@ -4601,6 +4624,8 @@
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()))
@@ -4621,6 +4646,8 @@
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()))
@@ -4636,8 +4663,16 @@
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)
@@ -4646,29 +4681,28 @@
}
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;
}
--- 1.105/sql/item_func.h 2005-04-19 10:50:59 +01:00
+++ 1.106/sql/item_func.h 2005-04-20 18:08:27 +01:00
@@ -1283,8 +1283,11 @@
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:
@@ -1296,6 +1299,12 @@
virtual ~Item_func_sp()
{}
+ void cleanup()
+ {
+ Item_func::cleanup();
+ result_field= NULL;
+ }
+
const char *func_name() const;
enum enum_field_types field_type() const;
@@ -1308,63 +1317,30 @@
longlong val_int()
{
- Item *it;
- longlong l;
-
- if (execute(&it))
- {
- null_value= 1;
+ if (execute(&result_field))
return 0LL;
- }
- l= it->val_int();
- null_value= it->null_value;
- return l;
+ 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;
- }
- result= it->val_decimal(dec_buf);
- null_value= it->null_value;
- return result;
+ return result_field->val_decimal(dec_buf);
}
-
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();
--- 1.115/mysql-test/r/sp.result 2005-04-19 10:50:58 +01:00
+++ 1.116/mysql-test/r/sp.result 2005-04-20 18:08:26 +01:00
@@ -2960,14 +2960,35 @@
drop function bug9902|
drop function if exists bug9102|
create function bug9102() returns blob return 'a'|
-select bug9102();
-drop function bug9102|
+select bug9102()|
bug9102()
a
-drop procedure if exists bug7648|
+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 table t1,t2;
--- 1.110/mysql-test/t/sp.test 2005-04-19 10:50:59 +01:00
+++ 1.111/mysql-test/t/sp.test 2005-04-20 18:08:27 +01:00
@@ -3643,11 +3643,32 @@
# BUG#7648: Stored procedure crash when invoking a function that returns a bit
#
--disable_warnings
-drop procedure if exists bug7648|
+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|
#
--- 1.127/sql/sp_head.cc 2005-04-19 09:09:11 +01:00
+++ 1.128/sql/sp_head.cc 2005-04-20 18:08:28 +01:00
@@ -378,8 +378,9 @@
result->count= src->elements;
result->name= "";
if (!(result->type_names=(const char **)
- alloc_root(mem_root,sizeof(char *)*(result->count+1))))
+ alloc_root(mem_root,(sizeof(char *)+sizeof(int))*(result->count+1))))
return 0;
+ result->type_lengths= (unsigned int *)(result->type_names +
result->count+1);
List_iterator<String> it(*src);
String conv, *tmp;
uint32 dummy;
@@ -397,8 +398,10 @@
result->type_names[i]= buf;
result->type_lengths[i]= conv.length();
}
- else
+ else {
result->type_names[i]= strdup_root(mem_root, tmp->c_ptr());
+ result->type_lengths[i]= tmp->length();
+ }
// Strip trailing spaces.
uint lengthsp= cs->cset->lengthsp(cs, result->type_names[i],
@@ -407,6 +410,7 @@
((uchar *)result->type_names[i])[lengthsp]= '\0';
}
result->type_names[result->count]= 0;
+ result->type_lengths[result->count]= 0;
}
return result;
}
| Thread |
|---|
| • bk commit into 5.0 tree (acurtis:1.1856) BUG#9775 | antony | 20 Apr |