summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-04-25 13:10:33 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2023-04-25 13:10:33 +0300
commit818d5e48146b7938a7ccca4ccf819afe3ea8a005 (patch)
tree3fd9c85866cc4cd504e316268b84582260fae180 /sql
parent0976afec889d8914326f9e71b15ea215470dadba (diff)
parent50f3b7d1649002df3c73ec88827707096ce3135c (diff)
downloadmariadb-git-818d5e48146b7938a7ccca4ccf819afe3ea8a005.tar.gz
Merge 10.5 into 10.6
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc15
-rw-r--r--sql/log.cc2
-rw-r--r--sql/log_event.h4
-rw-r--r--sql/log_event_server.cc64
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/opt_range.cc3
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_table.cc13
-rw-r--r--sql/sql_yacc.yy56
-rw-r--r--sql/wsrep_client_service.cc2
-rw-r--r--sql/wsrep_high_priority_service.cc2
13 files changed, 126 insertions, 49 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index b3b22874735..c683a94e292 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2174,8 +2174,11 @@ int ha_rollback_trans(THD *thd, bool all)
rollback without signalling following transactions. And in release
builds, we explicitly do the signalling before rolling back.
*/
- DBUG_ASSERT(!(thd->rgi_slave && thd->rgi_slave->did_mark_start_commit) ||
- thd->transaction->xid_state.is_explicit_XA());
+ DBUG_ASSERT(
+ !(thd->rgi_slave && thd->rgi_slave->did_mark_start_commit) ||
+ (thd->transaction->xid_state.is_explicit_XA() ||
+ (thd->rgi_slave->gtid_ev_flags2 & Gtid_log_event::FL_PREPARED_XA)));
+
if (thd->rgi_slave && thd->rgi_slave->did_mark_start_commit)
thd->rgi_slave->unmark_start_commit();
}
@@ -7208,7 +7211,13 @@ static int wsrep_after_row(THD *thd)
thd->wsrep_affected_rows > wsrep_max_ws_rows &&
wsrep_thd_is_local(thd))
{
- trans_rollback_stmt(thd) || trans_rollback(thd);
+ /*
+ If we are inside stored function or trigger we should not commit or
+ rollback current statement transaction. See comment in ha_commit_trans()
+ call for more information.
+ */
+ if (!thd->in_sub_stmt)
+ trans_rollback_stmt(thd) || trans_rollback(thd);
my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0));
DBUG_RETURN(ER_ERROR_DURING_COMMIT);
}
diff --git a/sql/log.cc b/sql/log.cc
index 2dbfa8278a2..76a94c2814e 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -416,7 +416,7 @@ private:
Rows_log_event *m_pending;
/*
- Bit flags for what has been writting to cache. Used to
+ Bit flags for what has been writing to cache. Used to
discard logs without any data changes.
see enum_logged_status;
*/
diff --git a/sql/log_event.h b/sql/log_event.h
index 6203c57ead2..88db7984714 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -727,7 +727,7 @@ enum Log_event_type
/*
- Bit flags for what has been writting to cache. Used to
+ Bit flags for what has been writing to cache. Used to
discard logs with table map events but not row events and
nothing else important. This is stored by cache.
*/
@@ -3057,7 +3057,7 @@ private:
virtual int do_commit()= 0;
virtual int do_apply_event(rpl_group_info *rgi);
int do_record_gtid(THD *thd, rpl_group_info *rgi, bool in_trans,
- void **out_hton);
+ void **out_hton, bool force_err= false);
enum_skip_reason do_shall_skip(rpl_group_info *rgi);
virtual const char* get_query()= 0;
#endif
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index 48903fead4c..013515850ef 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -152,6 +152,30 @@ is_parallel_retry_error(rpl_group_info *rgi, int err)
return has_temporary_error(rgi->thd);
}
+/**
+ Accumulate a Diagnostics_area's errors and warnings into an output buffer
+
+ @param errbuf The output buffer to write error messages
+ @param errbuf_size The size of the output buffer
+ @param da The Diagnostics_area to check for errors
+*/
+static void inline aggregate_da_errors(char *errbuf, size_t errbuf_size,
+ Diagnostics_area *da)
+{
+ const char *errbuf_end= errbuf + errbuf_size;
+ char *slider;
+ Diagnostics_area::Sql_condition_iterator it= da->sql_conditions();
+ const Sql_condition *err;
+ size_t len;
+ for (err= it++, slider= errbuf; err && slider < errbuf_end - 1;
+ slider += len, err= it++)
+ {
+ len= my_snprintf(slider, errbuf_end - slider,
+ " %s, Error_code: %d;", err->get_message_text(),
+ err->get_sql_errno());
+ }
+}
+
/**
Error reporting facility for Rows_log_event::do_apply_event
@@ -172,13 +196,8 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
const char *log_name, my_off_t pos)
{
const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
- char buff[MAX_SLAVE_ERRMSG], *slider;
- const char *buff_end= buff + sizeof(buff);
- size_t len;
- Diagnostics_area::Sql_condition_iterator it=
- thd->get_stmt_da()->sql_conditions();
+ char buff[MAX_SLAVE_ERRMSG];
Relay_log_info const *rli= rgi->rli;
- const Sql_condition *err;
buff[0]= 0;
int errcode= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
@@ -191,13 +210,7 @@ static void inline slave_rows_error_report(enum loglevel level, int ha_error,
if (is_parallel_retry_error(rgi, errcode))
return;
- for (err= it++, slider= buff; err && slider < buff_end - 1;
- slider += len, err= it++)
- {
- len= my_snprintf(slider, buff_end - slider,
- " %s, Error_code: %d;", err->get_message_text(),
- err->get_sql_errno());
- }
+ aggregate_da_errors(buff, sizeof(buff), thd->get_stmt_da());
if (ha_error != 0)
rli->report(level, errcode, rgi->gtid_info(),
@@ -3941,7 +3954,8 @@ bool slave_execute_deferred_events(THD *thd)
#if defined(HAVE_REPLICATION)
int Xid_apply_log_event::do_record_gtid(THD *thd, rpl_group_info *rgi,
- bool in_trans, void **out_hton)
+ bool in_trans, void **out_hton,
+ bool force_err)
{
int err= 0;
Relay_log_info const *rli= rgi->rli;
@@ -3956,14 +3970,26 @@ int Xid_apply_log_event::do_record_gtid(THD *thd, rpl_group_info *rgi,
int ec= thd->get_stmt_da()->sql_errno();
/*
Do not report an error if this is really a kill due to a deadlock.
- In this case, the transaction will be re-tried instead.
+ In this case, the transaction will be re-tried instead. Unless force_err
+ is set, as in the case of XA PREPARE, as the GTID state is updated as a
+ separate transaction, and if that fails, we should not retry but exit in
+ error immediately.
*/
- if (!is_parallel_retry_error(rgi, ec))
+ if (!is_parallel_retry_error(rgi, ec) || force_err)
+ {
+ char buff[MAX_SLAVE_ERRMSG];
+ buff[0]= 0;
+ aggregate_da_errors(buff, sizeof(buff), thd->get_stmt_da());
+
+ if (force_err)
+ thd->clear_error();
+
rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, rgi->gtid_info(),
"Error during XID COMMIT: failed to update GTID state in "
- "%s.%s: %d: %s",
+ "%s.%s: %d: %s the event's master log %s, end_log_pos %llu",
"mysql", rpl_gtid_slave_state_table_name.str, ec,
- thd->get_stmt_da()->message());
+ buff, RPL_LOG_NAME, log_pos);
+ }
thd->is_slave_error= 1;
}
@@ -4037,7 +4063,7 @@ int Xid_apply_log_event::do_apply_event(rpl_group_info *rgi)
{
DBUG_ASSERT(!thd->transaction->xid_state.is_explicit_XA());
- if ((err= do_record_gtid(thd, rgi, false, &hton)))
+ if ((err= do_record_gtid(thd, rgi, false, &hton, true)))
return err;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5e14739ee82..2cb26845e43 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4597,7 +4597,10 @@ static void init_ssl()
{
sql_print_error("Failed to setup SSL");
sql_print_error("SSL error: %s", sslGetErrString(error));
- unireg_abort(1);
+ if (!opt_bootstrap)
+ unireg_abort(1);
+ opt_use_ssl = 0;
+ have_ssl= SHOW_OPTION_DISABLED;
}
else
ssl_acceptor_stats.init();
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 44cf08d9323..3bbb6144c0b 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3554,7 +3554,10 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
}
else
{
+ enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
rows= records_in_column_ranges(&param, idx, key);
+ thd->count_cuted_fields= save_count_cuted_fields;
if (rows != DBL_MAX)
{
key->field->cond_selectivity= rows/table_records;
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 22503106350..e5362ffe0a9 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -803,6 +803,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
cursor->outer_join|= JOIN_TYPE_OUTER;
}
}
+ // Prevent it for possible ORDER BY clause
+ if (unit->fake_select_lex)
+ unit->fake_select_lex->context.outer_context= 0;
if (unlikely(thd->trace_started()))
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a7d43229818..f2f622e78c8 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1338,7 +1338,7 @@ dispatch_command_return do_command(THD *thd, bool blocking)
in wsrep_before_command().
*/
WSREP_LOG_THD(thd, "enter found BF aborted");
- DBUG_ASSERT(!thd->mdl_context.has_locks());
+ DBUG_ASSERT(!thd->mdl_context.has_transactional_locks());
DBUG_ASSERT(!thd->get_stmt_da()->is_set());
/* We let COM_QUIT and COM_STMT_CLOSE to execute even if wsrep aborted. */
if (command == COM_STMT_EXECUTE)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 83ec5476669..eda833b89b0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -28739,7 +28739,7 @@ void st_select_lex::print_item_list(THD *thd, String *str,
outer_select() can not be used here because it is for name resolution
and will return NULL at any end of name resolution chain (view/derived)
*/
- bool top_level= (get_master()->get_master() == 0);
+ bool top_level= (get_master() == &thd->lex->unit);
List_iterator_fast<Item> it(item_list);
Item *item;
while ((item= it++))
@@ -28846,7 +28846,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
return;
}
- bool top_level= (get_master()->get_master() == 0);
+ bool top_level= (get_master() == &thd->lex->unit);
enum explainable_cmd_type sel_type= SELECT_CMD;
if (top_level)
sel_type= get_explainable_cmd_type(thd);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 28c0ba60d70..a281bdd7bcc 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -11766,6 +11766,19 @@ bool Sql_cmd_create_table_like::execute(THD *thd)
}
#endif
+#ifdef WITH_WSREP
+ if (select_lex->item_list.elements && // With SELECT
+ WSREP(thd) && thd->variables.wsrep_trx_fragment_size > 0)
+ {
+ my_message(
+ ER_NOT_ALLOWED_COMMAND,
+ "CREATE TABLE AS SELECT is not supported with streaming replication",
+ MYF(0));
+ res= 1;
+ goto end_with_restore_list;
+ }
+#endif /* WITH_WSREP */
+
if (select_lex->item_list.elements || select_lex->tvc) // With select or TVC
{
select_result *result;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 935617e6fc5..be1acd1f5ba 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -349,9 +349,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
*/
%ifdef MARIADB
-%expect 82
+%expect 64
%else
-%expect 83
+%expect 65
%endif
/*
@@ -1180,7 +1180,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left PREC_BELOW_NOT
-%nonassoc LOW_PRIORITY_NOT
+/* The precendence of boolean NOT is in fact here. See the comment below. */
+
%left '=' EQUAL_SYM GE '>' LE '<' NE
%nonassoc IS
%right BETWEEN_SYM
@@ -1192,6 +1193,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left '*' '/' '%' DIV_SYM MOD_SYM
%left '^'
%left MYSQL_CONCAT_SYM
+/*
+ Boolean negation has a special branch in "expr" starting with NOT_SYM.
+ The precedence of logical negation is determined by the grammar itself
+ (without using Bison terminal symbol precedence) in this order
+ - Boolean factor (i.e. logical AND)
+ - Boolean NOT
+ - Boolean test (such as '=', IS NULL, IS TRUE)
+
+ But we also need a precedence for NOT_SYM in other contexts,
+ to shift (without reduce) in these cases:
+ predicate <here> NOT IN ...
+ predicate <here> NOT BETWEEN ...
+ predicate <here> NOT LIKE ...
+ predicate <here> NOT REGEXP ...
+ If the precedence of NOT_SYM was low, it would reduce immediately
+ after scanning "predicate" and then produce a syntax error on "NOT".
+*/
+%nonassoc NOT_SYM
%nonassoc NEG '~' NOT2_SYM BINARY
%nonassoc COLLATE_SYM
%nonassoc SUBQUERY_AS_EXPR
@@ -1467,6 +1486,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
literal insert_ident order_ident temporal_literal
simple_ident expr sum_expr in_sum_expr
variable variable_aux
+ boolean_test
predicate bit_expr parenthesized_expr
table_wild simple_expr column_default_non_parenthesized_expr udf_expr
primary_expr string_factor_expr mysql_concatenation_expr
@@ -9423,79 +9443,83 @@ expr:
MYSQL_YYABORT;
}
}
- | NOT_SYM expr %prec LOW_PRIORITY_NOT
+ | NOT_SYM expr
{
$$= negate_expression(thd, $2);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS TRUE_SYM %prec IS
+ | boolean_test %prec PREC_BELOW_NOT
+ ;
+
+boolean_test:
+ boolean_test IS TRUE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_istrue(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS not TRUE_SYM %prec IS
+ | boolean_test IS not TRUE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnottrue(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS FALSE_SYM %prec IS
+ | boolean_test IS FALSE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isfalse(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS not FALSE_SYM %prec IS
+ | boolean_test IS not FALSE_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotfalse(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS UNKNOWN_SYM %prec IS
+ | boolean_test IS UNKNOWN_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS not UNKNOWN_SYM %prec IS
+ | boolean_test IS not UNKNOWN_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS NULL_SYM %prec PREC_BELOW_NOT
+ | boolean_test IS NULL_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr IS not NULL_SYM %prec IS
+ | boolean_test IS not NULL_SYM %prec IS
{
$$= new (thd->mem_root) Item_func_isnotnull(thd, $1);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr EQUAL_SYM predicate %prec EQUAL_SYM
+ | boolean_test EQUAL_SYM predicate %prec EQUAL_SYM
{
$$= new (thd->mem_root) Item_func_equal(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr comp_op predicate %prec '='
+ | boolean_test comp_op predicate %prec '='
{
$$= (*$2)(0)->create(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | expr comp_op all_or_any '(' subselect ')' %prec '='
+ | boolean_test comp_op all_or_any '(' subselect ')' %prec '='
{
$$= all_any_subquery_creator(thd, $1, $2, $3, $5);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
- | predicate
+ | predicate %prec BETWEEN_SYM
;
predicate:
diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc
index 628a408b49b..d3b4a18195b 100644
--- a/sql/wsrep_client_service.cc
+++ b/sql/wsrep_client_service.cc
@@ -374,8 +374,6 @@ int Wsrep_client_service::bf_rollback()
m_thd->global_read_lock.unlock_global_read_lock(m_thd);
}
m_thd->release_transactional_locks();
- mysql_ull_cleanup(m_thd);
- m_thd->mdl_context.release_explicit_locks();
}
DBUG_RETURN(ret);
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index d9988914c4d..53ef20f3e78 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -391,8 +391,6 @@ int Wsrep_high_priority_service::rollback(const wsrep::ws_handle& ws_handle,
m_thd->killed);
m_thd->release_transactional_locks();
- mysql_ull_cleanup(m_thd);
- m_thd->mdl_context.release_explicit_locks();
free_root(m_thd->mem_root, MYF(MY_KEEP_PREALLOC));