Commit 0a28cac0 authored by unknown's avatar unknown

Bug #29804 UDF parameters don't contain correct string length

  
Previously, UDF *_init functions were passed constant strings with erroneous lengths.
The length came from the containing variable's size, not the length of the value itself.
  
Now the *_init functions get the constant as a null terminated string with the correct
length supplied too.


mysql-test/r/udf.result:
  Test case to check constants passed UDFs.
mysql-test/t/udf.test:
  Test case to check constants passed UDFs.
sql/item_func.cc:
  UDF _init functions are now passed the length of the constants, rather than the max
  length of the var containing the constant.
sql/udf_example.c:
  Added check_const_len functions. The check_const_len_init functions checks that the
  lengths of constants are correctly passed.
sql/udf_example.def:
  Add new example functions to windows dll export list.
parent 3e7b724c
...@@ -296,4 +296,28 @@ Qcache_queries_in_cache 0 ...@@ -296,4 +296,28 @@ Qcache_queries_in_cache 0
drop table t1; drop table t1;
drop function metaphon; drop function metaphon;
set GLOBAL query_cache_size=default; set GLOBAL query_cache_size=default;
CREATE TABLE const_len_bug (
str_const varchar(4000),
result1 varchar(4000),
result2 varchar(4000)
);
CREATE TRIGGER check_const_len_trigger BEFORE INSERT ON const_len_bug FOR EACH ROW BEGIN
set NEW.str_const = 'bar';
set NEW.result2 = check_const_len(NEW.str_const);
END |
CREATE PROCEDURE check_const_len_sp (IN str_const VARCHAR(4000))
BEGIN
DECLARE result VARCHAR(4000);
SET result = check_const_len(str_const);
insert into const_len_bug values(str_const, result, "");
END |
CREATE FUNCTION check_const_len RETURNS string SONAME "UDF_EXAMPLE_LIB";
CALL check_const_len_sp("foo");
SELECT * from const_len_bug;
str_const result1 result2
bar Correct length Correct length
DROP FUNCTION check_const_len;
DROP PROCEDURE check_const_len_sp;
DROP TRIGGER check_const_len_trigger;
DROP TABLE const_len_bug;
End of 5.0 tests. End of 5.0 tests.
...@@ -312,4 +312,40 @@ drop function metaphon; ...@@ -312,4 +312,40 @@ drop function metaphon;
set GLOBAL query_cache_size=default; set GLOBAL query_cache_size=default;
#
# Bug #29804 UDF parameters don't contain correct string length
#
CREATE TABLE const_len_bug (
str_const varchar(4000),
result1 varchar(4000),
result2 varchar(4000)
);
DELIMITER |;
CREATE TRIGGER check_const_len_trigger BEFORE INSERT ON const_len_bug FOR EACH ROW BEGIN
set NEW.str_const = 'bar';
set NEW.result2 = check_const_len(NEW.str_const);
END |
CREATE PROCEDURE check_const_len_sp (IN str_const VARCHAR(4000))
BEGIN
DECLARE result VARCHAR(4000);
SET result = check_const_len(str_const);
insert into const_len_bug values(str_const, result, "");
END |
DELIMITER ;|
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION check_const_len RETURNS string SONAME "$UDF_EXAMPLE_LIB";
CALL check_const_len_sp("foo");
SELECT * from const_len_bug;
DROP FUNCTION check_const_len;
DROP PROCEDURE check_const_len_sp;
DROP TRIGGER check_const_len_trigger;
DROP TABLE const_len_bug;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -2924,7 +2924,8 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func, ...@@ -2924,7 +2924,8 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
String *res= arguments[i]->val_str(&buffers[i]); String *res= arguments[i]->val_str(&buffers[i]);
if (arguments[i]->null_value) if (arguments[i]->null_value)
continue; continue;
f_args.args[i]= (char*) res->ptr(); f_args.args[i]= (char*) res->c_ptr();
f_args.lengths[i]= res->length();
break; break;
} }
case INT_RESULT: case INT_RESULT:
......
...@@ -1106,4 +1106,39 @@ char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)), ...@@ -1106,4 +1106,39 @@ char * is_const(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)),
} }
my_bool check_const_len_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if (args->arg_count != 1)
{
strmov(message, "CHECK_CONST_LEN accepts only one argument");
return 1;
}
if (args->args[0] == 0)
{
initid->ptr= (char*)"Not constant";
}
else if(strlen(args->args[0]) == args->lengths[0])
{
initid->ptr= (char*)"Correct length";
}
else
{
initid->ptr= (char*)"Wrong length";
}
initid->max_length = 100;
return 0;
}
char * check_const_len(UDF_INIT *initid, UDF_ARGS *args __attribute__((unused)),
char *result, unsigned long *length,
char *is_null, char *error __attribute__((unused)))
{
strmov(result, initid->ptr);
*length= strlen(result);
*is_null= 0;
return result;
}
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
...@@ -23,3 +23,5 @@ EXPORTS ...@@ -23,3 +23,5 @@ EXPORTS
avgcost avgcost
is_const is_const
is_const_init is_const_init
check_const_len
check_const_len_init
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment