summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpem@mysql.com <>2003-02-27 19:08:52 +0100
committerpem@mysql.com <>2003-02-27 19:08:52 +0100
commit16cff7e75d2c9895772554894c4e4ff5722664ae (patch)
treeb7efe78983c562d9dd31ef6ae9f1c7728e01aca8
parentca2e77ca7a4cd4cbdb08425044ca71f3d38def64 (diff)
downloadmariadb-git-16cff7e75d2c9895772554894c4e4ff5722664ae.tar.gz
A small step forward. Fixed a few bugs and made string type functions work,
but still strange interferences between multiple function invocations...
-rw-r--r--mysql-test/r/sp.result19
-rw-r--r--mysql-test/t/sp.test12
-rw-r--r--sql/item_func.cc46
-rw-r--r--sql/item_func.h6
-rw-r--r--sql/sp_head.cc6
5 files changed, 52 insertions, 37 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 7beaa9fe673..ab445e44a5a 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -377,9 +377,10 @@ end;
drop procedure create_select;
create function e() returns double
return 2.7182818284590452354;
-select e();
-e()
-2.718281828459
+set @e = e();
+select e(), @e;
+e() @e
+2.718281828459 2.718281828459
create function inc(i int) returns int
return i+1;
select inc(1), inc(99), inc(-71);
@@ -390,6 +391,11 @@ return x*y;
select mul(1,1), mul(3,5), mul(4711, 666);
mul(1,1) mul(3,5) mul(4711, 666)
1 15 3137526
+create function append(s1 char(8), s2 char(8)) returns char(16)
+return concat(s1, s2);
+select append("foo", "bar");
+append("foo", "bar")
+foobar
create function fac(n int unsigned) returns bigint unsigned
begin
declare f bigint unsigned;
@@ -400,11 +406,12 @@ set n = n - 1;
end while;
return f;
end;
-select fac(1), fac(2), fac(10);
-fac(1) fac(2) fac(10)
-1 2 3628800
+select fac(1), fac(2), fac(5), fac(10);
+fac(1) fac(2) fac(5) fac(10)
+1 2 120 3628800
drop function e;
drop function inc;
drop function mul;
+drop function append;
drop function fac;
drop table t1;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index b509ff8e557..17b21f612d6 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -445,7 +445,8 @@ drop procedure create_select|
create function e() returns double
return 2.7182818284590452354|
-select e()|
+set @e = e()|
+select e(), @e|
# A minimal function with one argument
create function inc(i int) returns int
@@ -459,6 +460,12 @@ create function mul(x int, y int) returns int
select mul(1,1), mul(3,5), mul(4711, 666)|
+# A minimal string function
+create function append(s1 char(8), s2 char(8)) returns char(16)
+ return concat(s1, s2)|
+
+select append("foo", "bar")|
+
# A function with flow control
create function fac(n int unsigned) returns bigint unsigned
begin
@@ -472,11 +479,12 @@ begin
return f;
end|
-select fac(1), fac(2), fac(10)|
+select fac(1), fac(2), fac(5), fac(10)|
drop function e|
drop function inc|
drop function mul|
+drop function append|
drop function fac|
delimiter ;|
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 945a6e25e4f..7c3faae8e6e 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2781,44 +2781,42 @@ Item_func_sp::execute(Item **itp)
DBUG_ENTER("Item_func_sp::execute");
THD *thd= current_thd;
- if (!m_sp && !(m_sp= sp_find_function(thd, &m_name)))
+ if (! m_sp)
+ m_sp= sp_find_function(thd, &m_name);
+ if (! m_sp)
DBUG_RETURN(-1);
DBUG_RETURN(m_sp->execute_function(thd, args, arg_count, itp));
}
-Item_result
-Item_func_sp::result_type() const
+enum enum_field_types
+Item_func_sp::field_type() const
{
- DBUG_ENTER("Item_func_sp::result_type");
- DBUG_PRINT("info", ("m_sp = %p", m_sp));
+ DBUG_ENTER("Item_func_sp::field_type");
+ if (! m_sp)
+ m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name));
if (m_sp)
{
- DBUG_RETURN(m_sp->result());
- }
- else
- {
- sp_head *sp= sp_find_function(current_thd, (LEX_STRING *)(&m_name));
- if (sp)
- DBUG_RETURN(m_sp->result());
- DBUG_RETURN(STRING_RESULT);
+ DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns));
+ DBUG_RETURN(m_sp->m_returns);
}
+ DBUG_RETURN(MYSQL_TYPE_STRING);
}
-void
-Item_func_sp::make_field(Send_field *field)
+Item_result
+Item_func_sp::result_type() const
{
- DBUG_ENTER("Item_func_sp::make_field");
- Item *it;
+ DBUG_ENTER("Item_func_sp::result_type");
+ DBUG_PRINT("info", ("m_sp = %p", m_sp));
- if (!execute(&it))
+ if (! m_sp)
+ m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name));
+ if (m_sp)
{
- it->set_name(name, 0);
- init_make_field(field, field_type());
- it->make_field(field);
+ DBUG_RETURN(m_sp->result());
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(STRING_RESULT);
}
void
@@ -2826,7 +2824,9 @@ 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)
+ m_sp= sp_find_function(current_thd, &m_name);
+ if (m_sp)
{
switch (m_sp->result()) {
case STRING_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index 07201093473..00794b048a2 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1161,7 +1161,7 @@ class Item_func_sp :public Item_func
{
private:
LEX_STRING m_name;
- sp_head *m_sp;
+ mutable sp_head *m_sp;
int execute(Item **itp);
@@ -1183,6 +1183,8 @@ public:
return m_name.str;
}
+ enum enum_field_types field_type() const;
+
Item_result result_type() const;
longlong val_int()
@@ -1208,8 +1210,6 @@ public:
return it->val_str(str);
}
- void make_field(Send_field *field);
-
void fix_length_and_dec();
};
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 64ecdc5b380..b461f2035ad 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -70,11 +70,11 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type)
default:
{
char buffer[MAX_FIELD_WIDTH];
- String tmp(buffer, sizeof(buffer), default_charset_info);
+ String tmp(buffer, sizeof(buffer), it->charset());
String *s= it->val_str(&tmp);
- it= new Item_string(s->c_ptr_quick(), s->length(),
- default_charset_info);
+ it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()),
+ s->length(), it->charset());
break;
}
}