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.cc153
1 files changed, 147 insertions, 6 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index ef845bb8266..7c5b584e645 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -28,6 +28,9 @@
#include <time.h>
#include <ft_global.h>
+#include "sp_head.h"
+#include "sp_rcontext.h"
+#include "sp.h"
bool check_reserved_words(LEX_STRING *name)
{
@@ -786,7 +789,7 @@ double Item_func_log2::val()
double value=args[0]->val();
if ((null_value=(args[0]->null_value || value <= 0.0)))
return 0.0;
- return log(value) / log(2.0);
+ return log(value) / M_LN2;
}
double Item_func_log10::val()
@@ -1587,11 +1590,16 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
const_item_cache&=item->const_item();
f_args.arg_type[i]=item->result_type();
}
+ //TODO: why all folowing memory is not allocated with 1 call of sql_alloc?
if (!(buffers=new String[arg_count]) ||
!(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) ||
- !(f_args.lengths=(ulong*) sql_alloc(arg_count * sizeof(long))) ||
- !(f_args.maybe_null=(char*) sql_alloc(arg_count * sizeof(char))) ||
- !(num_buffer= (char*) sql_alloc(ALIGN_SIZE(sizeof(double))*arg_count)))
+ !(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) ||
+ !(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) ||
+ !(num_buffer= (char*) sql_alloc(arg_count *
+ ALIGN_SIZE(sizeof(double)))) ||
+ !(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) ||
+ !(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count *
+ sizeof(long))))
{
free_udf(u_d);
DBUG_RETURN(1);
@@ -1610,8 +1618,10 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
for (uint i=0; i < arg_count; i++)
{
f_args.args[i]=0;
- f_args.lengths[i]=arguments[i]->max_length;
- f_args.maybe_null[i]=(char) arguments[i]->maybe_null;
+ f_args.lengths[i]= arguments[i]->max_length;
+ f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
+ f_args.attributes[i]= arguments[i]->name;
+ f_args.attribute_lengths[i]= arguments[i]->name_length;
switch(arguments[i]->type()) {
case Item::STRING_ITEM: // Constant string !
@@ -3253,6 +3263,137 @@ longlong Item_func_is_used_lock::val_int()
}
+longlong Item_func_row_count::val_int()
+{
+ DBUG_ASSERT(fixed == 1);
+ THD *thd= current_thd;
+
+ return thd->row_count_func;
+}
+
+
+Item_func_sp::Item_func_sp(sp_name *name)
+ :Item_func(), m_name(name), m_sp(NULL)
+{
+ m_name->init_qname(current_thd);
+}
+
+Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
+ :Item_func(list), m_name(name), m_sp(NULL)
+{
+ m_name->init_qname(current_thd);
+}
+
+const char *
+Item_func_sp::func_name() const
+{
+ return m_name->m_name.str;
+}
+
+int
+Item_func_sp::execute(Item **itp)
+{
+ DBUG_ENTER("Item_func_sp::execute");
+ THD *thd= current_thd;
+ int res;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ st_sp_security_context save_ctx;
+#endif
+
+ if (! m_sp)
+ m_sp= sp_find_function(thd, m_name);
+ if (! m_sp)
+ {
+ my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0),
+ "FUNCTION", m_name->m_qname);
+ DBUG_RETURN(-1);
+ }
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ sp_change_security_context(thd, m_sp, &save_ctx);
+#endif
+
+ res= m_sp->execute_function(thd, args, arg_count, itp);
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ sp_restore_security_context(thd, m_sp, &save_ctx);
+#endif
+
+ DBUG_RETURN(res);
+}
+
+enum enum_field_types
+Item_func_sp::field_type() const
+{
+ DBUG_ENTER("Item_func_sp::field_type");
+
+ if (! m_sp)
+ m_sp= sp_find_function(current_thd, m_name);
+ if (m_sp)
+ {
+ DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns));
+ DBUG_RETURN(m_sp->m_returns);
+ }
+ my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0),
+ "FUNCTION", m_name->m_qname);
+ DBUG_RETURN(MYSQL_TYPE_STRING);
+}
+
+Item_result
+Item_func_sp::result_type() const
+{
+ 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);
+ if (m_sp)
+ {
+ DBUG_RETURN(m_sp->result());
+ }
+ my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0),
+ "FUNCTION", m_name->m_qname);
+ DBUG_RETURN(STRING_RESULT);
+}
+
+void
+Item_func_sp::fix_length_and_dec()
+{
+ DBUG_ENTER("Item_func_sp::fix_length_and_dec");
+
+ if (! m_sp)
+ m_sp= sp_find_function(current_thd, m_name);
+ if (! m_sp)
+ {
+ my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0),
+ "FUNCTION", m_name->m_qname);
+ }
+ else
+ {
+ switch (m_sp->result()) {
+ 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 ROW_RESULT:
+ default:
+ // This case should never be choosen
+ DBUG_ASSERT(0);
+ break;
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+
longlong Item_func_found_rows::val_int()
{
DBUG_ASSERT(fixed == 1);