summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Richter <georg@mariadb.com>2019-06-13 08:29:41 +0200
committerGeorg Richter <georg@mariadb.com>2019-06-13 08:29:41 +0200
commit6fa4cf1856bd3a3edac16fc53e3a1abf1d99fae9 (patch)
treeb186376862c1de21134818a4ecd394ee9fbe4f46
parentffa32522c0dafed10151750c7d295ceb3b66c2c4 (diff)
parent8e3a4be45c551883d37e5598f0b4108ccf31521c (diff)
downloadmariadb-git-6fa4cf1856bd3a3edac16fc53e3a1abf1d99fae9.tar.gz
Merge branch '10.4' of https://github.com/MariaDB/server into bb-10.4-MDEV14101
-rw-r--r--client/CMakeLists.txt4
-rw-r--r--client/mysqldump.c4
-rw-r--r--extra/mariabackup/xtrabackup.cc6
-rw-r--r--mysql-test/lib/My/Config.pm17
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm8
-rw-r--r--mysql-test/main/invisible_field.result4
-rw-r--r--mysql-test/main/join.result31
-rw-r--r--mysql-test/main/join.test30
-rw-r--r--mysql-test/main/opt_trace.result318
-rw-r--r--mysql-test/main/opt_trace.test54
-rw-r--r--mysql-test/main/opt_trace_ucs2.result54
-rw-r--r--mysql-test/main/opt_trace_ucs2.test10
-rw-r--r--mysql-test/main/order_by.result2
-rw-r--r--mysql-test/main/subselect_no_semijoin.result55
-rw-r--r--mysql-test/main/subselect_no_semijoin.test23
-rw-r--r--mysql-test/main/subselect_sj.result79
-rw-r--r--mysql-test/main/subselect_sj.test52
-rw-r--r--mysql-test/main/subselect_sj_jcl6.result63
-rw-r--r--mysql-test/main/subselect_sj_nonmerged.result12
-rw-r--r--mysql-test/main/table_elim.result2
-rw-r--r--mysql-test/main/win.result27
-rw-r--r--mysql-test/main/win.test16
-rw-r--r--mysql-test/suite/archive/disabled.def2
-rw-r--r--mysql-test/suite/binlog/r/flashback-largebinlog.result71
-rw-r--r--mysql-test/suite/binlog/t/flashback-largebinlog.test110
-rw-r--r--mysql-test/suite/encryption/r/compressed_import_tablespace.result39
-rw-r--r--mysql-test/suite/encryption/t/compressed_import_tablespace.opt3
-rw-r--r--mysql-test/suite/encryption/t/compressed_import_tablespace.test45
-rw-r--r--mysql-test/suite/gcol/r/gcol_select_myisam.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result4
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--plugin/auth_ed25519/CMakeLists.txt4
-rw-r--r--sql/field.cc55
-rw-r--r--sql/field.h14
-rw-r--r--sql/ha_partition.cc26
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_windowfunc.h12
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/opt_range.cc32
-rw-r--r--sql/records.cc18
-rw-r--r--sql/records.h5
-rw-r--r--sql/sql_bitmap.h12
-rw-r--r--sql/sql_explain.cc5
-rw-r--r--sql/sql_explain.h1
-rw-r--r--sql/sql_select.cc56
-rw-r--r--sql/sql_string.cc12
-rw-r--r--sql/sql_string.h3
-rw-r--r--sql/sql_window.cc2
-rw-r--r--storage/innobase/buf/buf0buf.cc4
-rw-r--r--storage/innobase/include/buf0buf.h71
-rw-r--r--storage/innobase/include/buf0types.h71
-rw-r--r--storage/innobase/include/log0recv.h4
-rw-r--r--storage/innobase/include/os0file.h6
-rw-r--r--storage/innobase/include/os0file.ic2
-rw-r--r--storage/innobase/include/row0merge.h4
-rw-r--r--storage/innobase/log/log0recv.cc6
-rw-r--r--storage/innobase/os/os0file.cc6
-rw-r--r--storage/innobase/row/row0import.cc14
-rw-r--r--storage/innobase/row/row0merge.cc4
-rw-r--r--storage/maria/ha_maria.cc7
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/slow_query_log.awk2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_slocket_socket.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_table.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_and_run.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_slocket.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/remove_slocket_socket.sh2
-rwxr-xr-xstorage/rocksdb/mysql-test/rocksdb_hotbackup/include/setup_replication_gtid.sh2
-rw-r--r--storage/spider/ha_spider.cc4
-rw-r--r--storage/spider/ha_spider.h2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/same_server_link_deinit.inc11
-rw-r--r--storage/spider/mysql-test/spider/bugfix/include/same_server_link_init.inc15
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/same_server_link.result42
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/same_server_link.cnf2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/same_server_link.test55
-rw-r--r--storage/spider/spd_db_mysql.cc30
-rw-r--r--storage/spider/spd_err.h3
-rw-r--r--storage/spider/spd_table.cc8
-rw-r--r--support-files/rpm/server-preun.sh6
-rw-r--r--tests/mysql_client_test.c30
-rw-r--r--unittest/mysys/CMakeLists.txt4
-rw-r--r--unittest/sql/CMakeLists.txt2
84 files changed, 1595 insertions, 256 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 96346808a62..37087b7c6c6 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -72,10 +72,10 @@ MYSQL_ADD_EXECUTABLE(mysql_plugin mysql_plugin.c)
TARGET_LINK_LIBRARIES(mysql_plugin ${CLIENT_LIB})
MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc)
-TARGET_LINK_LIBRARIES(mysqlbinlog ${CLIENT_LIB})
+TARGET_LINK_LIBRARIES(mysqlbinlog ${CLIENT_LIB} mysys_ssl)
MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc ../sql/password.c)
-TARGET_LINK_LIBRARIES(mysqladmin ${CLIENT_LIB})
+TARGET_LINK_LIBRARIES(mysqladmin ${CLIENT_LIB} mysys_ssl)
MYSQL_ADD_EXECUTABLE(mysqlslap mysqlslap.c)
SET_SOURCE_FILES_PROPERTIES(mysqlslap.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 16dab10f3fb..7cc61720bbe 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -971,6 +971,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
exit(1);
}
break;
+ case (int) OPT_DEFAULT_CHARSET:
+ if (default_charset == disabled_my_option)
+ default_charset= (char *)mysql_universal_client_charset;
+ break;
}
return 0;
}
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 51133b083e8..f0388048cdd 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -5207,7 +5207,11 @@ next_file_item_1:
goto next_datadir_item;
}
- snprintf(dbpath, sizeof(dbpath)-1, "%s/%s", path, dbinfo.name);
+ snprintf(dbpath, sizeof(dbpath), "%.*s/%.*s",
+ OS_FILE_MAX_PATH/2-1,
+ path,
+ OS_FILE_MAX_PATH/2-1,
+ dbinfo.name);
os_normalize_path(dbpath);
diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm
index 12647edf0a4..ecc0830c3df 100644
--- a/mysql-test/lib/My/Config.pm
+++ b/mysql-test/lib/My/Config.pm
@@ -21,6 +21,17 @@ use strict;
use warnings;
use Carp;
+# Define all MariaDB options that the user should be able to specify
+# many times in the config file. Note that options must be written
+# using '-' instead of '_' here!
+
+my %multipart_options=
+ (
+ "plugin-load-add" => 1,
+ "optimizer-switch" => 1,
+);
+
+
sub new {
my ($class, $option_name, $option_value)= @_;
my $self= bless { name => $option_name,
@@ -327,7 +338,6 @@ sub new {
# Skip comment
next;
}
-
else {
croak "Unexpected line '$line' found in '$path'";
}
@@ -355,6 +365,11 @@ sub insert {
if ( defined $option ) {
#print "option: $option, value: $value\n";
+ my $tmp_option= $option;
+ $tmp_option =~ s/_/-/g;
+
+ # If the option is an option that one can specify many times, always add
+ $if_not_exist= 1 if ($multipart_options{$tmp_option});
# Add the option to the group
$group->insert($option, $value, $if_not_exist);
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index 60eb1ee94d5..261de37ab54 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -291,7 +291,7 @@ sub post_check_client_groups {
$first_mysqld->name());
# Then generate [client.<suffix>] for each [mysqld.<suffix>]
- foreach my $mysqld ( $config->like('mysqld.') ) {
+ foreach my $mysqld ( $config->like('mysqld\.') ) {
$self->post_check_client_group($config,
'client'.$mysqld->after('mysqld'),
$mysqld->name())
@@ -313,7 +313,7 @@ sub post_check_embedded_group {
my $mysqld= $config->group('mysqld') or
croak "Can't run with embedded, config has no default mysqld section";
- my $first_mysqld= $config->first_like('mysqld.') or
+ my $first_mysqld= $config->first_like('mysqld\.') or
croak "Can't run with embedded, config has no mysqld";
my %no_copy = map { $_ => 1 }
@@ -351,7 +351,7 @@ sub resolve_at_variable {
}
$res .= $after;
- $config->insert($group->name(), $option->name(), $res)
+ $option->{value}= $res;
}
@@ -436,7 +436,7 @@ sub new_config {
}
$self->run_section_rules($config,
- 'mysqld.',
+ 'mysqld\.',
@mysqld_rules);
# [mysqlbinlog] need additional settings
diff --git a/mysql-test/main/invisible_field.result b/mysql-test/main/invisible_field.result
index 36e62645ef2..87c2b940c7e 100644
--- a/mysql-test/main/invisible_field.result
+++ b/mysql-test/main/invisible_field.result
@@ -404,8 +404,8 @@ b int(11) YES NULL
c int(11) YES NULL
explain select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b,c NULL NULL NULL 10
-1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using where
+1 SIMPLE t1 ref b,c b 5 test.t2.c 1 Using where
select * from t1,t2 where t1.b = t2.c and t1.c = t2.b;
a a b c
1 1 1 1
diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result
index 47c3e78116f..5c7f24b8d62 100644
--- a/mysql-test/main/join.result
+++ b/mysql-test/main/join.result
@@ -1605,3 +1605,34 @@ SELECT STRAIGHT_JOIN * FROM t1, t2 AS t2_1, t2 AS t2_2
WHERE t2_2.c = t2_1.c AND t2_2.b = t2_1.b AND ( a IS NULL OR t2_1.c = a );
a b c b c
DROP TABLE t1,t2;
+#
+# MDEV-19600: The optimizer should be able to produce rows=1 estimate for unique index with NULLable columns
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+pk int not null primary key auto_increment,
+a int,
+b int,
+unique key(a)
+);
+insert into t1 (a,b) select null, 12345 from t0 A, t0 B, t0 C;
+insert into t1 (a,b) select a,a from t0;
+# Simulate InnoDB's persistent statistics (It always uses nulls_equal)
+set @tmp1= @@myisam_stats_method;
+set myisam_stats_method=nulls_equal;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+set myisam_stats_method=@tmp1;
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+t1 0 PRIMARY 1 pk A 1010 NULL NULL BTREE
+t1 0 a 1 a A 1010 NULL NULL YES BTREE
+# t1 must use ref(t1.a=t0.a) and rows must be 1 (and not 45):
+explain select * from t0,t1 where t0.a=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
+1 SIMPLE t1 ref a a 5 test.t0.a 1
+drop table t0,t1;
diff --git a/mysql-test/main/join.test b/mysql-test/main/join.test
index 6b0481d859b..223886b579c 100644
--- a/mysql-test/main/join.test
+++ b/mysql-test/main/join.test
@@ -1255,3 +1255,33 @@ SELECT STRAIGHT_JOIN * FROM t1, t2 AS t2_1, t2 AS t2_2
WHERE t2_2.c = t2_1.c AND t2_2.b = t2_1.b AND ( a IS NULL OR t2_1.c = a );
DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-19600: The optimizer should be able to produce rows=1 estimate for unique index with NULLable columns
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (
+ pk int not null primary key auto_increment,
+ a int,
+ b int,
+ unique key(a)
+);
+
+# 10K of null values
+insert into t1 (a,b) select null, 12345 from t0 A, t0 B, t0 C;
+insert into t1 (a,b) select a,a from t0;
+
+--echo # Simulate InnoDB's persistent statistics (It always uses nulls_equal)
+set @tmp1= @@myisam_stats_method;
+set myisam_stats_method=nulls_equal;
+analyze table t1;
+set myisam_stats_method=@tmp1;
+show keys from t1;
+
+--echo # t1 must use ref(t1.a=t0.a) and rows must be 1 (and not 45):
+explain select * from t0,t1 where t0.a=t1.a;
+
+drop table t0,t1;
diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result
index 3e4b7fe6e8a..c0e0b4807a1 100644
--- a/mysql-test/main/opt_trace.result
+++ b/mysql-test/main/opt_trace.result
@@ -867,7 +867,7 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b {
"table": "t1",
"field": "a",
"equals": "t2.b + 2",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t2",
@@ -1446,7 +1446,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id {
{
"index": "id",
"covering": true,
- "ranges": ["(0x24a20f) <= (a)"],
+ "ranges": ["(2001-01-04) <= (a)"],
"rows": 9,
"cost": 2.35
}
@@ -1462,7 +1462,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id {
"rows": 9,
"cost": 2.35,
"key_parts_used_for_access": ["id"],
- "ranges": ["(0x24a20f) <= (a)"],
+ "ranges": ["(2001-01-04) <= (a)"],
"chosen": false,
"cause": "cost"
},
@@ -1624,7 +1624,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id {
{
"index": "id",
"covering": true,
- "ranges": ["(0x24a20f) <= (a) <= (0x24a20f)"],
+ "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"],
"rows": 9,
"cost": 2.35
}
@@ -1640,7 +1640,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id {
"rows": 9,
"cost": 2.35,
"key_parts_used_for_access": ["id", "a"],
- "ranges": ["(0x24a20f) <= (a) <= (0x24a20f)"],
+ "ranges": ["(2001-01-04) <= (a) <= (2001-01-04)"],
"chosen": false,
"cause": "cost"
},
@@ -1805,19 +1805,19 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 {
"table": "t1",
"field": "a",
"equals": "1",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "a",
"equals": "1",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "b",
"equals": "2",
- "null_rejecting": false
+ "null_rejecting": true
}
]
},
@@ -2821,37 +2821,37 @@ explain select * from t1 where pk = 2 and a=5 and b=1 {
"table": "t1",
"field": "pk",
"equals": "2",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "pk",
"equals": "2",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "a",
"equals": "5",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "pk",
"equals": "2",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "a",
"equals": "5",
- "null_rejecting": false
+ "null_rejecting": true
},
{
"table": "t1",
"field": "b",
"equals": "1",
- "null_rejecting": false
+ "null_rejecting": true
}
]
},
@@ -6130,7 +6130,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
"index": "start_date",
"ranges":
[
- "(0x4ac60f,NULL) < (start_date,end_date)"
+ "(2019-02-10,NULL) < (start_date,end_date)"
],
"rowid_ordered": false,
"using_mrr": false,
@@ -6214,7 +6214,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
"index": "i_b",
"ranges":
[
- "(0xd95b94336a9946a39cf5b58cfe772d8c) <= (b) <= (0xd95b94336a9946a39cf5b58cfe772d8c)"
+ "(\xD9[\x943j\x99F\xA3\x9C\xF5\xB5\x8C\xFEw-\x8C) <= (b) <= (\xD9[\x943j\x99F\xA3\x9C\xF5\xB5\x8C\xFEw-\x8C)"
],
"rowid_ordered": true,
"using_mrr": false,
@@ -6268,4 +6268,290 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
}
]
drop table t1;
+#
+# MDEV-18880: Optimizer trace prints date in hexadecimal
+#
+CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10) CHARSET BINARY , INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 13 const 1 Using index condition
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\x0A) <= (b) <= (ab\x0A)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1,
+ "cost": 2.3787,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+ALTER TABLE t1 modify column b BINARY(10) AFTER i;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 11 const 1 Using index condition
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\x0A\x00\x00\x00\x00\x00\x00\x00) <= (b) <= (ab\x0A\x00\x00\x00\x00\x00\x00\x00)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1,
+ "cost": 2.3785,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+ALTER TABLE t1 modify column b VARBINARY(10) AFTER i;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 13 const 1 Using index condition
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\x0A) <= (b) <= (ab\x0A)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1,
+ "cost": 2.3787,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
+CREATE TABLE t1(i INT PRIMARY KEY, b CHAR(10), INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 11 const 1 Using index condition
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\n) <= (b) <= (ab\n)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1,
+ "cost": 2.3785,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
+CREATE TABLE t1(i INT PRIMARY KEY, b blob , INDEX i_b(b));
+Warnings:
+Note 1071 Specified key was too long; max key length is 1000 bytes
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b= 'ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 1003 const 1 Using where
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\x0A) <= (b) <= (ab\x0A)"
+ ],
+ "rowid_ordered": false,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1,
+ "cost": 3.5719,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
+CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10), INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, 'ab\n');
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref i_b i_b 13 const 2 Using index condition
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "i_b",
+ "ranges":
+ [
+ "(ab\n) <= (b) <= (ab\n)"
+ ],
+ "rowid_ordered": true,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 2,
+ "cost": 3.6324,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table one_k (a int);
+insert into one_k select A.a + B.a*10 + C.a*100 from t0 A, t0 B, t0 C;
+create table t1 (start_date date, end_date date, filler char(100), key(start_date, end_date)) ;
+insert into t1 select date_add(now(), interval a day), date_add(now(), interval (a+7) day), 'data' from one_k;
+explain format=json select * from t1 force index(start_date) where start_date >= '2019-02-10' and end_date <'2019-04-01';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["start_date"],
+ "key": "start_date",
+ "key_length": "8",
+ "used_key_parts": ["start_date", "end_date"],
+ "rows": 1000,
+ "filtered": 100,
+ "index_condition": "t1.start_date >= '2019-02-10' and t1.end_date < '2019-04-01'"
+ }
+ }
+}
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "start_date",
+ "ranges":
+ [
+ "(2019-02-10,NULL) < (start_date,end_date)"
+ ],
+ "rowid_ordered": false,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 1000,
+ "cost": 1282.2,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1, t0, one_k;
set optimizer_trace='enabled=off';
diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test
index 981a53ac1ad..916b9313ca6 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -444,4 +444,58 @@ select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) fr
drop table t1;
+--echo #
+--echo # MDEV-18880: Optimizer trace prints date in hexadecimal
+--echo #
+
+CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10) CHARSET BINARY , INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+
+ALTER TABLE t1 modify column b BINARY(10) AFTER i;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+
+ALTER TABLE t1 modify column b VARBINARY(10) AFTER i;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
+
+CREATE TABLE t1(i INT PRIMARY KEY, b CHAR(10), INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
+
+CREATE TABLE t1(i INT PRIMARY KEY, b blob , INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, NULL);
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b= 'ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
+
+CREATE TABLE t1(i INT PRIMARY KEY, b VARCHAR(10), INDEX i_b(b));
+INSERT INTO t1 VALUES (1, 'ab\n');
+INSERT INTO t1 VALUES (2, 'ab\n');
+set optimizer_trace=1;
+EXPLAIN SELECT * FROM t1 WHERE b='ab\n';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table one_k (a int);
+insert into one_k select A.a + B.a*10 + C.a*100 from t0 A, t0 B, t0 C;
+create table t1 (start_date date, end_date date, filler char(100), key(start_date, end_date)) ;
+--disable_warnings
+insert into t1 select date_add(now(), interval a day), date_add(now(), interval (a+7) day), 'data' from one_k;
+--enable_warnings
+explain format=json select * from t1 force index(start_date) where start_date >= '2019-02-10' and end_date <'2019-04-01';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1, t0, one_k;
+
set optimizer_trace='enabled=off';
diff --git a/mysql-test/main/opt_trace_ucs2.result b/mysql-test/main/opt_trace_ucs2.result
new file mode 100644
index 00000000000..306fdbf94ad
--- /dev/null
+++ b/mysql-test/main/opt_trace_ucs2.result
@@ -0,0 +1,54 @@
+create or replace table t1 (col1 char(10) character set ucs2, filler char(100), key(col1)) ;
+insert into t1 values ('a', 'a');
+insert into t1 values ('a', 'a');
+set optimizer_trace=1;
+explain format=json select * from t1 force index(col1) where col1 >='a';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "range",
+ "possible_keys": ["col1"],
+ "key": "col1",
+ "key_length": "21",
+ "used_key_parts": ["col1"],
+ "rows": 2,
+ "filtered": 100,
+ "index_condition": "t1.col1 >= 'a'"
+ }
+ }
+}
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives'))
+[
+
+ {
+ "range_scan_alternatives":
+ [
+
+ {
+ "index": "col1",
+ "ranges":
+ [
+ "(a) <= (col1)"
+ ],
+ "rowid_ordered": false,
+ "using_mrr": false,
+ "index_only": false,
+ "rows": 2,
+ "cost": 3.7609,
+ "chosen": true
+ }
+ ],
+ "analyzing_roworder_intersect":
+ {
+ "cause": "too few roworder scans"
+ },
+ "analyzing_index_merge_union":
+ [
+ ]
+ }
+]
+drop table t1;
diff --git a/mysql-test/main/opt_trace_ucs2.test b/mysql-test/main/opt_trace_ucs2.test
new file mode 100644
index 00000000000..827dc403d58
--- /dev/null
+++ b/mysql-test/main/opt_trace_ucs2.test
@@ -0,0 +1,10 @@
+--source include/not_embedded.inc
+--source include/have_ucs2.inc
+
+create or replace table t1 (col1 char(10) character set ucs2, filler char(100), key(col1)) ;
+insert into t1 values ('a', 'a');
+insert into t1 values ('a', 'a');
+set optimizer_trace=1;
+explain format=json select * from t1 force index(col1) where col1 >='a';
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+drop table t1;
diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result
index 9532c2995ce..b059cc686cd 100644
--- a/mysql-test/main/order_by.result
+++ b/mysql-test/main/order_by.result
@@ -1589,7 +1589,7 @@ WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range a,b,c c 5 NULL 420 Using where
-1 SIMPLE t1 ref a a 39 test.t2.a,const 10 Using where; Using index
+1 SIMPLE t1 ref a a 39 test.t2.a,const 1 Using where; Using index
SELECT d FROM t3 AS t1, t2 AS t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result
index 3265a4f81bb..c9a52512614 100644
--- a/mysql-test/main/subselect_no_semijoin.result
+++ b/mysql-test/main/subselect_no_semijoin.result
@@ -7314,5 +7314,60 @@ ERROR HY000: Illegal parameter data types row and boolean for operation '='
#
# End of 10.4 tests
#
+#
+# MDEV-19714: JOIN::pseudo_bits_cond is not visible in EXPLAIN FORMAT=JSON
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+SET @tmp19714=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=off';
+explain format=json
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100
+ },
+ "subqueries": [
+ {
+ "query_block": {
+ "select_id": 2,
+ "pseudo_bits_condition": "1 = t1.a or <in_optimizer>(1,<exists>(subquery#3))",
+ "table": {
+ "table_name": "t2",
+ "access_type": "system",
+ "rows": 1,
+ "filtered": 100
+ },
+ "subqueries": [
+ {
+ "query_block": {
+ "select_id": 3,
+ "table": {
+ "table_name": "t3",
+ "access_type": "ALL",
+ "rows": 2,
+ "filtered": 100,
+ "attached_condition": "1 = t3.c"
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+}
+SET optimizer_switch=@tmp19714;
+drop table t1,t2,t3;
set @optimizer_switch_for_subselect_test=null;
set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/main/subselect_no_semijoin.test b/mysql-test/main/subselect_no_semijoin.test
index 6b82b748912..84d312c03c8 100644
--- a/mysql-test/main/subselect_no_semijoin.test
+++ b/mysql-test/main/subselect_no_semijoin.test
@@ -8,5 +8,28 @@ set @join_cache_level_for_subselect_test=@@join_cache_level;
--source subselect.test
+--echo #
+--echo # MDEV-19714: JOIN::pseudo_bits_cond is not visible in EXPLAIN FORMAT=JSON
+--echo #
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1),(5);
+
+# t2 must be MyISAM or Aria and contain 1 row
+CREATE TABLE t2 ( b INT ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1);
+
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (4),(5);
+
+SET @tmp19714=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=off';
+
+explain format=json
+SELECT ( SELECT b FROM t2 WHERE b = a OR EXISTS ( SELECT c FROM t3 WHERE c = b ) ) FROM t1;
+
+SET optimizer_switch=@tmp19714;
+
+drop table t1,t2,t3;
+
set @optimizer_switch_for_subselect_test=null;
set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/main/subselect_sj.result b/mysql-test/main/subselect_sj.result
index 7114024310c..98143246673 100644
--- a/mysql-test/main/subselect_sj.result
+++ b/mysql-test/main/subselect_sj.result
@@ -2555,33 +2555,94 @@ CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) );
INSERT INTO t1 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),
(6,3),(7,1),(8,4),(9,3),(10,2);
-CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+CREATE TABLE t2 ( c INT, d INT, KEY(c) );
INSERT INTO t2 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+explain
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+( SELECT b, d FROM t1, t2 WHERE b = c );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+1 PRIMARY t1 index b b 5 NULL 10 Using where; Using index; LooseScan
+1 PRIMARY t2 ref c c 5 test.t1.b 1 Using where; FirstMatch(t1)
+1 PRIMARY t1 ref b b 5 test.t1.b 2
SELECT a, b, d FROM t1, t2
WHERE ( b, d ) IN
( SELECT b, d FROM t1, t2 WHERE b = c );
a b d
2 1 2
7 1 2
-2 1 2
-7 1 2
-1 2 1
-4 2 1
-10 2 1
+8 4 2
1 2 1
4 2 1
10 2 1
3 3 3
6 3 3
9 3 3
+2 1 2
+7 1 2
+8 4 2
+5 5 5
3 3 3
6 3 3
9 3 3
-8 4 2
-8 4 2
-5 5 5
+1 2 1
+4 2 1
+10 2 1
DROP TABLE t1, t2;
+# Another testcase for the above that still uses LooseScan:
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t10(a int primary key);
+insert into t10 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t1 (
+pk int primary key auto_increment,
+kp1 int,
+kp2 int,
+filler char(100),
+key (kp1, kp2)
+);
+insert into t1 (kp1, kp2, filler)
+select
+A.a, B.a, 'filler-data'
+from t0 A, t0 B;
+create table t2 (a int, filler char(100), key(a));
+create table t3 (a int);
+insert into t3 values (1),(2);
+insert into t2
+select (A.a+1000*B.a)/20, 'filler_data' from t10 A, t0 B;
+analyze table t1,t2,t3;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status Table is already up to date
+test.t3 analyze status Engine-independent statistics collected
+test.t3 analyze status OK
+delete from t1 where kp2 in (1,3);
+# Ref + LooseScan on t1:
+explain select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 10 Using where; Using index; LooseScan
+1 PRIMARY t2 ref a a 5 test.t1.kp2 19 Using index
+select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+sum(t2.a)
+1640
+drop table t0,t10;
+drop table t1,t2,t3;
#
# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
#
diff --git a/mysql-test/main/subselect_sj.test b/mysql-test/main/subselect_sj.test
index ad4577b72b0..b693f7b5b93 100644
--- a/mysql-test/main/subselect_sj.test
+++ b/mysql-test/main/subselect_sj.test
@@ -2285,16 +2285,66 @@ INSERT INTO t1 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),
(6,3),(7,1),(8,4),(9,3),(10,2);
-CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+CREATE TABLE t2 ( c INT, d INT, KEY(c) );
INSERT INTO t2 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+analyze table t1,t2;
+explain
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+ ( SELECT b, d FROM t1, t2 WHERE b = c );
SELECT a, b, d FROM t1, t2
WHERE ( b, d ) IN
( SELECT b, d FROM t1, t2 WHERE b = c );
DROP TABLE t1, t2;
+--echo # Another testcase for the above that still uses LooseScan:
+
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t10(a int primary key);
+insert into t10 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+
+create table t1 (
+ pk int primary key auto_increment,
+ kp1 int,
+ kp2 int,
+ filler char(100),
+ key (kp1, kp2)
+);
+
+# 10 groups, each has 10 elements.
+insert into t1 (kp1, kp2, filler)
+select
+ A.a, B.a, 'filler-data'
+from t0 A, t0 B;
+
+create table t2 (a int, filler char(100), key(a));
+
+create table t3 (a int);
+insert into t3 values (1),(2);
+
+insert into t2
+select (A.a+1000*B.a)/20, 'filler_data' from t10 A, t0 B;
+
+analyze table t1,t2,t3;
+delete from t1 where kp2 in (1,3);
+
+--echo # Ref + LooseScan on t1:
+explain select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+
+select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+
+drop table t0,t10;
+drop table t1,t2,t3;
+
--echo #
--echo # BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
--echo #
diff --git a/mysql-test/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result
index f7f87fc2511..acfafde6d7e 100644
--- a/mysql-test/main/subselect_sj_jcl6.result
+++ b/mysql-test/main/subselect_sj_jcl6.result
@@ -2569,9 +2569,24 @@ CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, KEY(b) );
INSERT INTO t1 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),
(6,3),(7,1),(8,4),(9,3),(10,2);
-CREATE TABLE t2 ( c INT, d INT, UNIQUE KEY(c) );
+CREATE TABLE t2 ( c INT, d INT, KEY(c) );
INSERT INTO t2 VALUES
(1,2),(2,1),(3,3),(4,2),(5,5),(6,3),(7,1);
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+explain
+SELECT a, b, d FROM t1, t2
+WHERE ( b, d ) IN
+( SELECT b, d FROM t1, t2 WHERE b = c );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7
+1 PRIMARY t1 index b b 5 NULL 10 Using where; Using index; LooseScan
+1 PRIMARY t2 ref c c 5 test.t1.b 1 Using where; FirstMatch(t1)
+1 PRIMARY t1 ref b b 5 test.t1.b 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
SELECT a, b, d FROM t1, t2
WHERE ( b, d ) IN
( SELECT b, d FROM t1, t2 WHERE b = c );
@@ -2596,6 +2611,52 @@ a b d
10 2 1
10 2 1
DROP TABLE t1, t2;
+# Another testcase for the above that still uses LooseScan:
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t10(a int primary key);
+insert into t10 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t1 (
+pk int primary key auto_increment,
+kp1 int,
+kp2 int,
+filler char(100),
+key (kp1, kp2)
+);
+insert into t1 (kp1, kp2, filler)
+select
+A.a, B.a, 'filler-data'
+from t0 A, t0 B;
+create table t2 (a int, filler char(100), key(a));
+create table t3 (a int);
+insert into t3 values (1),(2);
+insert into t2
+select (A.a+1000*B.a)/20, 'filler_data' from t10 A, t0 B;
+analyze table t1,t2,t3;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status Table is already up to date
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status Table is already up to date
+test.t3 analyze status Engine-independent statistics collected
+test.t3 analyze status OK
+delete from t1 where kp2 in (1,3);
+# Ref + LooseScan on t1:
+explain select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 10 Using where; Using index; LooseScan
+1 PRIMARY t2 ref a a 5 test.t1.kp2 19 Using index
+select sum(t2.a)
+from t2,t3
+where (t3.a,t2.a) in (select kp1,kp2 from t1,t0 where t0.a=2);
+sum(t2.a)
+1640
+drop table t0,t10;
+drop table t1,t2,t3;
#
# BUG#920713: Wrong result (missing rows) with firstmatch+BNL, IN subquery, ...
#
diff --git a/mysql-test/main/subselect_sj_nonmerged.result b/mysql-test/main/subselect_sj_nonmerged.result
index 47970668ae5..4d9a70e6bba 100644
--- a/mysql-test/main/subselect_sj_nonmerged.result
+++ b/mysql-test/main/subselect_sj_nonmerged.result
@@ -67,9 +67,9 @@ insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B;
explain select * from t0, t4 where
t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 10
-1 PRIMARY t4 ALL a NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t4.a 1
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),test.t0.a 1
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
@@ -77,9 +77,9 @@ explain select * from t4 where
t4.a in (select max(t2.a) from t1, t2 group by t2.b) and
t4.b in (select max(t2.a) from t1, t2 group by t2.b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5
-1 PRIMARY t4 ref a a 5 <subquery2>.max(t2.a) 12 Using index condition
-1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 test.t4.b 1
+1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join)
+1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
diff --git a/mysql-test/main/table_elim.result b/mysql-test/main/table_elim.result
index 2bfbbfb433f..bc03e1b251d 100644
--- a/mysql-test/main/table_elim.result
+++ b/mysql-test/main/table_elim.result
@@ -279,7 +279,7 @@ insert into t2 values
explain select t1.* from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
-1 SIMPLE t2 ref a a 3 test.t1.a 2 Using where
+1 SIMPLE t2 ref a a 3 test.t1.a 1 Using where
drop table t1, t2;
#
# check UPDATE/DELETE that look like they could be eliminated
diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result
index 85d645359ea..51a0f35ad61 100644
--- a/mysql-test/main/win.result
+++ b/mysql-test/main/win.result
@@ -3607,6 +3607,33 @@ b row_number() over (partition by sum(a)+1)
2000 1
drop table t1;
#
+# MDEV-18015: Assertion `global_status_var.global_memory_used == 0' failed when using UDF,
+# window functions and views
+#
+create table t1 (id int, n1 int);
+insert into t1 values (1,1),(2,1),(3,2),(4,4);
+explain
+select max(n1) over (partition by 'abc') from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary
+select max(n1) over (partition by 'abc') from t1;
+max(n1) over (partition by 'abc')
+4
+4
+4
+4
+explain
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+rank() over (partition by 'abc' order by 'xyz')
+1
+1
+1
+1
+drop table t1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test
index c5c5215b215..01b8f17b0f2 100644
--- a/mysql-test/main/win.test
+++ b/mysql-test/main/win.test
@@ -2326,6 +2326,22 @@ select b, row_number() over (partition by sum(a)+1) from t1 group by b;
drop table t1;
--echo #
+--echo # MDEV-18015: Assertion `global_status_var.global_memory_used == 0' failed when using UDF,
+--echo # window functions and views
+--echo #
+
+create table t1 (id int, n1 int);
+insert into t1 values (1,1),(2,1),(3,2),(4,4);
+explain
+select max(n1) over (partition by 'abc') from t1;
+select max(n1) over (partition by 'abc') from t1;
+
+explain
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+select rank() over (partition by 'abc' order by 'xyz') from t1;
+drop table t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/suite/archive/disabled.def b/mysql-test/suite/archive/disabled.def
index ae841eaaf33..888298bbb09 100644
--- a/mysql-test/suite/archive/disabled.def
+++ b/mysql-test/suite/archive/disabled.def
@@ -9,5 +9,3 @@
# Do not use any TAB characters for whitespace.
#
##############################################################################
-
-archive_gis : MDEV-17297 wait for the fix and then enable it
diff --git a/mysql-test/suite/binlog/r/flashback-largebinlog.result b/mysql-test/suite/binlog/r/flashback-largebinlog.result
new file mode 100644
index 00000000000..526204f259f
--- /dev/null
+++ b/mysql-test/suite/binlog/r/flashback-largebinlog.result
@@ -0,0 +1,71 @@
+#
+# Preparatory cleanup.
+#
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+DROP TABLE IF EXISTS t1;
+#
+# We need a fixed timestamp to avoid varying results.
+#
+SET timestamp=1000000000;
+#
+# We need big packets.
+#
+# Capture initial value to reset at the end of the test
+# Now adjust max_allowed_packet
+SET @@global.max_allowed_packet= 10*1024*1024*1024;
+Warnings:
+Warning 1292 Truncated incorrect max_allowed_packet value: '10737418240'
+max_allowed_packet is a global variable.
+In order for the preceding change in max_allowed_packets' value
+to be seen and used, we must start a new connection.
+The change does not take effect with the current one.
+For simplicity, we just disconnect / reconnect connection default here.
+disconnect default;
+connect default, localhost,root,,;
+#
+# Delete all existing binary logs.
+#
+RESET MASTER;
+#
+# Create a test table.
+#
+use mysqltest;
+CREATE TABLE t1 (
+c1 LONGTEXT
+) DEFAULT CHARSET latin1;
+#
+# Show how many rows are affected by each statement.
+#
+#
+# Insert some big rows.
+#
+insert 1024MB data twice
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 67108864));
+affected rows: 1
+INSERT INTO t1 VALUES (REPEAT('MegaByteBlckMany', 67108864));
+affected rows: 1
+#
+# Flush all log buffers to the log file.
+#
+FLUSH LOGS;
+affected rows: 0
+#
+# Call mysqlbinlog to display the log file contents.
+# NOTE: The output of mysqlbinlog is redirected to
+# $MYSQLTEST_VARDIR/tmp/mysqlbinlog_big_1.out
+# If you want to examine it, disable remove_file
+# at the bottom of the test script.
+#
+#
+# Cleanup.
+#
+# reset variable value to pass testcase checks
+SET @@global.max_allowed_packet = 16777216;
+affected rows: 0
+DROP TABLE t1;
+affected rows: 0
+drop database if exists mysqltest;
+affected rows: 0
+remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_big_1.out
diff --git a/mysql-test/suite/binlog/t/flashback-largebinlog.test b/mysql-test/suite/binlog/t/flashback-largebinlog.test
new file mode 100644
index 00000000000..6ff58b706d3
--- /dev/null
+++ b/mysql-test/suite/binlog/t/flashback-largebinlog.test
@@ -0,0 +1,110 @@
+# mysqlbinlog_big.test
+#
+# Show that mysqlbinlog can handle big rows.
+#
+
+#
+# The *huge* output of mysqlbinlog will be redirected to
+# $MYSQLTEST_VARDIR/$mysqlbinlog_output
+#
+--let $mysqlbinlog_output= tmp/mysqlbinlog_big_1.out
+
+--source include/have_binlog_format_row.inc
+
+--source include/have_log_bin.inc
+
+# This is a big test.
+--source include/big_test.inc
+
+--echo #
+--echo # Preparatory cleanup.
+--echo #
+--disable_warnings
+drop database if exists mysqltest;
+create database mysqltest;
+use mysqltest;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # We need a fixed timestamp to avoid varying results.
+--echo #
+SET timestamp=1000000000;
+
+--echo #
+--echo # We need big packets.
+--echo #
+--echo # Capture initial value to reset at the end of the test
+# use let $<var> = query_get_value as FLUSH statements
+# in the test will set @<var> values to NULL
+let $orig_max_allowed_packet =
+query_get_value(SELECT @@global.max_allowed_packet, @@global.max_allowed_packet, 1);
+
+--echo # Now adjust max_allowed_packet
+SET @@global.max_allowed_packet= 10*1024*1024*1024;
+
+--echo max_allowed_packet is a global variable.
+--echo In order for the preceding change in max_allowed_packets' value
+--echo to be seen and used, we must start a new connection.
+--echo The change does not take effect with the current one.
+--echo For simplicity, we just disconnect / reconnect connection default here.
+disconnect default;
+connect (default, localhost,root,,);
+
+--echo #
+--echo # Delete all existing binary logs.
+--echo #
+RESET MASTER;
+
+--echo #
+--echo # Create a test table.
+--echo #
+use mysqltest;
+eval CREATE TABLE t1 (
+ c1 LONGTEXT
+ ) DEFAULT CHARSET latin1;
+
+--echo #
+--echo # Show how many rows are affected by each statement.
+--echo #
+--enable_info
+
+--echo #
+--echo # Insert some big rows.
+--echo #
+
+--echo insert 1024MB data twice
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 67108864));
+INSERT INTO t1 VALUES (REPEAT('MegaByteBlckMany', 67108864));
+
+--echo #
+--echo # Flush all log buffers to the log file.
+--echo #
+FLUSH LOGS;
+
+--echo #
+--echo # Call mysqlbinlog to display the log file contents.
+--echo # NOTE: The output of mysqlbinlog is redirected to
+--echo # \$MYSQLTEST_VARDIR/$mysqlbinlog_output
+--echo # If you want to examine it, disable remove_file
+--echo # at the bottom of the test script.
+--echo #
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLTEST_VARDIR <MYSQLTEST_VARDIR>
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/
+--exec $MYSQL_BINLOG -B -v -v $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/$mysqlbinlog_output
+
+--echo #
+--echo # Cleanup.
+--echo #
+--echo # reset variable value to pass testcase checks
+eval SET @@global.max_allowed_packet = $orig_max_allowed_packet;
+DROP TABLE t1;
+drop database if exists mysqltest;
+
+--echo remove_file \$MYSQLTEST_VARDIR/$mysqlbinlog_output
+#
+# NOTE: If you want to see the *huge* mysqlbinlog output, disable next line:
+#
+--remove_file $MYSQLTEST_VARDIR/$mysqlbinlog_output
+
diff --git a/mysql-test/suite/encryption/r/compressed_import_tablespace.result b/mysql-test/suite/encryption/r/compressed_import_tablespace.result
new file mode 100644
index 00000000000..63e7cf8b0c3
--- /dev/null
+++ b/mysql-test/suite/encryption/r/compressed_import_tablespace.result
@@ -0,0 +1,39 @@
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
+INSERT INTO t1 VALUES(1, repeat('Nesamani', 10));
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `a` varchar(255) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES
+# Wait max 10 min for key encryption threads to encrypt all spaces
+db.opt
+t1.frm
+t1.ibd
+FLUSH TABLES t1 FOR EXPORT;
+backup: t1
+db.opt
+t1.cfg
+t1.frm
+t1.ibd
+UNLOCK TABLES;
+DROP TABLE t1;
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
+ALTER TABLE t1 DISCARD TABLESPACE;
+restore: t1 .ibd and .cfg files
+ALTER TABLE t1 IMPORT TABLESPACE;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `a` varchar(255) DEFAULT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES
+DROP TABLE t1;
diff --git a/mysql-test/suite/encryption/t/compressed_import_tablespace.opt b/mysql-test/suite/encryption/t/compressed_import_tablespace.opt
new file mode 100644
index 00000000000..a9893ed4b29
--- /dev/null
+++ b/mysql-test/suite/encryption/t/compressed_import_tablespace.opt
@@ -0,0 +1,3 @@
+--innodb-encrypt-tables=ON
+--innodb-encryption-threads=4
+--innodb-tablespaces-encryption
diff --git a/mysql-test/suite/encryption/t/compressed_import_tablespace.test b/mysql-test/suite/encryption/t/compressed_import_tablespace.test
new file mode 100644
index 00000000000..e79fdb17f02
--- /dev/null
+++ b/mysql-test/suite/encryption/t/compressed_import_tablespace.test
@@ -0,0 +1,45 @@
+-- source include/have_innodb.inc
+-- source include/have_example_key_management_plugin.inc
+-- source include/not_valgrind.inc
+-- source include/not_embedded.inc
+
+let MYSQLD_DATADIR = `SELECT @@datadir`;
+--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
+INSERT INTO t1 VALUES(1, repeat('Nesamani', 10));
+
+SELECT COUNT(*) FROM t1;
+SHOW CREATE TABLE t1;
+
+--echo # Wait max 10 min for key encryption threads to encrypt all spaces
+--let $wait_timeout= 600
+--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING <> 0
+--source include/wait_condition.inc
+
+let $restart_noprint=2;
+--source include/restart_mysqld.inc
+let MYSQLD_DATADIR =`SELECT @@datadir`;
+
+--list_files $MYSQLD_DATADIR/test
+FLUSH TABLES t1 FOR EXPORT;
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_backup_tablespaces("test", "t1");
+EOF
+--list_files $MYSQLD_DATADIR/test
+UNLOCK TABLES;
+DROP TABLE t1;
+
+CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
+ALTER TABLE t1 DISCARD TABLESPACE;
+perl;
+do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
+ib_discard_tablespaces("test", "t1");
+ib_restore_tablespaces("test", "t1");
+EOF
+
+ALTER TABLE t1 IMPORT TABLESPACE;
+
+SELECT COUNT(*) FROM t1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result
index 853412fe7fe..45c3f73ed8e 100644
--- a/mysql-test/suite/gcol/r/gcol_select_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result
@@ -1110,7 +1110,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 AS t2 STRAIGHT_JOIN t1 FORCE INDEX(b) WHERE t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where
-1 SIMPLE t1 ref b b 5 test.t2.b 2
+1 SIMPLE t1 ref b b 5 test.t2.b 1
EXPLAIN SELECT b FROM t1 FORCE INDEX(b);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL b 5 NULL 2 Using index
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
index 5e79a12d17e..05c68e5d893 100644
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -64,7 +64,7 @@ a b c
explain select * from t1 where b in (select c from t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
-1 PRIMARY t3 ref c c 5 test.t1.b 2 Using index
+1 PRIMARY t3 ref c c 5 test.t1.b 1 Using index
# select_type=PRIMARY, type=range,ref
select * from t1 where c in (select c from t3 where c between -2 and -1);
a b c
@@ -74,7 +74,7 @@ a b c
explain select * from t1 where c in (select c from t3 where c between -2 and -1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 range c c 5 NULL 3 Using index condition
-1 PRIMARY t3 index c c 5 NULL 6 Using where; Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ref c c 5 test.t1.c 1 Using index
# select_type=UNION, type=system
# select_type=UNION RESULT, type=<union1,2>
select * from t1 union select * from t2;
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 78fee354592..6990d1350e3 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -74,7 +74,7 @@ IF(HAVE_MLOCK)
ENDIF()
ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES})
-TARGET_LINK_LIBRARIES(mysys dbug strings mysys_ssl ${ZLIB_LIBRARY}
+TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY}
${LIBNSL} ${LIBM} ${LIBRT} ${LIBDL} ${LIBSOCKET} ${LIBEXECINFO} ${CRC32_LIBRARY})
DTRACE_INSTRUMENT(mysys)
diff --git a/plugin/auth_ed25519/CMakeLists.txt b/plugin/auth_ed25519/CMakeLists.txt
index ffd2523d1af..1a3d5cc4bce 100644
--- a/plugin/auth_ed25519/CMakeLists.txt
+++ b/plugin/auth_ed25519/CMakeLists.txt
@@ -25,8 +25,8 @@ MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY)
# client plugin and unit test ed25519-t can use the library
#MYSQL_ADD_PLUGIN(client_ed25519 client_ed25519.c MODULE_ONLY
-# CLIENT LINK_LIBRARIES mysys_ssl ref10 COMPONENT ClientPlugins)
+# CLIENT LINK_LIBRARIES ref10 mysys_ssl COMPONENT ClientPlugins)
IF(WITH_UNIT_TESTS)
- MY_ADD_TESTS(ed25519 LINK_LIBRARIES mysys ref10)
+ MY_ADD_TESTS(ed25519 LINK_LIBRARIES ref10 mysys_ssl)
ENDIF()
diff --git a/sql/field.cc b/sql/field.cc
index a671195ba2b..46e33dc8526 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11242,3 +11242,58 @@ bool Field::val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to)
thd->variables.sql_mode= sql_mode_backup;
return rc;
}
+
+
+void Field::print_key_value(String *out, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ print_key_value_binary(out, ptr, length);
+ else
+ val_str(out);
+}
+
+
+void Field_string::print_key_value(String *out, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ {
+ size_t len= field_charset->cset->lengthsp(field_charset, (const char*) ptr, length);
+ print_key_value_binary(out, ptr, static_cast<uint32>(len));
+ }
+ else
+ {
+ THD *thd= get_thd();
+ sql_mode_t sql_mode_backup= thd->variables.sql_mode;
+ thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
+ val_str(out,out);
+ thd->variables.sql_mode= sql_mode_backup;
+ }
+}
+
+
+void Field_varstring::print_key_value(String *out, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ print_key_value_binary(out, get_data(), get_length());
+ else
+ val_str(out,out);
+}
+
+
+void Field_blob::print_key_value(String *out, uint32 length)
+{
+ if (charset() == &my_charset_bin)
+ {
+ uchar *blob;
+ memcpy(&blob, ptr+packlength, sizeof(uchar*));
+ print_key_value_binary(out, blob, get_length());
+ }
+ else
+ val_str(out, out);
+}
+
+
+void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
+{
+ out->append_semi_hex((const char*)key, length, charset());
+} \ No newline at end of file
diff --git a/sql/field.h b/sql/field.h
index ceb4a8bb93f..8b65f2e95e4 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1383,6 +1383,8 @@ public:
virtual int set_time() { return 1; }
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
int cuted_increment, ulong current_row=0) const;
+ virtual void print_key_value(String *out, uint32 length);
+ void print_key_value_binary(String *out, const uchar* key, uint32 length);
protected:
bool set_warning(unsigned int code, int cuted_increment) const
{
@@ -3592,6 +3594,7 @@ public:
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
virtual uint get_key_image(uchar *buff,uint length, imagetype type);
+ void print_key_value(String *out, uint32 length);
private:
int save_field_metadata(uchar *first_byte);
};
@@ -3697,6 +3700,7 @@ public:
uint is_equal(Create_field *new_field);
void hash(ulong *nr, ulong *nr2);
uint length_size() { return length_bytes; }
+ void print_key_value(String *out, uint32 length);
private:
int save_field_metadata(uchar *first_byte);
};
@@ -4035,6 +4039,7 @@ public:
uint32 char_length() const;
uint32 character_octet_length() const;
uint is_equal(Create_field *new_field);
+ void print_key_value(String *out, uint32 length);
friend void TABLE::remember_blob_values(String *blob_storage);
friend void TABLE::restore_blob_values(String *blob_storage);
@@ -4159,6 +4164,10 @@ public:
geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
uint get_srid() { return srid; }
+ void print_key_value(String *out, uint32 length)
+ {
+ out->append(STRING_WITH_LEN("unprintable_geometry_value"));
+ }
};
uint gis_field_options_image(uchar *buff, List<Create_field> &create_fields);
@@ -4466,6 +4475,11 @@ public:
{
return get_mm_leaf_int(param, key_part, cond, op, value, true);
}
+ void print_key_value(String *out, uint32 length)
+ {
+ val_int_as_str(out, 1);
+ }
+
private:
virtual size_t do_last_null_byte() const;
int save_field_metadata(uchar *first_byte);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index e47da94ab20..8a0b9822493 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -10645,22 +10645,20 @@ int ha_partition::calculate_checksum()
}
}
m_pre_calling= FALSE;
- if ((table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM)))
+
+ handler **file= m_file;
+ do
{
- handler **file= m_file;
- do
+ if ((error= (*file)->calculate_checksum()))
{
- if ((error= (*file)->calculate_checksum()))
- {
- DBUG_RETURN(error);
- }
- if (!(*file)->stats.checksum_null)
- {
- stats.checksum+= (*file)->stats.checksum;
- stats.checksum_null= FALSE;
- }
- } while (*(++file));
- }
+ DBUG_RETURN(error);
+ }
+ if (!(*file)->stats.checksum_null)
+ {
+ stats.checksum+= (*file)->stats.checksum;
+ stats.checksum_null= FALSE;
+ }
+ } while (*(++file));
DBUG_RETURN(0);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index 908d49d861a..dfb5c69e675 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -5054,7 +5054,7 @@ int handler::calculate_checksum()
return HA_ERR_ABORTED_BY_USER;
ha_checksum row_crc= 0;
- error= table->file->ha_rnd_next(table->record[0]);
+ error= ha_rnd_next(table->record[0]);
if (error)
break;
@@ -5108,7 +5108,7 @@ int handler::calculate_checksum()
stats.checksum+= row_crc;
}
- table->file->ha_rnd_end();
+ ha_rnd_end();
return error == HA_ERR_END_OF_FILE ? 0 : error;
}
diff --git a/sql/handler.h b/sql/handler.h
index 7f178dad265..94e7ddef5b1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1036,7 +1036,7 @@ typedef bool (stat_print_fn)(THD *thd, const char *type, size_t type_len,
const char *file, size_t file_len,
const char *status, size_t status_len);
enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
-extern st_plugin_int *hton2plugin[MAX_HA];
+extern MYSQL_PLUGIN_IMPORT st_plugin_int *hton2plugin[MAX_HA];
/* Transaction log maintains type definitions */
enum log_status
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 9f58999d4cc..1d950a7dad3 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -3913,7 +3913,6 @@ int subselect_single_select_engine::exec()
tab->save_read_record= tab->read_record.read_record_func;
tab->read_record.read_record_func= rr_sequential;
tab->read_first_record= read_first_record_seq;
- tab->read_record.record= tab->table->record[0];
tab->read_record.thd= join->thd;
tab->read_record.ref_length= tab->table->file->ref_length;
tab->read_record.unlock_row= rr_unlock_row;
@@ -3931,7 +3930,6 @@ int subselect_single_select_engine::exec()
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
{
JOIN_TAB *tab= *ptab;
- tab->read_record.record= 0;
tab->read_record.ref_length= 0;
tab->read_first_record= tab->save_read_first_record;
tab->read_record.read_record_func= tab->save_read_record;
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index 8c6a661366f..ecac80d2aaa 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -44,11 +44,6 @@ public:
first_check= true;
}
- void cleanup()
- {
- group_fields.empty();
- }
-
/*
Check if the current row is in a different group than the previous row
this function was called for.
@@ -86,6 +81,10 @@ public:
}
return 0;
}
+ ~Group_bound_tracker()
+ {
+ group_fields.delete_elements();
+ }
private:
List<Cached_item> group_fields;
@@ -213,7 +212,6 @@ public:
{
if (peer_tracker)
{
- peer_tracker->cleanup();
delete peer_tracker;
peer_tracker= NULL;
}
@@ -284,7 +282,6 @@ class Item_sum_dense_rank: public Item_sum_int
{
if (peer_tracker)
{
- peer_tracker->cleanup();
delete peer_tracker;
peer_tracker= NULL;
}
@@ -548,7 +545,6 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
{
if (peer_tracker)
{
- peer_tracker->cleanup();
delete peer_tracker;
peer_tracker= NULL;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e3f5483a552..8b3a63e686e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8486,8 +8486,10 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
opt_specialflag|= SPECIAL_NO_HOST_CACHE;
break;
case (int) OPT_SKIP_RESOLVE:
- opt_skip_name_resolve= 1;
- opt_specialflag|=SPECIAL_NO_RESOLVE;
+ if ((opt_skip_name_resolve= (argument != disabled_my_option)))
+ opt_specialflag|= SPECIAL_NO_RESOLVE;
+ else
+ opt_specialflag&= ~SPECIAL_NO_RESOLVE;
break;
case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL;
@@ -8546,6 +8548,8 @@ mysqld_get_one_option(int optid, const struct my_option *opt, char *argument)
break;
case OPT_PLUGIN_LOAD:
free_list(opt_plugin_load_list_ptr);
+ if (argument == disabled_my_option)
+ break; // Resets plugin list
/* fall through */
case OPT_PLUGIN_LOAD_ADD:
opt_plugin_load_list_ptr->push_back(new i_string(argument));
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index bff5bd371b6..d0c4ed2ffbc 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -15835,12 +15835,10 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part,
{
// Byte 0 of a nullable key is the null-byte. If set, key is NULL.
if (field->real_maybe_null() && *key)
+ {
out->append(STRING_WITH_LEN("NULL"));
- else
- (field->type() == MYSQL_TYPE_GEOMETRY)
- ? out->append(STRING_WITH_LEN("unprintable_geometry_value"))
- : out->append(STRING_WITH_LEN("unprintable_blob_value"));
- goto next;
+ goto next;
+ }
}
if (field->real_maybe_null())
@@ -15859,28 +15857,12 @@ static void print_key_value(String *out, const KEY_PART_INFO *key_part,
store_length--;
}
- /*
- Binary data cannot be converted to UTF8 which is what the
- optimizer trace expects. If the column is binary, the hex
- representation is printed to the trace instead.
- */
- if (field->flags & BINARY_FLAG)
- {
- out->append("0x");
- for (uint i = 0; i < store_length; i++)
- {
- out->append(_dig_vec_lower[*(key + i) >> 4]);
- out->append(_dig_vec_lower[*(key + i) & 0x0F]);
- }
- goto next;
- }
-
field->set_key_image(key, key_part->length);
- if (field->type() == MYSQL_TYPE_BIT)
- (void)field->val_int_as_str(&tmp, 1); // may change tmp's charset
+ field->print_key_value(&tmp, key_part->length);
+ if (field->charset() == &my_charset_bin)
+ out->append(tmp.ptr(), tmp.length(), tmp.charset());
else
- field->val_str(&tmp); // may change tmp's charset
- out->append(tmp.ptr(), tmp.length(), tmp.charset());
+ tmp.print(out, system_charset_info);
next:
if (key + store_length < key_end)
diff --git a/sql/records.cc b/sql/records.cc
index c2db29c4912..5dd4318b105 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -77,7 +77,6 @@ bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bzero((char*) info,sizeof(*info));
info->thd= thd;
info->table= table;
- info->record= table->record[0];
info->print_error= print_error;
info->unlock_row= rr_unlock_row;
@@ -210,7 +209,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
else
{
empty_record(table);
- info->record= table->record[0];
info->ref_length= (uint)table->file->ref_length;
}
info->select=select;
@@ -393,7 +391,7 @@ static int rr_index_first(READ_RECORD *info)
return tmp;
}
- tmp= info->table->file->ha_index_first(info->record);
+ tmp= info->table->file->ha_index_first(info->record());
info->read_record_func= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -416,7 +414,7 @@ static int rr_index_first(READ_RECORD *info)
static int rr_index_last(READ_RECORD *info)
{
- int tmp= info->table->file->ha_index_last(info->record);
+ int tmp= info->table->file->ha_index_last(info->record());
info->read_record_func= rr_index_desc;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -442,7 +440,7 @@ static int rr_index_last(READ_RECORD *info)
static int rr_index(READ_RECORD *info)
{
- int tmp= info->table->file->ha_index_next(info->record);
+ int tmp= info->table->file->ha_index_next(info->record());
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -467,7 +465,7 @@ static int rr_index(READ_RECORD *info)
static int rr_index_desc(READ_RECORD *info)
{
- int tmp= info->table->file->ha_index_prev(info->record);
+ int tmp= info->table->file->ha_index_prev(info->record());
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -477,7 +475,7 @@ static int rr_index_desc(READ_RECORD *info)
int rr_sequential(READ_RECORD *info)
{
int tmp;
- while ((tmp= info->table->file->ha_rnd_next(info->record)))
+ while ((tmp= info->table->file->ha_rnd_next(info->record())))
{
tmp= rr_handle_error(info, tmp);
break;
@@ -493,7 +491,7 @@ static int rr_from_tempfile(READ_RECORD *info)
{
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
return -1; /* End of file */
- if (!(tmp= info->table->file->ha_rnd_pos(info->record,info->ref_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record(), info->ref_pos)))
break;
/* The following is extremely unlikely to happen */
if (tmp == HA_ERR_KEY_NOT_FOUND)
@@ -543,7 +541,7 @@ int rr_from_pointers(READ_RECORD *info)
cache_pos= info->cache_pos;
info->cache_pos+= info->ref_length;
- if (!(tmp= info->table->file->ha_rnd_pos(info->record,cache_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record(), cache_pos)))
break;
/* The following is extremely unlikely to happen */
@@ -638,7 +636,7 @@ static int rr_from_cache(READ_RECORD *info)
else
{
error=0;
- memcpy(info->record,info->cache_pos,
+ memcpy(info->record(), info->cache_pos,
(size_t) info->table->s->reclength);
}
info->cache_pos+=info->reclength;
diff --git a/sql/records.h b/sql/records.h
index e97f6b273cc..faf0d13c9a9 100644
--- a/sql/records.h
+++ b/sql/records.h
@@ -19,9 +19,10 @@
#pragma interface /* gcc class implementation */
#endif
+#include "table.h"
+
struct st_join_table;
class handler;
-struct TABLE;
class THD;
class SQL_SELECT;
class Copy_field;
@@ -58,7 +59,6 @@ struct READ_RECORD
SQL_SELECT *select;
uint ref_length, reclength, rec_cache_size, error_offset;
uchar *ref_pos; /* pointer to form->refpos */
- uchar *record;
uchar *rec_buf; /* to read field values after filesort */
uchar *cache,*cache_pos,*cache_end,*read_positions;
struct st_sort_addon_field *addon_field; /* Pointer to the fields info */
@@ -67,6 +67,7 @@ struct READ_RECORD
void (*unpack)(struct st_sort_addon_field *, uchar *, uchar *);
int read_record() { return read_record_func(this); }
+ uchar *record() const { return table->record[0]; }
/*
SJ-Materialization runtime may need to read fields from the materialized
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index 4f1acb60161..cce80ce2bc8 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -27,10 +27,14 @@
#include <my_bitmap.h>
#include <my_bit.h>
+
+template <uint width> class Bitmap
+{
+
/*
Workaround GCC optimizer bug (generating SSE instuctions on unaligned data)
*/
-#if defined (__GNUC__) && defined(__x86_64__) && (__GNUC__ < 6)
+#if defined (__GNUC__) && defined(__x86_64__) && (__GNUC__ < 6) && !defined(__clang__)
#define NEED_GCC_NO_SSE_WORKAROUND
#endif
@@ -39,8 +43,6 @@
#pragma GCC target ("no-sse")
#endif
-template <uint width> class Bitmap
-{
uint32 buffer[(width + 31) / 32];
public:
Bitmap()
@@ -276,13 +278,15 @@ public:
}
enum { BITMAP_END = width };
};
-};
#ifdef NEED_GCC_NO_SSE_WORKAROUND
#pragma GCC pop_options
#undef NEED_GCC_NO_SSE_WORKAROUND
#endif
+};
+
+
/* An iterator to quickly walk over bits in ulonglong bitmap. */
class Table_map_iterator
{
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 51412aedaf2..03ca08fb3fb 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -941,6 +941,11 @@ void Explain_select::print_explain_json(Explain_query *query,
writer->add_member("outer_ref_condition");
write_item(writer, outer_ref_cond);
}
+ if (pseudo_bits_cond)
+ {
+ writer->add_member("pseudo_bits_condition");
+ write_item(writer, pseudo_bits_cond);
+ }
/* we do not print HAVING which always evaluates to TRUE */
if (having || (having_value == Item::COND_FALSE))
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 35388416908..3896636f9fd 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -236,6 +236,7 @@ public:
/* Expensive constant condition */
Item *exec_const_cond;
Item *outer_ref_cond;
+ Item *pseudo_bits_cond;
/* HAVING condition */
Item *having;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 46be6dfef27..04981bd1a31 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -5900,18 +5900,16 @@ add_key_field(JOIN *join,
(*key_fields)->level= and_level;
(*key_fields)->optimize= optimize;
/*
- If the condition has form "tbl.keypart = othertbl.field" and
- othertbl.field can be NULL, there will be no matches if othertbl.field
- has NULL value.
- We use null_rejecting in add_not_null_conds() to add
- 'othertbl.field IS NOT NULL' to tab->select_cond.
+ If the condition we are analyzing is NULL-rejecting and at least
+ one side of the equalities is NULLable, mark the KEY_FIELD object as
+ null-rejecting. This property is used by:
+ - add_not_null_conds() to add "column IS NOT NULL" conditions
+ - best_access_path() to produce better estimates for NULL-able unique keys.
*/
{
- Item *real= (*value)->real_item();
- if (((cond->functype() == Item_func::EQ_FUNC) ||
- (cond->functype() == Item_func::MULT_EQUAL_FUNC)) &&
- (real->type() == Item::FIELD_ITEM) &&
- ((Item_field*)real)->field->maybe_null())
+ if ((cond->functype() == Item_func::EQ_FUNC ||
+ cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
+ ((*value)->maybe_null || field->real_maybe_null()))
(*key_fields)->null_rejecting= true;
else
(*key_fields)->null_rejecting= false;
@@ -7235,6 +7233,7 @@ best_access_path(JOIN *join,
ulong key_flags;
uint key_parts;
key_part_map found_part= 0;
+ key_part_map notnull_part=0; // key parts which won't have NULL in lookup tuple.
table_map found_ref= 0;
uint key= keyuse->key;
filter= 0;
@@ -7294,6 +7293,9 @@ best_access_path(JOIN *join,
if (!(keyuse->used_tables & ~join->const_table_map))
const_part|= keyuse->keypart_map;
+ if (!keyuse->val->maybe_null || keyuse->null_rejecting)
+ notnull_part|=keyuse->keypart_map;
+
double tmp2= prev_record_reads(join->positions, idx,
(found_ref | keyuse->used_tables));
if (tmp2 < best_prev_record_reads)
@@ -7347,12 +7349,19 @@ best_access_path(JOIN *join,
loose_scan_opt.check_ref_access_part1(s, key, start_key, found_part);
/* Check if we found full key */
- if (found_part == PREV_BITS(uint, key_parts) &&
- !ref_or_null_part)
+ const key_part_map all_key_parts= PREV_BITS(uint, key_parts);
+ if (found_part == all_key_parts && !ref_or_null_part)
{ /* use eq key */
max_key_part= (uint) ~0;
- if ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME ||
- MY_TEST(key_flags & HA_EXT_NOSAME))
+ /*
+ If the index is a unique index (1), and
+ - all its columns are not null (2), or
+ - equalities we are using reject NULLs (3)
+ then the estimate is rows=1.
+ */
+ if ((key_flags & (HA_NOSAME | HA_EXT_NOSAME)) && // (1)
+ (!(key_flags & HA_NULL_PART_KEY) || // (2)
+ all_key_parts == notnull_part)) // (3)
{
trace_access_idx.add("access_type", "eq_ref")
.add("index", keyinfo->name);
@@ -10565,8 +10574,16 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
uint maybe_null= MY_TEST(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
j->ref.cond_guards[i]= keyuse->cond_guard;
- if (keyuse->null_rejecting)
+
+ /*
+ Set ref.null_rejecting to true only if we are going to inject a
+ "keyuse->val IS NOT NULL" predicate.
+ */
+ Item *real= (keyuse->val)->real_item();
+ if (keyuse->null_rejecting && (real->type() == Item::FIELD_ITEM) &&
+ ((Item_field*)real)->field->maybe_null())
j->ref.null_rejecting|= (key_part_map)1 << i;
+
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
/*
We don't want to compute heavy expressions in EXPLAIN, an example would
@@ -21060,7 +21077,6 @@ join_read_first(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record_func= join_read_next;
tab->read_record.table=table;
- tab->read_record.record=table->record[0];
if (!table->file->inited)
error= table->file->ha_index_init(tab->index, tab->sorted);
if (likely(!error))
@@ -21080,7 +21096,7 @@ static int
join_read_next(READ_RECORD *info)
{
int error;
- if (unlikely((error= info->table->file->ha_index_next(info->record))))
+ if (unlikely((error= info->table->file->ha_index_next(info->record()))))
return report_error(info->table, error);
return 0;
@@ -21100,7 +21116,6 @@ join_read_last(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record_func= join_read_prev;
tab->read_record.table=table;
- tab->read_record.record=table->record[0];
if (!table->file->inited)
error= table->file->ha_index_init(tab->index, 1);
if (likely(!error))
@@ -21117,7 +21132,7 @@ static int
join_read_prev(READ_RECORD *info)
{
int error;
- if (unlikely((error= info->table->file->ha_index_prev(info->record))))
+ if (unlikely((error= info->table->file->ha_index_prev(info->record()))))
return report_error(info->table, error);
return 0;
}
@@ -21147,7 +21162,7 @@ static int
join_ft_read_next(READ_RECORD *info)
{
int error;
- if (unlikely((error= info->table->file->ha_ft_read(info->table->record[0]))))
+ if (unlikely((error= info->table->file->ha_ft_read(info->record()))))
return report_error(info->table, error);
return 0;
}
@@ -26401,6 +26416,7 @@ int JOIN::save_explain_data_intern(Explain_query *output,
xpl_sel->exec_const_cond= exec_const_cond;
xpl_sel->outer_ref_cond= outer_ref_cond;
+ xpl_sel->pseudo_bits_cond= pseudo_bits_cond;
if (tmp_having)
xpl_sel->having= tmp_having;
else
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 410f52a8c74..1b567ecb325 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1196,3 +1196,15 @@ uint convert_to_printable(char *to, size_t to_len,
*t= '\0';
return (uint) (t - to);
}
+
+
+bool String::append_semi_hex(const char *s, uint len, CHARSET_INFO *cs)
+{
+ size_t dst_len= len * 4 + 1; //extra length for the '\0' character
+ if (reserve(dst_len))
+ return true;
+ uint nbytes= convert_to_printable(Ptr + str_length, dst_len, s, len, cs);
+ DBUG_ASSERT((ulonglong) str_length + nbytes < UINT_MAX32);
+ str_length+= nbytes;
+ return false;
+}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index caefee7ec09..d8edf5e81f0 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -674,6 +674,7 @@ public:
int reserve(size_t space_needed)
{
+ DBUG_ASSERT((ulonglong) str_length + space_needed < UINT_MAX32);
return realloc(str_length + space_needed);
}
int reserve(size_t space_needed, size_t grow_by);
@@ -959,6 +960,8 @@ public:
{
return !sortcmp(this, other, cs);
}
+private:
+ bool append_semi_hex(const char *s, uint len, CHARSET_INFO *cs);
};
diff --git a/sql/sql_window.cc b/sql/sql_window.cc
index 487242933d4..a6c9dd3fea7 100644
--- a/sql/sql_window.cc
+++ b/sql/sql_window.cc
@@ -898,7 +898,7 @@ public:
{
Rowid_seq_cursor::init(info);
table= info->table;
- record= info->record;
+ record= info->record();
}
virtual int fetch()
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index bfd3ffce69b..706d058b338 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -6111,10 +6111,12 @@ database_corrupted:
if (err == DB_PAGE_CORRUPTED
|| err == DB_DECRYPTION_FAILED) {
+ const page_id_t corrupt_page_id = bpage->id;
+
buf_corrupt_page_release(bpage, space);
if (recv_recovery_is_on()) {
- recv_recover_corrupt_page(bpage);
+ recv_recover_corrupt_page(corrupt_page_id);
}
space->release_for_io();
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index bd726265a42..ea2348d61fd 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -214,77 +214,6 @@ struct buf_pools_list_size_t {
};
#endif /* !UNIV_INNOCHECKSUM */
-/** Page identifier. */
-class page_id_t {
-public:
-
- /** Constructor from (space, page_no).
- @param[in] space tablespace id
- @param[in] page_no page number */
- page_id_t(ulint space, ulint page_no)
- : m_space(uint32_t(space)), m_page_no(uint32(page_no))
- {
- ut_ad(space <= 0xFFFFFFFFU);
- ut_ad(page_no <= 0xFFFFFFFFU);
- }
-
- bool operator==(const page_id_t& rhs) const
- {
- return m_space == rhs.m_space && m_page_no == rhs.m_page_no;
- }
- bool operator!=(const page_id_t& rhs) const { return !(*this == rhs); }
-
- bool operator<(const page_id_t& rhs) const
- {
- if (m_space == rhs.m_space) {
- return m_page_no < rhs.m_page_no;
- }
-
- return m_space < rhs.m_space;
- }
-
- /** Retrieve the tablespace id.
- @return tablespace id */
- uint32_t space() const { return m_space; }
-
- /** Retrieve the page number.
- @return page number */
- uint32_t page_no() const { return m_page_no; }
-
- /** Retrieve the fold value.
- @return fold value */
- ulint fold() const { return (m_space << 20) + m_space + m_page_no; }
-
- /** Reset the page number only.
- @param[in] page_no page number */
- inline void set_page_no(ulint page_no)
- {
- m_page_no = uint32_t(page_no);
-
- ut_ad(page_no <= 0xFFFFFFFFU);
- }
-
-private:
-
- /** Tablespace id. */
- uint32_t m_space;
-
- /** Page number. */
- uint32_t m_page_no;
-
- /** Declare the overloaded global operator<< as a friend of this
- class. Refer to the global declaration for further details. Print
- the given page_id_t object.
- @param[in,out] out the output stream
- @param[in] page_id the page_id_t object to be printed
- @return the output stream */
- friend
- std::ostream&
- operator<<(
- std::ostream& out,
- const page_id_t page_id);
-};
-
/** Print the given page_id_t object.
@param[in,out] out the output stream
@param[in] page_id the page_id_t object to be printed
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index 20c70cc9a0e..67e2548b944 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -134,6 +134,77 @@ this must be equal to srv_page_size */
#define BUF_BUDDY_HIGH (BUF_BUDDY_LOW << BUF_BUDDY_SIZES)
/* @} */
+/** Page identifier. */
+class page_id_t {
+public:
+
+ /** Constructor from (space, page_no).
+ @param[in] space tablespace id
+ @param[in] page_no page number */
+ page_id_t(ulint space, ulint page_no)
+ : m_space(uint32_t(space)), m_page_no(uint32(page_no))
+ {
+ ut_ad(space <= 0xFFFFFFFFU);
+ ut_ad(page_no <= 0xFFFFFFFFU);
+ }
+
+ bool operator==(const page_id_t& rhs) const
+ {
+ return m_space == rhs.m_space && m_page_no == rhs.m_page_no;
+ }
+ bool operator!=(const page_id_t& rhs) const { return !(*this == rhs); }
+
+ bool operator<(const page_id_t& rhs) const
+ {
+ if (m_space == rhs.m_space) {
+ return m_page_no < rhs.m_page_no;
+ }
+
+ return m_space < rhs.m_space;
+ }
+
+ /** Retrieve the tablespace id.
+ @return tablespace id */
+ uint32_t space() const { return m_space; }
+
+ /** Retrieve the page number.
+ @return page number */
+ uint32_t page_no() const { return m_page_no; }
+
+ /** Retrieve the fold value.
+ @return fold value */
+ ulint fold() const { return (m_space << 20) + m_space + m_page_no; }
+
+ /** Reset the page number only.
+ @param[in] page_no page number */
+ void set_page_no(ulint page_no)
+ {
+ m_page_no = uint32_t(page_no);
+
+ ut_ad(page_no <= 0xFFFFFFFFU);
+ }
+
+private:
+
+ /** Tablespace id. */
+ uint32_t m_space;
+
+ /** Page number. */
+ uint32_t m_page_no;
+
+ /** Declare the overloaded global operator<< as a friend of this
+ class. Refer to the global declaration for further details. Print
+ the given page_id_t object.
+ @param[in,out] out the output stream
+ @param[in] page_id the page_id_t object to be printed
+ @return the output stream */
+ friend
+ std::ostream&
+ operator<<(
+ std::ostream& out,
+ const page_id_t page_id);
+};
+
#ifndef UNIV_INNOCHECKSUM
#include "ut0mutex.h"
diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h
index cfa0443f301..347d33e0907 100644
--- a/storage/innobase/include/log0recv.h
+++ b/storage/innobase/include/log0recv.h
@@ -50,8 +50,8 @@ recv_find_max_checkpoint(ulint* max_field)
/** Reduces recv_sys.n_addrs for the corrupted page.
This function should called when srv_force_recovery > 0.
-@param[in] bpage buffer pool page */
-void recv_recover_corrupt_page(buf_page_t* bpage);
+@param[in] page_id page id of the corrupted page */
+void recv_recover_corrupt_page(page_id_t page_id);
/** Apply any buffered redo log to a page that was just read from a data file.
@param[in,out] bpage buffer pool page */
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 57fb26378c9..a87ce5ec07b 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -777,9 +777,7 @@ os_file_rename
os_aio
os_file_read
os_file_read_no_error_handling
-os_file_read_no_error_handling_int_fd
os_file_write
-os_file_write_int_fd
The wrapper functions have the prefix of "innodb_". */
@@ -1155,13 +1153,9 @@ to original un-instrumented file I/O APIs */
# define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
-# define os_file_read_no_error_handling_int_fd(type, file, buf, offset, n) \
- os_file_read_no_error_handling_func(type, OS_FILE_FROM_FD(file), buf, offset, n, NULL)
# define os_file_write(type, name, file, buf, offset, n) \
os_file_write_func(type, name, file, buf, offset, n)
-# define os_file_write_int_fd(type, name, file, buf, offset, n) \
- os_file_write_func(type, name, OS_FILE_FROM_FD(file), buf, offset, n)
# define os_file_flush(file) os_file_flush_func(file)
diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
index f1b8aa67180..e01fcb41afb 100644
--- a/storage/innobase/include/os0file.ic
+++ b/storage/innobase/include/os0file.ic
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2017, MariaDB Corporation.
+Copyright (c) 2013, 2019, MariaDB Corporation.
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 the Free Software
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h
index 45366f9128a..27bd19252ac 100644
--- a/storage/innobase/include/row0merge.h
+++ b/storage/innobase/include/row0merge.h
@@ -370,7 +370,9 @@ row_merge_buf_sort(
/********************************************************************//**
Write a merge block to the file system.
-@return whether the request was completed successfully */
+@return whether the request was completed successfully
+@retval false on error
+@retval true on success */
UNIV_INTERN
bool
row_merge_write(
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index f0b62eb8de5..5cb27a4a68c 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2102,8 +2102,8 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
/** Reduces recv_sys.n_addrs for the corrupted page.
This function should called when srv_force_recovery > 0.
-@param[in] bpage buffer pool page */
-void recv_recover_corrupt_page(buf_page_t* bpage)
+@param[in] page_id page id of the corrupted page */
+void recv_recover_corrupt_page(page_id_t page_id)
{
ut_ad(srv_force_recovery);
mutex_enter(&recv_sys.mutex);
@@ -2114,7 +2114,7 @@ void recv_recover_corrupt_page(buf_page_t* bpage)
}
recv_addr_t* recv_addr = recv_get_fil_addr_struct(
- bpage->id.space(), bpage->id.page_no());
+ page_id.space(), page_id.page_no());
ut_ad(recv_addr->state != RECV_WILL_NOT_READ);
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 5cb2c452be6..594e9f0aeb4 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -4869,7 +4869,8 @@ Requests a synchronous write operation.
@param[out] buf buffer from which to write
@param[in] offset file offset from the start where to read
@param[in] n number of bytes to read, starting from offset
-@return DB_SUCCESS if request was successful, false if fail */
+@return error code
+@retval DB_SUCCESS if the operation succeeded */
dberr_t
os_file_write_func(
const IORequest& type,
@@ -5354,7 +5355,8 @@ Requests a synchronous positioned read operation.
@param[out] buf buffer where to read
@param[in] offset file offset from the start where to read
@param[in] n number of bytes to read, starting from offset
-@return DB_SUCCESS or error code */
+@return error code
+@retval DB_SUCCESS if the operation succeeded */
dberr_t
os_file_read_func(
const IORequest& type,
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 52eec25ce9b..39dc8f4bba4 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3424,8 +3424,12 @@ page_corrupted:
if (!encrypted) {
} else if (!key_version) {
not_encrypted:
- if (!page_compressed
- && !block->page.zip.data) {
+ if (block->page.id.page_no() == 0
+ && block->page.zip.data) {
+ block->page.zip.data = src;
+ frame_changed = true;
+ } else if (!page_compressed
+ && !block->page.zip.data) {
block->frame = src;
frame_changed = true;
} else {
@@ -3529,7 +3533,11 @@ not_encrypted:
}
if (frame_changed) {
- block->frame = dst;
+ if (block->page.zip.data) {
+ block->page.zip.data = dst;
+ } else {
+ block->frame = dst;
+ }
}
src = io_buffer + (i * size);
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index d1568764c18..a7129b588b9 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1123,7 +1123,9 @@ row_merge_read(
/********************************************************************//**
Write a merge block to the file system.
-@return whether the request was completed successfully */
+@return whether the request was completed successfully
+@retval false on error
+@retval true on success */
UNIV_INTERN
bool
row_merge_write(
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 6de37852848..ba90fe79453 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2778,9 +2778,12 @@ int ha_maria::external_lock(THD *thd, int lock_type)
}
}
} /* if transactional table */
- DBUG_RETURN(maria_lock_database(file, !table->s->tmp_table ?
+ int result = maria_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
- F_UNLCK : F_EXTRA_LCK)));
+ F_UNLCK : F_EXTRA_LCK));
+ if (!file->s->base.born_transactional)
+ file->state= &file->s->state.state; // Restore state if clone
+ DBUG_RETURN(result);
}
int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
diff --git a/storage/rocksdb/mysql-test/rocksdb/slow_query_log.awk b/storage/rocksdb/mysql-test/rocksdb/slow_query_log.awk
index 4617b6d9fc3..a921f47243e 100644
--- a/storage/rocksdb/mysql-test/rocksdb/slow_query_log.awk
+++ b/storage/rocksdb/mysql-test/rocksdb/slow_query_log.awk
@@ -1,5 +1,3 @@
-#!/bin/awk
-
/Query_time:/ {
results["Rows_examined:"] = "uninit";
results["RocksDB_key_skipped:"] = "uninit";
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_slocket_socket.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_slocket_socket.sh
index 6174e5d1864..db470f527ca 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_slocket_socket.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_slocket_socket.sh
@@ -1,2 +1,4 @@
+#!/bin/bash
+
src_data_dir="${MYSQLTEST_VARDIR}/mysqld.1/data/"
python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('${src_data_dir}/slocket')"
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_table.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_table.sh
index a4d60dc864c..2004caca160 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_table.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/create_table.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
set -e
COPY_LOG=$1
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data.sh
index f3836ab75e5..80f1a5e2567 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
set -e
# Insert 100 batches of 100 records each to a table with following schema:
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_and_run.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_and_run.sh
index a4e4afab9d4..a8e6fc445bb 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_and_run.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_and_run.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
set -e
# Initially loads a chunk of data.
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_slocket.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_slocket.sh
index ed0b3cb5c1c..036d68662d4 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_slocket.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/load_data_slocket.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
set -e
# Insert 10 batches of 10 records each to a table with following schema:
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/remove_slocket_socket.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/remove_slocket_socket.sh
index 0c2c71aad68..9114629ba31 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/remove_slocket_socket.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/remove_slocket_socket.sh
@@ -1,2 +1,4 @@
+#!/bin/bash
+
src_data_dir="${MYSQLTEST_VARDIR}/mysqld.1/data/"
rm "${src_data_dir}/slocket"
diff --git a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/setup_replication_gtid.sh b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/setup_replication_gtid.sh
index 18e1feeda96..3c95068a488 100755
--- a/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/setup_replication_gtid.sh
+++ b/storage/rocksdb/mysql-test/rocksdb_hotbackup/include/setup_replication_gtid.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
set -e
binlog_line=($(grep -o "Last binlog file position [0-9]*, file name .*\.[0-9]*" ${MYSQLTEST_VARDIR}/log/mysqld.2.err | tail -1))
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 4fbb6d1a8c1..33e81201fff 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -9431,9 +9431,9 @@ int ha_spider::calculate_checksum()
stats.checksum = 0;
} else {
share->stat.checksum_null = FALSE;
- share->stat.checksum = checksum_val;
+ share->stat.checksum = (ha_checksum) checksum_val;
stats.checksum_null = FALSE;
- stats.checksum = checksum_val;
+ stats.checksum = (ha_checksum) checksum_val;
}
DBUG_RETURN(0);
}
diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h
index 6ac71254b12..6f5359007f1 100644
--- a/storage/spider/ha_spider.h
+++ b/storage/spider/ha_spider.h
@@ -245,7 +245,7 @@ public:
#endif
ha_rows table_rows;
#ifdef HA_HAS_CHECKSUM_EXTENDED
- ulonglong checksum_val;
+ ha_checksum checksum_val;
bool checksum_null;
uint action_flags;
#endif
diff --git a/storage/spider/mysql-test/spider/bugfix/include/same_server_link_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/same_server_link_deinit.inc
new file mode 100644
index 00000000000..a4e8a10db19
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/same_server_link_deinit.inc
@@ -0,0 +1,11 @@
+--connection master_1
+set global spider_same_server_link= @old_global_spider_same_server_link;
+set session spider_same_server_link= @old_session_spider_same_server_link;
+--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_deinit.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
diff --git a/storage/spider/mysql-test/spider/bugfix/include/same_server_link_init.inc b/storage/spider/mysql-test/spider/bugfix/include/same_server_link_init.inc
new file mode 100644
index 00000000000..2c8150c905d
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/include/same_server_link_init.inc
@@ -0,0 +1,15 @@
+--disable_warnings
+--disable_query_log
+--disable_result_log
+--source ../t/test_init.inc
+--enable_result_log
+--enable_query_log
+--enable_warnings
+--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
+let $MASTER_1_COMMENT_2_1=
+ COMMENT='table "tbl_b", host "127.0.0.1", port "$MASTER_1_MYPORT", user "root"';
+--connection master_1
+set @old_global_spider_same_server_link= @@global.spider_same_server_link;
+set @old_session_spider_same_server_link= @@session.spider_same_server_link;
+set global spider_same_server_link= 0;
+set session spider_same_server_link= 0;
diff --git a/storage/spider/mysql-test/spider/bugfix/r/same_server_link.result b/storage/spider/mysql-test/spider/bugfix/r/same_server_link.result
new file mode 100644
index 00000000000..1f4177568a7
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/r/same_server_link.result
@@ -0,0 +1,42 @@
+for master_1
+for child2
+for child3
+connection master_1;
+set @old_global_spider_same_server_link= @@global.spider_same_server_link;
+set @old_session_spider_same_server_link= @@session.spider_same_server_link;
+set global spider_same_server_link= 0;
+set session spider_same_server_link= 0;
+
+this test is for MDEV-6268
+
+drop and create databases
+connection master_1;
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+
+create table
+connection master_1;
+CREATE TABLE tbl_a (
+pkey int NOT NULL,
+PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+CREATE TABLE tbl_b (
+pkey int NOT NULL,
+PRIMARY KEY (pkey)
+) MASTER_1_ENGINE2 MASTER_1_CHARSET MASTER_1_COMMENT_2_1
+
+select test 1
+connection master_1;
+INSERT INTO tbl_a VALUES(1);
+
+deinit
+connection master_1;
+DROP DATABASE IF EXISTS auto_test_local;
+connection master_1;
+set global spider_same_server_link= @old_global_spider_same_server_link;
+set session spider_same_server_link= @old_session_spider_same_server_link;
+for master_1
+for child2
+for child3
+
+end of test
diff --git a/storage/spider/mysql-test/spider/bugfix/t/same_server_link.cnf b/storage/spider/mysql-test/spider/bugfix/t/same_server_link.cnf
new file mode 100644
index 00000000000..b0853e32654
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/same_server_link.cnf
@@ -0,0 +1,2 @@
+!include include/default_mysqld.cnf
+!include ../my_1_1.cnf
diff --git a/storage/spider/mysql-test/spider/bugfix/t/same_server_link.test b/storage/spider/mysql-test/spider/bugfix/t/same_server_link.test
new file mode 100644
index 00000000000..1468f00cd1c
--- /dev/null
+++ b/storage/spider/mysql-test/spider/bugfix/t/same_server_link.test
@@ -0,0 +1,55 @@
+--source ../include/same_server_link_init.inc
+--echo
+--echo this test is for MDEV-6268
+--echo
+--echo drop and create databases
+
+--connection master_1
+--disable_warnings
+CREATE DATABASE auto_test_local;
+USE auto_test_local;
+--enable_warnings
+
+--echo
+--echo create table
+
+--connection master_1
+--disable_query_log
+echo CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_a (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+echo CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) MASTER_1_ENGINE2 MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
+eval CREATE TABLE tbl_b (
+ pkey int NOT NULL,
+ PRIMARY KEY (pkey)
+) $MASTER_1_ENGINE2 $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
+--enable_query_log
+
+--echo
+--echo select test 1
+
+--connection master_1
+--disable_result_log
+--error 12720
+INSERT INTO tbl_a VALUES(1);
+--enable_result_log
+
+--echo
+--echo deinit
+--disable_warnings
+
+--connection master_1
+DROP DATABASE IF EXISTS auto_test_local;
+
+--enable_warnings
+--source ../include/same_server_link_deinit.inc
+--echo
+--echo end of test
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 313c6d0495c..18e2d2acbd5 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -56,6 +56,8 @@ extern HASH spider_open_connections;
extern HASH spider_ipport_conns;
extern SPIDER_DBTON spider_dbton[SPIDER_DBTON_SIZE];
extern const char spider_dig_upper[];
+extern const char **spd_mysqld_unix_port;
+extern uint *spd_mysqld_port;
spider_db_mysql_util spider_db_mysql_utility;
spider_db_mariadb_util spider_db_mariadb_utility;
@@ -1142,9 +1144,9 @@ int spider_db_mbase_result::fetch_simple_action(
if (mysql_row[position])
{
spider->checksum_val =
- (ulonglong) my_strtoll10(mysql_row[position], (char**) NULL,
+ (ha_checksum) my_strtoll10(mysql_row[position], (char**) NULL,
&error_num);
- DBUG_PRINT("info", ("spider checksum=%llu", spider->checksum_val));
+ DBUG_PRINT("info", ("spider checksum=%llu", (ulonglong)spider->checksum_val));
spider->checksum_null = FALSE;
} else {
spider->checksum_null = TRUE;
@@ -1970,6 +1972,30 @@ int spider_db_mbase::connect(
conn->tgt_default_group);
}
+ if (!spider_param_same_server_link(thd))
+ {
+ if (!strcmp(tgt_host, my_localhost))
+ {
+ if (!strcmp(tgt_socket, *spd_mysqld_unix_port))
+ {
+ my_printf_error(ER_SPIDER_SAME_SERVER_LINK_NUM,
+ ER_SPIDER_SAME_SERVER_LINK_STR1, MYF(0),
+ tgt_host, tgt_socket);
+ DBUG_RETURN(ER_SPIDER_SAME_SERVER_LINK_NUM);
+ }
+ } else if (!strcmp(tgt_host, "127.0.0.1") ||
+ !strcmp(tgt_host, glob_hostname))
+ {
+ if (tgt_port == *spd_mysqld_port)
+ {
+ my_printf_error(ER_SPIDER_SAME_SERVER_LINK_NUM,
+ ER_SPIDER_SAME_SERVER_LINK_STR2, MYF(0),
+ tgt_host, tgt_port);
+ DBUG_RETURN(ER_SPIDER_SAME_SERVER_LINK_NUM);
+ }
+ }
+ }
+
if (connect_mutex)
pthread_mutex_lock(&spider_open_conn_mutex);
/* tgt_db not use */
diff --git a/storage/spider/spd_err.h b/storage/spider/spd_err.h
index a80d903bd6e..9889fcfa7fb 100644
--- a/storage/spider/spd_err.h
+++ b/storage/spider/spd_err.h
@@ -124,6 +124,9 @@
#define ER_SPIDER_CON_COUNT_ERROR_STR "Too many connections between spider and remote"
#define ER_SPIDER_TABLE_OPEN_TIMEOUT_NUM 12714
#define ER_SPIDER_TABLE_OPEN_TIMEOUT_STR "Table %s.%s open timeout"
+#define ER_SPIDER_SAME_SERVER_LINK_NUM 12720
+#define ER_SPIDER_SAME_SERVER_LINK_STR1 "Host:%s and Socket:%s aim self server. Please change spider_same_server_link parameter if this link is required."
+#define ER_SPIDER_SAME_SERVER_LINK_STR2 "Host:%s and Port:%ld aim self server. Please change spider_same_server_link parameter if this link is required."
#define ER_SPIDER_COND_SKIP_NUM 12801
#define ER_SPIDER_UNKNOWN_NUM 12500
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index ad3d10dc642..fc2aa6c1d60 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -122,6 +122,8 @@ HASH *spd_db_att_xid_cache;
struct charset_info_st *spd_charset_utf8_bin;
const char **spd_defaults_extra_file;
const char **spd_defaults_file;
+const char **spd_mysqld_unix_port;
+uint *spd_mysqld_port;
bool volatile *spd_abort_loop;
Time_zone *spd_tz_system;
extern long spider_conn_mutex_id;
@@ -6934,6 +6936,10 @@ int spider_db_init(
GetProcAddress(current_module, "my_defaults_extra_file");
spd_defaults_file = (const char **)
GetProcAddress(current_module, "my_defaults_file");
+ spd_mysqld_unix_port = (const char **)
+ GetProcAddress(current_module, "?mysqld_unix_port@@3PADA");
+ spd_mysqld_port = (uint *)
+ GetProcAddress(current_module, "?mysqld_port@@3IA");
spd_abort_loop = (bool volatile *)
GetProcAddress(current_module, "?abort_loop@@3_NC");
spd_tz_system = *(Time_zone **)
@@ -6960,6 +6966,8 @@ int spider_db_init(
spd_charset_utf8_bin = &my_charset_utf8_bin;
spd_defaults_extra_file = &my_defaults_extra_file;
spd_defaults_file = &my_defaults_file;
+ spd_mysqld_unix_port = (const char **) &mysqld_unix_port;
+ spd_mysqld_port = &mysqld_port;
spd_abort_loop = &abort_loop;
spd_tz_system = my_tz_SYSTEM;
#endif
diff --git a/support-files/rpm/server-preun.sh b/support-files/rpm/server-preun.sh
index 1d733a7d899..f4eb81a7f75 100644
--- a/support-files/rpm/server-preun.sh
+++ b/support-files/rpm/server-preun.sh
@@ -7,9 +7,9 @@ if [ $1 = 0 ] ; then
fi
if [ -x %{_sysconfdir}/init.d/mysql ] ; then
%{_sysconfdir}/init.d/mysql stop > /dev/null
- fi
- if [ -x /sbin/chkconfig ] ; then
- /sbin/chkconfig --del mysql > /dev/null 2>&1
+ if [ -x /sbin/chkconfig ] ; then
+ /sbin/chkconfig --del mysql > /dev/null 2>&1
+ fi
fi
fi
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 40fbffa57bc..16bfa72985f 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -2348,6 +2348,12 @@ static void test_ps_query_cache()
"(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
myquery(rc);
+ rc= mysql_query(mysql,
+ "set @save_query_cache_type="
+ "@@global.query_cache_type,"
+ "@save_query_cache_size="
+ "@@global.query_cache_size");
+ myquery(rc);
rc= mysql_query(lmysql, "set global query_cache_type=ON");
myquery(rc);
rc= mysql_query(lmysql, "set local query_cache_type=ON");
@@ -2504,9 +2510,9 @@ static void test_ps_query_cache()
if (lmysql != mysql)
mysql_close(lmysql);
- rc= mysql_query(mysql, "set global query_cache_size=default");
+ rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
myquery(rc);
- rc= mysql_query(mysql, "set global query_cache_type=default");
+ rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
myquery(rc);
}
@@ -13522,6 +13528,12 @@ static void test_open_cursor_prepared_statement_query_cache()
return;
}
+ rc= mysql_query(mysql,
+ "set @save_query_cache_type="
+ "@@global.query_cache_type,"
+ "@save_query_cache_size="
+ "@@global.query_cache_size");
+ myquery(rc);
rc= mysql_query(mysql, "set global query_cache_type=ON");
myquery(rc);
rc= mysql_query(mysql, "set local query_cache_type=ON");
@@ -13548,9 +13560,9 @@ static void test_open_cursor_prepared_statement_query_cache()
check_execute(stmt, rc);
mysql_stmt_close(stmt);
- rc= mysql_query(mysql, "set global query_cache_type=default");
+ rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
myquery(rc);
- rc= mysql_query(mysql, "set global query_cache_size=default");
+ rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
myquery(rc);
}
@@ -18335,6 +18347,12 @@ static void test_bug36326()
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
myquery(rc);
+ rc= mysql_query(mysql,
+ "set @save_query_cache_type="
+ "@@global.query_cache_type,"
+ "@save_query_cache_size="
+ "@@global.query_cache_size");
+ myquery(rc);
rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
myquery(rc);
rc= mysql_query(mysql, "SET LOCAL query_cache_type = 1");
@@ -18362,8 +18380,8 @@ static void test_bug36326()
DIE_UNLESS(rc == 1);
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
- rc= mysql_query(mysql, "SET GLOBAL query_cache_size = default");
- rc= mysql_query(mysql, "SET GLOBAL query_cache_type = default");
+ rc= mysql_query(mysql, "SET GLOBAL query_cache_size = @save_query_cache_size");
+ rc= mysql_query(mysql, "SET GLOBAL query_cache_type = @save_query_cache_type");
myquery(rc);
DBUG_VOID_RETURN;
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
index f06d63d05fb..1d97340784d 100644
--- a/unittest/mysys/CMakeLists.txt
+++ b/unittest/mysys/CMakeLists.txt
@@ -14,10 +14,10 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
- aes byte_order
+ byte_order
LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
-
+MY_ADD_TESTS(aes LINK_LIBRARIES mysys mysys_ssl)
ADD_DEFINITIONS(${SSL_DEFINES})
MY_ADD_TESTS(ma_dyncol LINK_LIBRARIES mysys)
diff --git a/unittest/sql/CMakeLists.txt b/unittest/sql/CMakeLists.txt
index f63dc0b2a21..a4ba1019e49 100644
--- a/unittest/sql/CMakeLists.txt
+++ b/unittest/sql/CMakeLists.txt
@@ -31,6 +31,6 @@ TARGET_LINK_LIBRARIES(explain_filename-t sql mytap)
MY_ADD_TEST(explain_filename)
ADD_EXECUTABLE(mf_iocache-t mf_iocache-t.cc ../../sql/mf_iocache_encr.cc)
-TARGET_LINK_LIBRARIES(mf_iocache-t mysys mytap)
+TARGET_LINK_LIBRARIES(mf_iocache-t mysys mytap mysys_ssl)
ADD_DEPENDENCIES(mf_iocache-t GenError)
MY_ADD_TEST(mf_iocache)