Bug #15498 UDF called cosh is never called, renaming to cosH solves the problem
Submitted: 5 Dec 2005 20:17 Modified: 3 Sep 2008 16:54
Reporter: Roland Bouman Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Documentation Severity:S3 (Non-critical)
Version:5.0.16, 5.0.15 OS:Windows (Windows XP)
Assigned to: Paul DuBois CPU Architecture:Any

[5 Dec 2005 20:17] Roland Bouman
Description:
A (REAL / double) UDF called cosh was succesfully registered with mysql. However, SELECT ing the function never gives the expected result. Instead, the same constant result (1.00000...) is always returned. This is true even if the UDF is rewritten to return just a constant (double) value of 0.0

It should be mentioned that simply renaming the function names (in the source and module definition file, and in the create ddl) by changing the 'h' in cosh into a capital 'H' solves the problem. The function can be called, and returns the expected result, a constant value of 0.0

How to repeat:
Here's the C code:

(start contents of C code .cpp file) --> 

#include <my_global.h>
#include <mysql.h>

my_bool cosh_init(
    UDF_INIT* initid
,   UDF_ARGS* args
,   char *message
){ 
    initid->decimals = 14;
    initid->max_length = 32;
    return 0; 
}

double cosh(
    UDF_INIT *initid
,   UDF_ARGS *args
,   char *is_null
,   char *error
){
    return 0.0;
}

<-- (end contents of the .cpp file)

this is compiled to a dll, MySQLUDFCosHBug.dll, using this module definition:

(start contents of module definition .def file) --> 
LIBRARY	MySQLUDFCosHBug
EXPORTS

    cosh_init
    cosh
<-- (end contents  of the .def file)

and here's the SQL:

(start sql commands) --> 

mysql> create function cosh returns real soname 'MySQLUDFCosHBug.dll';
Query OK, 0 rows affected (0.00 sec)

mysql> select cosh();
+------------------+
| cosh()           |
+------------------+
| 1.00000000000000 |
+------------------+
1 row in set (0.00 sec)

<-- (endsql commands)

Suggested fix:
Please allow us to create a function called cosh. If there's something that prevents this, please document that.
[5 Dec 2005 20:19] Roland Bouman
dll to reproduce the problem.

Attachment: MySQLUDFCosHBug.dll (application/octet-stream, text), 56.00 KiB.

[6 Dec 2005 14:07] Valeriy Kravchuk
Thank you for a problem report. 

Verified just as described with .dll built from sources uploaded to bug #15439 and modified as explained by the reporter. 

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.0.16-nt |
+-----------+
1 row in set (0.00 sec)

mysql> create function cosh returns real soname 'MySQLUDFCosHBug.dll';
Query OK, 0 rows affected (0.00 sec)

mysql> select cosh();
+------------------+
| cosh()           |
+------------------+
| 1.00000000000000 |
+------------------+
1 row in set (0.00 sec)

Really weird and strange behaviour. Checked also with 5.0.15 and VC++ 6.0.
[7 Dec 2005 21:57] Roland Bouman
Hi, 

following the advice from a good friend (who's a very experienced C/C++ programmer), I compiled it as a C++ project (for a number of reasons). This does not solve this problem however.

I can also add that the hyperbolic sine function sinh suffers from a similar problem. sinh consistently returns 0.0.....  I used the same quick fix there, rename and export as sinH.
[15 Jan 2007 7:50] 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/18103

ChangeSet@1.2377, 2007-01-15 11:53:31+04:00, holyfoot@mysql.com +2 -0
  bug #15498 UDF 'cosh' is never called
  
  The problem is mainly about the Windows linker.
  If the file includes 'math.h', it can't define math function
  like 'cosh' (see 'cosh' help page in MSDN for example).
  C++ makes it possible to have 'cosh' in the file, but
  it because C++ internally renames functions, so
  if one exports 'cosh' in dll, he's going to export
  mathlib's 'cosh', not the user-defined one.
  
  Solution here is to make possible to exclude 'math.h' from headers with
  MYSQL_NO_MATH_H macrodefinition.
  Like that: (user's my_cosh.cpp)
  
  #define MYSQL_NO_MATH_H
  #include <my_global.h>
  #include <mysql.h>
  ...
  double cosh(UDF_INIT *initid ...)
  my_bool cosh_init(UDF_INIT *initid ...)
[31 Jan 2007 16:36] Georgi Kodinov
Updated cpp file to use namespaces.

Attachment: MySQLUDFCosHBug.cpp (text/plain), 4.00 KiB.

[31 Jan 2007 16:46] Georgi Kodinov
An alternative approach is to use C++ namespaces. 
One can isolate the mysql headers in a namespace and use them quoted.
This way there will be no C++ name collision and the linker will be able to choose the right symbol.
The attached file can be compiled from the command line with :
cl /MDd /LDd MySQLUDFCosHBug.cpp -I <where you MySQL headers are>

The produced .DLL file exports the unmangled cosh and cosh_init and they are the right ones (as demonstrated by MySQL returning 12 as a result of 'select cosh()').
[1 Feb 2007 16:20] Sergei Golubchik
It's not a bug. You define a function that matches the name of a built-in function. There's nothing MySQL can do here.

MYSQL_NO_MATH_H hack only helps until you create a function that collides with some other built-in, not from math.h.

Possible solutions for your problem:

In C you can rename the symbol from math.h:

  #define cosh cosh_renamed
  #include <mysql.h>
  #undef cosh_renamed

In C++ - use namespaces, as Georgi shows in his comment.
[31 Aug 2008 13:01] Hartmut Holzgraefe
Reopened as documentation problem ...
[3 Sep 2008 16:54] Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products.

Already covered here:
http://dev.mysql.com/doc/refman/5.0/en/function-resolution.html