Merge 10.2 into 10.3
This commit is contained in:
commit
b50685af82
@ -17,10 +17,15 @@ see the Credits appendix. You can also run 'SHOW authors' to get a
|
|||||||
list of active contributors.
|
list of active contributors.
|
||||||
|
|
||||||
A description of the MariaDB project and a manual can be found at:
|
A description of the MariaDB project and a manual can be found at:
|
||||||
|
|
||||||
https://mariadb.org/
|
https://mariadb.org/
|
||||||
|
|
||||||
https://mariadb.com/kb/en/
|
https://mariadb.com/kb/en/
|
||||||
|
|
||||||
https://mariadb.com/kb/en/mariadb-vs-mysql-features/
|
https://mariadb.com/kb/en/mariadb-vs-mysql-features/
|
||||||
|
|
||||||
https://mariadb.com/kb/en/mariadb-versus-mysql-features/
|
https://mariadb.com/kb/en/mariadb-versus-mysql-features/
|
||||||
|
|
||||||
https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/
|
https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/
|
||||||
|
|
||||||
As MariaDB is a full replacement of MySQL, the MySQL manual at
|
As MariaDB is a full replacement of MySQL, the MySQL manual at
|
||||||
|
@ -1462,3 +1462,19 @@ a b
|
|||||||
4 5
|
4 5
|
||||||
4 3
|
4 3
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-16353: unreferenced CTE specified by query with UNION
|
||||||
|
#
|
||||||
|
with cte as
|
||||||
|
(select 1 union select 2 union select 3)
|
||||||
|
select 1 as f;
|
||||||
|
f
|
||||||
|
1
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (2), (1), (7), (1), (4);
|
||||||
|
with cte as
|
||||||
|
(select * from t1 where a < 2 union select * from t1 where a > 5)
|
||||||
|
select 2 as f;
|
||||||
|
f
|
||||||
|
2
|
||||||
|
drop table t1;
|
||||||
|
@ -1012,3 +1012,21 @@ SELECT a FROM cte;
|
|||||||
WITH cte(a,b) AS (SELECT 4,5 UNION SELECT 4,3) SELECT a,b FROM cte;
|
WITH cte(a,b) AS (SELECT 4,5 UNION SELECT 4,3) SELECT a,b FROM cte;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16353: unreferenced CTE specified by query with UNION
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
with cte as
|
||||||
|
(select 1 union select 2 union select 3)
|
||||||
|
select 1 as f;
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
insert into t1 values (2), (1), (7), (1), (4);
|
||||||
|
|
||||||
|
with cte as
|
||||||
|
(select * from t1 where a < 2 union select * from t1 where a > 5)
|
||||||
|
select 2 as f;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
@ -64,11 +64,19 @@ INSERT INTO t VALUES (18, 1, DEFAULT, 'mm');
|
|||||||
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
INSERT INTO t VALUES (28, 1, DEFAULT, 'mm');
|
||||||
INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
||||||
CREATE INDEX idx_1 on t(c);
|
CREATE INDEX idx_1 on t(c);
|
||||||
SET SESSION debug_dbug="+d,create_index_fail";
|
SET @saved_dbug = @@SESSION.debug_dbug;
|
||||||
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x);
|
SET debug_dbug = '+d,create_index_fail';
|
||||||
|
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x),
|
||||||
|
ADD INDEX idcx (c,x);
|
||||||
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
||||||
SET SESSION debug_dbug="";
|
UPDATE t SET a=a+1;
|
||||||
|
affected rows: 3
|
||||||
|
info: Rows matched: 4 Changed: 3 Warnings: 0
|
||||||
|
ALTER TABLE t ADD INDEX idc(c);
|
||||||
|
ERROR 23000: Duplicate entry '' for key '*UNKNOWN*'
|
||||||
|
SET debug_dbug = @saved_dbug;
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
|
UPDATE t SET b=b-1;
|
||||||
SHOW CREATE TABLE t;
|
SHOW CREATE TABLE t;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t CREATE TABLE `t` (
|
t CREATE TABLE `t` (
|
||||||
|
@ -119,14 +119,23 @@ INSERT INTO t VALUES (null, null, DEFAULT, 'mm');
|
|||||||
|
|
||||||
CREATE INDEX idx_1 on t(c);
|
CREATE INDEX idx_1 on t(c);
|
||||||
|
|
||||||
SET SESSION debug_dbug="+d,create_index_fail";
|
SET @saved_dbug = @@SESSION.debug_dbug;
|
||||||
|
SET debug_dbug = '+d,create_index_fail';
|
||||||
|
|
||||||
--enable_info
|
--enable_info
|
||||||
--error ER_DUP_ENTRY
|
--error ER_DUP_ENTRY
|
||||||
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x);
|
ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x),
|
||||||
SET SESSION debug_dbug="";
|
ADD INDEX idcx (c,x);
|
||||||
|
|
||||||
|
UPDATE t SET a=a+1;
|
||||||
|
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
ALTER TABLE t ADD INDEX idc(c);
|
||||||
|
SET debug_dbug = @saved_dbug;
|
||||||
--disable_info
|
--disable_info
|
||||||
|
|
||||||
|
UPDATE t SET b=b-1;
|
||||||
|
|
||||||
SHOW CREATE TABLE t;
|
SHOW CREATE TABLE t;
|
||||||
|
|
||||||
SELECT c FROM t;
|
SELECT c FROM t;
|
||||||
|
@ -1008,7 +1008,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
|
|||||||
{
|
{
|
||||||
if (with_element)
|
if (with_element)
|
||||||
{
|
{
|
||||||
if (derived_arg->with->rename_columns_of_derived_unit(thd, this))
|
if (with_element->rename_columns_of_derived_unit(thd, this))
|
||||||
goto err;
|
goto err;
|
||||||
if (check_duplicate_names(thd, sl->item_list, 0))
|
if (check_duplicate_names(thd, sl->item_list, 0))
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -2612,37 +2612,7 @@ dict_index_remove_from_cache_low(
|
|||||||
UT_LIST_REMOVE(table->indexes, index);
|
UT_LIST_REMOVE(table->indexes, index);
|
||||||
|
|
||||||
/* Remove the index from affected virtual column index list */
|
/* Remove the index from affected virtual column index list */
|
||||||
if (dict_index_has_virtual(index)) {
|
index->detach_columns();
|
||||||
const dict_col_t* col;
|
|
||||||
const dict_v_col_t* vcol;
|
|
||||||
|
|
||||||
for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
|
|
||||||
col = dict_index_get_nth_col(index, i);
|
|
||||||
if (col->is_virtual()) {
|
|
||||||
vcol = reinterpret_cast<const dict_v_col_t*>(
|
|
||||||
col);
|
|
||||||
|
|
||||||
/* This could be NULL, when we do add virtual
|
|
||||||
column, add index together. We do not need to
|
|
||||||
track this virtual column's index */
|
|
||||||
if (vcol->v_indexes == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dict_v_idx_list::iterator it;
|
|
||||||
|
|
||||||
for (it = vcol->v_indexes->begin();
|
|
||||||
it != vcol->v_indexes->end(); ++it) {
|
|
||||||
dict_v_idx_t v_index = *it;
|
|
||||||
if (v_index.index == index) {
|
|
||||||
vcol->v_indexes->erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dict_mem_index_free(index);
|
dict_mem_index_free(index);
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,6 @@ Smart ALTER TABLE
|
|||||||
#include "ha_innodb.h"
|
#include "ha_innodb.h"
|
||||||
#include "ut0new.h"
|
#include "ut0new.h"
|
||||||
#include "ut0stage.h"
|
#include "ut0stage.h"
|
||||||
#ifdef WITH_WSREP
|
|
||||||
//#include "wsrep_api.h"
|
|
||||||
#include <sql_acl.h> // PROCESS_ACL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN=
|
static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN=
|
||||||
"INPLACE ADD or DROP of virtual columns cannot be "
|
"INPLACE ADD or DROP of virtual columns cannot be "
|
||||||
@ -289,6 +285,16 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
|
|||||||
@return whether the table will be rebuilt */
|
@return whether the table will be rebuilt */
|
||||||
bool need_rebuild () const { return(old_table != new_table); }
|
bool need_rebuild () const { return(old_table != new_table); }
|
||||||
|
|
||||||
|
/** Clear uncommmitted added indexes after a failed operation. */
|
||||||
|
void clear_added_indexes()
|
||||||
|
{
|
||||||
|
for (ulint i = 0; i < num_to_add_index; i++) {
|
||||||
|
if (!add_index[i]->is_committed()) {
|
||||||
|
add_index[i]->detach_columns();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Convert table-rebuilding ALTER to instant ALTER. */
|
/** Convert table-rebuilding ALTER to instant ALTER. */
|
||||||
void prepare_instant()
|
void prepare_instant()
|
||||||
{
|
{
|
||||||
@ -6726,7 +6732,8 @@ check_if_can_drop_indexes:
|
|||||||
for (dict_index_t* index = dict_table_get_first_index(indexed_table);
|
for (dict_index_t* index = dict_table_get_first_index(indexed_table);
|
||||||
index != NULL; index = dict_table_get_next_index(index)) {
|
index != NULL; index = dict_table_get_next_index(index)) {
|
||||||
|
|
||||||
if (!index->to_be_dropped && index->is_corrupted()) {
|
if (!index->to_be_dropped && index->is_committed()
|
||||||
|
&& index->is_corrupted()) {
|
||||||
my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
|
my_error(ER_INDEX_CORRUPT, MYF(0), index->name());
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
@ -7293,6 +7300,7 @@ oom:
|
|||||||
that we hold at most a shared lock on the table. */
|
that we hold at most a shared lock on the table. */
|
||||||
m_prebuilt->trx->error_info = NULL;
|
m_prebuilt->trx->error_info = NULL;
|
||||||
ctx->trx->error_state = DB_SUCCESS;
|
ctx->trx->error_state = DB_SUCCESS;
|
||||||
|
ctx->clear_added_indexes();
|
||||||
|
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
@ -731,13 +731,9 @@ dict_index_is_spatial(
|
|||||||
/*==================*/
|
/*==================*/
|
||||||
const dict_index_t* index) /*!< in: index */
|
const dict_index_t* index) /*!< in: index */
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
/** Check whether the index contains a virtual column.
|
|
||||||
@param[in] index index
|
#define dict_index_has_virtual(index) (index)->has_virtual()
|
||||||
@return nonzero for index on virtual column, zero for other indexes */
|
|
||||||
UNIV_INLINE
|
|
||||||
ulint
|
|
||||||
dict_index_has_virtual(
|
|
||||||
const dict_index_t* index);
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Check whether the index is the insert buffer tree.
|
Check whether the index is the insert buffer tree.
|
||||||
@return nonzero for insert buffer, zero for other indexes */
|
@return nonzero for insert buffer, zero for other indexes */
|
||||||
|
@ -314,20 +314,6 @@ dict_index_is_spatial(
|
|||||||
return ulint(UNIV_EXPECT(index->type & DICT_SPATIAL, 0));
|
return ulint(UNIV_EXPECT(index->type & DICT_SPATIAL, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check whether the index contains a virtual column
|
|
||||||
@param[in] index index
|
|
||||||
@return nonzero for the index has virtual column, zero for other indexes */
|
|
||||||
UNIV_INLINE
|
|
||||||
ulint
|
|
||||||
dict_index_has_virtual(
|
|
||||||
const dict_index_t* index)
|
|
||||||
{
|
|
||||||
ut_ad(index);
|
|
||||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
|
||||||
|
|
||||||
return(index->type & DICT_VIRTUAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Check whether the index is the insert buffer tree.
|
Check whether the index is the insert buffer tree.
|
||||||
@return nonzero for insert buffer, zero for other indexes */
|
@return nonzero for insert buffer, zero for other indexes */
|
||||||
|
@ -588,6 +588,10 @@ struct dict_col_t{
|
|||||||
3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
|
3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
|
||||||
bytes. */
|
bytes. */
|
||||||
|
|
||||||
|
/** Detach the column from an index.
|
||||||
|
@param[in] index index to be detached from */
|
||||||
|
inline void detach(const dict_index_t& index);
|
||||||
|
|
||||||
/** Data for instantly added columns */
|
/** Data for instantly added columns */
|
||||||
struct {
|
struct {
|
||||||
/** original default value of instantly added column */
|
/** original default value of instantly added column */
|
||||||
@ -1045,9 +1049,24 @@ struct dict_index_t{
|
|||||||
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
|
return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether the index includes virtual columns */
|
||||||
|
bool has_virtual() const { return type & DICT_VIRTUAL; }
|
||||||
|
|
||||||
/** @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. */
|
||||||
|
void detach_columns()
|
||||||
|
{
|
||||||
|
if (has_virtual()) {
|
||||||
|
for (unsigned i = 0; i < n_fields; i++) {
|
||||||
|
fields[i].col->detach(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
n_fields = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Determine how many fields of a given prefix can be set NULL.
|
/** Determine how many fields of a given prefix can be set NULL.
|
||||||
@param[in] n_prefix number of fields in the prefix
|
@param[in] n_prefix number of fields in the prefix
|
||||||
@return number of fields 0..n_prefix-1 that can be set NULL */
|
@return number of fields 0..n_prefix-1 that can be set NULL */
|
||||||
@ -1112,6 +1131,26 @@ struct dict_index_t{
|
|||||||
vers_history_row(const rec_t* rec, bool &history_row);
|
vers_history_row(const rec_t* rec, bool &history_row);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Detach a column from an index.
|
||||||
|
@param[in] index index to be detached from */
|
||||||
|
inline void dict_col_t::detach(const dict_index_t& index)
|
||||||
|
{
|
||||||
|
if (!is_virtual()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dict_v_idx_list* v_indexes = reinterpret_cast<const dict_v_col_t*>
|
||||||
|
(this)->v_indexes) {
|
||||||
|
for (dict_v_idx_list::iterator i = v_indexes->begin();
|
||||||
|
i != v_indexes->end(); i++) {
|
||||||
|
if (i->index == &index) {
|
||||||
|
v_indexes->erase(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** The status of online index creation */
|
/** The status of online index creation */
|
||||||
enum online_index_status {
|
enum online_index_status {
|
||||||
/** the index is complete and ready for access */
|
/** the index is complete and ready for access */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
|
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
|
||||||
Copyright (C) 2014, 2017, MariaDB Corporation. All Rights Reserved.
|
Copyright (C) 2014, 2018, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
This program is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free Software
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@ -160,7 +160,7 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false)
|
|||||||
<< "Obtaining redo log encryption key version "
|
<< "Obtaining redo log encryption key version "
|
||||||
<< info->key_version << " failed (" << rc
|
<< info->key_version << " failed (" << rc
|
||||||
<< "). Maybe the key or the required encryption "
|
<< "). Maybe the key or the required encryption "
|
||||||
<< " key management plugin was not found.";
|
"key management plugin was not found.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +280,12 @@ log_crypt_101_read_block(byte* buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (infos_used == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* MariaDB Server 10.1 would use the first key if it fails to
|
||||||
|
find a key for the current checkpoint. */
|
||||||
|
info = infos;
|
||||||
found:
|
found:
|
||||||
byte dst[OS_FILE_LOG_BLOCK_SIZE];
|
byte dst[OS_FILE_LOG_BLOCK_SIZE];
|
||||||
uint dst_len;
|
uint dst_len;
|
||||||
|
@ -858,12 +858,11 @@ recv_find_max_checkpoint_0(ulint* max_field)
|
|||||||
|
|
||||||
/** Determine if a pre-MySQL 5.7.9/MariaDB 10.2.2 redo log is clean.
|
/** Determine if a pre-MySQL 5.7.9/MariaDB 10.2.2 redo log is clean.
|
||||||
@param[in] lsn checkpoint LSN
|
@param[in] lsn checkpoint LSN
|
||||||
|
@param[in] crypt whether the log might be encrypted
|
||||||
@return error code
|
@return error code
|
||||||
@retval DB_SUCCESS if the redo log is clean
|
@retval DB_SUCCESS if the redo log is clean
|
||||||
@retval DB_ERROR if the redo log is corrupted or dirty */
|
@retval DB_ERROR if the redo log is corrupted or dirty */
|
||||||
static
|
static dberr_t recv_log_format_0_recover(lsn_t lsn, bool crypt)
|
||||||
dberr_t
|
|
||||||
recv_log_format_0_recover(lsn_t lsn)
|
|
||||||
{
|
{
|
||||||
log_mutex_enter();
|
log_mutex_enter();
|
||||||
const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn);
|
const lsn_t source_offset = log_sys.log.calc_lsn_offset(lsn);
|
||||||
@ -891,7 +890,13 @@ recv_log_format_0_recover(lsn_t lsn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (log_block_get_data_len(buf)
|
if (log_block_get_data_len(buf)
|
||||||
!= (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
|
== (source_offset & (OS_FILE_LOG_BLOCK_SIZE - 1))) {
|
||||||
|
} else if (crypt) {
|
||||||
|
ib::error() << "Cannot decrypt log for upgrading."
|
||||||
|
" The encrypted log was created"
|
||||||
|
" before MariaDB 10.2.2.";
|
||||||
|
return DB_ERROR;
|
||||||
|
} else {
|
||||||
ib::error() << NO_UPGRADE_RECOVERY_MSG << ".";
|
ib::error() << NO_UPGRADE_RECOVERY_MSG << ".";
|
||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
@ -3153,7 +3158,8 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
|
|||||||
switch (log_sys.log.format) {
|
switch (log_sys.log.format) {
|
||||||
case 0:
|
case 0:
|
||||||
log_mutex_exit();
|
log_mutex_exit();
|
||||||
return(recv_log_format_0_recover(checkpoint_lsn));
|
return recv_log_format_0_recover(checkpoint_lsn,
|
||||||
|
buf[20 + 32 * 9] == 2);
|
||||||
default:
|
default:
|
||||||
if (end_lsn == 0) {
|
if (end_lsn == 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -581,7 +581,7 @@ row_upd_changes_field_size_or_external(
|
|||||||
/* We should ignore virtual field if the index is not
|
/* We should ignore virtual field if the index is not
|
||||||
a virtual index */
|
a virtual index */
|
||||||
if (upd_fld_is_virtual_col(upd_field)
|
if (upd_fld_is_virtual_col(upd_field)
|
||||||
&& dict_index_has_virtual(index) != DICT_VIRTUAL) {
|
&& !index->has_virtual()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user