Commit befb0bed authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.2 into 10.3

parents a9bee988 f458b40f
This diff is collapsed.
......@@ -2424,6 +2424,30 @@ select * from cte1, cte2 where cte1.c1 = 3;
eval $q3;
let $q4=
with recursive
rcte(a) as
(select 1 union select cast(a+1 as unsigned) from rcte where a < 10),
cte1 as
(select count(*) as c1 from rcte,t1 where a between 3 and 5 and id=a-3),
cte2 as
(select count(*) as c2 from rcte,t1 where a between 7 and 8 and id=a-7)
select * from cte2, cte1;
eval $q4;
eval explain extended $q4;
eval prepare stmt from "$q4";
execute stmt;
execute stmt;
drop procedure p;
drop table t2;
create table t2 (c1 int, c2 int);
eval create procedure p() insert into t2 $q4;
call p();
select * from t2;
drop procedure p;
drop table t1,t2;
......@@ -2609,7 +2633,51 @@ eval analyze format=json $q;
drop function f1;
drop table t1,t2;
--echo End of 10.2 tests
--echo #
--echo # MDEV-22748: two materialized CTEs using the same recursive CTE
--echo # (see also test case for MDEV-17024)
--echo #
CREATE TABLE t1 (YEAR int(4), d1 date , d2 date) ;
INSERT INTO t1 VALUES (2018,'2018-01-01','2018-09-20');
CREATE TABLE t2 (id int, tm date);
INSERT INTO t2 VALUES (1,'2018-08-30'),(2,'2018-08-30'),(3,'2018-08-30');
CREATE TABLE t3 (id int, tm date);
INSERT INTO t3 VALUES (1,'2018-08-30'),(2,'2018-08-30');
let $q=
WITH RECURSIVE
cte AS
(SELECT YEAR(t1.d1) AS YEAR, t1.d1 AS st, t1.d1 + INTERVAL 1 MONTH AS fn
FROM t1
UNION ALL
SELECT YEAR(cte.st + INTERVAL 1 MONTH),
cte.st + INTERVAL 1 MONTH, t1.d2 + INTERVAL 1 DAY
FROM cte JOIN t1
WHERE cte.st + INTERVAL 1 MONTH < t1.d2 ),
cte2 AS (SELECT YEAR, COUNT(*)
FROM cte JOIN t2 ON t2.tm BETWEEN cte.st AND cte.fn),
cte3 AS (SELECT YEAR, COUNT(*)
FROM cte JOIN t3 ON t3.tm BETWEEN cte.st AND cte.fn)
SELECT t1.* FROM t1 JOIN cte2 USING (YEAR) JOIN cte3 USING (YEAR);
eval $q;
eval EXPLAIN EXTENDED $q;
eval PREPARE stmt FROM "$q";
EXECUTE stmt;
EXECUTE stmt;
CREATE TABLE t4 (YEAR int(4), d1 date , d2 date);
eval CREATE PROCEDURE p() INSERT INTO t4 $q;
CALL p();
SELECT * FROM t4;
DROP PROCEDURE p;
DROP TABLE t1,t2,t3,t4;
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
......
......@@ -1114,6 +1114,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
{
derived= with_elem->spec;
if (derived != select_lex->master_unit() &&
!with_elem->is_recursive &&
!is_with_table_recursive_reference())
{
derived->move_as_slave(select_lex);
......
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates.
Copyright (c) 2010, 2015, MariaDB
Copyright (c) 2010, 2020, MariaDB
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
......@@ -1110,7 +1110,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
DBUG_ASSERT(derived->table && derived->table->is_created());
select_unit *derived_result= derived->derived_result;
SELECT_LEX *save_current_select= lex->current_select;
bool derived_recursive_is_filled= false;
if (unit->executed && !derived_is_recursive &&
(unit->uncacheable & UNCACHEABLE_DEPENDENT))
......@@ -1139,7 +1138,6 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{
/* In this case all iteration are performed */
res= derived->fill_recursive(thd);
derived_recursive_is_filled= true;
}
}
else if (unit->is_unit_op())
......@@ -1195,8 +1193,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
}
}
err:
if (res || (!lex->describe && !unit->uncacheable &&
(!derived_is_recursive || derived_recursive_is_filled)))
if (res || (!derived_is_recursive && !lex->describe && !unit->uncacheable))
unit->cleanup();
lex->current_select= save_current_select;
......
......@@ -2030,6 +2030,19 @@ bool st_select_lex::cleanup()
delete join;
join= 0;
}
for (TABLE_LIST *tbl= get_table_list(); tbl; tbl= tbl->next_local)
{
if (tbl->is_recursive_with_table() &&
!tbl->is_with_table_recursive_reference())
{
/*
If query is killed before open_and_process_table() for tbl
is called then 'with' is already set, but 'derived' is not.
*/
st_select_lex_unit *unit= tbl->with->spec;
error|= (bool) error | (uint) unit->cleanup();
}
}
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
lex_unit= lex_unit->next_unit())
{
......
......@@ -2678,7 +2678,7 @@ srv_purge_coordinator_suspend(
rw_lock_x_lock(&purge_sys.latch);
stop = srv_shutdown_state == SRV_SHUTDOWN_NONE
stop = srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& purge_sys.paused_latched();
if (!stop) {
......@@ -2743,7 +2743,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
/* If there are no records to purge or the last
purge didn't purge any records then wait for activity. */
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
if (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_undo_sources
&& (n_total_purged == 0 || purge_sys.paused())) {
......
......@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -2426,7 +2426,7 @@ dberr_t srv_start(bool create_new_db)
thread_started[5 + i + SRV_MAX_N_IO_THREADS] = true;
}
while (srv_shutdown_state == SRV_SHUTDOWN_NONE
while (srv_shutdown_state <= SRV_SHUTDOWN_INITIATED
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND
&& !purge_sys.enabled()) {
ib::info() << "Waiting for purge to start";
......
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