summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgregor herrmann <gregoa@debian.org>2022-04-22 01:33:38 +0200
committergregor herrmann <gregoa@debian.org>2022-04-22 01:33:38 +0200
commit1db14134aace8d5357161ebcdc1085bac6774ffe (patch)
tree67cb50543c656dda0db594ac68f08d48ec90e9ad
parent7b3ae2effdde243491e7d5833e6265d91dc6b147 (diff)
parent55abe2ff07a84348bff0bed8722db15e55743603 (diff)
Update upstream source from tag 'upstream/1.22'
Update to upstream version '1.22' with Debian dir 8f8501829ece5ee4b3acbf9c64abddb10e398163
-rw-r--r--Changes11
-rw-r--r--META.json2
-rw-r--r--META.yml2
-rw-r--r--Makefile.PL21
-rw-r--r--dbdimp.c52
-rw-r--r--dbdimp.h26
-rw-r--r--lib/DBD/MariaDB.pm2
-rw-r--r--socket.c5
-rw-r--r--t/40server_prepare.t9
-rw-r--r--t/45bind_no_backslash_escapes.t4
10 files changed, 108 insertions, 26 deletions
diff --git a/Changes b/Changes
index 84719b7..f7e440f 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,14 @@
+1.22 2022-04-22
+ - Disable usage of libmysqld.a from MySQL 8.x series
+ - Install README.pod into DBD/MariaDB/ subdirectory
+ (https://github.com/gooddata/DBD-MariaDB/issues/146)
+ - Do not export driver private C functions
+ - Fix typo in error message
+ - Fix compatibility with new MariaDB client and server versions
+ (https://github.com/perl5-dbi/DBD-MariaDB/issues/164)
+ (https://github.com/perl5-dbi/DBD-MariaDB/issues/167)
+ (https://github.com/perl5-dbi/DBD-mysql/issues/333)
+
1.21 2019-02-27
- Fix skipping test t/14destruct.t
- Revert "MySQL bug #93276 is fixed in 8.0.15"
diff --git a/META.json b/META.json
index 78c1569..40024ea 100644
--- a/META.json
+++ b/META.json
@@ -97,7 +97,7 @@
"x_IRC" : "irc://irc.perl.org/#dbi",
"x_MailingList" : "mailto:dbi-dev@perl.org"
},
- "version" : "1.21",
+ "version" : "1.22",
"x_contributors" : [
"Alexandr Ciornii <alexchorny@gmail.com>",
"Alexey Molchanov <alexey.molchanov@portaone.com>",
diff --git a/META.yml b/META.yml
index d07b1cd..bfbb612 100644
--- a/META.yml
+++ b/META.yml
@@ -55,7 +55,7 @@ resources:
homepage: https://github.com/gooddata/DBD-MariaDB
license: http://dev.perl.org/licenses/
repository: git://github.com/gooddata/DBD-MariaDB.git
-version: '1.21'
+version: '1.22'
x_contributors:
- 'Alexandr Ciornii <alexchorny@gmail.com>'
- 'Alexey Molchanov <alexey.molchanov@portaone.com>'
diff --git a/Makefile.PL b/Makefile.PL
index 6acce9d..f28a8df 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -450,6 +450,17 @@ my %o = ( 'NAME' => 'DBD::MariaDB',
'realclean' => { 'FILES' => 't/MariaDB.mtest' },
'C' => ["dbdimp.c", "MariaDB.c", "socket.c"],
'XS' => {'MariaDB.xs' => 'MariaDB.c'},
+ 'PM' => {
+ 'lib/DBD/MariaDB.pm' => '$(INST_LIB)/DBD/MariaDB.pm',
+ 'lib/DBD/MariaDB.pod' => '$(INST_LIB)/DBD/MariaDB.pod',
+ 'lib/DBD/MariaDB/INSTALL.pod' => '$(INST_LIB)/DBD/MariaDB/INSTALL.pod',
+ 'README.pod' => '$(INST_LIB)/DBD/MariaDB/README.pod',
+ },
+ 'MAN3PODS' => {
+ 'lib/DBD/MariaDB.pod' => '$(INST_MAN3DIR)/DBD::MariaDB.$(MAN3EXT)',
+ 'lib/DBD/MariaDB/INSTALL.pod' => '$(INST_MAN3DIR)/DBD::MariaDB::INSTALL.$(MAN3EXT)',
+ 'README.pod' => '$(INST_MAN3DIR)/DBD::MariaDB::README.$(MAN3EXT)',
+ },
'OBJECT' => '$(O_FILES)',
'LIBS' => (join ' ', @libdirs, $main_lib, @libs),
@ldflags ? (dynamic_lib => { OTHERLDFLAGS => (join ' ', @ldflags) }) : (),
@@ -743,8 +754,16 @@ sub Configure {
# and always crash in mysql_real_connect() function, so avoid its usage
# 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";
+ # libmysqld.a from MySQL 8.x is broken too
+ $function .= "\n#if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_PACKAGE_VERSION)\nif (mysql_get_client_version() >= 80000) 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.c b/dbdimp.c
index 5618430..433a1c0 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -15,6 +15,16 @@
#include "dbdimp.h"
+#ifdef HAVE_GET_CHARSET_NUMBER
+/* Available only in some clients and declared in header file my_sys.h which cannot be included */
+unsigned int get_charset_number(const char *cs_name, unsigned int cs_flags);
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+/* Do not export non-static functions from driver library */
+#pragma GCC visibility push(hidden)
+#endif
+
#define ASYNC_CHECK_RETURN(h, value)\
if(imp_dbh->async_query_in_flight) {\
mariadb_dr_do_error(h, CR_UNKNOWN_ERROR, "Calling a synchronous function on an asynchronous handle", "HY000");\
@@ -513,7 +523,7 @@ PERL_STATIC_INLINE bool mysql_charsetnr_is_utf8(unsigned int id)
/*
count embedded options
*/
-int count_embedded_options(char *st)
+static int count_embedded_options(char *st)
{
int rc;
char c;
@@ -538,7 +548,7 @@ int count_embedded_options(char *st)
/*
Free embedded options
*/
-int free_embedded_options(char ** options_list, int options_count)
+static int free_embedded_options(char ** options_list, int options_count)
{
int i;
@@ -556,7 +566,7 @@ int free_embedded_options(char ** options_list, int options_count)
Print out embedded option settings
*/
-int print_embedded_options(PerlIO *stream, char ** options_list, int options_count)
+static int print_embedded_options(PerlIO *stream, char ** options_list, int options_count)
{
int i;
@@ -573,7 +583,7 @@ int print_embedded_options(PerlIO *stream, char ** options_list, int options_cou
/*
*/
-char **fill_out_embedded_options(char *options,
+static char **fill_out_embedded_options(char *options,
int options_type,
STRLEN slen, int cnt)
{
@@ -617,6 +627,25 @@ char **fill_out_embedded_options(char *options,
return options_list;
}
+#if MYSQL_VERSION_ID < 50001
+/* MySQL client prior to version 5.0.1 does not implement mysql_real_escape_string() for SERVER_STATUS_NO_BACKSLASH_ESCAPES */
+static unsigned long string_escape_quotes(char *to, const char *from, unsigned long len)
+{
+ const char *to_start = to;
+ const char *end = from + len;
+
+ while (from < end)
+ {
+ if (*from == '\'')
+ *to++ = '\'';
+ *to++ = *from++;
+ }
+
+ *to = '\0';
+ return to - to_start;
+}
+#endif
+
/*
constructs an SQL statement previously prepared with
actual values replacing placeholders
@@ -828,9 +857,8 @@ static char *parse_params(
#if MYSQL_VERSION_ID < 50001
if (sock->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
{
- *ptr++ = 'X';
*ptr++ = '\'';
- ptr += mysql_hex_string(ptr, ph->value, ph->len);
+ ptr += string_escape_quotes(ptr, ph->value, ph->len);
*ptr++ = '\'';
}
else
@@ -1364,11 +1392,6 @@ static void error_no_connection(SV *h, const char *msg)
mariadb_dr_do_error(h, CR_CONNECTION_ERROR, msg, "HY000");
}
-#ifdef HAVE_GET_CHARSET_NUMBER
-/* Available only in some clients and declared in header file my_sys.h which cannot be included */
-unsigned int get_charset_number(const char *cs_name, unsigned int cs_flags);
-#endif
-
/***************************************************************************
*
* Name: mariadb_dr_connect
@@ -2221,7 +2244,7 @@ static bool mariadb_dr_connect(
}
if (connected && mysql_get_server_version(sock) < 40100)
{
- mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older then 4.1.0", "HY000");
+ mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older than 4.1.0", "HY000");
mariadb_db_disconnect(dbh, imp_dbh);
return FALSE;
}
@@ -2238,7 +2261,7 @@ static bool mariadb_dr_connect(
}
if (mysql_get_server_version(sock) < 40100)
{
- mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older then 4.1.0", "HY000");
+ mariadb_dr_do_error(dbh, CR_CONNECTION_ERROR, "Connection error: MariaDB or MySQL server version is older than 4.1.0", "HY000");
mariadb_db_disconnect(dbh, imp_dbh);
return FALSE;
}
@@ -6406,9 +6429,8 @@ SV* mariadb_db_quote(SV *dbh, SV *str, SV *type)
#if MYSQL_VERSION_ID < 50001
if (imp_dbh->pmysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
{
- *sptr++ = 'X';
*sptr++ = '\'';
- sptr += mysql_hex_string(sptr, ptr, len);
+ sptr += string_escape_quotes(sptr, ptr, len);
*sptr++ = '\'';
}
else
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
diff --git a/lib/DBD/MariaDB.pm b/lib/DBD/MariaDB.pm
index d5bf081..6737de9 100644
--- a/lib/DBD/MariaDB.pm
+++ b/lib/DBD/MariaDB.pm
@@ -10,7 +10,7 @@ use DBI;
use DynaLoader();
our @ISA = qw(DynaLoader);
-our $VERSION = '1.21';
+our $VERSION = '1.22';
bootstrap DBD::MariaDB $VERSION;
diff --git a/socket.c b/socket.c
index 1ea6204..9e210a3 100644
--- a/socket.c
+++ b/socket.c
@@ -16,6 +16,11 @@
#include <unistd.h>
#endif
+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+/* Do not export non-static functions from driver library */
+#pragma GCC visibility push(hidden)
+#endif
+
/*
* Warning: Native socket code must be outside of dbdimp.c and dbdimp.h because
* perl header files redefine socket function. This file must not
diff --git a/t/40server_prepare.t b/t/40server_prepare.t
index 6eb2cf1..29aa6fd 100644
--- a/t/40server_prepare.t
+++ b/t/40server_prepare.t
@@ -72,16 +72,19 @@ ok($sth3->execute(1, 2), "insert t3");
is_deeply($dbh->selectall_arrayref('SELECT id, mydata FROM t3'), [[1, 2]]);
+# MariaDB server since version 10.6.2 can prepare all statements except PREPARE, EXECUTE, and DEALLOCATE / DROP PREPARE. Previous MariaDB and MySQL versions cannot prepare USE statement.
+my $non_preparable_statement = ($dbh->{mariadb_serverversion} >= 100602) ? q(PREPARE stmt FROM "SELECT 1") : ("USE " . $dbh->quote_identifier($test_db));
+
$dbh->{mariadb_server_prepare_disable_fallback} = 1;
my $error_handler_called = 0;
$dbh->{HandleError} = sub { $error_handler_called = 1; die $_[0]; };
-eval { $dbh->prepare("USE " . $dbh->quote_identifier($test_db)) };
+eval { $dbh->prepare($non_preparable_statement); };
$dbh->{HandleError} = undef;
-ok($error_handler_called, 'USE is not supported with mariadb_server_prepare_disable_fallback=1');
+ok($error_handler_called, "Non-preparable statement '$non_preparable_statement' is not supported with mariadb_server_prepare_disable_fallback=1");
$dbh->{mariadb_server_prepare_disable_fallback} = 0;
my $sth4;
-ok($sth4 = $dbh->prepare("USE " . $dbh->quote_identifier($test_db)), 'USE is supported with mariadb_server_prepare_disable_fallback=0');
+ok($sth4 = $dbh->prepare($non_preparable_statement), "Non-preparable statement '$non_preparable_statement' is supported with mariadb_server_prepare_disable_fallback=0");
ok($sth4->execute());
ok ($dbh->do(qq{DROP TABLE t3}), "cleaning up");
diff --git a/t/45bind_no_backslash_escapes.t b/t/45bind_no_backslash_escapes.t
index 13dce12..eaf011b 100644
--- a/t/45bind_no_backslash_escapes.t
+++ b/t/45bind_no_backslash_escapes.t
@@ -18,10 +18,6 @@ if ($dbh->{mariadb_serverversion} < 50001) {
plan skip_all => "Servers < 5.0.1 do not support sql_mode NO_BACKSLASH_ESCAPES";
}
-if ($dbh->{mariadb_clientversion} < 50001) {
- $id2_quoted_no_backslash = q(X'737472696E675C737472696E6722737472696E6727737472696E67');
-}
-
plan tests => 20;
ok $dbh->do('CREATE TEMPORARY TABLE t(id VARCHAR(255), value TEXT)');