Bug #24736 UDF functions parsed as Stored Functions
Submitted: 30 Nov 2006 21:23 Modified: 11 Dec 2006 4:38
Reporter: Marc Alff Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:5.1 OS:
Assigned to: Marc Alff CPU Architecture:Any

[30 Nov 2006 21:23] Marc Alff
Description:
In some cases, a function that should be parsed as a User Defined Function,
in in fact parsed as a Stored Function.

The root cause of the problem seems to be related to Bug#21809,
and the merge of the fix in the 5.1 tree.

Version :
5.1.14-beta-debug-log

How to repeat:
Thanks to magnus for isolating a test case :

--source include/have_udf.inc
#
# To run this tests the "sql/udf_example.c" need to be compiled into
# udf_example.so and LD_LIBRARY_PATH should be setup to point out where
# the library are.
#

--disable_warnings
drop table if exists t1;
--enable_warnings

#
# Create the myfunc_double functions from udf_example
#

--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";

select myfunc_double(3);
select myfunc_double(3), myfunc_double(sin(3));

DROP FUNCTION myfunc_double;

In 5.1, myfunc_double(sin(x)) fails, where it should succeed.

Suggested fix:
The root cause seems to be that :

In sql_yacc.yy, in function_call_generic:

[1] lex->current_select->udf_list.push_front(udf);
[2] if (NULL != (udf= lex->current_select->udf_list.pop()))

[1] happens for native, UDF and Stored functions,
but [2] happens only for UDF and stored functions.

In case of nested calls, the 'udf_list' stack is out of sync.

Suggested fix:
- remove completely the use of st_select_lex::udf_list,
the internal bison stack ($<udf>3 = ...) should be used instead,
as in the original code.
[2 Dec 2006 2:16] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/16346

ChangeSet@1.2399, 2006-12-01 19:16:03-07:00, malff@weblab.(none) +9 -0
  Bug#24736: UDF functions parsed as Stored Functions
  
  Before this fix, a call to a User Defined Function (UDF) could,
  under some circumstances, be interpreted as a call to a Stored function
  instead. This occurred if a native function was invoked in the parameters
  for the UDF, as in "select my_udf(abs(x))".
  
  The root cause of this defect is the introduction, by the fix for Bug 21809,
  of st_select_lex::udf_list, and it's usage in the parser in sql_yacc.yy
  in the rule function_call_generic (in 5.1).
  
  While the fix itself for Bug 21809 is correct in 5.0, the code change
  merged into the 5.1 release created the issue, because the calls in 5.1 to :
  - lex->current_select->udf_list.push_front(udf)
  - lex->current_select->udf_list.pop()
  are not balanced in case of native functions, causing the udf_list,
  which is really a stack, to be out of sync with the internal stack
  maintained by the bison parser.
  
  Instead of moving the call to udf_list.pop(), which would have fixed the
  symptom, this patch goes further and removes the need for udf_list.
  
  This is motivated by two reasons:
  
  a) Maintaining a stack in the MySQL code in sync with the stack maintained
  internally in sql_yacc.cc (not .yy) is extremely dependent of the
  implementation of yacc/bison, and extremely difficult to maintain.
  It's also totally dependent of the structure of the grammar, and has a risk
  to break with regression defects each time the grammar itself is changed.
  
  b) The previous code did report construct like "foo(expr AS name)" as
  syntax errors (ER_PARSER_ERROR), which is incorrect, and misleading.
  The syntax is perfectly valid, as this expression is valid when "foo" is
  a UDF. Whether this syntax is legal or not depends of the semantic of "foo".
  
  With this change:
  
  a) There is only one stack (in bison), and no List<udf_func> to maintain.
  
  b) "foo(expr AS name)", when used incorrectly, is reported as semantic error:
  - ER_WRONG_PARAMETERS_TO_NATIVE_FCT (for native functions)
  - ER_WRONG_PARAMETERS_TO_STORED_FCT (for stored functions)
  This is achieved by the changes implemented in item_create.cc
[5 Dec 2006 16:12] Mads Martin Joergensen
Daniel merged the fix to mysql-5.1
[11 Dec 2006 4:38] Paul Dubois
Noted in 5.1.14 changelog.

In some cases, a function that should be parsed as a user-defined
function was parsed as a stored function.