diff --git a/include/thr_lock.h b/include/thr_lock.h
index c7754ada299..e409df30972 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -159,7 +159,8 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock);
my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread);
void thr_print_locks(void); /* For debugging */
-my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data);
+my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
+ enum thr_lock_type new_lock_type);
void thr_downgrade_write_lock(THR_LOCK_DATA *data,
enum thr_lock_type new_lock_type);
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result
index bcda6ddb6ab..4d5d656f3ce 100644
--- a/mysql-test/r/delayed.result
+++ b/mysql-test/r/delayed.result
@@ -284,4 +284,30 @@ ERROR 22007: Incorrect date value: '0000-00-00' for column 'f1' at row 1
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
ERROR 22007: Incorrect date value: '2007-00-00' for column 'f1' at row 1
DROP TABLE t1,t2;
+set @old_delayed_updates = @@global.low_priority_updates;
+set global low_priority_updates = 1;
+select @@global.low_priority_updates;
+@@global.low_priority_updates
+1
+drop table if exists t1;
+create table t1 (a int, b int);
+insert into t1 values (1,1);
+lock table t1 read;
+connection: update
+insert delayed into t1 values (2,2);;
+connection: select
+select * from t1;
+a b
+1 1
+connection: default
+select * from t1;
+a b
+1 1
+unlock tables;
+select * from t1;
+a b
+1 1
+2 2
+drop table t1;
+set global low_priority_updates = @old_delayed_updates;
End of 5.1 tests
diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result
index 41c0d6bee21..404b0dc3789 100644
--- a/mysql-test/r/xml.result
+++ b/mysql-test/r/xml.result
@@ -1053,4 +1053,15 @@ ExtractValue('CharData', '/xml')
NULL
Warnings:
Warning 1525 Incorrect XML value: 'parse error at line 1 pos 17: STRING unexpected ('>' wanted)'
+set @x=10;
+select extractvalue('','$@x/a');
+ERROR HY000: XPATH syntax error: '/a'
+select extractvalue('','round(123.4)/a');
+ERROR HY000: XPATH syntax error: '/a'
+select extractvalue('','1/a');
+ERROR HY000: XPATH syntax error: '/a'
+select extractvalue('','"b"/a');
+ERROR HY000: XPATH syntax error: '/a'
+select extractvalue('','(1)/a');
+ERROR HY000: XPATH syntax error: '/a'
End of 5.1 tests
diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def
index 694f7098980..6908269d014 100644
--- a/mysql-test/suite/rpl_ndb/t/disabled.def
+++ b/mysql-test/suite/rpl_ndb/t/disabled.def
@@ -10,7 +10,4 @@
#
##############################################################################
-rpl_ndb_circular : Bug#41183 rpl_ndb_circular, rpl_ndb_circular_simplex need maintenance, crash
-rpl_ndb_circular_simplex : Bug#41183 rpl_ndb_circular, rpl_ndb_circular_simplex need maintenance, crash
-
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index ce57645bd4b..94ad22b80d0 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -285,4 +285,47 @@ INSERT DELAYED INTO t2 VALUES (0,'0000-00-00');
INSERT DELAYED INTO t2 VALUES (0,'2007-00-00');
DROP TABLE t1,t2;
+#
+# Bug#40536: SELECT is blocked by INSERT DELAYED waiting on upgrading lock,
+# even with low_priority_updates
+#
+
+set @old_delayed_updates = @@global.low_priority_updates;
+set global low_priority_updates = 1;
+select @@global.low_priority_updates;
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int, b int);
+insert into t1 values (1,1);
+lock table t1 read;
+connect (update,localhost,root,,);
+connection update;
+--echo connection: update
+--send insert delayed into t1 values (2,2);
+connection default;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where command = "Delayed insert" and state = "upgrading lock";
+--source include/wait_condition.inc
+connect (select,localhost,root,,);
+--echo connection: select
+select * from t1;
+connection default;
+--echo connection: default
+select * from t1;
+connection default;
+disconnect update;
+disconnect select;
+unlock tables;
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where command = "Delayed insert" and state = "Waiting for INSERT";
+--source include/wait_condition.inc
+select * from t1;
+drop table t1;
+
+set global low_priority_updates = @old_delayed_updates;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test
index d840e14ba5f..74bce8dc962 100644
--- a/mysql-test/t/xml.test
+++ b/mysql-test/t/xml.test
@@ -575,5 +575,19 @@ SELECT ExtractValue(@xml, 'html/body');
SELECT ExtractValue('CharData', '/xml');
SELECT ExtractValue('CharData', '/xml');
+#
+# Bug#42495 updatexml: Assertion failed: xpath->context, file .\item_xmlfunc.cc, line 2507
+#
+set @x=10;
+--error ER_UNKNOWN_ERROR
+select extractvalue('','$@x/a');
+--error ER_UNKNOWN_ERROR
+select extractvalue('','round(123.4)/a');
+--error ER_UNKNOWN_ERROR
+select extractvalue('','1/a');
+--error ER_UNKNOWN_ERROR
+select extractvalue('','"b"/a');
+--error ER_UNKNOWN_ERROR
+select extractvalue('','(1)/a');
--echo End of 5.1 tests
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index b13e8411771..31638ecee9a 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1359,7 +1359,8 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data,
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
-my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
+my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
+ enum thr_lock_type new_lock_type)
{
THR_LOCK *lock=data->lock;
DBUG_ENTER("thr_upgrade_write_delay_lock");
@@ -1372,7 +1373,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
}
check_locks(lock,"before upgrading lock",0);
/* TODO: Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
- data->type=TL_WRITE; /* Upgrade lock */
+ data->type= new_lock_type; /* Upgrade lock */
/* Check if someone has given us the lock */
if (!data->cond)
@@ -1411,6 +1412,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
{
THR_LOCK *lock=data->lock;
+ enum thr_lock_type write_lock_type;
DBUG_ENTER("thr_reschedule_write_lock");
pthread_mutex_lock(&lock->mutex);
@@ -1420,6 +1422,7 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
DBUG_RETURN(0);
}
+ write_lock_type= data->type;
data->type=TL_WRITE_DELAYED;
if (lock->update_status)
(*lock->update_status)(data->status_param);
@@ -1438,7 +1441,7 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
free_all_read_locks(lock,0);
pthread_mutex_unlock(&lock->mutex);
- DBUG_RETURN(thr_upgrade_write_delay_lock(data));
+ DBUG_RETURN(thr_upgrade_write_delay_lock(data, write_lock_type));
}
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 68d85418324..5601a2b18c6 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1969,6 +1969,13 @@ my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(MY_XPATH *xpath)
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH))
return 1;
+ if (xpath->item->type() != Item::XPATH_NODESET)
+ {
+ xpath->lasttok= xpath->prevtok;
+ xpath->error= 1;
+ return 0;
+ }
+
my_xpath_parse_term(xpath, MY_XPATH_LEX_SLASH);
return my_xpath_parse_RelativeLocationPath(xpath);
}
@@ -1976,7 +1983,6 @@ static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{
return my_xpath_parse_LocationPath(xpath) ||
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath(xpath);
-
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 0f980f1808d..0e400ac2705 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -53,6 +53,8 @@
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
+
static const char *HA_ERR(int i)
{
switch (i) {
@@ -2894,7 +2896,37 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
clear_all_errors(thd, const_cast(rli));
- const_cast(rli)->clear_tables_to_lock();
+ if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock)
+ {
+ /*
+ Cleaning-up the last statement context:
+ the terminal event of the current statement flagged with
+ STMT_END_F got filtered out in ndb circular replication.
+ */
+ int error;
+ char llbuff[22];
+ if ((error= rows_event_stmt_cleanup(const_cast(rli), thd)))
+ {
+ const_cast(rli)->report(ERROR_LEVEL, error,
+ "Error in cleaning up after an event preceeding the commit; "
+ "the group log file/position: %s %s",
+ const_cast(rli)->group_master_log_name,
+ llstr(const_cast(rli)->group_master_log_pos,
+ llbuff));
+ }
+ /*
+ Executing a part of rli->stmt_done() logics that does not deal
+ with group position change. The part is redundant now but is
+ future-change-proof addon, e.g if COMMIT handling will start checking
+ invariants like IN_STMT flag must be off at committing the transaction.
+ */
+ const_cast(rli)->inc_event_relay_log_pos();
+ const_cast(rli)->clear_flag(Relay_log_info::IN_STMT);
+ }
+ else
+ {
+ const_cast(rli)->clear_tables_to_lock();
+ }
/*
Note: We do not need to execute reset_one_shot_variables() if this
@@ -7403,16 +7435,20 @@ Rows_log_event::do_shall_skip(Relay_log_info *rli)
return Log_event::do_shall_skip(rli);
}
-int
-Rows_log_event::do_update_pos(Relay_log_info *rli)
+/**
+ The function is called at Rows_log_event statement commit time,
+ normally from Rows_log_event::do_update_pos() and possibly from
+ Query_log_event::do_apply_event() of the COMMIT.
+ The function commits the last statement for engines, binlog and
+ releases resources have been allocated for the statement.
+
+ @retval 0 Ok.
+ @retval non-zero Error at the commit.
+ */
+
+static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
{
- DBUG_ENTER("Rows_log_event::do_update_pos");
- int error= 0;
-
- DBUG_PRINT("info", ("flags: %s",
- get_flags(STMT_END_F) ? "STMT_END_F " : ""));
-
- if (get_flags(STMT_END_F))
+ int error;
{
/*
This is the end of a statement or transaction, so close (and
@@ -7454,14 +7490,39 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
thd->reset_current_stmt_binlog_row_based();
- rli->cleanup_context(thd, 0);
- if (error == 0)
+ const_cast(rli)->cleanup_context(thd, 0);
+ }
+ return error;
+}
+
+/**
+ The method either increments the relay log position or
+ commits the current statement and increments the master group
+ possition if the event is STMT_END_F flagged and
+ the statement corresponds to the autocommit query (i.e replicated
+ without wrapping in BEGIN/COMMIT)
+
+ @retval 0 Success
+ @retval non-zero Error in the statement commit
+ */
+int
+Rows_log_event::do_update_pos(Relay_log_info *rli)
+{
+ DBUG_ENTER("Rows_log_event::do_update_pos");
+ int error= 0;
+
+ DBUG_PRINT("info", ("flags: %s",
+ get_flags(STMT_END_F) ? "STMT_END_F " : ""));
+
+ if (get_flags(STMT_END_F))
+ {
+ if ((error= rows_event_stmt_cleanup(rli, thd)) == 0)
{
/*
Indicate that a statement is finished.
Step the group log position if we are not in a transaction,
otherwise increase the event log position.
- */
+ */
rli->stmt_done(log_pos, when);
/*
@@ -7475,11 +7536,13 @@ Rows_log_event::do_update_pos(Relay_log_info *rli)
thd->clear_error();
}
else
+ {
rli->report(ERROR_LEVEL, error,
"Error in %s event: commit of row events failed, "
"table `%s`.`%s`",
get_type_str(), m_table->s->db.str,
m_table->s->table_name.str);
+ }
}
else
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index fb437bed3fa..fcf86edeaa9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1690,6 +1690,7 @@ public:
class Delayed_insert :public ilink {
uint locks_in_memory;
+ thr_lock_type delayed_lock;
public:
THD thd;
TABLE *table;
@@ -1731,6 +1732,8 @@ public:
pthread_cond_init(&cond_client,NULL);
VOID(pthread_mutex_lock(&LOCK_thread_count));
delayed_insert_threads++;
+ delayed_lock= global_system_variables.low_priority_updates ?
+ TL_WRITE_LOW_PRIORITY : TL_WRITE;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
}
~Delayed_insert()
@@ -2540,7 +2543,7 @@ bool Delayed_insert::handle_inserts(void)
table->use_all_columns();
thd_proc_info(&thd, "upgrading lock");
- if (thr_upgrade_write_delay_lock(*thd.lock->locks))
+ if (thr_upgrade_write_delay_lock(*thd.lock->locks, delayed_lock))
{
/*
This can happen if thread is killed either by a shutdown