Skip to content

Commit 5eb76eb

Browse files
author
Daniel Blanchard
committed
Merge branch 'mysql-8.0' into mysql-8.4
Change-Id: Idefd2013bc21c2481db02f2ca04cc80de6f1956a
2 parents da1b69d + 920f373 commit 5eb76eb

10 files changed

+100
-39
lines changed

mysql-test/r/ps_ddl.result

+20-20
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,7 @@ alter table t1 drop column b;
13321332
execute stmt;
13331333
alter table t1 drop column b;
13341334
execute stmt;
1335-
call p_verify_reprepare_count(0);
1335+
call p_verify_reprepare_count(3);
13361336
SUCCESS
13371337

13381338
drop table t1;
@@ -1818,7 +1818,7 @@ drop table t2;
18181818
execute stmt;
18191819
drop table t2;
18201820
execute stmt;
1821-
call p_verify_reprepare_count(0);
1821+
call p_verify_reprepare_count(2);
18221822
SUCCESS
18231823

18241824
execute stmt;
@@ -1828,13 +1828,13 @@ SUCCESS
18281828

18291829
execute stmt;
18301830
ERROR 42S01: Table 't2' already exists
1831-
call p_verify_reprepare_count(0);
1831+
call p_verify_reprepare_count(1);
18321832
SUCCESS
18331833

18341834
drop table t2;
18351835
create temporary table t2 (a int);
18361836
execute stmt;
1837-
call p_verify_reprepare_count(0);
1837+
call p_verify_reprepare_count(1);
18381838
SUCCESS
18391839

18401840
execute stmt;
@@ -1845,12 +1845,12 @@ SUCCESS
18451845
drop temporary table t2;
18461846
execute stmt;
18471847
ERROR 42S01: Table 't2' already exists
1848-
call p_verify_reprepare_count(0);
1848+
call p_verify_reprepare_count(1);
18491849
SUCCESS
18501850

18511851
drop table t2;
18521852
execute stmt;
1853-
call p_verify_reprepare_count(0);
1853+
call p_verify_reprepare_count(1);
18541854
SUCCESS
18551855

18561856
drop table t2;
@@ -1862,7 +1862,7 @@ SUCCESS
18621862

18631863
execute stmt;
18641864
Got one of the listed errors
1865-
call p_verify_reprepare_count(0);
1865+
call p_verify_reprepare_count(1);
18661866
SUCCESS
18671867

18681868
drop view t2;
@@ -1876,7 +1876,7 @@ select * from t2;
18761876
x
18771877
drop table t2;
18781878
execute stmt;
1879-
call p_verify_reprepare_count(0);
1879+
call p_verify_reprepare_count(1);
18801880
SUCCESS
18811881

18821882
drop table t2;
@@ -1889,7 +1889,7 @@ select * from t2;
18891889
x y
18901890
drop table t2;
18911891
execute stmt;
1892-
call p_verify_reprepare_count(0);
1892+
call p_verify_reprepare_count(1);
18931893
SUCCESS
18941894

18951895
drop table t1;
@@ -1900,7 +1900,7 @@ prepare stmt from "create temporary table if not exists t2 as select * from t1";
19001900
execute stmt;
19011901
drop table t2;
19021902
execute stmt;
1903-
call p_verify_reprepare_count(0);
1903+
call p_verify_reprepare_count(1);
19041904
SUCCESS
19051905

19061906
execute stmt;
@@ -1915,7 +1915,7 @@ a
19151915
execute stmt;
19161916
Warnings:
19171917
Note 1050 Table 't2' already exists
1918-
call p_verify_reprepare_count(0);
1918+
call p_verify_reprepare_count(1);
19191919
SUCCESS
19201920

19211921
select * from t2;
@@ -1942,7 +1942,7 @@ SUCCESS
19421942
execute stmt;
19431943
Warnings:
19441944
Note 1050 Table 't2' already exists
1945-
call p_verify_reprepare_count(0);
1945+
call p_verify_reprepare_count(1);
19461946
SUCCESS
19471947

19481948
drop table t1;
@@ -1957,19 +1957,19 @@ SUCCESS
19571957

