summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc84
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);
+}