Merge 10.2 into 10.3

This commit is contained in:
Marko Mäkelä 2018-07-05 17:08:44 +03:00
commit b4c377f215
14 changed files with 167 additions and 50 deletions

View File

@ -3269,6 +3269,64 @@ select 3, 0*(@d:=@d+1) from qn where @d<1
select * from qn;
ERROR 42000: This version of MariaDB doesn't yet support 'mix of ALL and DISTINCT UNION operations in recursive CTE spec'
drop table t1;
#
# MDEV-16629: function with recursive CTE using a base table
#
CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES (0), (1),(2);
WITH recursive cte AS
(SELECT id FROM t1 UNION SELECT 3 FROM cte)
SELECT count(id) FROM cte;
count(id)
4
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH recursive cte AS
(SELECT id FROM t1 UNION SELECT 3 FROM cte)
SELECT count(id) FROM cte
);
SELECT func();
func()
4
DROP FUNCTION func;
DROP TABLE t1;
#
# MDEV-16661: function with recursive CTE using no base tables
# (fixed by the patch for MDEV-16629)
#
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH RECURSIVE cte AS
(SELECT 1 as id UNION SELECT * FROM cte)
SELECT count(id) FROM cte
);
SELECT func();
func()
1
DROP FUNCTION func;
#
# MDEV-15151: function with recursive CTE using no base tables
# (duplicate of MDEV-16661)
#
connection default;
CREATE TABLE t1 (id int KEY);
INSERT INTO t1 VALUES (0), (1),(2);
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH recursive cte AS
(SELECT 1 a UNION SELECT cte.* FROM cte natural join t1)
SELECT * FROM cte limit 1
);
connect con1,localhost,root,,;
SELECT func();
connection default;
KILL QUERY 5;
DROP FUNCTION func;
DROP TABLE t1;
disconnect con1;
# Start of 10.3 tests
#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field

View File

@ -1,3 +1,4 @@
--source include/not_embedded.inc
create table t1 (a int, b varchar(32));
insert into t1 values
(4,'aaaa' ), (7,'bb'), (1,'ccc'), (4,'dd');
@ -2283,6 +2284,77 @@ select * from qn;
drop table t1;
--echo #
--echo # MDEV-16629: function with recursive CTE using a base table
--echo #
CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES (0), (1),(2);
WITH recursive cte AS
(SELECT id FROM t1 UNION SELECT 3 FROM cte)
SELECT count(id) FROM cte;
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH recursive cte AS
(SELECT id FROM t1 UNION SELECT 3 FROM cte)
SELECT count(id) FROM cte
);
SELECT func();
DROP FUNCTION func;
DROP TABLE t1;
--echo #
--echo # MDEV-16661: function with recursive CTE using no base tables
--echo # (fixed by the patch for MDEV-16629)
--echo #
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH RECURSIVE cte AS
(SELECT 1 as id UNION SELECT * FROM cte)
SELECT count(id) FROM cte
);
SELECT func();
DROP FUNCTION func;
--echo #
--echo # MDEV-15151: function with recursive CTE using no base tables
--echo # (duplicate of MDEV-16661)
--echo #
--connection default
CREATE TABLE t1 (id int KEY);
INSERT INTO t1 VALUES (0), (1),(2);
CREATE OR REPLACE FUNCTION func() RETURNS int
RETURN
(
WITH recursive cte AS
(SELECT 1 a UNION SELECT cte.* FROM cte natural join t1)
SELECT * FROM cte limit 1
);
--connect (con1,localhost,root,,)
--let $conid= `SELECT CONNECTION_ID()`
--send SELECT func()
--connection default
--eval KILL QUERY $conid
--source include/restart_mysqld.inc
DROP FUNCTION func;
DROP TABLE t1;
--disconnect con1
--echo # Start of 10.3 tests
--echo #

View File

@ -124,7 +124,7 @@ SELECT * FROM t1;
DROP TABLE t1;
# Test adding virutal index on existing virtual column
# Test adding index on existing virtual column
CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b));
INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4);
@ -156,7 +156,9 @@ INSERT INTO t1(a, b) VALUES (8, 8);
COMMIT;
--echo # wait for purge to process the deleted/updated records.
let $wait_all_purged=1;
--source ../../innodb/include/wait_all_purged.inc
let $wait_all_purged=0;
SET DEBUG_SYNC= 'now SIGNAL purged';