19581958
drop table t2;
19591959
execute stmt;
1960-
call p_verify_reprepare_count(0);
1960+
call p_verify_reprepare_count(1);
19611961
SUCCESS
19621962

19631963
drop table t2;
19641964
drop table t1;
19651965
execute stmt;
19661966
ERROR 42S02: Table 'test.t1' doesn't exist
1967-
call p_verify_reprepare_count(0);
1967+
call p_verify_reprepare_count(1);
19681968
SUCCESS
19691969

19701970
execute stmt;
19711971
ERROR 42S02: Table 'test.t1' doesn't exist
1972-
call p_verify_reprepare_count(0);
1972+
call p_verify_reprepare_count(1);
19731973
SUCCESS
19741974

19751975
create table t1 (x char(17));
@@ -1979,7 +1979,7 @@ SUCCESS
19791979

19801980
drop table t2;
19811981
execute stmt;
1982-
call p_verify_reprepare_count(0);
1982+
call p_verify_reprepare_count(1);
19831983
SUCCESS
19841984

19851985
drop table t2;
@@ -1992,7 +1992,7 @@ select * from t2;
19921992
x y
19931993
drop table t2;
19941994
execute stmt;
1995-
call p_verify_reprepare_count(0);
1995+
call p_verify_reprepare_count(1);
19961996
SUCCESS
19971997

19981998
drop table t1;
@@ -2362,9 +2362,9 @@ drop table t1;
23622362
deallocate prepare stmt;
23632363
# Intermediate result: number of reprepares matches the number
23642364
# of tests
2365-
call p_verify_reprepare_count(17);
2366-
ERROR
2367-
Expected: 17, actual: 18
2365+
call p_verify_reprepare_count(18);
2366+
SUCCESS
2367+
23682368
#
23692369
# SQLCOM_ALTER_VIEW
23702370
#

mysql-test/t/ps_ddl.test

+18-18
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ execute stmt;
10841084

10851085
alter table t1 drop column b;
10861086
execute stmt;
1087-
call p_verify_reprepare_count(0);
1087+
call p_verify_reprepare_count(3);
10881088

10891089
drop table t1;
10901090

