Commit 15a42a0a authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.6 into 10.9

parents ecd23f62 2855bc53
...@@ -299,6 +299,7 @@ ENDIF() ...@@ -299,6 +299,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 ;$$
...@@ -620,20 +620,24 @@ class sp_head :private Query_arena, ...@@ -620,20 +620,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;
...@@ -6831,7 +6835,6 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, ...@@ -6831,7 +6835,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);
/* /*
......
...@@ -3471,6 +3471,12 @@ struct LEX: public Query_tables_list ...@@ -3471,6 +3471,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;
......
...@@ -10406,6 +10406,15 @@ bool parse_sql(THD *thd, Parser_state *parser_state, ...@@ -10406,6 +10406,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);
...@@ -1554,6 +1546,19 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1554,6 +1546,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
...@@ -1563,6 +1568,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1563,6 +1568,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
...@@ -3857,7 +3877,6 @@ expr_lex: ...@@ -3857,7 +3877,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())
...@@ -3889,7 +3908,6 @@ assignment_source_expr: ...@@ -3889,7 +3908,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
...@@ -3910,7 +3928,6 @@ for_loop_bound_expr: ...@@ -3910,7 +3928,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)))
......
...@@ -362,8 +362,20 @@ static bool fil_node_open_file_low(fil_node_t *node) ...@@ -362,8 +362,20 @@ 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))
{
os_file_close(node->handle);
node->handle= OS_FILE_CLOSED;
return false;
}
#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 &&
......
...@@ -243,21 +243,11 @@ mysql_mutex_t ibuf_mutex, ...@@ -243,21 +243,11 @@ mysql_mutex_t ibuf_mutex,
ibuf_pessimistic_insert_mutex; ibuf_pessimistic_insert_mutex;
/** The area in pages from which contract looks for page numbers for merge */ /** The area in pages from which contract looks for page numbers for merge */
const ulint IBUF_MERGE_AREA = 8; constexpr ulint IBUF_MERGE_AREA = 8;
/** Inside the merge area, pages which have at most 1 per this number less /** In ibuf_contract() at most this number of pages is read to memory in one
buffered entries compared to maximum volume that can buffered for a single batch, in order to merge the entries for them in the change buffer */
page are merged along with the page whose buffer became full */ constexpr ulint IBUF_MAX_N_PAGES_MERGED = IBUF_MERGE_AREA;
const ulint IBUF_MERGE_THRESHOLD = 4;
/** In ibuf_contract at most this number of pages is read to memory in one
batch, in order to merge the entries for them in the insert buffer */
const ulint IBUF_MAX_N_PAGES_MERGED = IBUF_MERGE_AREA;
/** If the combined size of the ibuf trees exceeds ibuf.max_size by
this many pages, we start to contract it synchronous contract, but do
not insert */
const ulint IBUF_CONTRACT_DO_NOT_INSERT = 10;
/* TODO: how to cope with drop table if there are records in the insert /* TODO: how to cope with drop table if there are records in the insert
buffer for the indexes of the table? Is there actually any problem, buffer for the indexes of the table? Is there actually any problem,
...@@ -2005,11 +1995,11 @@ ibuf_free_excess_pages(void) ...@@ -2005,11 +1995,11 @@ ibuf_free_excess_pages(void)
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,pages,n_stored) \ # define ibuf_get_merge_page_nos(rec,mtr,ids,pages,n_stored) \
ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,pages,n_stored) ibuf_get_merge_page_nos_func(rec,mtr,ids,pages,n_stored)
#else /* UNIV_DEBUG */ #else /* UNIV_DEBUG */
# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,pages,n_stored) \ # define ibuf_get_merge_page_nos(rec,mtr,ids,pages,n_stored) \
ibuf_get_merge_page_nos_func(contract,rec,ids,pages,n_stored) ibuf_get_merge_page_nos_func(rec,ids,pages,n_stored)
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/*********************************************************************//** /*********************************************************************//**
...@@ -2020,10 +2010,6 @@ static ...@@ -2020,10 +2010,6 @@ static
ulint ulint
ibuf_get_merge_page_nos_func( ibuf_get_merge_page_nos_func(
/*=========================*/ /*=========================*/
ibool contract,/*!< in: TRUE if this function is called to
contract the tree, FALSE if this is called
when a single page becomes full and we look
if it pays to read also nearby pages */
const rec_t* rec, /*!< in: insert buffer record */ const rec_t* rec, /*!< in: insert buffer record */
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
mtr_t* mtr, /*!< in: mini-transaction holding rec */ mtr_t* mtr, /*!< in: mini-transaction holding rec */
...@@ -2154,22 +2140,10 @@ ibuf_get_merge_page_nos_func( ...@@ -2154,22 +2140,10 @@ ibuf_get_merge_page_nos_func(
|| rec_page_no != prev_page_no) || rec_page_no != prev_page_no)
&& (prev_space_id != 0 || prev_page_no != 0)) { && (prev_space_id != 0 || prev_page_no != 0)) {
if (contract space_ids[*n_stored] = prev_space_id;
|| (prev_page_no == first_page_no page_nos[*n_stored] = prev_page_no;
&& prev_space_id == first_space_id) (*n_stored)++;
|| (volume_for_page sum_volumes += volume_for_page;
> ((IBUF_MERGE_THRESHOLD - 1)
* 4U << srv_page_size_shift
/ IBUF_PAGE_SIZE_PER_FREE_SPACE)
/ IBUF_MERGE_THRESHOLD)) {
space_ids[*n_stored] = prev_space_id;
page_nos[*n_stored] = prev_page_no;
(*n_stored)++;
sum_volumes += volume_for_page;
}
if (rec_space_id != first_space_id if (rec_space_id != first_space_id
|| rec_page_no / IBUF_MERGE_AREA || rec_page_no / IBUF_MERGE_AREA
...@@ -2429,7 +2403,7 @@ static void ibuf_read_merge_pages(const uint32_t* space_ids, ...@@ -2429,7 +2403,7 @@ static void ibuf_read_merge_pages(const uint32_t* space_ids,
@return a lower limit for the combined size in bytes of entries which @return a lower limit for the combined size in bytes of entries which
will be merged from ibuf trees to the pages read will be merged from ibuf trees to the pages read
@retval 0 if ibuf.empty */ @retval 0 if ibuf.empty */
ulint ibuf_contract() ATTRIBUTE_COLD ulint ibuf_contract()
{ {
if (UNIV_UNLIKELY(!ibuf.index)) return 0; if (UNIV_UNLIKELY(!ibuf.index)) return 0;
mtr_t mtr; mtr_t mtr;
...@@ -2461,10 +2435,8 @@ ulint ibuf_contract() ...@@ -2461,10 +2435,8 @@ ulint ibuf_contract()
} }
ulint n_pages = 0; ulint n_pages = 0;
sum_sizes = ibuf_get_merge_page_nos(TRUE, sum_sizes = ibuf_get_merge_page_nos(btr_cur_get_rec(&cur), &mtr,
btr_cur_get_rec(&cur), &mtr, space_ids, page_nos, &n_pages);
space_ids,
page_nos, &n_pages);
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
ibuf_read_merge_pages(space_ids, page_nos, n_pages); ibuf_read_merge_pages(space_ids, page_nos, n_pages);
...@@ -2554,30 +2526,6 @@ ibuf_merge_space( ...@@ -2554,30 +2526,6 @@ ibuf_merge_space(
return(n_pages); return(n_pages);
} }
/*********************************************************************//**
Contract insert buffer trees after insert if they are too big. */
UNIV_INLINE
void
ibuf_contract_after_insert(
/*=======================*/
ulint entry_size) /*!< in: size of a record which was inserted
into an ibuf tree */
{
/* dirty comparison, to avoid contention on ibuf_mutex */
if (ibuf.size < ibuf.max_size) {
return;
}
/* Contract at least entry_size many bytes */
ulint sum_sizes = 0;
ulint size;
do {
size = ibuf_contract();
sum_sizes += size;
} while (size > 0 && sum_sizes < entry_size);
}
/** Determine if a change buffer record has been encountered already. /** Determine if a change buffer record has been encountered already.
@param rec change buffer record in the MySQL 5.5 format @param rec change buffer record in the MySQL 5.5 format
@param hash hash table of encountered records @param hash hash table of encountered records
...@@ -3176,10 +3124,6 @@ ibuf_insert_low( ...@@ -3176,10 +3124,6 @@ ibuf_insert_low(
buf_block_t* block = NULL; buf_block_t* block = NULL;
page_t* root; page_t* root;
dberr_t err; dberr_t err;
ibool do_merge;
uint32_t space_ids[IBUF_MAX_N_PAGES_MERGED];
uint32_t page_nos[IBUF_MAX_N_PAGES_MERGED];
ulint n_stored;
mtr_t mtr; mtr_t mtr;
mtr_t bitmap_mtr; mtr_t bitmap_mtr;
...@@ -3190,28 +3134,9 @@ ibuf_insert_low( ...@@ -3190,28 +3134,9 @@ ibuf_insert_low(
ut_ad(page_id.space() == index->table->space_id); ut_ad(page_id.space() == index->table->space_id);
ut_a(op < IBUF_OP_COUNT); ut_a(op < IBUF_OP_COUNT);
do_merge = FALSE;
/* Perform dirty comparison of ibuf.max_size and ibuf.size to /* Perform dirty comparison of ibuf.max_size and ibuf.size to
reduce ibuf_mutex contention. This should be OK; at worst we reduce ibuf_mutex contention. */
are doing some excessive ibuf_contract() or occasionally if (ibuf.size >= ibuf.max_size) {
skipping an ibuf_contract(). */
const ulint max_size = ibuf.max_size;
if (max_size == 0) {
return(DB_STRONG_FAIL);
}
if (ibuf.size >= max_size + IBUF_CONTRACT_DO_NOT_INSERT) {
/* Insert buffer is now too big, contract it but do not try
to insert */
#ifdef UNIV_IBUF_DEBUG
fputs("Ibuf too big\n", stderr);
#endif
ibuf_contract();
return(DB_STRONG_FAIL); return(DB_STRONG_FAIL);
} }
...@@ -3263,17 +3188,6 @@ ibuf_insert_low( ...@@ -3263,17 +3188,6 @@ ibuf_insert_low(
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
ut_free(pcur.old_rec_buf); ut_free(pcur.old_rec_buf);
mem_heap_free(heap); mem_heap_free(heap);
if (err == DB_SUCCESS && mode == BTR_INSERT_TREE) {
ibuf_contract_after_insert(entry_size);
}
if (do_merge) {
#ifdef UNIV_IBUF_DEBUG
ut_a(n_stored <= IBUF_MAX_N_PAGES_MERGED);
#endif
ibuf_read_merge_pages(space_ids, page_nos, n_stored);
}
return err; return err;
} }
...@@ -3363,15 +3277,6 @@ ibuf_insert_low( ...@@ -3363,15 +3277,6 @@ ibuf_insert_low(
bits)) { bits)) {
/* Release the bitmap page latch early. */ /* Release the bitmap page latch early. */
ibuf_mtr_commit(&bitmap_mtr); ibuf_mtr_commit(&bitmap_mtr);
/* It may not fit */
do_merge = TRUE;
ibuf_get_merge_page_nos(FALSE,
btr_pcur_get_rec(&pcur), &mtr,
space_ids,
page_nos, &n_stored);
goto fail_exit; goto fail_exit;
} }
} }
......
...@@ -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