diff options
author | unknown <kostja@bodhi.(none)> | 2007-11-01 00:31:57 +0300 |
---|---|---|
committer | unknown <kostja@bodhi.(none)> | 2007-11-01 00:31:57 +0300 |
commit | 189ec0e0af2ab7d50340f66285ffecc4f06586c6 (patch) | |
tree | bcaa91f1539817a06d3c4e08a7e7caf42e152c40 | |
parent | c2dadab13649b036b910596382307ffeef2a1951 (diff) | |
download | mariadb-git-189ec0e0af2ab7d50340f66285ffecc4f06586c6.tar.gz |
A fix for Bug#32007 select udf_function() doesn't return an error if error
during udf initialization. The bug is spotted while working on Bug 12713.
If a user-defined function was used in a SELECT statement, and an
error would occur during UDF initialization, this error would not terminate
execution of the SELECT, but rather would be converted to a warning.
The fix is to use a stack buffer to store the message from udf_init instead
of private my_error() buffer.
mysql-test/r/udf.result:
Update the result to reflect the fix for Bug#32007 select udf_function()
doesn't return an error if error during udf initialization
mysql-test/t/udf.test:
Update the test to reflect the fix for Bug #32007 select udf_function()
doesn't return an error if error during udf initialization
sql/item_func.cc:
A fix for Bug#32007.
net.last_error buffer was used to store the temporary message from udf_init.
Then, when my_error() was called, net.last_error was not empty so
my_error() would conclude that there is already an error in the error stack,
and not "overwrite" it.
However, thd->net.report_error was not set, so the the
SELECT was not aborted.
The fix is to use a stack buffer instead of thd->net.last_error
to store the message from udf_init. The message will end up in
thd->net.last_error anyway after a call to my_error.
-rw-r--r-- | mysql-test/r/udf.result | 12 | ||||
-rw-r--r-- | mysql-test/t/udf.test | 12 | ||||
-rw-r--r-- | sql/item_func.cc | 5 |
3 files changed, 15 insertions, 14 deletions
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index da27a71c1a1..cb5afcf5f17 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -11,7 +11,7 @@ RETURNS STRING SONAME "UDF_EXAMPLE_LIB"; CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "UDF_EXAMPLE_LIB"; select myfunc_double(); -ERROR HY000: myfunc_double must have at least one argument +ERROR HY000: Can't initialize function 'myfunc_double'; myfunc_double must have at least one argument select myfunc_double(1); myfunc_double(1) 49.00 @@ -24,26 +24,26 @@ select myfunc_int(); myfunc_int() 0 select lookup(); -ERROR HY000: Wrong arguments to lookup; Use the source +ERROR HY000: Can't initialize function 'lookup'; 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 +ERROR HY000: Can't initialize function 'lookup'; 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 +ERROR HY000: Can't initialize function 'reverse_lookup'; Wrong number of arguments to reverse_lookup; Use the source select reverse_lookup("127.0.0.1"); select reverse_lookup(127,0,0,1); select reverse_lookup("localhost"); reverse_lookup("localhost") NULL select avgcost(); -ERROR HY000: wrong number of arguments: AVGCOST() requires two arguments +ERROR HY000: Can't initialize function 'avgcost'; 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 +ERROR HY000: Can't initialize function 'avgcost'; 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; diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index 663dc08d72e..32cfca57546 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -35,20 +35,20 @@ eval CREATE FUNCTION reverse_lookup eval CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "$UDF_EXAMPLE_LIB"; ---error 0 +--error ER_CANT_INITIALIZE_UDF select myfunc_double(); select myfunc_double(1); select myfunc_double(78654); --error 1305 select myfunc_nonexist(); select myfunc_int(); ---error 0 +--error ER_CANT_INITIALIZE_UDF select lookup(); select lookup("127.0.0.1"); ---error 0 +--error ER_CANT_INITIALIZE_UDF select lookup(127,0,0,1); select lookup("localhost"); ---error 0 +--error ER_CANT_INITIALIZE_UDF select reverse_lookup(); # These two functions should return "localhost", but it's @@ -59,9 +59,9 @@ select reverse_lookup(127,0,0,1); --enable_result_log select reverse_lookup("localhost"); ---error 0 +--error ER_CANT_INITIALIZE_UDF select avgcost(); ---error 0 +--error ER_CANT_INITIALIZE_UDF select avgcost(100,23.76); create table t1(sum int, price float(24)); insert into t1 values(100, 50.00), (100, 100.00); diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d4d61de61b..ec0ecc89394 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2897,6 +2897,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, if (u_d->func_init) { + char init_msg_buff[MYSQL_ERRMSG_SIZE]; char *to=num_buffer; for (uint i=0; i < arg_count; i++) { @@ -2949,10 +2950,10 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, } thd->net.last_error[0]=0; Udf_func_init init= u_d->func_init; - if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) + if ((error=(uchar) init(&initid, &f_args, init_msg_buff))) { my_error(ER_CANT_INITIALIZE_UDF, MYF(0), - u_d->name.str, thd->net.last_error); + u_d->name.str, init_msg_buff); free_udf(u_d); DBUG_RETURN(TRUE); } |