summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Powers <chris.powers@oracle.com>2010-08-23 08:29:59 -0500
committerChristopher Powers <chris.powers@oracle.com>2010-08-23 08:29:59 -0500
commit6e7687ddbbb5dd7e307599e290c07ea004ef868a (patch)
tree0a4e33947c62ee231de57d017d4ddadd7eca4677
parent7b23098493d733f7c9a455539038774eceec7cb5 (diff)
parent622250cba7fb85321814187a84732cbeb2c40088 (diff)
downloadmariadb-git-6e7687ddbbb5dd7e307599e290c07ea004ef868a.tar.gz
merge
-rw-r--r--mysql-test/suite/parts/r/part_ctype_utf32.result14
-rw-r--r--mysql-test/suite/parts/t/part_ctype_utf32.test28
-rw-r--r--sql/field.cc2
-rw-r--r--sql/sql_audit.cc44
-rw-r--r--sql/sql_audit.h1
-rw-r--r--sql/sql_plugin.cc44
6 files changed, 117 insertions, 16 deletions
diff --git a/mysql-test/suite/parts/r/part_ctype_utf32.result b/mysql-test/suite/parts/r/part_ctype_utf32.result
new file mode 100644
index 00000000000..5d52a8eace4
--- /dev/null
+++ b/mysql-test/suite/parts/r/part_ctype_utf32.result
@@ -0,0 +1,14 @@
+#
+# Bug#52121 partition by key on utf32 enum field cause debug assertion: (length % 4) == 0
+#
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (
+a enum('a') CHARACTER SET utf32 COLLATE utf32_spanish2_ci
+) ENGINE=MYISAM PARTITION BY KEY(a) PARTITIONS 2;
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1;
+a
+a
+DROP TABLE t1;
diff --git a/mysql-test/suite/parts/t/part_ctype_utf32.test b/mysql-test/suite/parts/t/part_ctype_utf32.test
new file mode 100644
index 00000000000..12aa1fb3751
--- /dev/null
+++ b/mysql-test/suite/parts/t/part_ctype_utf32.test
@@ -0,0 +1,28 @@
+################################################################################
+# t/partition_ctype_utf32.test #
+# #
+# Purpose: #
+# Tests for partitions + UTF32 #
+# #
+#------------------------------------------------------------------------------#
+# Original Author: Alexander Barkov #
+# Original Date: 2010-08-05 #
+# Change Author: #
+# Change Date: #
+# Change: #
+################################################################################
+
+--source include/have_partition.inc
+--source include/have_utf32.inc
+
+--echo #
+--echo # Bug#52121 partition by key on utf32 enum field cause debug assertion: (length % 4) == 0
+--echo #
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+ a enum('a') CHARACTER SET utf32 COLLATE utf32_spanish2_ci
+) ENGINE=MYISAM PARTITION BY KEY(a) PARTITIONS 2;
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1;
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index 3c93ffadac5..fc55426b177 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1329,7 +1329,7 @@ void Field::hash(ulong *nr, ulong *nr2)
else
{
uint len= pack_length();
- CHARSET_INFO *cs= charset();
+ CHARSET_INFO *cs= sort_charset();
cs->coll->hash_sort(cs, ptr, len, nr, nr2);
}
}
diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc
index 7d269d455a9..b7d363dc09a 100644
--- a/sql/sql_audit.cc
+++ b/sql/sql_audit.cc
@@ -138,6 +138,30 @@ static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg)
/**
+ @brief Acquire audit plugins
+
+ @param[in] thd MySQL thread handle
+ @param[in] event_class Audit event class
+
+ @details Ensure that audit plugins interested in given event
+ class are locked by current thread.
+*/
+void mysql_audit_acquire_plugins(THD *thd, uint event_class)
+{
+ unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
+ DBUG_ENTER("mysql_audit_acquire_plugins");
+ set_audit_mask(event_class_mask, event_class);
+ if (thd && !check_audit_mask(mysql_global_audit_mask, event_class_mask) &&
+ check_audit_mask(thd->audit_class_mask, event_class_mask))
+ {
+ plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, &event_class);
+ add_audit_mask(thd->audit_class_mask, event_class_mask);
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/**
Notify the audit system of an event
@param[in] thd
@@ -151,21 +175,8 @@ void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...)
{
va_list ap;
audit_handler_t *handlers= audit_handlers + event_class;
- unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
-
DBUG_ASSERT(event_class < audit_handlers_count);
-
- set_audit_mask(event_class_mask, event_class);
- /*
- Check to see if we have acquired the audit plugins for the
- required audit event classes.
- */
- if (thd && check_audit_mask(thd->audit_class_mask, event_class_mask))
- {
- plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, &event_class);
- add_audit_mask(thd->audit_class_mask, event_class_mask);
- }
-
+ mysql_audit_acquire_plugins(thd, event_class);
va_start(ap, event_subtype);
(*handlers)(thd, event_subtype, ap);
va_end(ap);
@@ -448,6 +459,11 @@ static void event_class_dispatch(THD *thd, const struct mysql_event *event)
#else /* EMBEDDED_LIBRARY */
+void mysql_audit_acquire_plugins(THD *thd, uint event_class)
+{
+}
+
+
void mysql_audit_initialize()
{
}
diff --git a/sql/sql_audit.h b/sql/sql_audit.h
index 5b6962b9ecb..953e41f1f06 100644
--- a/sql/sql_audit.h
+++ b/sql/sql_audit.h
@@ -29,6 +29,7 @@ extern void mysql_audit_finalize();
extern void mysql_audit_init_thd(THD *thd);
extern void mysql_audit_free_thd(THD *thd);
+extern void mysql_audit_acquire_plugins(THD *thd, uint event_class);
extern void mysql_audit_notify(THD *thd, uint event_class,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 0020741b78f..956be657af2 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -29,7 +29,7 @@
#include "records.h" // init_read_record, end_read_record
#include <my_pthread.h>
#include <my_getopt.h>
-#include <mysql/plugin_audit.h>
+#include "sql_audit.h"
#include "lock.h" // MYSQL_LOCK_IGNORE_TIMEOUT
#define REPORT_TO_LOG 1
#define REPORT_TO_USER 2
@@ -1709,6 +1709,27 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
+ /*
+ Pre-acquire audit plugins for events that may potentially occur
+ during [UN]INSTALL PLUGIN.
+
+ When audit event is triggered, audit subsystem acquires interested
+ plugins by walking through plugin list. Evidently plugin list
+ iterator protects plugin list by acquiring LOCK_plugin, see
+ plugin_foreach_with_mask().
+
+ On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin
+ rather for a long time.
+
+ When audit event is triggered during [UN]INSTALL PLUGIN, plugin
+ list iterator acquires the same lock (within the same thread)
+ second time.
+
+ This hack should be removed when LOCK_plugin is fixed so it
+ protects only what it supposed to protect.
+ */
+ mysql_audit_acquire_plugins(thd, MYSQL_AUDIT_GENERAL_CLASS);
+
mysql_mutex_lock(&LOCK_plugin);
mysql_rwlock_wrlock(&LOCK_system_variables_hash);
@@ -1789,6 +1810,27 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
+ /*
+ Pre-acquire audit plugins for events that may potentially occur
+ during [UN]INSTALL PLUGIN.
+
+ When audit event is triggered, audit subsystem acquires interested
+ plugins by walking through plugin list. Evidently plugin list
+ iterator protects plugin list by acquiring LOCK_plugin, see
+ plugin_foreach_with_mask().
+
+ On the other hand [UN]INSTALL PLUGIN is acquiring LOCK_plugin
+ rather for a long time.
+
+ When audit event is triggered during [UN]INSTALL PLUGIN, plugin
+ list iterator acquires the same lock (within the same thread)
+ second time.
+
+ This hack should be removed when LOCK_plugin is fixed so it
+ protects only what it supposed to protect.
+ */
+ mysql_audit_acquire_plugins(thd, MYSQL_AUDIT_GENERAL_CLASS);
+
mysql_mutex_lock(&LOCK_plugin);
if (!(plugin= plugin_find_internal(name, MYSQL_ANY_PLUGIN)))
{