Bug#17261 Passing a variable from a stored procedure to UDF crashes mysqld
- Pass "buffers[i]" to val_str() in udf_handler::fix_fields insteead of NULL. - Add testcase for UDF that will load and run the udf_example functions if available sql/item_func.cc: Instead of passing a NULL pointer into val_str, use the "buffers" array to provide a temp string buffer. sql/udf_example.cc: Spelling error"on"->"one" mysql-test/include/have_udf.inc: New BitKeeper file ``mysql-test/include/have_udf.inc'' mysql-test/r/have_udf.require: New BitKeeper file ``mysql-test/r/have_udf.require'' mysql-test/r/udf.result: New BitKeeper file ``mysql-test/r/udf.result'' mysql-test/t/udf.test: New BitKeeper file ``mysql-test/t/udf.test''
This commit is contained in:
parent
86c920ba77
commit
79258e4480
12
mysql-test/include/have_udf.inc
Normal file
12
mysql-test/include/have_udf.inc
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# To check if the udf_example.so is available,
|
||||
# try to load one function from it.
|
||||
#
|
||||
#
|
||||
--require r/have_udf.require
|
||||
--disable_abort_on_error
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
|
||||
--disable_query_log
|
||||
DROP FUNCTION metaphon;
|
||||
--enable_query_log
|
||||
--enable_abort_on_error
|
1
mysql-test/r/have_udf.require
Normal file
1
mysql-test/r/have_udf.require
Normal file
@ -0,0 +1 @@
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
|
86
mysql-test/r/udf.result
Normal file
86
mysql-test/r/udf.result
Normal file
@ -0,0 +1,86 @@
|
||||
drop table if exists t1;
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
|
||||
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
|
||||
ERROR HY000: Can't find function 'myfunc_int_init' in library
|
||||
CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so";
|
||||
CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE FUNCTION reverse_lookup
|
||||
RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE AGGREGATE FUNCTION avgcost
|
||||
RETURNS REAL SONAME 'udf_example.so';
|
||||
select myfunc_double();
|
||||
ERROR HY000: myfunc_double must have at least on argument
|
||||
select myfunc_double(1);
|
||||
myfunc_double(1)
|
||||
49.00
|
||||
select myfunc_double(78654);
|
||||
myfunc_double(78654)
|
||||
54.00
|
||||
select myfunc_int();
|
||||
ERROR 42000: FUNCTION test.myfunc_int does not exist
|
||||
select lookup();
|
||||
ERROR HY000: Wrong arguments to lookup; Use the source
|
||||
select lookup("127.0.0.1");
|
||||
lookup("127.0.0.1")
|
||||
127.0.0.1
|
||||
select lookup(127,0,0,1);
|
||||
ERROR HY000: Wrong arguments to lookup; Use the source
|
||||
select lookup("localhost");
|
||||
lookup("localhost")
|
||||
127.0.0.1
|
||||
select reverse_lookup();
|
||||
ERROR HY000: Wrong number of arguments to reverse_lookup; Use the source
|
||||
select reverse_lookup("127.0.0.1");
|
||||
reverse_lookup("127.0.0.1")
|
||||
localhost
|
||||
select reverse_lookup(127,0,0,1);
|
||||
reverse_lookup(127,0,0,1)
|
||||
localhost
|
||||
select reverse_lookup("localhost");
|
||||
reverse_lookup("localhost")
|
||||
NULL
|
||||
select avgcost();
|
||||
ERROR HY000: wrong number of arguments: AVGCOST() requires two arguments
|
||||
select avgcost(100,23.76);
|
||||
ERROR HY000: wrong argument type: AVGCOST() requires an INT and a REAL
|
||||
create table t1(sum int, price float(24));
|
||||
insert into t1 values(100, 50.00), (100, 100.00);
|
||||
select avgcost(sum, price) from t1;
|
||||
avgcost(sum, price)
|
||||
75.0000
|
||||
delete from t1;
|
||||
insert into t1 values(100, 54.33), (200, 199.99);
|
||||
select avgcost(sum, price) from t1;
|
||||
avgcost(sum, price)
|
||||
151.4367
|
||||
drop table t1;
|
||||
select metaphon('hello');
|
||||
metaphon('hello')
|
||||
HL
|
||||
CREATE PROCEDURE `XXX1`(in testval varchar(10))
|
||||
begin
|
||||
select metaphon(testval);
|
||||
end//
|
||||
call XXX1('hello');
|
||||
metaphon(testval)
|
||||
HL
|
||||
drop procedure xxx1;
|
||||
CREATE PROCEDURE `XXX2`()
|
||||
begin
|
||||
declare testval varchar(10);
|
||||
set testval = 'hello';
|
||||
select metaphon(testval);
|
||||
end//
|
||||
call XXX2();
|
||||
metaphon(testval)
|
||||
HL
|
||||
drop procedure xxx2;
|
||||
DROP FUNCTION metaphon;
|
||||
DROP FUNCTION myfunc_double;
|
||||
DROP FUNCTION myfunc_int;
|
||||
ERROR 42000: FUNCTION test.myfunc_int does not exist
|
||||
DROP FUNCTION sequence;
|
||||
DROP FUNCTION lookup;
|
||||
DROP FUNCTION reverse_lookup;
|
||||
DROP FUNCTION avgcost;
|
94
mysql-test/t/udf.test
Normal file
94
mysql-test/t/udf.test
Normal file
@ -0,0 +1,94 @@
|
||||
--source include/have_udf.inc
|
||||
#
|
||||
# To run this tests you need to compile "sql/udf_example.cc" into
|
||||
# udf_example.so and setup LD_LIBRARY_PATH to point out where
|
||||
# the library are.
|
||||
#
|
||||
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# Create the example functions from udf_example
|
||||
#
|
||||
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
|
||||
|
||||
# myfunc_int does not have a myfunc_int_init function and can
|
||||
# not be loaded unless server is started with --allow-suspicious-udfs
|
||||
--error 1127
|
||||
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
|
||||
CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so";
|
||||
CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE FUNCTION reverse_lookup
|
||||
RETURNS STRING SONAME 'udf_example.so';
|
||||
CREATE AGGREGATE FUNCTION avgcost
|
||||
RETURNS REAL SONAME 'udf_example.so';
|
||||
|
||||
select myfunc_double();
|
||||
select myfunc_double(1);
|
||||
select myfunc_double(78654);
|
||||
select myfunc_int();
|
||||
select lookup();
|
||||
select lookup("127.0.0.1");
|
||||
select lookup(127,0,0,1);
|
||||
select lookup("localhost");
|
||||
select reverse_lookup();
|
||||
select reverse_lookup("127.0.0.1");
|
||||
select reverse_lookup(127,0,0,1);
|
||||
select reverse_lookup("localhost");
|
||||
select avgcost();
|
||||
select avgcost(100,23.76);
|
||||
create table t1(sum int, price float(24));
|
||||
insert into t1 values(100, 50.00), (100, 100.00);
|
||||
select avgcost(sum, price) from t1;
|
||||
delete from t1;
|
||||
insert into t1 values(100, 54.33), (200, 199.99);
|
||||
select avgcost(sum, price) from t1;
|
||||
drop table t1;
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# BUG#17261 Passing a variable from a stored procedure to UDF crashes mysqld
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
select metaphon('hello');
|
||||
|
||||
delimiter //;
|
||||
CREATE PROCEDURE `XXX1`(in testval varchar(10))
|
||||
begin
|
||||
select metaphon(testval);
|
||||
end//
|
||||
delimiter ;//
|
||||
|
||||
call XXX1('hello');
|
||||
drop procedure xxx1;
|
||||
|
||||
delimiter //;
|
||||
CREATE PROCEDURE `XXX2`()
|
||||
begin
|
||||
declare testval varchar(10);
|
||||
set testval = 'hello';
|
||||
select metaphon(testval);
|
||||
end//
|
||||
delimiter ;//
|
||||
|
||||
call XXX2();
|
||||
drop procedure xxx2;
|
||||
|
||||
|
||||
#
|
||||
# Drop the example functions from udf_example
|
||||
#
|
||||
|
||||
DROP FUNCTION metaphon;
|
||||
DROP FUNCTION myfunc_double;
|
||||
--error 1305
|
||||
DROP FUNCTION myfunc_int;
|
||||
DROP FUNCTION sequence;
|
||||
DROP FUNCTION lookup;
|
||||
DROP FUNCTION reverse_lookup;
|
||||
DROP FUNCTION avgcost;
|
||||
|
@ -2606,7 +2606,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
|
||||
switch(arguments[i]->type()) {
|
||||
case Item::STRING_ITEM: // Constant string !
|
||||
{
|
||||
String *res=arguments[i]->val_str((String *) 0);
|
||||
String *res=arguments[i]->val_str(&buffers[i]);
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= (char*) res->ptr();
|
||||
|
@ -518,7 +518,7 @@ my_bool myfunc_double_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
if (!args->arg_count)
|
||||
{
|
||||
strcpy(message,"myfunc_double must have at least on argument");
|
||||
strcpy(message,"myfunc_double must have at least one argument");
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user