Merge 10.3 into 10.4

This commit is contained in:
Marko Mäkelä 2020-05-19 21:18:15 +03:00
commit 2bf93a8fd6
17 changed files with 278 additions and 173 deletions

View File

@ -5723,7 +5723,7 @@ static bool xtrabackup_prepare_func(char** argv)
error_cleanup: error_cleanup:
xb_filters_free(); xb_filters_free();
return ok; return ok && !ib::error::was_logged();
} }
/************************************************************************** /**************************************************************************

View File

@ -5472,6 +5472,23 @@ drop procedure p;
drop view v1; drop view v1;
drop table t1; drop table t1;
# #
# MDEV-22591 Debug build crashes on EXECUTE IMMEDIATE '... WHERE ?' USING IGNORE
#
CREATE TABLE t1 (a INT);
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING IGNORE;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING IGNORE;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING 0;
a
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING 0;
a
DROP TABLE t1;
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING 0;
Database
#
# End of 10.2 tests # End of 10.2 tests
# #
# #

View File

@ -4914,6 +4914,23 @@ drop procedure p;
drop view v1; drop view v1;
drop table t1; drop table t1;
--echo #
--echo # MDEV-22591 Debug build crashes on EXECUTE IMMEDIATE '... WHERE ?' USING IGNORE
--echo #
CREATE TABLE t1 (a INT);
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING IGNORE;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING IGNORE;
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE ?' USING 0;
EXECUTE IMMEDIATE 'SELECT * FROM t1 HAVING ?' USING 0;
DROP TABLE t1;
--error ER_INVALID_DEFAULT_PARAM
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING DEFAULT;
EXECUTE IMMEDIATE 'SHOW DATABASES WHERE ?' USING 0;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #

View File

@ -0,0 +1,20 @@
CREATE DATABASE test1;
CREATE PROCEDURE test1.sp3() BEGIN END;
SHOW PROCEDURE STATUS;
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
mtr add_suppression PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mtr check_testcase PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mtr check_warnings PROCEDURE root@localhost # # DEFINER utf8 utf8_general_ci latin1_swedish_ci
mysql AddGeometryColumn PROCEDURE mariadb.sys@localhost # # INVOKER latin1 latin1_swedish_ci latin1_swedish_ci
mysql DropGeometryColumn PROCEDURE mariadb.sys@localhost # # INVOKER latin1 latin1_swedish_ci latin1_swedish_ci
test sp2 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
test1 sp1 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
test1 sp3 PROCEDURE root@localhost # # DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
DROP PROCEDURE sp2;
DROP DATABASE test1;
select count(*) from mysql.event;
count(*)
416
flush tables;
show events;
truncate table mysql.event;

37
mysql-test/main/sp2.test Normal file

File diff suppressed because one or more lines are too long

View File

@ -20,5 +20,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SET @binlog_fragment_0='012345'; SET @binlog_fragment_0='012345';
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist; BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
ERROR 42000: Incorrect argument type to variable 'binlog_fragment_not_exist' ERROR 42000: Incorrect argument type to variable 'binlog_fragment_not_exist'
SET @a= '42';
BINLOG @a, @a;
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
# Cleanup # Cleanup
DROP TABLE t; DROP TABLE t;

View File

@ -41,6 +41,11 @@ SET @binlog_fragment_0='012345';
--error ER_WRONG_TYPE_FOR_VAR --error ER_WRONG_TYPE_FOR_VAR
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist; BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
# MDEV-22520
SET @a= '42';
--error ER_SYNTAX_ERROR
BINLOG @a, @a;
--echo # Cleanup --echo # Cleanup
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql --remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
DROP TABLE t; DROP TABLE t;

View File

@ -158,8 +158,9 @@ int binlog_defragment(THD *thd)
memcpy(const_cast<char*>(thd->lex->comment.str) + gathered_length, entry[k]->value, memcpy(const_cast<char*>(thd->lex->comment.str) + gathered_length, entry[k]->value,
entry[k]->length); entry[k]->length);
gathered_length += entry[k]->length; gathered_length += entry[k]->length;
update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
} }
for (uint k=0; k < 2; k++)
update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
DBUG_ASSERT(gathered_length == thd->lex->comment.length); DBUG_ASSERT(gathered_length == thd->lex->comment.length);

View File

@ -1970,7 +1970,9 @@ dict_index_remove_from_cache_low(
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
ut_ad(mutex_own(&dict_sys.mutex)); ut_ad(mutex_own(&dict_sys.mutex));
ut_ad(table->id); ut_ad(table->id);
#ifdef BTR_CUR_HASH_ADAPT
ut_ad(!index->freed()); ut_ad(!index->freed());
#endif /* BTR_CUR_HASH_ADAPT */
/* No need to acquire the dict_index_t::lock here because /* No need to acquire the dict_index_t::lock here because
there can't be any active operations on this index (or table). */ there can't be any active operations on this index (or table). */

