diff options
author | unknown <cmiller@zippy.cornsilk.net> | 2006-11-13 13:13:44 -0500 |
---|---|---|
committer | unknown <cmiller@zippy.cornsilk.net> | 2006-11-13 13:13:44 -0500 |
commit | 154c6e06775d6e644fd4e5f863104ab566fc4a68 (patch) | |
tree | 0ca8ebb00dc5407cb091951dbb2f6ce33551b95b /sql/item_func.cc | |
parent | e948c64ff52fda43d2a7cb59bc631e53051adc05 (diff) | |
download | mariadb-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.cc | 62 |
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; |