From 9743bec52db5e8f1beb2b31e4a55d6ea1a4edcdd Mon Sep 17 00:00:00 2001 From: Pali Date: Fri, 8 Apr 2022 21:36:47 +0200 Subject: [PATCH] Fix mysql_get_client_version() function MariaDB Connector/C 3.1.10 changed API of mysql_get_client_version() function. Before that release it returned client version. With that release it started returning Connector/C package version. So when compiling with MariaDB Connector/C client library, redefine mysql_get_client_version() to always returns client version via function mariadb_get_infov(MARIADB_CLIENT_VERSION_ID) call. Driver code expects for a long time that mysql_get_client_version() call returns client version and not something different. Function mariadb_get_infov() is supported since MariaDB Connector/C 3.0+. Fixes: https://github.com/perl5-dbi/DBD-mysql/issues/333 --- Makefile.PL | 8 +++++++- dbdimp.h | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Makefile.PL b/Makefile.PL index b9b046c..f28a8df 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -757,7 +757,13 @@ sub Configure { # https://jira.mariadb.org/browse/MDEV-16478 $function .= "\n#if defined(MARIADB_BASE_VERSION) || defined(MARIADB_PACKAGE_VERSION)\nif (mysql_get_client_version() >= 100301 && mysql_get_client_version() < 100308) return 1;\n#endif\n"; } - $function .= 'return (mysql_get_client_version() == MYSQL_VERSION_ID) ? 0 : 1;'; + # MariaDB Connector/C 3.1.10+ has broken mysql_get_client_version() function, so use mariadb_get_infov(MARIADB_CLIENT_VERSION_ID) instead + $function .= "size_t version;\n"; + $function .= "#if defined(MARIADB_PACKAGE_VERSION) && defined(MARIADB_PACKAGE_VERSION_ID) && MARIADB_PACKAGE_VERSION_ID >= 30000\n"; + $function .= "if (mariadb_get_infov((void *)0, MARIADB_CLIENT_VERSION_ID, &version) != 0)\n"; + $function .= "#endif\n"; + $function .= "version = mysql_get_client_version();\n"; + $function .= 'return (version == MYSQL_VERSION_ID) ? 0 : 1;'; # libmysqld is built using g++ rather than gcc and sometimes # we have to use libstdc++ to resolve linking problems foreach my $add_ldflags (undef, '-lstdc++') { diff --git a/dbdimp.h b/dbdimp.h index 41cc72a..aee608f 100644 --- a/dbdimp.h +++ b/dbdimp.h @@ -322,6 +322,32 @@ PERL_STATIC_INLINE UV SvUV_nomg(pTHX_ SV *sv) #define my_bool bool #endif +/* + * MariaDB Connector/C 3.1.10 changed API of mysql_get_client_version() + * function. Before that release it returned client version. With that release + * it started returning Connector/C package version. + * + * So when compiling with MariaDB Connector/C client library, redefine + * mysql_get_client_version() to always returns client version via function + * mariadb_get_infov(MARIADB_CLIENT_VERSION_ID) call. + * + * Driver code expects for a long time that mysql_get_client_version() call + * returns client version and not something different. + * + * Function mariadb_get_infov() is supported since MariaDB Connector/C 3.0+. + */ +#if defined(MARIADB_PACKAGE_VERSION) && defined(MARIADB_PACKAGE_VERSION_ID) && MARIADB_PACKAGE_VERSION_ID >= 30000 +PERL_STATIC_INLINE unsigned long mariadb_get_client_version(void) +{ + /* MARIADB_CLIENT_VERSION_ID really expects size_t type, documentation is wrong and says unsigned int. */ + size_t version; + if (mariadb_get_infov(NULL, MARIADB_CLIENT_VERSION_ID, &version) != 0) + version = mysql_get_client_version(); /* On error fallback to mysql_get_client_version() */ + return version; +} +#define mysql_get_client_version() mariadb_get_client_version() +#endif + /* MYSQL_SECURE_AUTH became a no-op from MySQL 5.7.5 and is removed from MySQL 8.0.3 */ #if defined(MARIADB_BASE_VERSION) || MYSQL_VERSION_ID <= 50704 #define HAVE_SECURE_AUTH -- 2.49.0