@@ -1526,30 +1526,30 @@ drop table t2;
15261526
execute stmt;
15271527
drop table t2;
15281528
execute stmt;
1529-
call p_verify_reprepare_count(0);
1529+
call p_verify_reprepare_count(2);
15301530
# Base table with name of table to be created exists
15311531
--error ER_TABLE_EXISTS_ERROR
15321532
execute stmt;
15331533
call p_verify_reprepare_count(1);
15341534
--error ER_TABLE_EXISTS_ERROR
15351535
execute stmt;
1536-
call p_verify_reprepare_count(0);
1536+
call p_verify_reprepare_count(1);
15371537
drop table t2;
15381538
# Temporary table with name of table to be created exists
15391539
create temporary table t2 (a int);
15401540
# Temporary table and base table are not in the same name space.
15411541
execute stmt;
1542-
call p_verify_reprepare_count(0);
1542+
call p_verify_reprepare_count(1);
15431543
--error ER_TABLE_EXISTS_ERROR
15441544
execute stmt;
15451545
call p_verify_reprepare_count(1);
15461546
drop temporary table t2;
15471547
--error ER_TABLE_EXISTS_ERROR
15481548
execute stmt;
1549-
call p_verify_reprepare_count(0);
1549+
call p_verify_reprepare_count(1);
15501550
drop table t2;
15511551
execute stmt;
1552-
call p_verify_reprepare_count(0);
1552+
call p_verify_reprepare_count(1);
15531553
drop table t2;
15541554
# View with name of table to be created exists
15551555
# Attention:
@@ -1564,7 +1564,7 @@ execute stmt;
15641564
call p_verify_reprepare_count(1);
15651565
--error ER_TABLE_EXISTS_ERROR,9999
15661566
execute stmt;
1567-
call p_verify_reprepare_count(0);
1567+
call p_verify_reprepare_count(1);
15681568
drop view t2;
15691569
drop table t1;
15701570
# Table to be used recreated (drop,create) with different layout
@@ -1574,7 +1574,7 @@ call p_verify_reprepare_count(1);
15741574
select * from t2;
15751575
drop table t2;
15761576
execute stmt;
1577-
call p_verify_reprepare_count(0);
1577+
call p_verify_reprepare_count(1);
15781578
drop table t2;
15791579
# Table to be used has a modified (alter table) layout
15801580
alter table t1 add column y decimal(10,3);
@@ -1583,7 +1583,7 @@ call p_verify_reprepare_count(1);
15831583
select * from t2;
15841584
drop table t2;
15851585
execute stmt;
1586-
call p_verify_reprepare_count(0);
1586+
call p_verify_reprepare_count(1);
15871587
drop table t1;
15881588
deallocate prepare stmt;
15891589
create table t1 (a int);
@@ -1592,12 +1592,12 @@ prepare stmt from "create temporary table if not exists t2 as select * from t1";
15921592
execute stmt;
15931593
drop table t2;
15941594
execute stmt;
1595-
call p_verify_reprepare_count(0);
1595+
call p_verify_reprepare_count(1);
15961596
execute stmt;
15971597
call p_verify_reprepare_count(1);
15981598
select * from t2;
15991599
execute stmt;
1600-
call p_verify_reprepare_count(0);
1600+
call p_verify_reprepare_count(1);
16011601
select * from t2;
16021602
drop table t2;
16031603
create temporary table t2 (a varchar(10));
@@ -1609,7 +1609,7 @@ create table t1 (x int);
16091609
execute stmt;
16101610
call p_verify_reprepare_count(1);
16111611
execute stmt;
1612-
call p_verify_reprepare_count(0);
1612+
call p_verify_reprepare_count(1);
16131613
drop table t1;
16141614
drop temporary table t2;
16151615
drop table t2;
@@ -1621,23 +1621,23 @@ execute stmt;
16211621
call p_verify_reprepare_count(0);
16221622
drop table t2;
16231623
execute stmt;
1624-
call p_verify_reprepare_count(0);
1624+
call p_verify_reprepare_count(1);
16251625
drop table t2;
16261626
# Table to be used does not exist
16271627
drop table t1;
16281628
--error ER_NO_SUCH_TABLE
16291629
execute stmt;
1630-
call p_verify_reprepare_count(0);
1630+
call p_verify_reprepare_count(1);
16311631
--error ER_NO_SUCH_TABLE
16321632
execute stmt;
1633-
call p_verify_reprepare_count(0);
1633+
call p_verify_reprepare_count(1);
16341634
# Table to be used recreated (drop,create) with different layout
16351635
create table t1 (x char(17));
16361636
execute stmt;
16371637
call p_verify_reprepare_count(1);
16381638
drop table t2;
16391639
execute stmt;
1640-
call p_verify_reprepare_count(0);
1640+
call p_verify_reprepare_count(1);
16411641
drop table t2;
16421642
# Table to be used has a modified (alter table) layout
16431643
alter table t1 add column y time;
@@ -1646,7 +1646,7 @@ call p_verify_reprepare_count(1);
16461646
select * from t2;
16471647
drop table t2;
16481648
execute stmt;
1649-
call p_verify_reprepare_count(0);
1649+
call p_verify_reprepare_count(1);
16501650
drop table t1;
16511651
drop table t2;
16521652
deallocate prepare stmt;
@@ -2057,7 +2057,7 @@ drop table t1;
20572057
deallocate prepare stmt;
20582058
--echo # Intermediate result: number of reprepares matches the number
20592059
--echo # of tests
2060-
call p_verify_reprepare_count(17);
2060+
call p_verify_reprepare_count(18);
20612061

20622062
--echo #
20632063
--echo # SQLCOM_ALTER_VIEW

