Merge 10.2 into 10.3
This commit is contained in:
commit
b4c377f215
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user