View File

@ -1059,12 +1059,8 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
/** Clear uncommmitted added indexes after a failed operation. */ /** Clear uncommmitted added indexes after a failed operation. */
void clear_added_indexes() void clear_added_indexes()
{ {
for (ulint i = 0; i < num_to_add_index; i++) { for (ulint i= 0; i < num_to_add_index; i++)
if (!add_index[i]->is_committed()) { add_index[i]->detach_columns(true);
add_index[i]->detach_columns();
add_index[i]->n_fields = 0;
}
}
} }
/** Convert table-rebuilding ALTER to instant ALTER. */ /** Convert table-rebuilding ALTER to instant ALTER. */

View File

@ -578,21 +578,22 @@ private:
static const unsigned DROPPED = 1023; static const unsigned DROPPED = 1023;
public: public:
/** Detach the column from an index. /** Detach a virtual column from an index.
@param[in] index index to be detached from */ @param index being-freed index */
inline void detach(const dict_index_t& index); inline void detach(const dict_index_t &index);
/** Data for instantly added columns */ /** Data for instantly added columns */
struct def_t { struct def_t
{
/** original default value of instantly added column */ /** original default value of instantly added column */
const void* data; const void *data;
/** len of data, or UNIV_SQL_DEFAULT if unavailable */ /** len of data, or UNIV_SQL_DEFAULT if unavailable */
ulint len; ulint len;
} def_val; } def_val;
/** Retrieve the column name. /** Retrieve the column name.
@param[in] table the table of this column */ @param table the table of this column */
const char* name(const dict_table_t& table) const; const char *name(const dict_table_t &table) const;
/** @return whether this is a virtual column */ /** @return whether this is a virtual column */
bool is_virtual() const { return prtype & DATA_VIRTUAL; } bool is_virtual() const { return prtype & DATA_VIRTUAL; }
@ -629,49 +630,50 @@ public:
/** Flag the column instantly dropped */ /** Flag the column instantly dropped */
void set_dropped() { ind = DROPPED; } void set_dropped() { ind = DROPPED; }
/** Flag the column instantly dropped. /** Flag the column instantly dropped.
@param[in] not_null whether the column was NOT NULL @param not_null whether the column was NOT NULL
@param[in] len2 whether the length exceeds 255 bytes @param len2 whether the length exceeds 255 bytes
@param[in] fixed_len the fixed length in bytes, or 0 */ @param fixed_len the fixed length in bytes, or 0 */
void set_dropped(bool not_null, bool len2, unsigned fixed) void set_dropped(bool not_null, bool len2, unsigned fixed)
{ {
DBUG_ASSERT(!len2 || !fixed); DBUG_ASSERT(!len2 || !fixed);
prtype = not_null prtype= not_null ? DATA_NOT_NULL | DATA_BINARY_TYPE : DATA_BINARY_TYPE;
? DATA_NOT_NULL | DATA_BINARY_TYPE if (fixed)
: DATA_BINARY_TYPE; {
if (fixed) { mtype= DATA_FIXBINARY;
mtype = DATA_FIXBINARY; len= fixed;
len = fixed;
} else {
mtype = DATA_BINARY;
len = len2 ? 65535 : 255;
} }
mbminlen = mbmaxlen = 0; else
ind = DROPPED; {
ord_part = 0; mtype= DATA_BINARY;
max_prefix = 0; len= len2 ? 65535 : 255;
}
mbminlen= mbmaxlen= 0;
ind= DROPPED;
ord_part= 0;
max_prefix= 0;
} }
/** @return whether the column was instantly dropped */ /** @return whether the column was instantly dropped */
bool is_dropped() const { return ind == DROPPED; } bool is_dropped() const { return ind == DROPPED; }
/** @return whether the column was instantly dropped /** @return whether the column was instantly dropped
@param[in] index the clustered index */ @param index the clustered index */
inline bool is_dropped(const dict_index_t& index) const; inline bool is_dropped(const dict_index_t &index) const;
/** Get the default value of an instantly-added column. /** Get the default value of an instantly-added column.
@param[out] len value length (in bytes), or UNIV_SQL_NULL @param[out] len value length (in bytes), or UNIV_SQL_NULL
@return default value @return default value
@retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */ @retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
const byte* instant_value(ulint* len) const const byte *instant_value(ulint *len) const
{ {
DBUG_ASSERT(is_added()); DBUG_ASSERT(is_added());
*len = def_val.len; *len= def_val.len;
return static_cast<const byte*>(def_val.data); return static_cast<const byte*>(def_val.data);
} }
/** Remove the 'instant ADD' status of the column */ /** Remove the 'instant ADD' status of the column */
void clear_instant() void clear_instant()
{ {
def_val.len = UNIV_SQL_DEFAULT; def_val.len= UNIV_SQL_DEFAULT;
def_val.data = NULL; def_val.data= NULL;
} }
/** @return whether two columns have compatible data type encoding */ /** @return whether two columns have compatible data type encoding */
@ -720,22 +722,19 @@ public:
/** Determine if the columns have the same format /** Determine if the columns have the same format
except for is_nullable() and is_versioned(). except for is_nullable() and is_versioned().
@param[in] other column to compare to @param other column to compare to
@return whether the columns have the same format */ @return whether the columns have the same format */
bool same_format(const dict_col_t& other) const bool same_format(const dict_col_t &other) const
{ {
return same_type(other) return same_type(other) && len >= other.len &&
&& len >= other.len mbminlen == other.mbminlen && mbmaxlen == other.mbmaxlen &&
&& mbminlen == other.mbminlen !((prtype ^ other.prtype) & ~(DATA_NOT_NULL | DATA_VERSIONED |
&& mbmaxlen == other.mbmaxlen CHAR_COLL_MASK << 16 |
&& !((prtype ^ other.prtype) DATA_LONG_TRUE_VARCHAR));
& ~(DATA_NOT_NULL | DATA_VERSIONED
| CHAR_COLL_MASK << 16
| DATA_LONG_TRUE_VARCHAR));
} }
/** @return whether the column values are comparable by memcmp() */ /** @return whether the column values are comparable by memcmp() */
inline bool is_binary() const { return prtype & DATA_BINARY_TYPE; } bool is_binary() const { return prtype & DATA_BINARY_TYPE; }
}; };
/** Index information put in a list of virtual column structure. Index /** Index information put in a list of virtual column structure. Index
@ -774,25 +773,28 @@ struct dict_v_col_t{
v_indexes; v_indexes;
/** Detach the column from an index. /** Detach the column from an index.
@param[in] index index to be detached from */ @param index index to be detached from */
void detach(const dict_index_t& index) void detach(const dict_index_t &index)
{ {
if (!n_v_indexes) return; if (!n_v_indexes) return;
auto i = v_indexes.before_begin(); auto i= v_indexes.before_begin();
ut_d(unsigned n = 0); ut_d(unsigned n= 0);
do { do {
auto prev = i++; auto prev = i++;
if (i == v_indexes.end()) { if (i == v_indexes.end())
{
ut_ad(n == n_v_indexes); ut_ad(n == n_v_indexes);
return; return;
} }
ut_ad(++n <= n_v_indexes); ut_ad(++n <= n_v_indexes);
if (i->index == &index) { if (i->index == &index)
{
v_indexes.erase_after(prev); v_indexes.erase_after(prev);
n_v_indexes--; n_v_indexes--;
return; return;
} }
} while (i != v_indexes.end()); }
while (i != v_indexes.end());
} }
}; };
@ -1197,13 +1199,20 @@ public:
/** @return whether the index is corrupted */ /** @return whether the index is corrupted */
inline bool is_corrupted() const; inline bool is_corrupted() const;
/** Detach the columns from the index that is to be freed. */ /** Detach the virtual columns from the index that is to be removed.
void detach_columns() @param whether to reset fields[].col */
void detach_columns(bool clear= false)
{ {
if (has_virtual()) { if (!has_virtual())
for (unsigned i = 0; i < n_fields; i++) { return;
fields[i].col->detach(*this); for (unsigned i= 0; i < n_fields; i++)
} {
dict_col_t* col= fields[i].col;
if (!col || !col->is_virtual())
continue;
col->detach(*this);
if (clear)
fields[i].col= nullptr;
} }
} }
@ -1351,13 +1360,12 @@ public:
inline record_size_info_t record_size_info() const; inline record_size_info_t record_size_info() const;
}; };
/** Detach a column from an index. /** Detach a virtual column from an index.
@param[in] index index to be detached from */ @param index being-freed index */
inline void dict_col_t::detach(const dict_index_t& index) inline void dict_col_t::detach(const dict_index_t &index)
{ {
if (is_virtual()) { if (is_virtual())
reinterpret_cast<dict_v_col_t*>(this)->detach(index); reinterpret_cast<dict_v_col_t*>(this)->detach(index);
}
} }
/** The status of online index creation */ /** The status of online index creation */

