mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 17:33:44 +01:00
Bug#18761: constant expression as UDF parameters not passed in as constant
The code that set up data to be passed to user-defined functions was very old and analyzed the "Type" of the data that was passed into the UDF, when it really should analyze the "return_type", which is hard-coded for simple Items and works correctly for complex ones like functions. --- Added test at Sergei's behest. mysql-test/r/udf.result: Verify that various arguments work. --- Added test at Sergei's behest. mysql-test/t/udf.test: Verify that various arguments work. --- Added test at Sergei's behest. sql/item_func.cc: For function-Items, test whether it is constant and set the struct members for the UDF parameter appropriately. Replace tabs with spaces in affected code. sql/udf_example.c: Include a simple function that is useful in testing.
This commit is contained in:
parent
e948c64ff5
commit
154c6e0677
5 changed files with 145 additions and 27 deletions
|
@ -15,3 +15,11 @@
|
|||
45214442pBGT9KuZEGixBH71jTzbOA
|
||||
45214a07hVsIGwvwa-WrO-jpeaSwVw
|
||||
452a92d0-31-8wSzSfZi165fcGcXPA
|
||||
454bb488ijVLOUK_GFjcoISE0GxPUA
|
||||
454bb9a8AwlGRC_wWLS2sNMoRBMRGw
|
||||
454c946ciQoR4dfTBZ0RTBmGJKp6lw
|
||||
454f6e7eAnfLD9OCbGr5X9KiKvfKcQ
|
||||
454f704bJiJy0_Nx2drY9P5kK3uOzg
|
||||
454fa71cxshxszXJQYa9jbo0-_hAHw
|
||||
4550b0ceIcozdgQhWFUTAtWkN196lA
|
||||
4558b3d73Cxjlb7Wv1oytdSTthxDfw
|
||||
|
|
|
@ -115,3 +115,38 @@ DROP FUNCTION sequence;
|
|||
DROP FUNCTION lookup;
|
||||
DROP FUNCTION reverse_lookup;
|
||||
DROP FUNCTION avgcost;
|
||||
CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
|
||||
select
|
||||
is_const(3) as const,
|
||||
is_const(3.14) as const,
|
||||
is_const('fnord') as const,
|
||||
is_const(2+3) as const,
|
||||
is_const(rand()) as 'nc rand()',
|
||||
is_const(sin(3.14)) as const,
|
||||
is_const(upper('test')) as const;
|
||||
const const const const nc rand() const const
|
||||
const const const const not const const const
|
||||
create table bug18761 (n int);
|
||||
insert into bug18761 values (null),(2);
|
||||
select
|
||||
is_const(3) as const,
|
||||
is_const(3.14) as const,
|
||||
is_const('fnord') as const,
|
||||
is_const(2+3) as const,
|
||||
is_const(2+n) as 'nc 2+n ',
|
||||
is_const(sin(n)) as 'nc sin(n)',
|
||||
is_const(sin(3.14)) as const,
|
||||
is_const(upper('test')) as const,
|
||||
is_const(rand()) as 'nc rand()',
|
||||
is_const(n) as 'nc n ',
|
||||
is_const(is_const(n)) as 'nc ic?(n)',
|
||||
is_const(is_const('c')) as const
|
||||
from
|
||||
bug18761;
|
||||
const const const const nc 2+n nc sin(n) const const nc rand() nc n nc ic?(n) const
|
||||
const const const const not const not const const const not const not const not const const
|
||||
const const const const not const not const const const not const not const not const const
|
||||
drop table bug18761;
|
||||
select is_const((1,2,3));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop function if exists is_const;
|
||||
|
|
|
@ -143,4 +143,41 @@ DROP FUNCTION lookup;
|
|||
DROP FUNCTION reverse_lookup;
|
||||
DROP FUNCTION avgcost;
|
||||
|
||||
#
|
||||
# Bug#18761: constant expression as UDF parameters not passed in as constant
|
||||
#
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION is_const RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
select
|
||||
is_const(3) as const,
|
||||
is_const(3.14) as const,
|
||||
is_const('fnord') as const,
|
||||
is_const(2+3) as const,
|
||||
is_const(rand()) as 'nc rand()',
|
||||
is_const(sin(3.14)) as const,
|
||||
is_const(upper('test')) as const;
|
||||
|
||||
create table bug18761 (n int);
|
||||
insert into bug18761 values (null),(2);
|
||||
select
|
||||
is_const(3) as const,
|
||||
is_const(3.14) as const,
|
||||
is_const('fnord') as const,
|
||||
is_const(2+3) as const,
|
||||
is_const(2+n) as 'nc 2+n ',
|
||||
is_const(sin(n)) as 'nc sin(n)',
|
||||
is_const(sin(3.14)) as const,
|
||||
is_const(upper('test')) as const,
|
||||
is_const(rand()) as 'nc rand()',
|
||||
is_const(n) as 'nc n ',
|
||||
is_const(is_const(n)) as 'nc ic?(n)',
|
||||
is_const(is_const('c')) as const
|
||||
from
|
||||
bug18761;
|
||||
drop table bug18761;
|
||||
|
||||
--error 1241
|
||||
select is_const((1,2,3));
|
||||
|
||||
drop function if exists is_const;
|
||||
|
|
|
@ -2683,39 +2683,47 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
|
|||
char *to=num_buffer;
|
||||
for (uint i=0; i < arg_count; i++)
|
||||
{
|
||||
f_args.args[i]=0;
|
||||
/*
|
||||
For a constant argument i, args->args[i] points to the argument value.
|
||||
For non-constant, args->args[i] is NULL.
|
||||
*/
|
||||
f_args.args[i]= NULL; /* Non-const unless updated below. */
|
||||
|
||||
f_args.lengths[i]= arguments[i]->max_length;
|
||||
f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
|
||||
f_args.attributes[i]= arguments[i]->name;
|
||||
f_args.attribute_lengths[i]= arguments[i]->name_length;
|
||||
|
||||
switch(arguments[i]->type()) {
|
||||
case Item::STRING_ITEM: // Constant string !
|
||||
if (arguments[i]->const_item())
|
||||
{
|
||||
String *res=arguments[i]->val_str(&buffers[i]);
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= (char*) res->ptr();
|
||||
break;
|
||||
}
|
||||
case Item::INT_ITEM:
|
||||
*((longlong*) to) = arguments[i]->val_int();
|
||||
if (!arguments[i]->null_value)
|
||||
{
|
||||
f_args.args[i]=to;
|
||||
to+= ALIGN_SIZE(sizeof(longlong));
|
||||
}
|
||||
break;
|
||||
case Item::REAL_ITEM:
|
||||
*((double*) to)= arguments[i]->val_real();
|
||||
if (!arguments[i]->null_value)
|
||||
{
|
||||
f_args.args[i]=to;
|
||||
to+= ALIGN_SIZE(sizeof(double));
|
||||
}
|
||||
break;
|
||||
default: // Skip these
|
||||
break;
|
||||
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]);
|
||||
f_args.args[i]= (char*) res->ptr();
|
||||
break;
|
||||
}
|
||||
case INT_RESULT:
|
||||
*((longlong*) to)= arguments[i]->val_int();
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(longlong));
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
*((double*) to)= arguments[i]->val_real();
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(double));
|
||||
break;
|
||||
case ROW_RESULT:
|
||||
default:
|
||||
// This case should never be chosen
|
||||
DBUG_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
thd->net.last_error[0]=0;
|
||||
|
|
|
@ -165,6 +165,9 @@ void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error
|
|||
void avgcost_clear( UDF_INIT* initid, char* is_null, char *error );
|
||||
void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
|
||||
double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error );
|
||||
my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
|
||||
char *is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
|
||||
*length, char *is_null, char *error);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1075,4 +1078,31 @@ char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)),
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
|
||||
{
|
||||
if (args->arg_count != 1)
|
||||
{
|
||||
strmov(message, "IS_CONST accepts only one argument");
|
||||
return 1;
|
||||
}
|
||||
initid->ptr= (args->args[0] != NULL) ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char * is_const(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long
|
||||
*length, char *is_null, char *error)
|
||||
{
|
||||
if (initid->ptr != 0) {
|
||||
sprintf(result, "const");
|
||||
} else {
|
||||
sprintf(result, "not const");
|
||||
}
|
||||
*is_null= 0;
|
||||
*length= strlen(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_DLOPEN */
|
||||
|
|
Loading…
Add table
Reference in a new issue