summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2006-11-13 13:13:44 -0500
committerunknown <cmiller@zippy.cornsilk.net>2006-11-13 13:13:44 -0500
commit154c6e06775d6e644fd4e5f863104ab566fc4a68 (patch)
tree0ca8ebb00dc5407cb091951dbb2f6ce33551b95b /sql/item_func.cc
parente948c64ff52fda43d2a7cb59bc631e53051adc05 (diff)
downloadmariadb-git-154c6e06775d6e644fd4e5f863104ab566fc4a68.tar.gz
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.
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc62
1 files changed, 35 insertions, 27 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index a294bbd7a71..8e6b4d82b1d 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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;