summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-07-08 09:56:28 +0200
committerSergei Golubchik <serg@mariadb.org>2017-07-08 09:56:28 +0200
commitc9801135c10d132304b03195b0b0ea0141347a45 (patch)
tree38e50be2f2a0089dbfecc1d14140953ded9149b7
parent5789934fda10aeba1ea2a562e503767e950a322d (diff)
parent9e11e055ce1461caecbb30e8300dfdcd48af22f1 (diff)
downloadmariadb-git-c9801135c10d132304b03195b0b0ea0141347a45.tar.gz
Merge branch '10.1' into 10.2
-rw-r--r--client/mysql.cc5
-rw-r--r--client/mysql_upgrade.c2
-rw-r--r--client/mysqldump.c5
-rw-r--r--client/mysqlimport.c2
-rw-r--r--client/mysqltest.cc5
-rw-r--r--mysql-test/r/subselect.result43
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result43
-rw-r--r--mysql-test/r/subselect_no_mat.result43
-rw-r--r--mysql-test/r/subselect_no_opts.result43
-rw-r--r--mysql-test/r/subselect_no_scache.result43
-rw-r--r--mysql-test/r/subselect_no_semijoin.result43
-rw-r--r--mysql-test/suite/parts/r/longname.result28
-rw-r--r--mysql-test/suite/parts/t/longname.test32
-rw-r--r--mysql-test/suite/rpl/r/circular_serverid0.result42
-rw-r--r--mysql-test/suite/rpl/t/circular_serverid0.cnf30
-rw-r--r--mysql-test/suite/rpl/t/circular_serverid0.test104
-rw-r--r--mysql-test/t/subselect.test42
-rw-r--r--sql/ha_partition.cc210
-rw-r--r--sql/item.cc6
-rw-r--r--sql/item_timefunc.cc2
-rw-r--r--sql/partition_info.cc14
-rw-r--r--sql/partition_info.h5
-rw-r--r--sql/slave.cc29
-rw-r--r--sql/sql_class.cc12
-rw-r--r--sql/sql_partition.cc118
-rw-r--r--sql/sql_partition.h12
-rw-r--r--sql/sql_partition_admin.cc8
-rw-r--r--storage/archive/ha_archive.cc1
-rw-r--r--storage/maria/ma_loghandler.c4
-rw-r--r--storage/maria/ma_pagecache.c1
-rw-r--r--storage/mroonga/mrn_table.cpp14
-rw-r--r--storage/spider/spd_table.cc29
32 files changed, 776 insertions, 244 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index d81d8abfcfd..213cdfd0e8d 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -4805,10 +4805,11 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "Protocol:\t\tCompressed\n");
#endif
- if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0])
+ const char *pos;
+ if ((status_str= mysql_stat(&mysql)) && !mysql_error(&mysql)[0] &&
+ (pos= strchr(status_str,' ')))
{
ulong sec;
- const char *pos= strchr(status_str,' ');
/* print label */
tee_fprintf(stdout, "%.*s\t\t\t", (int) (pos-status_str), status_str);
if ((status_str= str2int(pos,10,0,LONG_MAX,(long*) &sec)))
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 4e4970bacab..c10dc20e7d7 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -1171,6 +1171,8 @@ int main(int argc, char **argv)
{
int fd= create_temp_file(cnf_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL,
"mysql_upgrade-", O_CREAT | O_WRONLY, MYF(MY_FAE));
+ if (fd < 0)
+ die(NULL);
my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE));
my_write(fd, (uchar*)ds_args.str, ds_args.length, MYF(MY_FAE));
my_close(fd, MYF(0));
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 2028606cd5a..c8ebd2217a3 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -92,8 +92,7 @@
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
-static ulong find_set(TYPELIB *lib, const char *x, size_t length,
- char **err_pos, uint *err_len);
+static ulong find_set(TYPELIB *, const char *, size_t, char **, uint *);
static char *alloc_query_str(ulong size);
static void field_escape(DYNAMIC_STRING* in, const char *from);
@@ -5485,7 +5484,7 @@ static ulong find_set(TYPELIB *lib, const char *x, size_t length,
var_len= (uint) (pos - start);
strmake(buff, start, MY_MIN(sizeof(buff) - 1, var_len));
find= find_type(buff, lib, FIND_TYPE_BASIC);
- if (!find)
+ if (find <= 0)
{
*err_pos= (char*) start;
*err_len= var_len;
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 092ae555318..38b2eb5f672 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -677,7 +677,7 @@ int main(int argc, char **argv)
MYF(0))))
return -2;
- for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
+ for (; *argv != NULL; argv++) /* Loop through tables */
{
pthread_mutex_lock(&counter_mutex);
while (counter == opt_use_threads)
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 66e17673f08..f8f9721d583 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -602,7 +602,7 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
void str_to_file(const char *fname, char *str, int size);
void str_to_file2(const char *fname, char *str, int size, my_bool append);
-void fix_win_paths(char *val, int len);
+void fix_win_paths(char *val, size_t len);
const char *get_errname_from_code (uint error_code);
int multi_reg_replace(struct st_replace_regex* r,char* val);
@@ -2652,6 +2652,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
if (!mysql)
{
struct st_command command;
+ DBUG_ASSERT(query_end);
memset(&command, 0, sizeof(command));
command.query= (char*)query;
command.first_word_len= (*query_end - query);
@@ -7468,7 +7469,7 @@ void free_win_path_patterns()
=> all \ from c:\mysql\m... until next space is converted into /
*/
-void fix_win_paths(char *val, int len)
+void fix_win_paths(char *val, size_t len)
{
#ifdef _WIN32
uint i;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 85519828b14..3daaa633dfe 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -4706,7 +4706,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5581,7 +5581,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6193,7 +6193,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7150,9 +7150,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7160,9 +7161,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7177,6 +7179,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7203,7 +7228,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7217,4 +7242,4 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index deffc030d6b..2a0f542be19 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -4708,7 +4708,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5583,7 +5583,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6193,7 +6193,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7150,9 +7150,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7160,9 +7161,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7177,6 +7179,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7203,7 +7228,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7217,7 +7242,7 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
set optimizer_switch=default;
select @@optimizer_switch like '%exists_to_in=off%';
@@optimizer_switch like '%exists_to_in=off%'
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 202faf7f522..c941f924e21 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -4706,7 +4706,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5581,7 +5581,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6188,7 +6188,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7143,9 +7143,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7153,9 +7154,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7170,6 +7172,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7196,7 +7221,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7210,7 +7235,7 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 294107ef69e..2aebdd6c82d 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -4702,7 +4702,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5577,7 +5577,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6184,7 +6184,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7141,9 +7141,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7151,9 +7152,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7168,6 +7170,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7194,7 +7219,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7208,5 +7233,5 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index b9c06cae5bd..ca0a33382ff 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -4712,7 +4712,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5587,7 +5587,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6199,7 +6199,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7156,9 +7156,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7166,9 +7167,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7183,6 +7185,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7209,7 +7234,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7223,7 +7248,7 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
set optimizer_switch=default;
select @@optimizer_switch like '%subquery_cache=on%';
@@optimizer_switch like '%subquery_cache=on%'
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index e90d70fcc49..e789deb1b8b 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -4702,7 +4702,7 @@ pk
SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
-End of 5.0 tests.
+# End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
create table t_in (a2 char(2), b2 char(2), c2 char(2));
@@ -5577,7 +5577,7 @@ insert into t2 values ('x'), ('y');
select * from t2 where a=(select a from t1) and a='x';
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
-End of 5.1 tests
+# End of 5.1 tests
#
# Bug #11765713 58705:
# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
@@ -6184,7 +6184,7 @@ WHERE (c_sq1_alias1.col_int_nokey != @var2
OR c_sq1_alias1.pk != @var3)) ) AS alias3;
pk col_int_nokey col_int_key col_time_key col_varchar_key col_varchar_nokey
DROP TABLE t1,t2;
-End of 5.2 tests
+# End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
#
@@ -7141,9 +7141,10 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (f2 INT, KEY(f2));
INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-3
+ERROR 42000: Can't group on 'sq'
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
f2
3
@@ -7151,9 +7152,10 @@ SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
count(*)
1
delete from t1;
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+ERROR 42000: Can't group on 'sq'
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
-sq
-NULL
+ERROR 42000: Can't group on 'sq'
drop view v2;
drop table t1,t2;
#
@@ -7168,6 +7170,29 @@ f1 f2
foo bar
DROP TABLE t1;
#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+# End of 10.0 tests
+#
# MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
# with UNION in ALL subquery
#
@@ -7194,7 +7219,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
f1 f2 f3
DROP TABLE t1, t2;
SET NAMES default;
-End of 10.1 tests
+# End of 10.1 tests
#
# MDEV-12564: IN TO EXISTS transformation for rows after
# conversion an outer join to inner join
@@ -7208,6 +7233,6 @@ WHERE (t2.i, t2.pk) NOT IN ( SELECT t3.i, t3.i FROM t t3, t t4 ) AND t1.c = 'foo
pk i c pk i c
1 10 foo 1 10 foo
DROP TABLE t;
-End of 10.2 tests
+# End of 10.2 tests
set @optimizer_switch_for_subselect_test=null;
set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/suite/parts/r/longname.result b/mysql-test/suite/parts/r/longname.result
new file mode 100644
index 00000000000..c95e666625e
--- /dev/null
+++ b/mysql-test/suite/parts/r/longname.result
@@ -0,0 +1,28 @@
+set names utf8;
+create database mysqltest1;
+select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1';
+database_name table_name length(table_name)
+CREATE TABLE mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890 (
+id int(10) unsigned NOT NULL,
+id2 int(10) unsigned NOT NULL,
+PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+SUBPARTITION BY HASH ( id2 )
+SUBPARTITIONS 2 (
+PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LESS THAN (1000) ENGINE = InnoDB,
+PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1';
+database_name table_name length(table_name)
+CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé (
+id int(10) unsigned NOT NULL,
+id2 int(10) unsigned NOT NULL,
+PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+SUBPARTITION BY HASH ( id2 )
+SUBPARTITIONS 2 (
+PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
+PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+ERROR HY000: The path specified for @0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@ is too long
+drop database mysqltest1;
diff --git a/mysql-test/suite/parts/t/longname.test b/mysql-test/suite/parts/t/longname.test
new file mode 100644
index 00000000000..0f7378ef8e3
--- /dev/null
+++ b/mysql-test/suite/parts/t/longname.test
@@ -0,0 +1,32 @@
+source include/have_innodb.inc;
+source include/have_partition.inc;
+set names utf8;
+
+create database mysqltest1;
+select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1';
+CREATE TABLE mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890 (
+ id int(10) unsigned NOT NULL,
+ id2 int(10) unsigned NOT NULL,
+ PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+ SUBPARTITION BY HASH ( id2 )
+ SUBPARTITIONS 2 (
+ PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LESS THAN (1000) ENGINE = InnoDB,
+ PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+
+select database_name, table_name, length(table_name) from mysql.innodb_table_stats where database_name = 'mysqltest1';
+
+--error ER_PATH_LENGTH
+CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé (
+ id int(10) unsigned NOT NULL,
+ id2 int(10) unsigned NOT NULL,
+ PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+ SUBPARTITION BY HASH ( id2 )
+ SUBPARTITIONS 2 (
+ PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
+ PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+
+drop database mysqltest1;
diff --git a/mysql-test/suite/rpl/r/circular_serverid0.result b/mysql-test/suite/rpl/r/circular_serverid0.result
new file mode 100644
index 00000000000..112f9359ac4
--- /dev/null
+++ b/mysql-test/suite/rpl/r/circular_serverid0.result
@@ -0,0 +1,42 @@
+include/rpl_init.inc [topology=1->2->1]
+include/rpl_connect.inc [creating M4]
+include/rpl_connect.inc [creating M2]
+SET @old_debug= @@global.debug;
+connection M2;
+STOP SLAVE;
+SET GLOBAL debug_dbug= "+d,dbug.rows_events_to_delay_relay_logging";
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+connection M2;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b VARCHAR(30000)) ENGINE=innodb;
+connection M4;
+connection M4;
+INSERT INTO `t1` VALUES (null, repeat('a', 1024)), (null, repeat('b', 1024));
+connection M2;
+SET debug_sync='now WAIT_FOR start_sql_thread';
+START SLAVE SQL_THREAD;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b VARCHAR(30000)) ENGINE=innodb
+SET debug_sync='now SIGNAL go_on_relay_logging';
+connection M4;
+connection M4;
+connection M2;
+connection M2;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Gtid # # GTID #-#-#
+slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b VARCHAR(30000)) ENGINE=innodb
+slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
+slave-bin.000001 # Annotate_rows # # INSERT INTO `t1` VALUES (null, repeat('a', 1024)), (null, repeat('b', 1024))
+slave-bin.000001 # Table_map # # table_id: # (test.t1)
+slave-bin.000001 # Write_rows_v1 # # table_id: #
+slave-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F
+slave-bin.000001 # Xid # # COMMIT /* XID */
+connection M4;
+drop table t1;
+connection M2;
+SET GLOBAL debug_dbug= @old_debug;
+SET debug_sync='RESET';
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/circular_serverid0.cnf b/mysql-test/suite/rpl/t/circular_serverid0.cnf
new file mode 100644
index 00000000000..277aac2869b
--- /dev/null
+++ b/mysql-test/suite/rpl/t/circular_serverid0.cnf
@@ -0,0 +1,30 @@
+!include ../my.cnf
+
+[mysqld.1]
+gtid-domain-id=4
+server-id=4
+#
+log-slave-updates
+slave-parallel-threads=0
+gtid-strict-mode=1
+gtid-ignore-duplicates=1
+
+#
+# Max-size row events to minimum with the idea to create
+# a number of Rows_log_event per Query.
+#
+binlog-row-event-max-size=1024
+
+[mysqld.2]
+gtid-domain-id=2
+server-id=2
+#
+log-slave-updates
+slave-parallel-threads=0
+gtid-strict-mode=1
+gtid-ignore-duplicates=1
+binlog-row-event-max-size=1024
+# The slave will be initialized with a @@global.dbug-var value
+skip-slave-start=1
+
+
diff --git a/mysql-test/suite/rpl/t/circular_serverid0.test b/mysql-test/suite/rpl/t/circular_serverid0.test
new file mode 100644
index 00000000000..20ad58e2c52
--- /dev/null
+++ b/mysql-test/suite/rpl/t/circular_serverid0.test
@@ -0,0 +1,104 @@
+#
+# Testing chain/circular replication scenario of MDEV-9670
+# The effect of the bug was that we got a commit with a GTID with server_id
+#
+
+--source include/have_binlog_format_row.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--let $rpl_topology= 1->2->1
+--source include/rpl_init.inc
+
+--let $rpl_connection_name= M4
+--let $rpl_server_number= 1
+--source include/rpl_connect.inc
+
+--let $rpl_connection_name= M2
+--let $rpl_server_number= 2
+--source include/rpl_connect.inc
+
+# The parameter reflects binlog-row-event-max-size @cnf.
+--let $row_size=1024
+
+SET @old_debug= @@global.debug;
+
+--connection M2
+STOP SLAVE;
+SET GLOBAL debug_dbug= "+d,dbug.rows_events_to_delay_relay_logging";
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+--connection M2
+# This query also creates a Gtid event group whose Gtid will remain in
+# ignored status for too long causing a following group split.
+
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b VARCHAR(30000)) ENGINE=innodb;
+--sync_slave_with_master M4
+
+# This INSERT will be logged as two Write_log events which the buggy
+# slave applier would split.
+
+--connection M4
+eval INSERT INTO `t1` VALUES (null, repeat('a', $row_size)), (null, repeat('b', $row_size));
+
+# START M2 IO thread and wait for its signal to follow with the SQL
+# thread start. At this moment the SQL thread shall be having 2 and
+# "half" groups to execute. The "hafl" one would be committed by the
+# buggy applier after which the IO is released to queue the rest of
+# the 3rd group which the SQL thread commits separately to complete
+# the split.
+
+--connection M2
+
+# wait for IO signal to start the SQL thread. IO will be hanging upon that.
+SET debug_sync='now WAIT_FOR start_sql_thread';
+
+# Now the slave server has relay log whose last group is incomplete.
+# An unfixed slave server would go to "insert" a "fake"
+# Gtid_list_log_event event which actually would commit the incomplete
+# group. However before to actual commit do_apply_event() hits some assert.
+# In the fixed server the fake Gtid_list_log_event is *not* inserted
+# in the middle of a group.
+START SLAVE SQL_THREAD;
+
+# Sleep for a little time to give SQL thread a chance to commit while
+# the IO thread is hanging (see
+# DBUG_EXECUTE_IF("dbug.rows_events_to_delay_relay_logging"...) in
+# queue_event). Alternatively to reproduce the case when buggy slave
+# wait for the 1st group commit
+
+#--let $count= 1
+#--let $table= t1
+#--source include/wait_until_rows_count.inc
+
+--sleep 2
+
+# Demonstrate either no split group in the correct slave or the 1nd
+# group in the buggy one
+--source include/show_binlog_events.inc
+
+# Release the IO thread
+SET debug_sync='now SIGNAL go_on_relay_logging';
+
+# Sync servers
+--sync_slave_with_master M4
+--connection M4
+--sync_slave_with_master M2
+--connection M2
+
+# Demonstrate replication goes correctly not to create any split, or
+# the 2nd group in the buggy slave
+--source include/show_binlog_events.inc
+
+#
+# Cleanup
+#
+--connection M4
+drop table t1;
+
+--connection M2
+SET GLOBAL debug_dbug= @old_debug;
+SET debug_sync='RESET';
+--source include/rpl_end.inc
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 282013222de..2029e5a8f44 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -3602,7 +3602,7 @@ SET SESSION sql_mode=@old_sql_mode;
drop table t2, t1;
drop view v1;
---echo End of 5.0 tests.
+--echo # End of 5.0 tests.
#
# Test [NOT] IN truth table (both as top-level and general predicate).
@@ -4687,7 +4687,7 @@ select * from t2 where a=(select a from t1) and a='x';
drop table t1,t2;
---echo End of 5.1 tests
+--echo # End of 5.1 tests
--echo #
--echo # Bug #11765713 58705:
@@ -5159,7 +5159,7 @@ eval SELECT * FROM ( $subq ) AS alias3;
DROP TABLE t1,t2;
---echo End of 5.2 tests
+--echo # End of 5.2 tests
--echo #
--echo # BUG#779885: Crash in eliminate_item_equal with materialization=on in
@@ -6008,11 +6008,17 @@ INSERT INTO t2 VALUES (3);
CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+--error ER_WRONG_GROUP_FIELD
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+--error ER_WRONG_GROUP_FIELD
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
SELECT * FROM v2 where ( SELECT MIN(v2.f2) FROM t1 ) > 0;
SELECT count(*) FROM v2 group by ( SELECT MIN(v2.f2) FROM t1 );
delete from t1;
+--error ER_WRONG_GROUP_FIELD
+SELECT ( SELECT MIN(t2.f2) FROM t1 ) AS sq FROM t2 GROUP BY sq;
+--error ER_WRONG_GROUP_FIELD
SELECT ( SELECT MIN(v2.f2) FROM t1 ) AS sq FROM v2 GROUP BY sq;
drop view v2;
@@ -6028,6 +6034,32 @@ SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
DROP TABLE t1;
+--echo #
+--echo # MDEV-10146: Wrong result (or questionable result and behavior)
+--echo # with aggregate function in uncorrelated SELECT subquery
+--echo #
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (f2 int);
+
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+
+INSERT INTO t2 VALUES (4);
+
+--error ER_SUBQUERY_NO_1_ROW
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+--error ER_SUBQUERY_NO_1_ROW
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+
+drop view v1;
+drop table t1,t2;
+
+--echo # End of 10.0 tests
--echo #
--echo # MDEV-9487: Server crashes in Time_and_counter_tracker::incr_loops
@@ -6055,7 +6087,7 @@ SELECT * FROM t1, t2 WHERE f3 = f2 AND f1 > ANY ( SELECT 'foo');
DROP TABLE t1, t2;
SET NAMES default;
---echo End of 10.1 tests
+--echo # End of 10.1 tests
--echo #
--echo # MDEV-12564: IN TO EXISTS transformation for rows after
@@ -6072,4 +6104,4 @@ SELECT * FROM t t1 RIGHT JOIN t t2 ON (t2.pk = t1.pk)
DROP TABLE t;
---echo End of 10.2 tests
+--echo # End of 10.2 tests
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6099f40ba0c..2c91dfa0c65 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -674,7 +674,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
int error;
- char name_buff[FN_REFLEN], name_lc_buff[FN_REFLEN];
+ char name_buff[FN_REFLEN + 1], name_lc_buff[FN_REFLEN];
char *name_buffer_ptr;
const char *path;
uint i;
@@ -716,8 +716,9 @@ int ha_partition::create(const char *name, TABLE *table_arg,
for (j= 0; j < m_part_info->num_subparts; j++)
{
part_elem= sub_it++;
- create_partition_name(name_buff, path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto create_error;
if ((error= set_up_table_before_create(table_arg, name_buff,
create_info, part_elem)) ||
((error= (*file)->ha_create(name_buff, table_arg, create_info))))
@@ -729,8 +730,9 @@ int ha_partition::create(const char *name, TABLE *table_arg,
}
else
{
- create_partition_name(name_buff, path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto create_error;
if ((error= set_up_table_before_create(table_arg, name_buff,
create_info, part_elem)) ||
((error= (*file)->ha_create(name_buff, table_arg, create_info))))
@@ -746,9 +748,9 @@ create_error:
name_buffer_ptr= m_name_buffer_ptr;
for (abort_file= file, file= m_file; file < abort_file; file++)
{
- create_partition_name(name_buff, path, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
- (void) (*file)->ha_delete_table((const char*) name_buff);
+ if (!create_partition_name(name_buff, sizeof(name_buff), path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE))
+ (void) (*file)->ha_delete_table((const char*) name_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
handler::delete_table(name);
@@ -775,7 +777,7 @@ create_error:
int ha_partition::drop_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
- char part_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -808,9 +810,11 @@ int ha_partition::drop_partitions(const char *path)
{
partition_element *sub_elem= sub_it++;
part= i * num_subparts + j;
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name, name_variant);
+ if ((ret_error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, name_variant)))
+ error= ret_error;
file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff)))
@@ -821,15 +825,19 @@ int ha_partition::drop_partitions(const char *path)
}
else
{
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, name_variant,
- TRUE);
- file= m_file[i];
- DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
- if ((ret_error= file->ha_delete_table(part_name_buff)))
+ if ((ret_error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, name_variant, TRUE)))
error= ret_error;
- if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
+ else
+ {
+ file= m_file[i];
+ DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
+ if ((ret_error= file->ha_delete_table(part_name_buff)))
+ error= ret_error;
+ if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ }
}
if (part_elem->part_state == PART_IS_CHANGED)
part_elem->part_state= PART_NORMAL;
@@ -865,8 +873,8 @@ int ha_partition::rename_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator<partition_element> temp_it(m_part_info->temp_partitions);
- char part_name_buff[FN_REFLEN];
- char norm_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
+ char norm_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint part_count= 0;
uint num_subparts= m_part_info->num_subparts;
@@ -908,10 +916,11 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
file= m_reorged_file[part_count++];
- create_subpartition_name(norm_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if ((ret_error= create_subpartition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, NORMAL_PART_NAME)))
+ error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error;
@@ -924,16 +933,20 @@ int ha_partition::rename_partitions(const char *path)
else
{
file= m_reorged_file[part_count++];
- create_partition_name(norm_name_buff, path,
- part_elem->partition_name, NORMAL_PART_NAME,
- TRUE);
- DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
- if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ if ((ret_error= create_partition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name, NORMAL_PART_NAME, TRUE)))
error= ret_error;
- else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
else
- part_elem->log_entry= NULL; /* Indicate success */
+ {
+ DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
+ if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ error= ret_error;
+ else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ else
+ part_elem->log_entry= NULL; /* Indicate success */
+ }
}
} while (++i < temp_partitions);
(void) sync_ddl_log();
@@ -976,10 +989,11 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
part= i * num_subparts + j;
- create_subpartition_name(norm_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if ((ret_error= create_subpartition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, NORMAL_PART_NAME)))
+ error= ret_error;
if (part_elem->part_state == PART_IS_CHANGED)
{
file= m_reorged_file[part_count++];
@@ -991,10 +1005,11 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log();
}
file= m_new_file[part];
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- TEMP_PART_NAME);
+ if ((ret_error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, TEMP_PART_NAME)))
+ error= ret_error;
DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff,
@@ -1008,32 +1023,36 @@ int ha_partition::rename_partitions(const char *path)
}
else
{
- create_partition_name(norm_name_buff, path,
- part_elem->partition_name, NORMAL_PART_NAME,
- TRUE);
- if (part_elem->part_state == PART_IS_CHANGED)
+ if ((ret_error= create_partition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name, NORMAL_PART_NAME, TRUE)) ||
+ (ret_error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, TEMP_PART_NAME, TRUE)))
+ error= ret_error;
+ else
{
- file= m_reorged_file[part_count++];
- DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
- if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ if (part_elem->part_state == PART_IS_CHANGED)
+ {
+ file= m_reorged_file[part_count++];
+ DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
+ if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ error= ret_error;
+ else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ (void) sync_ddl_log();
+ }
+ file= m_new_file[i];
+ DBUG_PRINT("info", ("Rename partition from %s to %s",
+ part_name_buff, norm_name_buff));
+ if ((ret_error= file->ha_rename_table(part_name_buff,
+ norm_name_buff)))
error= ret_error;
else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1;
- (void) sync_ddl_log();
+ else
+ part_elem->log_entry= NULL;
}
- file= m_new_file[i];
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, TEMP_PART_NAME,
- TRUE);
- DBUG_PRINT("info", ("Rename partition from %s to %s",
- part_name_buff, norm_name_buff));
- if ((ret_error= file->ha_rename_table(part_name_buff,
- norm_name_buff)))
- error= ret_error;
- else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
- else
- part_elem->log_entry= NULL;
}
}
} while (++i < num_parts);
@@ -1649,7 +1668,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator <partition_element> t_it(m_part_info->temp_partitions);
- char part_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -1878,10 +1897,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
do
{
partition_element *sub_elem= sub_it++;
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- name_variant);
+ if ((error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, sub_elem->partition_name,
+ name_variant)))
+ {
+ cleanup_new_partition(part_count);
+ DBUG_RETURN(error);
+ }
part= i * num_subparts + j;
DBUG_PRINT("info", ("Add subpartition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
@@ -1899,9 +1922,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
}
else
{
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, name_variant,
- TRUE);
+ if ((error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path, part_elem->partition_name,
+ name_variant, TRUE)))
+ {
+ cleanup_new_partition(part_count);
+ DBUG_RETURN(error);
+ }
+
DBUG_PRINT("info", ("Add partition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
new_file_array[i],
@@ -2272,8 +2300,8 @@ uint ha_partition::del_ren_table(const char *from, const char *to)
{
int save_error= 0;
int error;
- char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
- to_lc_buff[FN_REFLEN];
+ char from_buff[FN_REFLEN + 1], to_buff[FN_REFLEN + 1],
+ from_lc_buff[FN_REFLEN], to_lc_buff[FN_REFLEN];
char *name_buffer_ptr;
const char *from_path;
const char *to_path= NULL;
@@ -2309,13 +2337,15 @@ uint ha_partition::del_ren_table(const char *from, const char *to)
i= 0;
do
{
- create_partition_name(from_buff, from_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(from_buff, sizeof(from_buff), from_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto rename_error;
if (to != NULL)
{ // Rename branch
- create_partition_name(to_buff, to_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(to_buff, sizeof(to_buff), to_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto rename_error;
error= (*file)->ha_rename_table(from_buff, to_buff);
if (error)
goto rename_error;
@@ -2344,12 +2374,14 @@ rename_error:
for (abort_file= file, file= m_file; file < abort_file; file++)
{
/* Revert the rename, back from 'to' to the original 'from' */
- create_partition_name(from_buff, from_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
- create_partition_name(to_buff, to_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
- /* Ignore error here */
- (void) (*file)->ha_rename_table(to_buff, from_buff);
+ if (!create_partition_name(from_buff, sizeof(from_buff), from_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE) &&
+ !create_partition_name(to_buff, sizeof(to_buff), to_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE))
+ {
+ /* Ignore error here */
+ (void) (*file)->ha_rename_table(to_buff, from_buff);
+ }
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
DBUG_RETURN(error);
@@ -3416,7 +3448,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION;
handler **file;
- char name_buff[FN_REFLEN];
+ char name_buff[FN_REFLEN + 1];
ulonglong check_table_flags;
DBUG_ENTER("ha_partition::open");
@@ -3470,8 +3502,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_is_clone_of->m_file;
for (i= 0; i < m_tot_parts; i++)
{
- create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto err_handler;
/* ::clone() will also set ha_share from the original. */
if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root)))
{
@@ -3487,8 +3520,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_file;
do
{
- create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto err_handler;
table->s->connect_string = m_connect_string[(uint)(file-m_file)];
if ((error= (*file)->ha_open(table, name_buff, mode,
test_if_locked | HA_OPEN_NO_PSI_CALL)))
diff --git a/sql/item.cc b/sql/item.cc
index adc1c1b9d46..6d999daf801 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5235,6 +5235,12 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
+ if (thd->lex->in_sum_func &&
+ thd->lex->in_sum_func->nest_level >= select->nest_level)
+ {
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ select->nest_level);
+ }
/*
A reference to a view field had been found and we
substituted it instead of this Item (find_field_in_tables
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 0a564780ac2..70f160991d0 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -3122,7 +3122,7 @@ get_date_time_result_type(const char *format, uint length)
const char *val= format;
const char *end= format + length;
- for (; val != end && val != end; val++)
+ for (; val != end; val++)
{
if (*val == '%' && val+1 != end)
{
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 2bf130fbf81..535ed4612e0 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -608,6 +608,7 @@ char* partition_info::find_duplicate_field()
*/
partition_element *partition_info::get_part_elem(const char *partition_name,
char *file_name,
+ size_t file_name_size,
uint32 *part_id)
{
List_iterator<partition_element> part_it(partitions);
@@ -629,10 +630,10 @@ partition_element *partition_info::get_part_elem(const char *partition_name,
sub_part_elem->partition_name, partition_name))
{
if (file_name)
- create_subpartition_name(file_name, "",
- part_elem->partition_name,
- partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(file_name, file_name_size, "",
+ part_elem->partition_name,
+ partition_name, NORMAL_PART_NAME))
+ DBUG_RETURN(NULL);
*part_id= j + (i * num_subparts);
DBUG_RETURN(sub_part_elem);
}
@@ -647,8 +648,9 @@ partition_element *partition_info::get_part_elem(const char *partition_name,
part_elem->partition_name, partition_name))
{
if (file_name)
- create_partition_name(file_name, "", partition_name,
- NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(file_name, file_name_size, "",
+ partition_name, NORMAL_PART_NAME, TRUE))
+ DBUG_RETURN(NULL);
*part_id= i;
DBUG_RETURN(part_elem);
}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 8ff7977373b..91ceee70ea4 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -328,9 +328,8 @@ public:
bool check_partition_field_length();
bool init_column_part(THD *thd);
bool add_column_list_value(THD *thd, Item *item);
- partition_element *get_part_elem(const char *partition_name,
- char *file_name,
- uint32 *part_id);
+ partition_element *get_part_elem(const char *partition_name, char *file_name,
+ size_t file_name_size, uint32 *part_id);
void report_part_expr_error(bool use_subpart_expr);
bool has_same_partitioning(partition_info *new_part_info);
private:
diff --git a/sql/slave.cc b/sql/slave.cc
index 61a22ce1f63..3beb8df04eb 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -2468,6 +2468,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
}
if (rli->ign_gtids.count())
{
+ DBUG_ASSERT(!rli->is_in_group()); // Ensure no active transaction
glev= new Gtid_list_log_event(&rli->ign_gtids,
Gtid_list_log_event::FLAG_IGN_GTIDS);
rli->ign_gtids.reset();
@@ -5750,6 +5751,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
bool gtid_skip_enqueue= false;
bool got_gtid_event= false;
rpl_gtid event_gtid;
+ static uint dbug_rows_event_count __attribute__((unused))= 0;
bool is_compress_event = false;
char* new_buf = NULL;
char new_buf_arr[4096];
@@ -5821,6 +5823,26 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
(uchar)buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
DBUG_RETURN(queue_old_event(mi,buf,event_len));
+#ifdef ENABLED_DEBUG_SYNC
+ /*
+ A (+d,dbug.rows_events_to_delay_relay_logging)-test is supposed to
+ create a few Write_log_events and after receiving the 1st of them
+ the IO thread signals to launch the SQL thread, and sets itself to
+ wait for a release signal.
+ */
+ DBUG_EXECUTE_IF("dbug.rows_events_to_delay_relay_logging",
+ if ((buf[EVENT_TYPE_OFFSET] == WRITE_ROWS_EVENT_V1 ||
+ buf[EVENT_TYPE_OFFSET] == WRITE_ROWS_EVENT) &&
+ ++dbug_rows_event_count == 2)
+ {
+ const char act[]=
+ "now SIGNAL start_sql_thread "
+ "WAIT_FOR go_on_relay_logging";
+ DBUG_ASSERT(debug_sync_service);
+ DBUG_ASSERT(!debug_sync_set_action(current_thd,
+ STRING_WITH_LEN(act)));
+ };);
+#endif
mysql_mutex_lock(&mi->data_lock);
switch ((uchar)buf[EVENT_TYPE_OFFSET]) {
@@ -7049,9 +7071,12 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
DBUG_RETURN(ev);
}
- if (rli->ign_gtids.count())
+ if (rli->ign_gtids.count() && !rli->is_in_group())
{
- /* We generate and return a Gtid_list, to update gtid_slave_pos. */
+ /*
+ We generate and return a Gtid_list, to update gtid_slave_pos,
+ unless being in the middle of a group.
+ */
DBUG_PRINT("info",("seeing ignored end gtids"));
ev= new Gtid_list_log_event(&rli->ign_gtids,
Gtid_list_log_event::FLAG_IGN_GTIDS);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index a4e522b90d3..e07b03f7bb1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -4041,7 +4041,7 @@ void Security_context::destroy()
if (external_user)
{
my_free(external_user);
- user= NULL;
+ external_user= NULL;
}
my_free(ip);
@@ -4259,6 +4259,10 @@ extern "C" enum thd_kill_levels thd_kill_level(const MYSQL_THD thd)
however not more often than global.progress_report_time.
If global.progress_report_time is 0, then don't send progress reports, but
check every second if the value has changed
+
+ We clear any errors that we get from sending the progress packet to
+ the client as we don't want to set an error without the caller knowing
+ about it.
*/
static void thd_send_progress(THD *thd)
@@ -4275,8 +4279,12 @@ static void thd_send_progress(THD *thd)
thd->progress.next_report_time= (report_time +
seconds_to_next * 1000000000ULL);
if (global_system_variables.progress_report_time &&
- thd->variables.progress_report_time)
+ thd->variables.progress_report_time && !thd->is_error())
+ {
net_send_progress_packet(thd);
+ if (thd->is_error())
+ thd->clear_error();
+ }
}
}
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 561ef91be4a..6d202477b76 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -5716,8 +5716,8 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
- char tmp_path[FN_REFLEN];
- char normal_path[FN_REFLEN];
+ char tmp_path[FN_REFLEN + 1];
+ char normal_path[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
uint temp_partitions= part_info->temp_partitions.elements;
uint num_elements= part_info->partitions.elements;
@@ -5741,14 +5741,15 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type);
- create_subpartition_name(tmp_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- TEMP_PART_NAME);
- create_subpartition_name(normal_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name,
+ TEMP_PART_NAME) ||
+ create_subpartition_name(normal_path, sizeof(normal_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name,
+ NORMAL_PART_NAME))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= normal_path;
ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED)
@@ -5769,12 +5770,13 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type);
- create_partition_name(tmp_path, path,
- part_elem->partition_name,
- TEMP_PART_NAME, TRUE);
- create_partition_name(normal_path, path,
- part_elem->partition_name,
- NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name, TEMP_PART_NAME,
+ TRUE) ||
+ create_partition_name(normal_path, sizeof(normal_path), path,
+ part_elem->partition_name, NORMAL_PART_NAME,
+ TRUE))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= normal_path;
ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED)
@@ -5813,7 +5815,7 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
- char tmp_path[FN_LEN];
+ char tmp_path[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
List_iterator<partition_element> temp_it(part_info->temp_partitions);
uint num_temp_partitions= part_info->temp_partitions.elements;
@@ -5852,10 +5854,10 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type);
- create_subpartition_name(tmp_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- name_variant);
+ if (create_subpartition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, name_variant))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= tmp_path;
if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{
@@ -5871,9 +5873,10 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type);
- create_partition_name(tmp_path, path,
- part_elem->partition_name,
- name_variant, TRUE);
+ if (create_partition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name, name_variant,
+ TRUE))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= tmp_path;
if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{
@@ -8031,31 +8034,41 @@ static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
return res;
}
+/* used in error messages below */
+static const char *longest_str(const char *s1, const char *s2,
+ const char *s3=0)
+{
+ if (strlen(s2) > strlen(s1)) s1= s2;
+ if (s3 && strlen(s3) > strlen(s1)) s1= s3;
+ return s1;
+}
+
/*
Create partition names
SYNOPSIS
create_partition_name()
- out:out Created partition name string
+ out:out The buffer for the created partition name string
+ must be *at least* of FN_REFLEN+1 bytes
in1 First part
in2 Second part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
- NONE
+ 0 if ok, error if name too long
DESCRIPTION
This method is used to calculate the partition name, service routine to
the del_ren_cre_table method.
*/
-void create_partition_name(char *out, const char *in1,
- const char *in2, uint name_variant,
- bool translate)
+int create_partition_name(char *out, size_t outlen, const char *in1,
+ const char *in2, uint name_variant, bool translate)
{
char transl_part_name[FN_REFLEN];
- const char *transl_part;
+ const char *transl_part, *end;
+ DBUG_ASSERT(outlen >= FN_REFLEN + 1); // consistency! same limit everywhere
if (translate)
{
@@ -8065,11 +8078,17 @@ void create_partition_name(char *out, const char *in1,
else
transl_part= in2;
if (name_variant == NORMAL_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, "#TMP#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, "#REN#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#REN#", NullS);
+ if (end - out == static_cast<ptrdiff_t>(outlen-1))
+ {
+ my_error(ER_PATH_LENGTH, MYF(0), longest_str(in1, transl_part));
+ return HA_WRONG_CREATE_OPTION;
+ }
+ return 0;
}
@@ -8078,37 +8097,46 @@ void create_partition_name(char *out, const char *in1,
SYNOPSIS
create_subpartition_name()
- out:out Created partition name string
+ out:out The buffer for the created partition name string
+ must be *at least* of FN_REFLEN+1 bytes
in1 First part
in2 Second part
in3 Third part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
- NONE
+ 0 if ok, error if name too long
DESCRIPTION
This method is used to calculate the subpartition name, service routine to
the del_ren_cre_table method.
*/
-void create_subpartition_name(char *out, const char *in1,
- const char *in2, const char *in3,
- uint name_variant)
+int create_subpartition_name(char *out, size_t outlen,
+ const char *in1, const char *in2,
+ const char *in3, uint name_variant)
{
- char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN];
+ char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN], *end;
+ DBUG_ASSERT(outlen >= FN_REFLEN + 1); // consistency! same limit everywhere
tablename_to_filename(in2, transl_part_name, FN_REFLEN);
tablename_to_filename(in3, transl_subpart_name, FN_REFLEN);
if (name_variant == NORMAL_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, NullS);
else if (name_variant == TEMP_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, "#TMP#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, "#REN#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, "#REN#", NullS);
+ if (end - out == static_cast<ptrdiff_t>(outlen-1))
+ {
+ my_error(ER_PATH_LENGTH, MYF(0),
+ longest_str(in1, transl_part_name, transl_subpart_name));
+ return HA_WRONG_CREATE_OPTION;
+ }
+ return 0;
}
uint get_partition_field_store_length(Field *field)
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 96136790046..2d0ec788332 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -280,12 +280,12 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
#define partition_key_modified(X,Y) 0
#endif
-void create_partition_name(char *out, const char *in1,
- const char *in2, uint name_variant,
- bool translate);
-void create_subpartition_name(char *out, const char *in1,
- const char *in2, const char *in3,
- uint name_variant);
+int __attribute__((warn_unused_result))
+ create_partition_name(char *out, size_t outlen, const char *in1, const char
+ *in2, uint name_variant, bool translate);
+int __attribute__((warn_unused_result))
+ create_subpartition_name(char *out, size_t outlen, const char *in1, const
+ char *in2, const char *in3, uint name_variant);
void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
const uchar *old_buf);
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 18f25ab7cf7..f5e47206963 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -493,7 +493,7 @@ bool Sql_cmd_alter_table_exchange_partition::
partition_element *part_elem;
char *partition_name;
char temp_name[FN_REFLEN+1];
- char part_file_name[FN_REFLEN+1];
+ char part_file_name[2*FN_REFLEN+1];
char swap_file_name[FN_REFLEN+1];
char temp_file_name[FN_REFLEN+1];
uint swap_part_id;
@@ -588,9 +588,9 @@ bool Sql_cmd_alter_table_exchange_partition::
temp_name, "", FN_IS_TMP);
if (!(part_elem= part_table->part_info->get_part_elem(partition_name,
- part_file_name +
- part_file_name_len,
- &swap_part_id)))
+ part_file_name + part_file_name_len,
+ sizeof(part_file_name) - part_file_name_len,
+ &swap_part_id)))
{
// my_error(ER_UNKNOWN_PARTITION, MYF(0), partition_name,
// part_table->alias);
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 810c0fd9c4d..7f83905547b 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1708,7 +1708,6 @@ int ha_archive::info(uint flag)
stats.update_time= (ulong) file_stat.st_mtime;
if (flag & HA_STATUS_CONST)
{
- stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length;
stats.max_data_file_length= MAX_FILE_SIZE;
stats.create_time= (ulong) file_stat.st_ctime;
}
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index e143ed793e4..defa11ad6b4 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -1263,6 +1263,7 @@ static my_bool translog_set_lsn_for_files(uint32 from_file, uint32 to_file,
mysql_file_close(fd, MYF(MY_WME))))
{
translog_stop_writing();
+ mysql_mutex_unlock(&log_descriptor.file_header_lock);
DBUG_RETURN(1);
}
}
@@ -2277,10 +2278,11 @@ static void translog_set_only_in_buffers(TRANSLOG_ADDRESS in_buffers)
if (cmp_translog_addr(in_buffers, log_descriptor.in_buffers_only) > 0)
{
if (translog_status != TRANSLOG_OK)
- DBUG_VOID_RETURN;
+ goto end;
log_descriptor.in_buffers_only= in_buffers;
DBUG_PRINT("info", ("set new in_buffers_only"));
}
+end:
mysql_mutex_unlock(&log_descriptor.sent_to_disk_lock);
DBUG_VOID_RETURN;
}
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index caaaacfc9b1..a1c407967b7 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -3475,6 +3475,7 @@ restart:
lock_to_read[lock].unlock_lock,
unlock_pin, FALSE))
{
+ pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_ASSERT(0);
return (uchar*) 0;
}
diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index 96f24ff2e00..2b29c46be77 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -202,7 +202,7 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
const TABLE *table, partition_element **part_elem,
partition_element **sub_elem)
{
- char tmp_name[FN_LEN];
+ char tmp_name[FN_REFLEN + 1];
partition_info *part_info = table->part_info;
partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL;
bool tmp_flg = FALSE, tmp_find_flg = FALSE;
@@ -224,9 +224,10 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
while ((*sub_elem = sub_it++))
{
- create_subpartition_name(tmp_name, table->s->path.str,
- (*part_elem)->partition_name, (*sub_elem)->partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(tmp_name, sizeof(tmp_name), table->s->path.str,
+ (*part_elem)->partition_name, (*sub_elem)->partition_name,
+ NORMAL_PART_NAME))
+ DBUG_VOID_RETURN;
DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name));
if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
@@ -243,8 +244,9 @@ void mrn_get_partition_info(const char *table_name, uint table_name_length,
}
}
} else {
- create_partition_name(tmp_name, table->s->path.str,
- (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(tmp_name, sizeof(tmp_name), table->s->path.str,
+ (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE))
+ DBUG_VOID_RETURN;
DBUG_PRINT("info", ("mroonga tmp_name=%s", tmp_name));
if (table_name && !memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index e980a42eef0..4b677b3b2fe 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -6937,7 +6937,7 @@ void spider_get_partition_info(
partition_element **part_elem,
partition_element **sub_elem
) {
- char tmp_name[FN_LEN];
+ char tmp_name[FN_REFLEN + 1];
partition_element *tmp_part_elem = NULL, *tmp_sub_elem = NULL;
bool tmp_flg = FALSE, tmp_find_flg = FALSE;
DBUG_ENTER("spider_get_partition_info");
@@ -6958,9 +6958,10 @@ void spider_get_partition_info(
List_iterator<partition_element> sub_it((*part_elem)->subpartitions);
while ((*sub_elem = sub_it++))
{
- create_subpartition_name(tmp_name, table_share->path.str,
- (*part_elem)->partition_name, (*sub_elem)->partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(tmp_name, sizeof(tmp_name),
+ table_share->path.str, (*part_elem)->partition_name,
+ (*sub_elem)->partition_name, NORMAL_PART_NAME))
+ DBUG_VOID_RETURN;
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
@@ -6976,8 +6977,10 @@ void spider_get_partition_info(
}
}
} else {
- create_partition_name(tmp_name, table_share->path.str,
- (*part_elem)->partition_name, NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(tmp_name, sizeof(tmp_name),
+ table_share->path.str, (*part_elem)->partition_name,
+ NORMAL_PART_NAME, TRUE))
+ DBUG_VOID_RETURN;
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!memcmp(table_name, tmp_name, table_name_length + 1))
DBUG_VOID_RETURN;
@@ -8443,7 +8446,7 @@ int spider_discover_table_structure(
spider_free_share_resource_only(spider_share);
#ifdef WITH_PARTITION_STORAGE_ENGINE
} else {
- char tmp_name[FN_LEN];
+ char tmp_name[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
partition_element *part_elem, *sub_elem;
while ((part_elem = part_it++))
@@ -8454,9 +8457,10 @@ int spider_discover_table_structure(
while ((sub_elem = sub_it++))
{
str.length(str_len);
- create_subpartition_name(tmp_name, table_name,
- (part_elem)->partition_name, (sub_elem)->partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(tmp_name, sizeof(tmp_name), table_name,
+ (part_elem)->partition_name, (sub_elem)->partition_name,
+ NORMAL_PART_NAME))
+ DBUG_RETURN(1);
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!(spider_share = spider_create_share(table_name, share,
part_info,
@@ -8479,8 +8483,9 @@ int spider_discover_table_structure(
break;
} else {
str.length(str_len);
- create_partition_name(tmp_name, table_name,
- (part_elem)->partition_name, NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(tmp_name, sizeof(tmp_name), table_name,
+ (part_elem)->partition_name, NORMAL_PART_NAME, TRUE))
+ DBUG_RETURN(1);
DBUG_PRINT("info",("spider tmp_name=%s", tmp_name));
if (!(spider_share = spider_create_share(table_name, share,
part_info,