sql/sp_instr.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,11 @@ bool sp_lex_instr::validate_lex_and_execute_core(THD *thd, uint *nextp,
722722

723723
while (true) {
724724
DBUG_EXECUTE_IF("simulate_bug18831513", { invalidate(); });
725-
if (is_invalid() || (m_lex->has_udf() && !m_first_execution)) {
725+
if (is_invalid() ||
726+
(!m_first_execution &&
727+
(m_lex->has_udf() ||
728+
(m_lex->m_sql_cmd != nullptr &&
729+
m_lex->m_sql_cmd->reprepare_on_execute_required())))) {
726730
free_lex();
727731
LEX *lex = parse_expr(thd, thd->sp_runtime_ctx->sp);
728732
if (lex == nullptr) return true;

sql/sql_alter.cc

+12
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,18 @@ bool Sql_cmd_alter_table::execute(THD *thd) {
356356
return result;
357357
}
358358

359+
bool Sql_cmd_alter_table::reprepare_on_execute_required() const {
360+
// Expressions in key and partition clauses end up with being allocated on
361+
// differing (incompatible) MEM_ROOTs and thus need to be reprepared. The
362+
// incompatibility arises in the case of prepared statements as a parse tree
363+
// MEM_ROOT whose lifetime is associated with the lifetime of the prepared
364+
// statement ends up containing pointers to parse tree objects that have been
365+
// allocated from a MEM_ROOT with a lifetime of the prepared statement's
366+
// execution. It's benign (though wasteful) to reprepare other alter table
367+
// statements as well.
368+
return true;
369+
}
370+
359371
bool Sql_cmd_discard_import_tablespace::execute(THD *thd) {
360372
/* Verify that exactly one of the DISCARD and IMPORT flags are set. */
361373
assert((m_alter_info->flags & Alter_info::ALTER_DISCARD_TABLESPACE) ^

sql/sql_alter.h

+1
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ class Sql_cmd_alter_table : public Sql_cmd_common_alter_table {
619619
using Sql_cmd_common_alter_table::Sql_cmd_common_alter_table;
620620

621621
bool execute(THD *thd) override;
622+
bool reprepare_on_execute_required() const override;
622623
};
623624

624625
/**

sql/sql_cmd.h

+8
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ class Sql_cmd {
133133
*/
134134
virtual bool execute(THD *thd) = 0;
135135

136+
/**
137+
Some SQL commands currently require re-preparation on re-execution of a
138+
prepared statement or stored procedure. For example, a CREATE TABLE command
139+
containing an index expression.
140+
@return true if re-preparation is required, false otherwise.
141+
*/
142+
virtual bool reprepare_on_execute_required() const { return false; }
143+
136144
/**
137145
Command-specific reinitialization before execution of prepared statement
138146

sql/sql_cmd_ddl_table.cc

+24
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,18 @@ bool Sql_cmd_create_table::execute(THD *thd) {
478478
return res;
479479
}
480480

481+
bool Sql_cmd_create_table::reprepare_on_execute_required() const {
482+
// Expressions in key and partition clauses end up with being allocated on
483+
// differing (incompatible) MEM_ROOTs and thus need to be reprepared. The
484+
// incompatibility arises in the case of prepared statements as a parse tree
485+
// MEM_ROOT whose lifetime is associated with the lifetime of the prepared
486+
// statement ends up containing pointers to parse tree objects that have been
487+
// allocated from a MEM_ROOT with a lifetime of the prepared statement's
488+
// execution. It's benign (though wasteful) to reprepare other create table
489+
// statements as well.
490+
return true;
491+
}
492+
481493
const MYSQL_LEX_CSTRING *
482494
Sql_cmd_create_table::eligible_secondary_storage_engine(THD *) const {
483495
// Now check if the opened tables are available in a secondary
@@ -563,6 +575,18 @@ bool Sql_cmd_create_or_drop_index_base::execute(THD *thd) {
563575
return res;
564576
}
565577

578+
bool Sql_cmd_create_index::reprepare_on_execute_required() const {
579+
// Expressions in index/key clauses end up with being allocated on
580+
// differing (incompatible) MEM_ROOTs and thus need to be reprepared.
581+
// The incompatibility arises in the case of prepared statements as a parse
582+
// tree MEM_ROOT whose lifetime is associated with the lifetime of the
583+
// prepared statement ends up containing pointers to parse tree objects that
584+
// have been allocated from a MEM_ROOT with a lifetime of the prepared
585+
// statement's execution. It's benign (though wasteful) to reprepare other
586+
// create index statements as well.
587+
return true;
588+
}
589+
566590
bool Sql_cmd_cache_index::execute(THD *thd) {
567591
Table_ref *const first_table = thd->lex->query_block->get_table_list();
568592
if (check_table_access(thd, INDEX_ACL, first_table, true, UINT_MAX, false))

0 commit comments

Comments
 (0)