diff options
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index 3742a13e0bc..d52b0a184da 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4318,13 +4318,33 @@ longlong Item_func_row_count::val_int() Item_func_sp::Item_func_sp(sp_name *name) :Item_func(), m_name(name), m_sp(NULL) { + char *empty_name= (char *) ""; + maybe_null= 1; m_name->init_qname(current_thd); + bzero(&dummy_table, sizeof(dummy_table)); + dummy_table.share.table_cache_key = empty_name; + dummy_table.share.table_name = empty_name; + dummy_table.table.alias = empty_name; + dummy_table.share.table_name = empty_name; + dummy_table.table.maybe_null = maybe_null; + dummy_table.table.in_use= current_thd; + dummy_table.table.s = &dummy_table.share; } Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list) :Item_func(list), m_name(name), m_sp(NULL) { + char *empty_name= (char *) ""; + maybe_null= 1; m_name->init_qname(current_thd); + bzero(&dummy_table, sizeof(dummy_table)); + dummy_table.share.table_cache_key = empty_name; + dummy_table.share.table_name = empty_name; + dummy_table.table.alias = empty_name; + dummy_table.share.table_name = empty_name; + dummy_table.table.maybe_null = maybe_null; + dummy_table.table.in_use= current_thd; + dummy_table.table.s = &dummy_table.share; } const char * @@ -4349,6 +4369,18 @@ Item_func_sp::func_name() const } +Field * +Item_func_sp::sp_result_field(void) const +{ + Field *field= 0; + THD *thd= current_thd; + DBUG_ENTER("Item_func_sp::sp_result_field"); + if (m_sp) + field= m_sp->make_field(max_length, name, &dummy_table.table); + DBUG_RETURN(field); +} + + int Item_func_sp::execute(Item **itp) { @@ -4404,17 +4436,38 @@ Item_func_sp::execute(Item **itp) } +void +Item_func_sp::make_field(Send_field *tmp_field) +{ + Field *field; + DBUG_ENTER("Item_func_sp::make_field"); + if (! m_sp) + m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only + if ((field= sp_result_field())) + { + field->make_field(tmp_field); + delete field; + DBUG_VOID_RETURN; + } + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); + init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); + DBUG_VOID_RETURN; +} + + enum enum_field_types Item_func_sp::field_type() const { + Field *field= 0; DBUG_ENTER("Item_func_sp::field_type"); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only - if (m_sp) + if ((field= sp_result_field())) { - DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); - DBUG_RETURN(m_sp->m_returns); + enum_field_types result= field->type(); + delete field; + DBUG_RETURN(result); } my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); DBUG_RETURN(MYSQL_TYPE_VARCHAR); @@ -4424,14 +4477,17 @@ Item_func_sp::field_type() const Item_result Item_func_sp::result_type() const { + Field *field= 0; DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); if (! m_sp) m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only - if (m_sp) + if ((field= sp_result_field())) { - DBUG_RETURN(m_sp->result()); + Item_result result= field->result_type(); + delete field; + DBUG_RETURN(result); } my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); DBUG_RETURN(STRING_RESULT); @@ -4450,7 +4506,7 @@ Item_func_sp::fix_length_and_dec() } else { - switch (m_sp->result()) { + switch (result_type()) { case STRING_RESULT: maybe_null= 1; max_length= MAX_BLOB_WIDTH; @@ -4485,3 +4541,19 @@ longlong Item_func_found_rows::val_int() return thd->found_rows(); } + +Field * +Item_func_sp::tmp_table_field(TABLE *t_arg) +{ + Field *res= 0; + enum_field_types ftype; + DBUG_ENTER("Item_func_sp::tmp_table_field"); + + if (m_sp) + res= m_sp->make_field(max_length, (const char *)name, t_arg); + + if (!res) + res= Item_func::tmp_table_field(t_arg); + + DBUG_RETURN(res); +} |