diff options
author | unknown <acurtis@xiphis.org> | 2005-04-20 18:08:42 +0100 |
---|---|---|
committer | unknown <acurtis@xiphis.org> | 2005-04-20 18:08:42 +0100 |
commit | de8a3b31218f66948ecfc4ce4fee85a0285ae161 (patch) | |
tree | 07e3fe7c833631d8a9038ef91df990a4483c109a /sql/item_func.cc | |
parent | f054047f022096efaeeec46381ddf86d59eed517 (diff) | |
download | mariadb-git-de8a3b31218f66948ecfc4ce4fee85a0285ae161.tar.gz |
Bug#9775 - Stored procedures: crash if create function that returns enum or set
Fix bug and implement return type casting.
mysql-test/r/sp.result:
Bug#9775
Test for bug + feature
Fix previous tests
mysql-test/t/sp.test:
Bug#9775
Test for bug + feature
Fix previous tests
sql/item_func.cc:
Bug#9775
new method Item_func_sp::execute(Field **)
some optimizations.
sql/item_func.h:
Bug#9775
results for Item_func_sp pass through a Field of the return type.
new method Item_func_sp::execute(Field **)
sql/sp_head.cc:
Bug#9775
missing initialiation for type_lengths in sp_head::create_typelib()
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index c607efa0797..fb21551e22f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -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); @@ -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); @@ -4527,6 +4527,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) { DBUG_ENTER("Item_func_sp::execute"); @@ -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())) @@ -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())) @@ -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) @@ -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; } |