From: Date: November 3 2006 10:50pm Subject: bk commit into 5.0 tree (cmiller:1.2333) BUG#18761 List-Archive: http://lists.mysql.com/commits/14825 X-Bug: 18761 Message-Id: <20061103215036.E923383049@zippy> Below is the list of changes that have just been committed into a local 5.0 repository of cmiller. When cmiller does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2006-11-03 16:50:32-05:00, cmiller@stripped +5 -0 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 neglected to take into account some things that could be parameters to a function, namely some kinds of numbers and results of other functions (including the implicit ones of Sum for K0+K1, e.g.). Added those and inserted a warning to go to the debug log, in case we add more types and such in the future and neglect to account for them. (I'm wary of ASSERTing this to be true.) BitKeeper/etc/collapsed@stripped, 2006-11-03 16:36:36-05:00, cmiller@stripped +1 -0 mysql-test/r/udf.result@stripped, 2006-11-03 16:50:30-05:00, cmiller@stripped +31 -0 Verify that various arguments work. mysql-test/t/udf.test@stripped, 2006-11-03 16:50:30-05:00, cmiller@stripped +32 -0 Verify that various arguments work. sql/item_func.cc@stripped, 2006-11-03 16:50:30-05:00, cmiller@stripped +26 -6 For function-Items, test whether it is constant and set the struct members for the UDF parameter appropriately. sql/udf_example.c@stripped, 2006-11-03 16:50:31-05:00, cmiller@stripped +31 -0 Include a simple function that is useful in testing. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: cmiller # Host: zippy.cornsilk.net # Root: /home/cmiller/work/mysql/bug18761/my50-bug18761 --- 1.309/sql/item_func.cc 2006-11-03 16:50:36 -05:00 +++ 1.310/sql/item_func.cc 2006-11-03 16:50:36 -05:00 @@ -2683,13 +2683,19 @@ udf_handler::fix_fields(THD *thd, Item_r char *to=num_buffer; for (uint i=0; i < arg_count; i++) { - f_args.args[i]=0; + Item::Type argument_type= arguments[i]->type(); + /* + For a constant argument i, args->args[i] points to the argument value. + For a non-constant argument, args->args[i] is 0. + */ + f_args.args[i]= 0; /* 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()) { + switch (argument_type) { case Item::STRING_ITEM: // Constant string ! { String *res=arguments[i]->val_str(&buffers[i]); @@ -2698,6 +2704,16 @@ udf_handler::fix_fields(THD *thd, Item_r f_args.args[i]= (char*) res->ptr(); break; } + case Item::FUNC_ITEM: /* storing as string */ + case Item::DECIMAL_ITEM: /* storing as string */ + { + String *res=arguments[i]->val_str(&buffers[i]); + if (arguments[i]->null_value) + continue; + if (arguments[i]->const_item()) + f_args.args[i]= (char*) res->ptr(); + break; + } case Item::INT_ITEM: *((longlong*) to) = arguments[i]->val_int(); if (!arguments[i]->null_value) @@ -2715,6 +2731,10 @@ udf_handler::fix_fields(THD *thd, Item_r } break; default: // Skip these + if (arguments[i]->const_item() != 0) + { + DBUG_PRINT("warning", ("Item with Type %d is const, yet we don't set the \"args\" to its value")); + } break; } } --- 1.30/sql/udf_example.c 2006-11-03 16:50:36 -05:00 +++ 1.31/sql/udf_example.c 2006-11-03 16:50:36 -05:00 @@ -165,6 +165,9 @@ void avgcost_reset( UDF_INIT* initid, UD 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); +void is_const_deinit(UDF_INIT *initid); /************************************************************************* @@ -1074,5 +1077,33 @@ char *myfunc_argument_name(UDF_INIT *ini result[*length]= 0; return result; } + + +/* is_const init function */ +my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + initid->ptr = (args->args[0] != NULL) ? 1 : 0; + return 0; +} + +/* is_const deinit function */ +void is_const_deinit(UDF_INIT *initid) +{ + return; +} + +/* is_const actual processing function */ +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 */ --- 1.10/BitKeeper/etc/collapsed 2006-11-03 16:50:36 -05:00 +++ 1.11/BitKeeper/etc/collapsed 2006-11-03 16:50:36 -05:00 @@ -15,3 +15,4 @@ 45214442pBGT9KuZEGixBH71jTzbOA 45214a07hVsIGwvwa-WrO-jpeaSwVw 452a92d0-31-8wSzSfZi165fcGcXPA +454bb488ijVLOUK_GFjcoISE0GxPUA --- 1.7/mysql-test/r/udf.result 2006-11-03 16:50:36 -05:00 +++ 1.8/mysql-test/r/udf.result 2006-11-03 16:50:36 -05:00 @@ -115,3 +115,34 @@ 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 ' +from +bug18761; +const const const const nc 2+n nc sin(n) const const nc rand() nc n +const const const const not const not const const const not const not const +const const const const not const not const const const not const not const +drop table bug18761; +drop function if exists is_const; --- 1.8/mysql-test/t/udf.test 2006-11-03 16:50:36 -05:00 +++ 1.9/mysql-test/t/udf.test 2006-11-03 16:50:36 -05:00 @@ -143,4 +143,36 @@ 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 ' +from + bug18761; +drop table bug18761; + +drop function if exists is_const;