View File

@ -1,12 +1,18 @@
# Wait for everything to be purged.
# The user should have set innodb_purge_rseg_truncate_frequency=1.
if (!$wait_all_purged)
{
let $wait_all_purged= 0;
}
let $remaining_expect= `select concat('InnoDB ',$wait_all_purged)`;
let $wait_counter= 300;
while ($wait_counter)
{
--replace_regex /.*History list length ([0-9]+).*/\1/
let $remaining= `SHOW ENGINE INNODB STATUS`;
if ($remaining == 'InnoDB 0')
if ($remaining == $remaining_expect)
{
let $wait_counter= 0;
}

View File

@ -192,25 +192,9 @@ ROLLBACK;
disconnect stop_purge;
# Wait for purge to empty the table.
# (This is based on wait_all_purged.inc, but there are 2 transactions
# from the pending ALTER TABLE t1 FORCE.)
let $wait_counter= 300;
while ($wait_counter)
{
--replace_regex /.*History list length ([0-9]+).*/\1/
let $remaining= `SHOW ENGINE INNODB STATUS`;
if ($remaining == 'InnoDB 2')
{
let $wait_counter= 0;
}
if ($wait_counter)
{
real_sleep 0.1;
dec $wait_counter;
}
}
echo $remaining transactions not purged;
let $wait_all_purged=2;
--source include/wait_all_purged.inc
let $wait_all_purged=0;
SET DEBUG_SYNC='now SIGNAL logged';
disconnect ddl;

View File

@ -27,6 +27,7 @@
#include "sql_array.h" // Dynamic_array
#include "log_event.h" // Query_log_event
#include "sql_derived.h" // mysql_handle_derived
#include "sql_cte.h"
#include "sql_select.h" // Virtual_tmp_table
#ifdef USE_PRAGMA_IMPLEMENTATION
@ -3313,7 +3314,8 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
#endif
if (open_tables)
res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
res= check_dependencies_in_with_clauses(m_lex->with_clauses_list) ||
instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
if (likely(!res))
{

View File

@ -1307,7 +1307,7 @@ void btr_search_drop_page_hash_when_freed(const page_id_t& page_id)
/* In all our callers, the table handle should
be open, or we should be in the process of
dropping the table (preventing eviction). */
ut_ad(index->table->n_ref_count > 0
ut_ad(index->table->get_ref_count() > 0
|| mutex_own(&dict_sys->mutex));
btr_search_drop_page_hash_index(block);
}

View File

@ -967,7 +967,7 @@ buf_flush_init_for_writing(
}
}
uint32_t checksum= 0;
uint32_t checksum = BUF_NO_CHECKSUM_MAGIC;
switch (srv_checksum_algorithm_t(srv_checksum_algorithm)) {
case SRV_CHECKSUM_ALGORITHM_INNODB:
@ -990,7 +990,6 @@ buf_flush_init_for_writing(
break;
case SRV_CHECKSUM_ALGORITHM_NONE:
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
checksum = BUF_NO_CHECKSUM_MAGIC;
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
checksum);
break;

View File

@ -418,7 +418,7 @@ dict_table_try_drop_aborted(
dict_table_t* table, /*!< in: table, or NULL if it
needs to be looked up again */
table_id_t table_id, /*!< in: table identifier */
ulint ref_count) /*!< in: expected table->n_ref_count */
int32 ref_count) /*!< in: expected table->n_ref_count */
{
trx_t* trx;
@ -1328,7 +1328,7 @@ static
ibool
dict_table_can_be_evicted(
/*======================*/
const dict_table_t* table) /*!< in: table to test */
dict_table_t* table) /*!< in: table to test */
{
ut_ad(mutex_own(&dict_sys->mutex));
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
@ -6872,6 +6872,7 @@ dict_foreign_qualify_index(
}
if (field->col->is_virtual()) {
col_name = "";
for (ulint j = 0; j < table->n_v_def; j++) {
col_name = dict_table_get_v_col_name(table, j);
if (innobase_strcasecmp(field->name,col_name) == 0) {

View File

@ -2971,7 +2971,7 @@ ha_innobase::update_thd(
m_user_thd, thd));
/* The table should have been opened in ha_innobase::open(). */
ut_ad(m_prebuilt->table->n_ref_count > 0);
DBUG_ASSERT(m_prebuilt->table->get_ref_count() > 0);
trx_t* trx = check_trx_exists(thd);
@ -13917,7 +13917,7 @@ ha_innobase::info_low(
m_prebuilt->trx->op_info = "returning various info to MariaDB";
ib_table = m_prebuilt->table;
ut_ad(ib_table->n_ref_count > 0);
DBUG_ASSERT(ib_table->get_ref_count() > 0);
if (flag & HA_STATUS_TIME) {
if (is_analyze || innobase_stats_on_metadata) {

View File

@ -1401,23 +1401,13 @@ dict_table_is_file_per_table(
&& table->space != fil_system.temp_space;
}
/** Get reference count.
@return current value of n_ref_count */
inline
ulint
dict_table_t::get_ref_count() const
{
ut_ad(mutex_own(&dict_sys->mutex));
return(n_ref_count);
}
/** Acquire the table handle. */
inline
void
dict_table_t::acquire()
{
ut_ad(mutex_own(&dict_sys->mutex));
++n_ref_count;
my_atomic_add32_explicit(&n_ref_count, 1, MY_MEMORY_ORDER_RELAXED);
}
/** Release the table handle.
@ -1426,9 +1416,10 @@ inline
bool
dict_table_t::release()
{
ut_ad(mutex_own(&dict_sys->mutex));
ut_ad(n_ref_count > 0);
return !--n_ref_count;
int32 n = my_atomic_add32_explicit(
&n_ref_count, -1, MY_MEMORY_ORDER_RELAXED);
ut_ad(n > 0);
return n == 1;
}
/** Encode the number of columns and number of virtual columns in a

View File

@ -1481,7 +1481,11 @@ struct dict_table_t {
/** Get reference count.
@return current value of n_ref_count */
inline ulint get_ref_count() const;
inline int32 get_ref_count()
{
return my_atomic_load32_explicit(&n_ref_count,
MY_MEMORY_ORDER_RELAXED);
}
/** Acquire the table handle. */
inline void acquire();
@ -1928,13 +1932,11 @@ struct dict_table_t {
It is protected by lock_sys.mutex. */
ulint n_rec_locks;
#ifndef DBUG_ASSERT_EXISTS
private:
#endif
/** Count of how many handles are opened to this table. Dropping of the
table is NOT allowed until this count gets to zero. MySQL does NOT
itself check the number of open handles at DROP. */
ulint n_ref_count;
int32 n_ref_count;
public:
/** List of locks on the table. Protected by lock_sys.mutex. */

View File

@ -1433,7 +1433,7 @@ lock_rec_create_low(
lock_rec_bitmap_reset(lock);
lock_rec_set_nth_bit(lock, heap_no);
index->table->n_rec_locks++;
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
ut_ad(index->table->get_ref_count() > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
if (c_lock && wsrep_on_trx(trx)
@ -3531,7 +3531,7 @@ lock_table_create(
lock->un_member.tab_lock.table = table;
ut_ad(table->n_ref_count > 0 || !table->can_be_evicted);
ut_ad(table->get_ref_count() > 0 || !table->can_be_evicted);
UT_LIST_ADD_LAST(trx->lock.trx_locks, lock);

View File

@ -3863,7 +3863,7 @@ row_ins_step(
/* No-rollback tables should only be written to by a
single thread at a time, but there can be multiple
concurrent readers. We must hold an open table handle. */
DBUG_ASSERT(node->table->n_ref_count > 0);
DBUG_ASSERT(node->table->get_ref_count() > 0);
DBUG_ASSERT(node->ins_type == INS_DIRECT);
/* No-rollback tables can consist only of a single index. */
DBUG_ASSERT(UT_LIST_GET_LEN(node->entry_list) == 1);