Commit 2855bc53 authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents 5b62644e bd7908e6
...@@ -298,6 +298,7 @@ ENDIF() ...@@ -298,6 +298,7 @@ ENDIF()
# MDEV-24629, we need it outside of ELSIFs # MDEV-24629, we need it outside of ELSIFs
IF(RPM MATCHES "fedora") IF(RPM MATCHES "fedora")
ALTERNATIVE_NAME("common" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1) ALTERNATIVE_NAME("common" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1)
ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1)
ENDIF() ENDIF()
SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang") SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang")
......
#
# MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks
#
BEGIN NOT ATOMIC
IF SCALAR() expected_THEN_here;
END
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_THEN_here;
END' at line 2
BEGIN NOT ATOMIC
WHILE SCALAR() expected_DO_here;
END
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_DO_here;
END' at line 2
BEGIN NOT ATOMIC
REPEAT SELECT 1; UNTIL SCALAR() expected_END_here;
END
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_END_here;
END' at line 2
#
# MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error
#
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
CLOSE cur;
END' at line 3
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(1,sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ';
CLOSE cur;
END' at line 3
--echo #
--echo # MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks
--echo #
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
IF SCALAR() expected_THEN_here;
END
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
WHILE SCALAR() expected_DO_here;
END
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
REPEAT SELECT 1; UNTIL SCALAR() expected_END_here;
END
$$
DELIMITER ;$$
--echo #
--echo # MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error
--echo #
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$
DELIMITER $$;
--error ER_PARSE_ERROR
BEGIN NOT ATOMIC
DECLARE cur CURSOR (a INT) FOR SELECT a+1;
OPEN cur(1,sp_followed_by_syntax_error();
CLOSE cur;
END;
$$
DELIMITER ;$$
...@@ -608,20 +608,24 @@ class sp_head :private Query_arena, ...@@ -608,20 +608,24 @@ class sp_head :private Query_arena,
restore_lex(THD *thd) restore_lex(THD *thd)
{ {
DBUG_ENTER("sp_head::restore_lex"); DBUG_ENTER("sp_head::restore_lex");
/*
There is no a need to free the current thd->lex here.
- In the majority of the cases restore_lex() is called
on success and thd->lex does not need to be deleted.
- In cases when restore_lex() is called on error,
e.g. from sp_create_assignment_instr(), thd->lex is
already linked to some sp_instr_xxx (using sp_lex_keeper).
Note, we don't get to here in case of a syntax error
when the current thd->lex is not yet completely
initialized and linked. It gets automatically deleted
by the Bison %destructor in sql_yacc.yy.
*/
LEX *oldlex= (LEX *) m_lex.pop(); LEX *oldlex= (LEX *) m_lex.pop();
if (!oldlex) if (!oldlex)
DBUG_RETURN(false); // Nothing to restore DBUG_RETURN(false); // Nothing to restore
LEX *sublex= thd->lex;
// This restores thd->lex and thd->stmt_lex // This restores thd->lex and thd->stmt_lex
if (thd->restore_from_local_lex_to_old_lex(oldlex)) DBUG_RETURN(thd->restore_from_local_lex_to_old_lex(oldlex));
DBUG_RETURN(true);
if (!sublex->sp_lex_in_use)
{
sublex->sphead= NULL;
lex_end(sublex);
delete sublex;
}
DBUG_RETURN(false);
} }
/** /**
......
...@@ -486,11 +486,15 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead, ...@@ -486,11 +486,15 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead,
be deleted by the destructor ~sp_instr_xxx(). be deleted by the destructor ~sp_instr_xxx().
So we should remove "lex" from the stack sp_head::m_lex, So we should remove "lex" from the stack sp_head::m_lex,
to avoid double free. to avoid double free.
Note, in case "lex" is not owned by any sp_instr_xxx,
it's also safe to remove it from the stack right now.
So we can remove it unconditionally, without testing lex->sp_lex_in_use.
*/ */
lex->sphead->restore_lex(thd); lex->sphead->restore_lex(thd);
/*
No needs for "delete lex" here: "lex" is already linked
to the sp_instr_stmt (using sp_lex_keeper) instance created by
the call for new_sp_instr_stmt() above. It will be freed
by ~sp_head/~sp_instr/~sp_lex_keeper during THD::end_statement().
*/
DBUG_ASSERT(lex->sp_lex_in_use); // used by sp_instr_stmt
return true; return true;
} }
enum_var_type inner_option_type= lex->option_type; enum_var_type inner_option_type= lex->option_type;
...@@ -6843,7 +6847,6 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, ...@@ -6843,7 +6847,6 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd,
if (unlikely(!(bounds->m_index= if (unlikely(!(bounds->m_index=
new (thd->mem_root) sp_assignment_lex(thd, this)))) new (thd->mem_root) sp_assignment_lex(thd, this))))
return true; return true;
bounds->m_index->sp_lex_in_use= true;
sphead->reset_lex(thd, bounds->m_index); sphead->reset_lex(thd, bounds->m_index);
DBUG_ASSERT(thd->lex != this); DBUG_ASSERT(thd->lex != this);
/* /*
......
...@@ -3474,6 +3474,12 @@ struct LEX: public Query_tables_list ...@@ -3474,6 +3474,12 @@ struct LEX: public Query_tables_list
sp_head *sphead; sp_head *sphead;
sp_name *spname; sp_name *spname;
void delete_if_not_sp_lex_in_use()
{
if (!sp_lex_in_use)
delete this;
}
sp_pcontext *spcont; sp_pcontext *spcont;
st_sp_chistics sp_chistics; st_sp_chistics sp_chistics;
......
...@@ -10399,6 +10399,15 @@ bool parse_sql(THD *thd, Parser_state *parser_state, ...@@ -10399,6 +10399,15 @@ bool parse_sql(THD *thd, Parser_state *parser_state,
bool mysql_parse_status= thd->variables.sql_mode & MODE_ORACLE bool mysql_parse_status= thd->variables.sql_mode & MODE_ORACLE
? ORAparse(thd) : MYSQLparse(thd); ? ORAparse(thd) : MYSQLparse(thd);
if (mysql_parse_status)
/*
Restore the original LEX if it was replaced when parsing
a stored procedure. We must ensure that a parsing error
does not leave any side effects in the THD.
*/
LEX::cleanup_lex_after_parse_error(thd);
DBUG_ASSERT(opt_bootstrap || mysql_parse_status || DBUG_ASSERT(opt_bootstrap || mysql_parse_status ||
thd->lex->select_stack_top == 0); thd->lex->select_stack_top == 0);
thd->lex->current_select= thd->lex->first_select_lex(); thd->lex->current_select= thd->lex->first_select_lex();
......
...@@ -99,7 +99,6 @@ int yylex(void *yylval, void *yythd); ...@@ -99,7 +99,6 @@ int yylex(void *yylval, void *yythd);
#define MYSQL_YYABORT \ #define MYSQL_YYABORT \
do \ do \
{ \ { \
LEX::cleanup_lex_after_parse_error(thd); \
YYABORT; \ YYABORT; \
} while (0) } while (0)
...@@ -150,13 +149,6 @@ static Item* escape(THD *thd) ...@@ -150,13 +149,6 @@ static Item* escape(THD *thd)
static void yyerror(THD *thd, const char *s) static void yyerror(THD *thd, const char *s)
{ {
/*
Restore the original LEX if it was replaced when parsing
a stored procedure. We must ensure that a parsing error
does not leave any side effects in the THD.
*/
LEX::cleanup_lex_after_parse_error(thd);
/* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
s= ER_THD(thd, ER_SYNTAX_ERROR); s= ER_THD(thd, ER_SYNTAX_ERROR);
...@@ -1542,6 +1534,19 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1542,6 +1534,19 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <expr_lex> %type <expr_lex>
expr_lex expr_lex
%destructor
{
/*
In case of a syntax/oom error let's free the sp_expr_lex
instance, but only if it has not been linked to any structures
such as sp_instr_jump_if_not::m_lex_keeper yet, e.g.:
IF f1() THEN1
i.e. THEN1 came instead of the expected THEN causing a syntax error.
*/
if (!$$->sp_lex_in_use)
delete $$;
} <expr_lex>
%type <assignment_lex> %type <assignment_lex>
assignment_source_lex assignment_source_lex
assignment_source_expr assignment_source_expr
...@@ -1551,6 +1556,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1551,6 +1556,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
cursor_actual_parameters cursor_actual_parameters
opt_parenthesized_cursor_actual_parameters opt_parenthesized_cursor_actual_parameters
%destructor
{
if ($$)
{
sp_assignment_lex *elem;
List_iterator<sp_assignment_lex> li(*$$);
while ((elem= li++))
{
if (!elem->sp_lex_in_use)
delete elem;
}
}
} <sp_assignment_lex_list>
%type <var_type> %type <var_type>
option_type opt_var_type opt_var_ident_type option_type opt_var_type opt_var_ident_type
...@@ -3832,7 +3852,6 @@ expr_lex: ...@@ -3832,7 +3852,6 @@ expr_lex:
expr expr
{ {
$$= $<expr_lex>1; $$= $<expr_lex>1;
$$->sp_lex_in_use= true;
$$->set_item($2); $$->set_item($2);
Lex->pop_select(); //min select Lex->pop_select(); //min select
if (Lex->check_cte_dependencies_and_resolve_references()) if (Lex->check_cte_dependencies_and_resolve_references())
...@@ -3864,7 +3883,6 @@ assignment_source_expr: ...@@ -3864,7 +3883,6 @@ assignment_source_expr:
{ {
DBUG_ASSERT($1 == thd->lex); DBUG_ASSERT($1 == thd->lex);
$$= $1; $$= $1;
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, thd->free_list); $$->set_item_and_free_list($3, thd->free_list);
thd->free_list= NULL; thd->free_list= NULL;
Lex->pop_select(); //min select Lex->pop_select(); //min select
...@@ -3885,7 +3903,6 @@ for_loop_bound_expr: ...@@ -3885,7 +3903,6 @@ for_loop_bound_expr:
{ {
DBUG_ASSERT($1 == thd->lex); DBUG_ASSERT($1 == thd->lex);
$$= $1; $$= $1;
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, NULL); $$->set_item_and_free_list($3, NULL);
Lex->pop_select(); //main select Lex->pop_select(); //main select
if (unlikely($$->sphead->restore_lex(thd))) if (unlikely($$->sphead->restore_lex(thd)))
......
...@@ -378,8 +378,16 @@ static bool fil_node_open_file_low(fil_node_t *node) ...@@ -378,8 +378,16 @@ static bool fil_node_open_file_low(fil_node_t *node)
: OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT,
OS_FILE_AIO, type, OS_FILE_AIO, type,
srv_read_only_mode, &success); srv_read_only_mode, &success);
if (success) if (node->is_open())
{
ut_ad(success);
#ifndef _WIN32
if (!node->space->id && !srv_read_only_mode && my_disable_locking &&
os_file_lock(node->handle, node->name))
goto fail;
#endif
break; break;
}
/* The following call prints an error message */ /* The following call prints an error message */
if (os_file_get_last_error(true) == EMFILE + 100 && if (os_file_get_last_error(true) == EMFILE + 100 &&
...@@ -393,6 +401,9 @@ static bool fil_node_open_file_low(fil_node_t *node) ...@@ -393,6 +401,9 @@ static bool fil_node_open_file_low(fil_node_t *node)
if (node->size); if (node->size);
else if (!node->read_page0() || !fil_comp_algo_validate(node->space)) else if (!node->read_page0() || !fil_comp_algo_validate(node->space))
{ {
#ifndef _WIN32
fail:
#endif
os_file_close(node->handle); os_file_close(node->handle);
node->handle= OS_FILE_CLOSED; node->handle= OS_FILE_CLOSED;
return false; return false;
......
...@@ -242,9 +242,11 @@ enum rec_leaf_format { ...@@ -242,9 +242,11 @@ enum rec_leaf_format {
REC_LEAF_INSTANT REC_LEAF_INSTANT
}; };
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 12 #if defined __GNUC__ && !defined __clang__
# pragma GCC diagnostic push # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion" /* GCC 5 to 11 need this */ # if __GNUC__ < 12 || defined WITH_UBSAN
# pragma GCC diagnostic ignored "-Wconversion"
# endif
#endif #endif
/** Determine the offset to each field in a leaf-page record /** Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT,DYNAMIC,COMPRESSED. in ROW_FORMAT=COMPACT,DYNAMIC,COMPRESSED.
...@@ -1707,7 +1709,7 @@ rec_convert_dtuple_to_rec_new( ...@@ -1707,7 +1709,7 @@ rec_convert_dtuple_to_rec_new(
REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT); REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);
return buf; return buf;
} }
#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 11 #if defined __GNUC__ && !defined __clang__
# pragma GCC diagnostic pop /* ignored "-Wconversion" */ # pragma GCC diagnostic pop /* ignored "-Wconversion" */
#endif #endif
......
...@@ -4,11 +4,11 @@ for child3 ...@@ -4,11 +4,11 @@ for child3
MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int); create table t2 (c int);
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t2"';
create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t1"';
alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"'; alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t0"';
select * from t0; select * from t0;
ERROR HY000: An infinite loop is detected when opening table test.t0 ERROR HY000: An infinite loop is detected when opening table test.t0
select * from t1; select * from t1;
......
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
--echo MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever --echo MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever
--echo --echo
--replace_regex /SOCKET ".*"/SOCKET "$MASTER_1_MYSOCK"/ --let $srv=srv_self_reference_multi
eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
create table t2 (c int); create table t2 (c int);
create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; eval create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t2"';
create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; eval create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t1"';
alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"'; eval alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t0"';
--error 12719 --error 12719
select * from t0; select * from t0;
--error 12719 --error 12719
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment