[CONC-374] mysql_errno(NULL) and mysql_error(NULL) always returns zero Created: 2018-11-22  Updated: 2023-12-25

Status: Open
Project: MariaDB Connector/C
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Pali Assignee: Georg Richter
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Some library functions like mysql_library_init() or mysql_init() may fail and on error they do not return MYSQL* structure. To detect their error code and message it was possible to call mysql_errno(NULL) and mysql_error(NULL) to retrieve them. This is working fine since MySQL version 5.0.60 (for 5.0 series) and globally since 5.1.24 (for 5.1 and new series). But MariaDB 10.2 stopped using MySQL client implementation (where it worked fine) and started to use MariaDB Connector/C which does not provide meaningful value from mysql_errno(NULL) and mysql_error(NULL) calls. It always returns 0 and empty string. So when mysql_library_init() or mysql_init() fails, caller does not why. Since MariaDB 10.2 started using MariaDB Connector/C there is no way to retrieve error code or message for these functions. So please fix mysql_errno(NULL) and mysql_error(NULL) functions to return real error code/messages for last mysql_* function call.



 Comments   
Comment by Georg Richter [ 2018-11-24 ]

Afaik, the NULL parameter was used for embedded only, since the internal error codes in libmysql are not thread safe.

Comment by Pali [ 2018-11-27 ]

Hm... if problem with global variable is when threads are used, then in C11, variable can be declared with _Thread_local. Or for older C versions you can use compiler extensions for TLS, e.g. in gcc (and also clang and icc) there is __thread keyword, in msvc there is __declspec(thread) keyword.

Comment by Pali [ 2019-06-18 ]

Is there any reason why to not use thread local variables in case global variables is a problem? Anyway, it is a problem that these global variables would not be thread-safe?

Comment by Pali [ 2020-02-02 ]

georg So what do you think about usage of thread-local variables for this problem?

Comment by Pali [ 2023-08-23 ]

Any updates?

Comment by Pali [ 2023-12-25 ]

georg , otto Any updates? I would like to remind that this is a regression since MariaDB 10.2 as written in the description.

Comment by Georg Richter [ 2023-12-25 ]

Hi Pali,

Happy holidays!

In MariaDB Connector/C we don't have any error messages, in case of an error in mysql_server_init application should check errno or WinGetLastErrror(). Even using a global variable would not be useful, since it will not be thread safe.

int STDCALL mysql_server_init(int argc __attribute__((unused)),
  char **argv __attribute__((unused)),
  char **groups __attribute__((unused)))
{
#ifdef _WIN32
  BOOL ret = InitOnceExecuteOnce(&init_once, win_init_once, NULL, NULL);
  return ret? 0: 1;
#else
  return pthread_once(&init_once, mysql_once_init);
#endif
}

The embedded library might be different, it's not using Connector/C.

Comment by Pali [ 2023-12-25 ]

pthread_once() does not set errno. Instead error is indicated by the return value. pthread functions differs here from other POSIX functions. Anyway, global variables can be also thread safe (one example is errno), variable just needs to be declared as thread local.

The bad thing is that MariaDB Connector/C has different API for error handling than the original MySQL library and also differnet than MariaDB embedded library. This makes problems for applications as they either need to add tons of #ifdef-s for MariaDB support or ignore error at all.

Generated at Thu Feb 08 03:04:51 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.