summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/udf.result34
-rw-r--r--mysql-test/t/udf.test47
-rw-r--r--sql/item_func.cc9
3 files changed, 87 insertions, 3 deletions
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index 64b7111bbc8..d5f59247084 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -240,3 +240,37 @@ drop table bug18761;
select is_const((1,2,3));
ERROR 21000: Operand should contain 1 column(s)
drop function if exists is_const;
+CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
+CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
+create function f1(p1 varchar(255))
+returns varchar(255)
+begin
+return metaphon(p1);
+end//
+create function f2(p1 varchar(255))
+returns double
+begin
+return myfunc_double(p1);
+end//
+create function f3(p1 varchar(255))
+returns double
+begin
+return myfunc_int(p1);
+end//
+select f3(NULL);
+f3(NULL)
+0
+select f2(NULL);
+f2(NULL)
+NULL
+select f1(NULL);
+f1(NULL)
+NULL
+drop function f1;
+drop function f2;
+drop function f3;
+drop function metaphon;
+drop function myfunc_double;
+drop function myfunc_int;
+End of 5.0 tests.
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index 65cbc7ae3ae..0b582dc61b6 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -242,3 +242,50 @@ drop table bug18761;
select is_const((1,2,3));
drop function if exists is_const;
+
+#
+# Bug #25382: Passing NULL to an UDF called from stored procedures
+# crashes server
+#
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
+
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
+
+--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
+eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
+
+delimiter //;
+create function f1(p1 varchar(255))
+returns varchar(255)
+begin
+ return metaphon(p1);
+end//
+
+create function f2(p1 varchar(255))
+returns double
+begin
+ return myfunc_double(p1);
+end//
+
+create function f3(p1 varchar(255))
+returns double
+begin
+ return myfunc_int(p1);
+end//
+
+delimiter ;//
+
+select f3(NULL);
+select f2(NULL);
+select f1(NULL);
+
+drop function f1;
+drop function f2;
+drop function f3;
+drop function metaphon;
+drop function myfunc_double;
+drop function myfunc_int;
+
+--echo End of 5.0 tests.
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4138573785e..02aad2cfdc7 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2729,25 +2729,28 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
if (arguments[i]->const_item())
{
- if (arguments[i]->null_value)
- continue;
-
switch (arguments[i]->result_type())
{
case STRING_RESULT:
case DECIMAL_RESULT:
{
String *res= arguments[i]->val_str(&buffers[i]);
+ if (arguments[i]->null_value)
+ continue;
f_args.args[i]= (char*) res->ptr();
break;
}
case INT_RESULT:
*((longlong*) to)= arguments[i]->val_int();
+ if (arguments[i]->null_value)
+ continue;
f_args.args[i]= to;
to+= ALIGN_SIZE(sizeof(longlong));
break;
case REAL_RESULT:
*((double*) to)= arguments[i]->val_real();
+ if (arguments[i]->null_value)
+ continue;
f_args.args[i]= to;
to+= ALIGN_SIZE(sizeof(double));
break;