View File

@ -411,6 +411,14 @@ class error : public logger {
public: public:
ATTRIBUTE_COLD ATTRIBUTE_COLD
~error(); ~error();
/** Indicates that error::~error() was invoked. Can be used to
determine if error messages were logged during innodb code execution.
@return true if there were error messages, false otherwise. */
static bool was_logged() { return logged; }
private:
/** true if error::~error() was invoked, false otherwise */
static bool logged;
}; };
/** The class fatal is used to emit an error message and stop the server /** The class fatal is used to emit an error message and stop the server

View File

@ -6314,7 +6314,7 @@ static my_bool lock_table_locks_lookup(rw_trx_hash_element_t *element,
ut_ad(lock->trx == element->trx); ut_ad(lock->trx == element->trx);
if (lock_get_type_low(lock) == LOCK_REC) if (lock_get_type_low(lock) == LOCK_REC)
{ {
ut_ad(!dict_index_is_online_ddl(lock->index) || ut_ad(lock->index->online_status != ONLINE_INDEX_CREATION ||
lock->index->is_primary()); lock->index->is_primary());
ut_ad(lock->index->table != table); ut_ad(lock->index->table != table);
} }

View File

@ -2121,14 +2121,14 @@ AIO::linux_create_io_ctx(
} }
/* Have tried enough. Better call it a day. */ /* Have tried enough. Better call it a day. */
ib::error() ib::warn()
<< "io_setup() failed with EAGAIN after " << "io_setup() failed with EAGAIN after "
<< OS_AIO_IO_SETUP_RETRY_ATTEMPTS << OS_AIO_IO_SETUP_RETRY_ATTEMPTS
<< " attempts."; << " attempts.";
break; break;
case -ENOSYS: case -ENOSYS:
ib::error() ib::warn()
<< "Linux Native AIO interface" << "Linux Native AIO interface"
" is not supported on this platform. Please" " is not supported on this platform. Please"
" check your OS documentation and install" " check your OS documentation and install"
@ -2137,7 +2137,7 @@ AIO::linux_create_io_ctx(
break; break;
default: default:
ib::error() ib::warn()
<< "Linux Native AIO setup" << "Linux Native AIO setup"
<< " returned following error[" << " returned following error["
<< ret << "]"; << ret << "]";

View File

@ -1290,10 +1290,6 @@ void
row_sel_open_pcur( row_sel_open_pcur(
/*==============*/ /*==============*/
plan_t* plan, /*!< in: table plan */ plan_t* plan, /*!< in: table plan */
#ifdef BTR_CUR_HASH_ADAPT
rw_lock_t* ahi_latch,
/*!< in: the adaptive hash index latch */
#endif /* BTR_CUR_HASH_ADAPT */
mtr_t* mtr) /*!< in/out: mini-transaction */ mtr_t* mtr) /*!< in/out: mini-transaction */
{ {
dict_index_t* index; dict_index_t* index;
@ -1337,7 +1333,7 @@ row_sel_open_pcur(
btr_pcur_open_with_no_init(index, plan->tuple, plan->mode, btr_pcur_open_with_no_init(index, plan->tuple, plan->mode,
BTR_SEARCH_LEAF, &plan->pcur, BTR_SEARCH_LEAF, &plan->pcur,
ahi_latch, mtr); NULL, mtr);
} else { } else {
/* Open the cursor to the start or the end of the index /* Open the cursor to the start or the end of the index
(FALSE: no init) */ (FALSE: no init) */
@ -1482,16 +1478,12 @@ row_sel_try_search_shortcut(
ut_ad(plan->unique_search); ut_ad(plan->unique_search);
ut_ad(!plan->must_get_clust); ut_ad(!plan->must_get_clust);
rw_lock_t* ahi_latch = btr_get_search_latch(index); row_sel_open_pcur(plan, mtr);
rw_lock_s_lock(ahi_latch);
row_sel_open_pcur(plan, ahi_latch, mtr);
const rec_t* rec = btr_pcur_get_rec(&(plan->pcur)); const rec_t* rec = btr_pcur_get_rec(&(plan->pcur));
if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, *index)) { if (!page_rec_is_user_rec(rec) || rec_is_metadata(rec, *index)) {
retry: retry:
rw_lock_s_unlock(ahi_latch);
return(SEL_RETRY); return(SEL_RETRY);
} }
@ -1503,7 +1495,6 @@ retry:
if (btr_pcur_get_up_match(&(plan->pcur)) < plan->n_exact_match) { if (btr_pcur_get_up_match(&(plan->pcur)) < plan->n_exact_match) {
exhausted: exhausted:
rw_lock_s_unlock(ahi_latch);
return(SEL_EXHAUSTED); return(SEL_EXHAUSTED);
} }
@ -1549,7 +1540,6 @@ exhausted:
ut_ad(plan->pcur.latch_mode == BTR_SEARCH_LEAF); ut_ad(plan->pcur.latch_mode == BTR_SEARCH_LEAF);
plan->n_rows_fetched++; plan->n_rows_fetched++;
rw_lock_s_unlock(ahi_latch);
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
@ -1671,11 +1661,7 @@ table_loop:
if (!plan->pcur_is_open) { if (!plan->pcur_is_open) {
/* Evaluate the expressions to build the search tuple and /* Evaluate the expressions to build the search tuple and
open the cursor */ open the cursor */
row_sel_open_pcur(plan, row_sel_open_pcur(plan, &mtr);
#ifdef BTR_CUR_HASH_ADAPT
NULL,
#endif /* BTR_CUR_HASH_ADAPT */
&mtr);
cursor_just_opened = TRUE; cursor_just_opened = TRUE;

View File

@ -576,9 +576,13 @@ warn::~warn()
sql_print_warning("InnoDB: %s", m_oss.str().c_str()); sql_print_warning("InnoDB: %s", m_oss.str().c_str());
} }
/** true if error::~error() was invoked, false otherwise */
bool error::logged;
error::~error() error::~error()
{ {
sql_print_error("InnoDB: %s", m_oss.str().c_str()); sql_print_error("InnoDB: %s", m_oss.str().c_str());
logged = true;
} }
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -1288,6 +1288,7 @@ static my_bool allocate_head(MARIA_FILE_BITMAP *bitmap, uint size,
uint byte= 6 * (last_insert_page / 16); uint byte= 6 * (last_insert_page / 16);
first_pattern= last_insert_page % 16; first_pattern= last_insert_page % 16;
data= bitmap->map+byte; data= bitmap->map+byte;
first_found= 0; /* Don't update full_head_size */
DBUG_ASSERT(data <= end); DBUG_ASSERT(data <= end);
} }
else else