
[Commits] 9c2f39e: MDEV-14667 Assertion `used_parts > 0' failed in ha_partition::init_record_priority_queue.
by holyfoot@askmonty.org 15 Apr '18
by holyfoot@askmonty.org 15 Apr '18
15 Apr '18
revision-id: 9c2f39ea72e0f11565016df4d13200ccfa5e0dca (mariadb-10.3.5-154-g9c2f39e)
parent(s): 560743198604caf677c543db9719cef871df09ce
committer: Alexey Botchkov
timestamp: 2018-04-15 21:35:30 +0400
message:
MDEV-14667 Assertion `used_parts > 0' failed in ha_partition::init_record_priority_queue.
ha_partition::init_record_priority_queue() made tolerant to
the case when all the partitions were pruned away.
---
mysql-test/main/partition_pruning.result | 10 ++++++++++
mysql-test/main/partition_pruning.test | 13 +++++++++++++
sql/ha_partition.cc | 5 ++++-
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/mysql-test/main/partition_pruning.result b/mysql-test/main/partition_pruning.result
index 422132d..7986e09 100644
--- a/mysql-test/main/partition_pruning.result
+++ b/mysql-test/main/partition_pruning.result
@@ -3484,3 +3484,13 @@ select * from t1 where (a = 1 AND b < 'd' AND (c = 'b' OR (c = 'c' AND d = 1)) O
a b c d
1 a b 1
drop table t1;
+#
+# MDEV-14667 Assertion `used_parts > 0' failed in ha_partition::init_record_priority_queue.
+#
+create table t1 (a int);
+insert into t1 values (1),(2);
+create table t2 (b int, c int, key(c,b)) partition by hash(b) partitions 2;
+insert into t2 values (3,4),(5,6);
+select straight_join * from t1, t2 where b != NULL;
+a b c
+drop table t1, t2;
diff --git a/mysql-test/main/partition_pruning.test b/mysql-test/main/partition_pruning.test
index 9d72e9c..592f5ba 100644
--- a/mysql-test/main/partition_pruning.test
+++ b/mysql-test/main/partition_pruning.test
@@ -1536,3 +1536,16 @@ select * from t1 where (a = 1 AND b < 'd' AND (c = 'b' OR (c = 'c' AND d = 1)) O
drop table t1;
+--echo #
+--echo # MDEV-14667 Assertion `used_parts > 0' failed in ha_partition::init_record_priority_queue.
+--echo #
+
+create table t1 (a int);
+insert into t1 values (1),(2);
+
+create table t2 (b int, c int, key(c,b)) partition by hash(b) partitions 2;
+insert into t2 values (3,4),(5,6);
+
+select straight_join * from t1, t2 where b != NULL;
+drop table t1, t2;
+
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 30d4b33..b0f82e8 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -5210,7 +5210,10 @@ bool ha_partition::init_record_priority_queue()
{
size_t alloc_len;
uint used_parts= bitmap_bits_set(&m_part_info->read_partitions);
- DBUG_ASSERT(used_parts > 0);
+
+ if (used_parts == 0) /* Do nothing since no records expected. */
+ DBUG_RETURN(false);
+
/* Allocate record buffer for each used partition. */
m_priority_queue_rec_len= m_rec_length + PARTITION_BYTES_IN_POS;
if (!m_using_extended_keys)
1
0

[Commits] 0fad97a: Post-merge fixes: add a suppression for rocksdb.skip_validate_tmP_table
by psergey@askmonty.org 15 Apr '18
by psergey@askmonty.org 15 Apr '18
15 Apr '18
revision-id: 0fad97a9ecbcb6a68ae396ea6f7a1dd4d933279c
parent(s): 261d4755f4418d3a1b4dadf8d1ed5098ae3aa92f
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-04-15 15:34:06 +0300
message:
Post-merge fixes: add a suppression for rocksdb.skip_validate_tmP_table
---
storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result | 1 +
storage/rocksdb/mysql-test/rocksdb/t/skip_validate_tmp_table.test | 3 +++
2 files changed, 4 insertions(+)
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result b/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
index d324793..92906f2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
@@ -3,6 +3,7 @@ show tables;
Tables_in_test
#mysql50#t1#sql-test
t1
+call mtr.add_suppression('Invalid .old.. table or database name .t1#sql-test.');
set session debug_dbug="+d,gen_sql_table_name";
rename table t1 to t2;
set session debug_dbug= "-d,gen_sql_table_name";
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/skip_validate_tmp_table.test b/storage/rocksdb/mysql-test/rocksdb/t/skip_validate_tmp_table.test
index 80c366d2..c432146 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/skip_validate_tmp_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/skip_validate_tmp_table.test
@@ -12,6 +12,9 @@ create table t1 (pk int primary key) engine=rocksdb;
show tables;
+# MariaDB produces a warning:
+call mtr.add_suppression('Invalid .old.. table or database name .t1#sql-test.');
+
# This will append '#sql-test' to the end of new name
set session debug_dbug="+d,gen_sql_table_name";
rename table t1 to t2;
1
0

[Commits] 261d475: Post-merge fixes: rocksdb.check_ignore_unknown_options
by psergey@askmonty.org 15 Apr '18
by psergey@askmonty.org 15 Apr '18
15 Apr '18
revision-id: 261d4755f4418d3a1b4dadf8d1ed5098ae3aa92f
parent(s): 8496e84f05e69a31e93653468b6e0579e154e8d8
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-04-15 14:34:56 +0300
message:
Post-merge fixes: rocksdb.check_ignore_unknown_options
---
.../mysql-test/rocksdb/r/check_ignore_unknown_options.result | 1 +
.../rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/check_ignore_unknown_options.result b/storage/rocksdb/mysql-test/rocksdb/r/check_ignore_unknown_options.result
index 24c1b73..6ff4990 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/check_ignore_unknown_options.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/check_ignore_unknown_options.result
@@ -1,6 +1,7 @@
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
variable_name variable_value
ROCKSDB_IGNORE_UNKNOWN_OPTIONS ON
+FOUND 1 /RocksDB: Compatibility check against existing database options failed/ in my_restart.err
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
variable_name variable_value
ROCKSDB_IGNORE_UNKNOWN_OPTIONS ON
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
index 2521354..b4866de 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test
@@ -4,12 +4,13 @@ let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err;
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
---exec find $MYSQLD_DATADIR/.rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}"
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--shutdown_server 10
+
--error 1
---exec $MYSQLD_CMD --rocksdb_ignore_unknown_options=0 --loose-console > $error_log 2>&1
+--exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --loose-console --log-error=$error_log
let SEARCH_FILE= $error_log;
let SEARCH_PATTERN= RocksDB: Compatibility check against existing database options failed;
@@ -17,5 +18,5 @@ let SEARCH_PATTERN= RocksDB: Compatibility check against existing database optio
--enable_reconnect
--exec echo "restart" > $restart_file
--source include/wait_until_connected_again.inc
---exec find $MYSQLD_DATADIR/.rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i '/hello=world/d' {}"
+--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i '/hello=world/d' {}"
select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options";
1
0
revision-id: 8496e84f05e69a31e93653468b6e0579e154e8d8
parent(s): 78e42153b51d6166b916a5bdb39e8726913c263e
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-04-15 12:52:27 +0300
message:
Trivial post-merge fixes
---
storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result | 12 ++++++------
.../mysql-test/rocksdb/r/skip_validate_tmp_table.result | 2 +-
.../mysql-test/rocksdb/r/ttl_primary_read_filtering.result | 2 +-
storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test | 12 ++++++------
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
index 79030e3..fe08cd7 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/autoinc_debug.result
@@ -2,7 +2,7 @@
# Testing upgrading from server without merges for auto_increment
# to new server with such support.
#
-set debug='+d,myrocks_autoinc_upgrade';
+set debug_dbug='+d,myrocks_autoinc_upgrade';
create table t (i int primary key auto_increment);
insert into t values ();
insert into t values ();
@@ -20,7 +20,7 @@ select table_name, index_name, auto_increment
from information_schema.rocksdb_ddl where table_name = 't';
table_name index_name auto_increment
t PRIMARY NULL
-set debug='-d,myrocks_autoinc_upgrade';
+set debug_dbug='-d,myrocks_autoinc_upgrade';
insert into t values ();
insert into t values ();
insert into t values ();
@@ -56,7 +56,7 @@ insert into t values ();
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_before";
+set debug_dbug="+d,crash_commit_before";
commit;
ERROR HY000: Lost connection to MySQL server during query
select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
@@ -69,7 +69,7 @@ max(i)
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after_prepare";
+set debug_dbug="+d,crash_commit_after_prepare";
commit;
ERROR HY000: Lost connection to MySQL server during query
select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
@@ -82,7 +82,7 @@ max(i)
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after_log";
+set debug_dbug="+d,crash_commit_after_log";
commit;
ERROR HY000: Lost connection to MySQL server during query
select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
@@ -95,7 +95,7 @@ max(i)
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after";
+set debug_dbug="+d,crash_commit_after";
commit;
ERROR HY000: Lost connection to MySQL server during query
select table_schema, table_name, auto_increment from information_schema.tables where table_name = 't';
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result b/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
index df04874..d324793 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/skip_validate_tmp_table.result
@@ -1,9 +1,9 @@
create table t1 (pk int primary key) engine=rocksdb;
show tables;
-set session debug_dbug="+d,gen_sql_table_name";
Tables_in_test
#mysql50#t1#sql-test
t1
+set session debug_dbug="+d,gen_sql_table_name";
rename table t1 to t2;
set session debug_dbug= "-d,gen_sql_table_name";
show tables;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/ttl_primary_read_filtering.result b/storage/rocksdb/mysql-test/rocksdb/r/ttl_primary_read_filtering.result
index 5bb3229..c66b179 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/ttl_primary_read_filtering.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/ttl_primary_read_filtering.result
@@ -210,8 +210,8 @@ select variable_value-@a from information_schema.global_status where variable_na
variable_value-@a
1
# Switching to connection 1
-select variable_value into @a from information_schema.global_status where variable_name='rocksdb_rows_filtered';
connection con1;
+select variable_value into @a from information_schema.global_status where variable_name='rocksdb_rows_filtered';
SELECT * FROM t1;
a
1
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
index df67338..abcae8d 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/autoinc_debug.test
@@ -7,7 +7,7 @@
--echo # to new server with such support.
--echo #
-set debug='+d,myrocks_autoinc_upgrade';
+set debug_dbug='+d,myrocks_autoinc_upgrade';
create table t (i int primary key auto_increment);
insert into t values ();
insert into t values ();
@@ -20,7 +20,7 @@ select * from t;
select table_name, index_name, auto_increment
from information_schema.rocksdb_ddl where table_name = 't';
-set debug='-d,myrocks_autoinc_upgrade';
+set debug_dbug='-d,myrocks_autoinc_upgrade';
--source include/restart_mysqld.inc
@@ -55,7 +55,7 @@ insert into t values ();
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_before";
+set debug_dbug="+d,crash_commit_before";
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--error 2013
commit;
@@ -71,7 +71,7 @@ select max(i) from t;
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after_prepare";
+set debug_dbug="+d,crash_commit_after_prepare";
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--error 2013
commit;
@@ -87,7 +87,7 @@ select max(i) from t;
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after_log";
+set debug_dbug="+d,crash_commit_after_log";
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--error 2013
commit;
@@ -103,7 +103,7 @@ select max(i) from t;
begin;
insert into t values ();
insert into t values ();
-set debug="+d,crash_commit_after";
+set debug_dbug="+d,crash_commit_after";
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--error 2013
commit;
1
0

[Commits] a91fdd1: Fixed the bug mdev-15575 different results when using CTE and big_tables=1.
by IgorBabaev 14 Apr '18
by IgorBabaev 14 Apr '18
14 Apr '18
revision-id: a91fdd1288b3cbc5616f2ef9e0ce04bf7f0ef9ce (mariadb-10.2.14-35-ga91fdd1)
parent(s): 740fc2ae084f8f81990de557d696aefbc507752d
author: Igor Babaev
committer: Igor Babaev
timestamp: 2018-04-14 21:32:41 -0700
message:
Fixed the bug mdev-15575 different results when using CTE and big_tables=1.
This bug happened due to a defect of the implementation of the handler
function ha_delete_all_rows() for the ARIA engine.
The function maria_delete_all_rows() truncated the table, but it didn't
touch the write cache, so the cache's write offset was not reset.
In the scenario like in the function st_select_lex_unit::exec_recursive
when first all records were deleted from the table and then several new
records were added some metadata became inconsistent with the state of
the cache. As a result the table scan function could not read records
at the end of the table.
The same defect could be found in the implementation of ha_delete_all_rows()
for the MYISAM engine mi_delete_all_rows().
Additionally made late instantiation for the temporary table used to store
rows that were used for each new iteration when executing a recursive CTE.
---
mysql-test/r/cte_recursive.result | 17 +++++++++++++++++
mysql-test/t/cte_recursive.test | 12 ++++++++++++
sql/sql_union.cc | 31 ++++++++++++++++++-------------
storage/maria/ma_delete_all.c | 3 +++
storage/myisam/mi_delete_all.c | 4 ++++
5 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result
index 4e9b4ae..55cd30f 100644
--- a/mysql-test/r/cte_recursive.result
+++ b/mysql-test/r/cte_recursive.result
@@ -3063,3 +3063,20 @@ SELECT * FROM cte;
5
2
3
+#
+# MDEV-15575: using recursive cte with big_tables enabled
+#
+set big_tables=1;
+with recursive qn as
+(select 123 as a union all select 1+a from qn where a<130)
+select * from qn;
+a
+123
+124
+125
+126
+127
+128
+129
+130
+set big_tables=default;
diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test
index c3a5ed5..373d6ca 100644
--- a/mysql-test/t/cte_recursive.test
+++ b/mysql-test/t/cte_recursive.test
@@ -2097,3 +2097,15 @@ WITH RECURSIVE cte AS
UNION
SELECT @c:=@c+1 FROM cte WHERE @c<3)
SELECT * FROM cte;
+
+--echo #
+--echo # MDEV-15575: using recursive cte with big_tables enabled
+--echo #
+
+set big_tables=1;
+
+with recursive qn as
+(select 123 as a union all select 1+a from qn where a<130)
+select * from qn;
+
+set big_tables=default;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 19c9330..3fe8a24 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -214,19 +214,13 @@ select_union_recursive::create_result_table(THD *thd_arg,
if (! (incr_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, false, 1,
options, HA_POS_ERROR, "",
- !create_table, keep_row_order)))
+ true, keep_row_order)))
return true;
incr_table->keys_in_use_for_query.clear_all();
for (uint i=0; i < table->s->fields; i++)
incr_table->field[i]->flags &= ~PART_KEY_FLAG;
- if (create_table)
- {
- incr_table->file->extra(HA_EXTRA_WRITE_CACHE);
- incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- }
-
TABLE *rec_table= 0;
if (! (rec_table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, false, 1,
@@ -270,8 +264,11 @@ void select_union_recursive::cleanup()
if (incr_table)
{
- incr_table->file->extra(HA_EXTRA_RESET_STATE);
- incr_table->file->ha_delete_all_rows();
+ if (incr_table->is_created())
+ {
+ incr_table->file->extra(HA_EXTRA_RESET_STATE);
+ incr_table->file->ha_delete_all_rows();
+ }
free_tmp_table(thd, incr_table);
}
@@ -1228,16 +1225,24 @@ bool st_select_lex_unit::exec_recursive()
if (!was_executed)
save_union_explain(thd->lex->explain);
- if ((saved_error= incr_table->file->ha_delete_all_rows()))
- goto err;
-
if (with_element->level == 0)
{
+ if (!incr_table->is_created() &&
+ instantiate_tmp_table(incr_table,
+ tmp_table_param->keyinfo,
+ tmp_table_param->start_recinfo,
+ &tmp_table_param->recinfo,
+ 0))
+ DBUG_RETURN(1);
+ incr_table->file->extra(HA_EXTRA_WRITE_CACHE);
+ incr_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
start= first_select();
if (with_element->with_anchor)
end= with_element->first_recursive;
}
-
+ else if ((saved_error= incr_table->file->ha_delete_all_rows()))
+ goto err;
+
for (st_select_lex *sl= start ; sl != end; sl= sl->next_select())
{
thd->lex->current_select= sl;
diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c
index a14603b..ee75218 100644
--- a/storage/maria/ma_delete_all.c
+++ b/storage/maria/ma_delete_all.c
@@ -135,6 +135,9 @@ int maria_delete_all_rows(MARIA_HA *info)
goto err;
}
+ if (info->opt_flag & WRITE_CACHE_USED)
+ reinit_io_cache(&info->rec_cache, WRITE_CACHE, 0, 1, 1);
+
_ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
#ifdef HAVE_MMAP
/* Map again */
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index 37fdf2d..c772e84 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -62,6 +62,10 @@ int mi_delete_all_rows(MI_INFO *info)
if (mysql_file_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
mysql_file_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)))
goto err;
+
+ if (info->opt_flag & WRITE_CACHE_USED)
+ reinit_io_cache(&info->rec_cache, WRITE_CACHE, 0, 1, 1);
+
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
DBUG_RETURN(0);
1
0

14 Apr '18
revision-id: 5db956f9df61eb11410cc8331853d43f6fd774d0 (mariadb-10.3.4-57-g5db956f)
parent(s): f80281d8d8afec96d89e2f18342f0acd28b3e55e
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-04-14 19:14:25 +0200
message:
Post review changes for MDEV-12387
Comments changed, test results added
---
.../suite/sys_vars/r/optimizer_switch_basic.result | 36 +-
.../sys_vars/r/sysvars_server_notembedded.result | 8 +-
sql/item_subselect.h | 10 +-
sql/opt_subselect.cc | 592 ++++++++++-----------
sql/opt_subselect.h | 16 +-
sql/sql_select.cc | 30 +-
.../mysql-test/tokudb/r/ext_key_2_tokudb.result | 2 +-
7 files changed, 339 insertions(+), 355 deletions(-)
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
index 87c8379..bc22fe1 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
@@ -1,63 +1,63 @@
SET @start_global_value = @@global.optimizer_switch;
SELECT @start_global_value;
@start_global_value
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
set global optimizer_switch=10;
set session optimizer_switch=5;
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
set global optimizer_switch="index_merge_sort_union=on";
set session optimizer_switch="index_merge=off";
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+optimizer_switch index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+OPTIMIZER_SWITCH index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
set session optimizer_switch="default";
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
Warnings:
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
set global optimizer_switch=1.1;
ERROR 42000: Incorrect argument type to variable 'optimizer_switch'
set global optimizer_switch=1e1;
@@ -69,4 +69,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 9ee1d72..b9286aa 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -2883,17 +2883,17 @@ ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_SWITCH
-SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
-GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
+GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
VARIABLE_SCOPE SESSION
VARIABLE_TYPE FLAGSET
VARIABLE_COMMENT Fine-tune the optimizer behavior
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
-ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,default
+ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,default
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_USE_CONDITION_SELECTIVITY
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 411407b..49dc582 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -905,12 +905,10 @@ class subselect_single_select_engine: public subselect_engine
friend class subselect_hash_sj_engine;
friend class Item_in_subselect;
- friend bool
- exec_engine_for_degenerated_jtbm_semi_join(THD *thd,
- JOIN *join,
- select_value_catcher **new_sink,
- Item_in_subselect *subq_pred);
-
+ friend bool execute_degenerate_jtbm_semi_join(THD *thd,
+ TABLE_LIST *tbl,
+ Item_in_subselect *subq_pred,
+ List<Item> &eq_list);
};
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index d2b15eb..69b96ec 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5431,12 +5431,11 @@ int select_value_catcher::send_data(List<Item> &items)
/**
@brief
- Try to merge item if it is an equality with the set of multiple
- equalities
+ Try to add an equality to some multiple equality
- @param thd the thread handle
- @param cond_equal set of multiple equalities
- @param item item that can be merged
+ @param thd the thread handle
+ @param cond_equal the set of multiple equalities
+ @param item the item that can be added
@note
To check this fact check_simple_equality is called
@@ -5445,8 +5444,8 @@ int select_value_catcher::send_data(List<Item> &items)
@retval FALSE otherwise
*/
bool join_equalities_for_setup_jtbm_semi_joins(THD *thd,
- COND_EQUAL *cond_equal,
- Item *item)
+ COND_EQUAL *cond_equal,
+ Item *item)
{
if (!(item->type() == Item::FUNC_ITEM &&
((Item_func *)item)->functype() == Item_func::EQ_FUNC))
@@ -5457,9 +5456,9 @@ bool join_equalities_for_setup_jtbm_semi_joins(THD *thd,
if (check_simple_equality(thd,
Item::Context(Item::ANY_SUBST,
- ((Item_func_equal *)item)->compare_type_handler(),
+ ((Item_func_equal *)item)->compare_type_handler(),
((Item_func_equal *)item)->compare_collation()),
- left_item, right_item, cond_equal))
+ left_item, right_item, cond_equal))
return true;
return false;
@@ -5467,32 +5466,31 @@ bool join_equalities_for_setup_jtbm_semi_joins(THD *thd,
/**
- @brief Push down equalities into the internal levels of condition if needed
+ @brief Push down equalities into the internal levels of the condition
+ if needed
@param thd the thread handle
- @param level current level number
- @param conds current level condition
- @param cond_equal equalities from the upper level that are pushed down
- @param cond_value the resulting value of the condition
+ @param level the current level number
+ @param conds the current level condition
+ @param cond_equal the equalities from the upper level that should
+ be pushed down
@details
- During the setup_jtbm_semi_joins work in the case when the join of the
- subquery is degenerated some new equalities appear. These equalities are
- attached to the top level of the WHERE clause (if it is a condition)
+ During the setup_jtbm_semi_joins work new equalities can appear.
+ These equalities are attached to the top level of the WHERE clause
but are not attached to the inner levels.
This procedure pushes equalities down to the inner levels if needed merging
- them with the existed equalities on the this level.
+ them with the exist equalities on the this level.
*/
Item *search_for_missing_parts_of_equalities(THD *thd,
- uint level,
- Item *conds,
- COND_EQUAL *cond_equal,
- Item::cond_result *cond_value)
+ uint level,
+ Item *conds,
+ COND_EQUAL *cond_equal)
{
if (conds->type() != Item::COND_ITEM)
{
/*
- If item is on the top level there is no need to attach anything to it
+ If current level is top level — nothing to add
*/
if (level<2)
return conds;
@@ -5520,8 +5518,8 @@ Item *search_for_missing_parts_of_equalities(THD *thd,
cond_equal= &((Item_cond_and *) conds)->m_cond_equal;
while ((item=li++))
- item= search_for_missing_parts_of_equalities(thd, level, item,
- cond_equal, cond_value);
+ item= search_for_missing_parts_of_equalities(thd, level,
+ item, cond_equal);
}
return conds;
}
@@ -5529,28 +5527,43 @@ Item *search_for_missing_parts_of_equalities(THD *thd,
/**
@brief
- Try to merge the set of equalities with the multiple equalities of
- the WHERE clause
+ Attach new equalities to the WHERE-clause condition
- @param thd the thread handle
- @param join pointer to the structure providing all context info for
- the query
- @param equal set of equalities to add
- @param cond_value the resulting value of the condition
+ @param join join of the select where equalities should be
+ attached
+ @param eq_list the set of the equalities to add
@details
- This method modifies WHERE clause trying to make a new condition
- consists of:
- 1. conds
- 2. multiple equalities from conds merged with the equal
- 3. the rest of equalities from the equal
+ The method modifies the condition of the join (the condition of the
+ WHERE clause) by adding new equalities from the eq_list. It adds new
+ equalities to the remain multiple equalities of the WHERE clause condition
+ or if it is not possible just attaches them to the WHERE clause condition.
+
+ First multiple equalities are disjoined from the join condition to avoid
+ repetitions. These multiple equalities are merged with the equalities from
+ the eq_list.
+
+ Example:
+
+ MULT_EQ(t1.a, t1.b) and (t1.a = 2) will become
+ MULT_EQ(2, t1.a, t1.b)
+
+ Sometimes it is not possible and in this case the eqialities that can't
+ be merged are saved to be attached to the condition later.
+ This situation can appear after the optimize of the IN subquery
+ predicate it is transformed in the knowlingly false equality.
+ For example, (3 = 1) equality.
+
+ Than a new condition is created. It consists of the old condition from
+ which multiple equalities were disjoint, new multiple equalities and
+ the equalities that weren't attached to the multiple equalities.
@retval TRUE if an error occurs
@retval FALSE otherwise
*/
-bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
- Item::cond_result *cond_value)
+bool join_equalities_after_optimize_cond(JOIN *join,
+ List<Item> &eq_list)
{
DBUG_ENTER("join_equalities_after_optimize_cond");
Item *conds= join->conds;
@@ -5559,6 +5572,7 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
Item_equal *item_equal;
List<Item_equal> *cond_equal_list=
(List<Item_equal> *) &join->cond_equal->current_level;
+ THD *thd= join->thd;
if (conds && conds->type() == Item::COND_ITEM &&
((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC)
@@ -5574,10 +5588,11 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
else if (join->cond_equal && join->cond_equal->current_level.elements)
{
/*
- Set to 0 to avoid repetitions from cond_equal after merging
+ If the condition of the WHERE clause is a multiple equality itself
+ it is set to 0.
*/
if (conds && conds->type() == Item::FUNC_ITEM &&
- ((Item_func*) conds)->functype() == Item_func::MULT_EQUAL_FUNC)
+ ((Item_func*) conds)->functype() == Item_func::MULT_EQUAL_FUNC)
conds= 0;
cond_equal.current_level.append(cond_equal_list);
@@ -5585,34 +5600,24 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
}
/*
- Merge equalities with multiple equalities of the WHERE clause.
- If the equality can't be merged leave it in the list to add to the
- WHERE clause later.
+ Merges the equalities from the equal_list with the multiple equalities
+ of the condition of the WHERE clause. If the equality can't be merged it
+ is left in the eq_list list so it can be later added to the WHERE clause.
*/
- if (equal && equal->type() == Item::COND_ITEM &&
- ((Item_cond*) equal)->functype() == Item_func::COND_AND_FUNC)
+ List_iterator<Item> li(eq_list);
+ Item *item;
+ while ((item=li++))
{
- List_iterator<Item> li(*((Item_cond *) equal)->argument_list());
- Item *item;
- while ((item=li++))
- {
- if (join_equalities_for_setup_jtbm_semi_joins(thd, &cond_equal, item))
- li.remove();
- }
+ if (join_equalities_for_setup_jtbm_semi_joins(thd, &cond_equal, item))
+ li.remove();
}
- else if (join_equalities_for_setup_jtbm_semi_joins(thd,
- &cond_equal,
- equal))
- equal= 0;
if (conds)
conds= conds->propagate_equal_fields(thd,
- Item::Context_boolean(),
- &cond_equal);
+ Item::Context_boolean(),
+ &cond_equal);
- /*
- Fix just created multiple equalities
- */
+ /* Fix just created multiple equalities */
List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++))
{
@@ -5626,22 +5631,22 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
}
/*
- Creates AND-condition for WITH clause if at list one of these conditions
- is satisfied:
+ Creates AND-condition for the WITH clause if at least one of these
+ conditions is satisfied:
1. there are several multiple inequalities
2. there remain several equalities in the equality list
3. in the {conds, equalities, cond_equal.current_level} set
- there are at least 2 not-null elements.
+ there are at least 2 non-empty elements.
*/
- uint eq_cnt= cond_equal.current_level.elements;
+ uint mult_eq_cnt= cond_equal.current_level.elements;
+ uint eq_cnt= eq_list.elements;
if (!and_args &&
- ((eq_cnt > 1) ||
- (equal && equal->type() == Item::COND_ITEM &&
- ((Item_cond*) equal)->functype() == Item_func::COND_AND_FUNC) ||
- (eq_cnt && equal) ||
- (eq_cnt && conds) ||
- (conds && equal)))
+ ((mult_eq_cnt > 1) ||
+ (eq_cnt > 1) ||
+ (mult_eq_cnt && eq_cnt) ||
+ (mult_eq_cnt && conds) ||
+ (conds && eq_cnt)))
{
if (!conds)
conds= new (thd->mem_root) Item_cond_and(thd);
@@ -5654,42 +5659,29 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
and_args= ((Item_cond*) conds)->argument_list();
}
- if (conds && !conds->fixed && conds->fix_fields(thd, NULL))
- DBUG_RETURN(TRUE);
-
- /*
- Joins conds with the remaining equalities
- */
- if (equal)
- {
- if (equal->type() == Item::COND_ITEM &&
- ((Item_cond*) equal)->functype() == Item_func::COND_AND_FUNC)
- and_args->append(((Item_cond *) equal)->argument_list());
- else if (and_args)
- and_args->push_back(equal, thd->mem_root);
- else
- conds= equal;
- }
-
- /*
- Joins conds with the multiple equalities
- */
+ /* Attaches the remaining equalities from the eq_list to the WHERE clause */
if (and_args)
- {
- ((Item_cond_and *)conds)->m_cond_equal.copy(cond_equal);
- cond_equal.current_level=
- ((Item_cond_and *)conds)->m_cond_equal.current_level;
+ and_args->append(&eq_list);
+ else
+ conds= new (thd->mem_root) Item_cond_and(thd, eq_list);
- and_args->append((List<Item> *)&cond_equal.current_level);
+ if (conds && !conds->fixed && conds->fix_fields(thd, NULL))
+ DBUG_RETURN(TRUE);
- conds= search_for_missing_parts_of_equalities(thd, 0, conds,
- &cond_equal, cond_value);
- }
- else if (eq_cnt == 1)
+ /* Attaches the multiple equalities to the WHERE clause condition */
+ ((Item_cond_and *)conds)->m_cond_equal.copy(cond_equal);
+ cond_equal.current_level=
+ ((Item_cond_and *)conds)->m_cond_equal.current_level;
+ if (mult_eq_cnt == 1)
{
it.rewind();
conds= it++;
}
+ else
+ {
+ and_args->append((List<Item> *)&cond_equal.current_level);
+ conds= search_for_missing_parts_of_equalities(thd, 0, conds, &cond_equal);
+ }
join->conds= conds;
@@ -5698,87 +5690,138 @@ bool join_equalities_after_optimize_cond(THD *thd, JOIN *join, Item *equal,
/**
- Execute the engine for the IN subquery
-**/
-bool exec_engine_for_degenerated_jtbm_semi_join(THD *thd,
- JOIN *join,
- select_value_catcher **new_sink,
- Item_in_subselect *subq_pred)
+ @brief Materialize a degenerate jtbm semi join
+
+ @param thd thread handler
+ @param tbl table list for the target jtbm semi join table
+ @param subq_pred IN subquery predicate with the degenerate jtbm semi join
+ @param eq_list IN/OUT the list where to add produced equalities
+
+ @details
+ The method materializes the degenerate jtbm semi join for the
+ subquery from the IN subquery predicate subq_pred taking table
+ as the target for materialization.
+ Any degenerate table is guaranteed to produce 0 or 1 record.
+ Examples of both cases:
+
+ select * from ot where col in (select ... from it where 2>3)
+ select * from ot where col in (select MY_MIN(it.key) from it)
+
+ in this case, there is no necessity to create a temp.table for
+ materialization.
+ We now just need to
+ 1. Check whether 1 or 0 records are produced, setup this as a
+ constant join tab.
+ 2. Create a dummy temporary table, because all of the join
+ optimization code relies on TABLE object being present.
+
+ In the case when materialization produces one row the function
+ additionally creates equalities between the expressions from the
+ left part of the IN subquery predicate and the corresponding
+ columns of the produced row. These equalities are added to the
+ list eq_list. They are supposed to be conjuncted with the condition
+ of the WHERE clause.
+
+ @retval TRUE if an error occurs
+ @retval FALSE otherwise
+*/
+
+bool execute_degenerate_jtbm_semi_join(THD *thd,
+ TABLE_LIST *tbl,
+ Item_in_subselect *subq_pred,
+ List<Item> &eq_list)
{
- DBUG_ENTER("exec_engine_for_degenerated_jtbm_semi_join");
+ DBUG_ENTER("execute_degenerate_jtbm_semi_join");
+ select_value_catcher *new_sink;
+
DBUG_ASSERT(subq_pred->engine->engine_type() ==
subselect_engine::SINGLE_SELECT_ENGINE);
subselect_single_select_engine *engine=
(subselect_single_select_engine*)subq_pred->engine;
- if (!(*new_sink=
- new (thd->mem_root) select_value_catcher(thd, subq_pred)))
+ if (!(new_sink= new (thd->mem_root) select_value_catcher(thd, subq_pred)))
DBUG_RETURN(TRUE);
- if ((*new_sink)->setup(&engine->select_lex->join->fields_list) ||
- engine->select_lex->join->change_result(*new_sink, NULL) ||
+ if (new_sink->setup(&engine->select_lex->join->fields_list) ||
+ engine->select_lex->join->change_result(new_sink, NULL) ||
engine->exec())
{
DBUG_RETURN(TRUE);
}
- DBUG_RETURN(FALSE);
-}
-
-
-/**
- @brief Set up a dummy TABLE*, optimizer code needs JOIN_TABs to have TABLE
+ subq_pred->is_jtbm_const_tab= TRUE;
- @param thd the thread handle
- @param table table for the materialized semijoin
+ if (new_sink->assigned)
+ {
+ /*
+ Subselect produced one row, which is saved in new_sink->row.
+ Save "left_expr[i] == row[i]" equalities into the eq_list.
+ */
+ subq_pred->jtbm_const_row_found= TRUE;
- @note
- The created table may be freed by:
- 1. JOIN_TAB::cleanup(), when the parent join is a regular join.
- 2. cleanup_empty_jtbm_semi_joins(), when the parent join is a
- degenerate join (e.g. one with "Impossible where").
+ Item *eq_cond;
+ for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
+ {
+ eq_cond=
+ new (thd->mem_root) Item_func_eq(thd,
+ subq_pred->left_expr->element_index(i),
+ new_sink->row[i]);
+ if (!eq_cond)
+ DBUG_RETURN(TRUE);
- @retval TRUE if an error occurs
- @retval FALSE otherwise
-**/
-bool setup_dummy_table_for_degenerated_jtbm_semi_join(THD *thd,
- TABLE_LIST *table)
-{
- DBUG_ENTER("setup_dummy_table_for_degenerated_jtbm_semi_join");
+ eq_list.push_back(eq_cond, thd->mem_root);
+ }
+ }
+ else
+ {
+ /* Subselect produced no rows. Just set the flag */
+ subq_pred->jtbm_const_row_found= FALSE;
+ }
TABLE *dummy_table;
if (!(dummy_table= create_dummy_tmp_table(thd)))
DBUG_RETURN(TRUE);
- table->table= dummy_table;
- table->table->pos_in_table_list= table;
- setup_table_map(table->table, table, table->jtbm_table_no);
+ tbl->table= dummy_table;
+ tbl->table->pos_in_table_list= tbl;
+ /*
+ Note: the table created above may be freed by:
+ 1. JOIN_TAB::cleanup(), when the parent join is a regular join.
+ 2. cleanup_empty_jtbm_semi_joins(), when the parent join is a
+ degenerate join (e.g. one with "Impossible where").
+ */
+ setup_table_map(tbl->table, tbl, tbl->jtbm_table_no);
DBUG_RETURN(FALSE);
}
/**
- @brief Setup degenerated JTBM join tables for execution
+ @brief Find degenerate jtbm semi joins
- @param join join being processed
- @param join_list list of tables
- @param join_where IN/OUT WHERE clause
- @param cond_value the returned value of the WHERE clause of the join
+ @param join the parent join for jtbm semi joins
+ @param join_list the list of TABLE_LIST objects where jtbm semi join can occur
+ @param eq_list IN/OUT the list where to add produced equalities
@details
- Calls setup_degenerated_jtbm_semi_join for each table used in join
- and for the nested joins lists of tables.
+ The method traverses join_list trying to find any degenerate jtbm semi
+ joins for subqueries of IN predicates. For each degenerate jtbm
+ semi join execute_degenerate_jtbm_semi_join is called.
+
+ In the case when a TABLE_LIST object is nested in another TABLE_LIST
+ 'nested_join' method is recursively called for the list
+ of TABLE_LIST objects of the 'nested_join' trying to find in the list
+ any degenerate jtbm semi joins.
@retval TRUE if an error occurs
@retval FALSE otherwise
-**/
+*/
+
bool
-setup_degenerated_semi_joins_before_optimize_cond(JOIN *join,
- List<TABLE_LIST> *join_list,
- Item **join_where,
- Item::cond_result *cond_value)
+setup_degenerate_jtbm_semi_joins(JOIN *join,
+ List<TABLE_LIST> *join_list,
+ List<Item> &eq_list)
{
TABLE_LIST *table;
NESTED_JOIN *nested_join;
List_iterator<TABLE_LIST> li(*join_list);
THD *thd= join->thd;
- DBUG_ENTER("setup_degenerated_semi_joins_before_optimize_cond");
+ DBUG_ENTER("setup_degenerate_jtbm_semi_joins");
while ((table= li++))
{
@@ -5790,87 +5833,84 @@ setup_degenerated_semi_joins_before_optimize_cond(JOIN *join,
if (!subq_join->tables_list || !subq_join->table_count)
{
- /*
- A special case; subquery's join is degenerate, and it either produces
- 0 or 1 record. Examples of both cases:
-
- select * from ot where col in (select ... from it where 2>3)
- select * from ot where col in (select MY_MIN(it.key) from it)
-
- in this case, the subquery predicate has not been setup for
- materialization. In particular, there is no materialized temp.table.
- We'll now need to
- 1. Check whether 1 or 0 records are produced, setup this as a
- constant join tab.
- 2. Create a dummy temporary table, because all of the join
- optimization code relies on TABLE object being present (here we
- follow a bad tradition started by derived tables)
- */
- select_value_catcher *new_sink;
-
- if (exec_engine_for_degenerated_jtbm_semi_join(thd, join,
- &new_sink, subq_pred))
- DBUG_RETURN(TRUE);
- subq_pred->is_jtbm_const_tab= TRUE;
-
- if (new_sink->assigned)
- {
- /*
- Subselect produced one row, which is saved in new_sink->row.
- Inject "left_expr[i] == row[i] equalities into parent's WHERE.
- */
- subq_pred->jtbm_const_row_found= TRUE;
- Item *eq_cond;
-
- for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
- {
- eq_cond= new (thd->mem_root)
- Item_func_eq(thd, subq_pred->left_expr->element_index(i),
- new_sink->row[i]);
- if (!eq_cond)
- DBUG_RETURN(TRUE);
-
- if (!((*join_where)= and_items(thd, *join_where, eq_cond)) ||
- (*join_where)->fix_fields(thd, join_where))
- DBUG_RETURN(TRUE);
- }
- }
- else
- {
- /* Subselect produced no rows. Just set the flag, */
- subq_pred->jtbm_const_row_found= FALSE;
- }
- if (setup_dummy_table_for_degenerated_jtbm_semi_join(thd, table))
+ if (execute_degenerate_jtbm_semi_join(thd,
+ table,
+ subq_pred,
+ eq_list))
DBUG_RETURN(TRUE);
- join->is_orig_degenerated= true;
+ join->is_orig_degenerated= true;
}
-
- if ((nested_join= table->nested_join))
- {
- if (setup_degenerated_semi_joins_before_optimize_cond(join,
- &nested_join->join_list,
- join_where, cond_value))
+ }
+ if ((nested_join= table->nested_join))
+ {
+ if (setup_degenerate_jtbm_semi_joins(join, &nested_join->join_list, eq_list))
DBUG_RETURN(TRUE);
- }
}
}
+
DBUG_RETURN(FALSE);
}
-/*
- Setup JTBM join tabs for execution
+/**
+ @brief Prepare jtbm semi joins for materialization
+
+ @param join the parent join for jtbm semi joins
+ @param join_list the list of TABLE_LIST objects where jtbm semi join can occur
+ @param eq_list IN/OUT the list where to add produced equalities
+
+ @details
+ The method traverses join_list trying to find any jtbm semi joins for
+ subqueries from IN predicates. It either materializes the jtbm semi join
+ or creates a temporary table into which the jtbm semi join will be
+ materialized. The IN subquery predicate is optimized first to get the
+ information about how it should be handled.
+
+ The first case is when the jtbm semi join is degenerate. Usually the
+ jtbm semi join is found degenerate before the optimization and on this
+ step it is already materialized by the setup_degenerate_jtbm_semi_joins
+ method. Btw there can appear a situation when the jtbm semi join becomes
+ degenerate only after the optimization of the IN subquery predicate.
+ In this case the execute_degenerate_jtbm_semi_join method is called.
+
+ Example taken from subselect.test:
+
+ SELECT * FROM t1
+ WHERE 4 IN (
+ SELECT MAX(b)
+ FROM t2
+ WHERE EXISTS (SELECT * FROM t1));
+
+ Only after the optimization of EXISTS it is found that the WHERE-clause
+ of the IN subquery predicate is impossible. So the jtbm semi join for
+ the subquery from this predicate is degenerate and should be materialized.
+
+ In the other case the IN subquery predicate should be computed via a
+ hash semi-join. It creates a temporary table in which the jtbm semi join
+ of the subquery from this predicate will be materialized.
+ The equalities between all pairs of expressions of the IN subquery
+ predicate are attached to the eq_list to be later conjuncted with the
+ condition of the WHERE clause.
+
+ In the case when a TABLE_LIST object is nested in another TABLE_LIST
+ the method is recursively called for the list of TABLE_LIST objects
+ of the nested join.
+
+ @retval TRUE if an error occurs
+ @retval FALSE otherwise
*/
+
bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
- Item **join_where, Item::cond_result *cond_value)
+ List<Item> &eq_list)
{
TABLE_LIST *table;
NESTED_JOIN *nested_join;
List_iterator<TABLE_LIST> li(*join_list);
THD *thd= join->thd;
DBUG_ENTER("setup_jtbm_semi_joins");
-
+ eq_list.empty();
+
while ((table= li++))
{
Item_in_subselect *subq_pred;
@@ -5894,77 +5934,10 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
if (!subq_join->tables_list || !subq_join->table_count)
{
- JOIN *subq_join= subq_pred->unit->first_select()->join;
-
- if (!join->is_orig_degenerated &&
- subq_join &&
- (!subq_join->tables_list || !subq_join->table_count))
- {
- /*
- If setup for degenerated joins wasn't done before
- */
- select_value_catcher *new_sink;
-
- if (exec_engine_for_degenerated_jtbm_semi_join(thd, join,
- &new_sink,
- subq_pred))
- DBUG_RETURN(TRUE);
- subq_pred->is_jtbm_const_tab= TRUE;
-
- if (new_sink->assigned)
- {
- /*
- Subselect produced one row, which is saved in new_sink->row.
- Create "left_expr[i] == row[i] equalities and join them with
- the created after optimize multiple equalities of parent's WHERE.
- */
- subq_pred->jtbm_const_row_found= TRUE;
-
- Item *eq_cond;
- Item *new_cond;
-
- if (join->conds)
- new_cond= new (thd->mem_root) Item_cond_and(thd);
-
- for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
- {
- eq_cond= new (thd->mem_root)
- Item_func_eq(thd, subq_pred->left_expr->element_index(i),
- new_sink->row[i]);
- if (!eq_cond)
- DBUG_RETURN(TRUE);
-
- if (join->conds)
- {
- if (!(new_cond= and_items(thd, new_cond, eq_cond)) ||
- new_cond->fix_fields(thd, &new_cond))
- DBUG_RETURN(TRUE);
- }
- else
- {
- new_cond= eq_cond;
- if (new_cond->fix_fields(thd, &new_cond))
- DBUG_RETURN(TRUE);
- }
- }
-
- if (join_equalities_after_optimize_cond(thd, join, new_cond,
- cond_value))
- DBUG_RETURN(TRUE);
- }
- else
- {
- /* Subselect produced no rows. Just set the flag, */
- subq_pred->jtbm_const_row_found= FALSE;
- }
-
- if (setup_dummy_table_for_degenerated_jtbm_semi_join(thd, table))
- DBUG_RETURN(TRUE);
-
- join->is_orig_degenerated= true;
- }
-
- join->conds= join->conds->remove_eq_conds(thd, cond_value, true);
+ if (!join->is_orig_degenerated &&
+ execute_degenerate_jtbm_semi_join(thd, table, subq_pred,
+ eq_list))
+ DBUG_RETURN(TRUE);
}
else
{
@@ -5978,22 +5951,16 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
setup_table_map(table->table, table, table->jtbm_table_no);
- /*
- Add to the condition equalities that join left and right parts
- of the subquery
- */
- if (join_equalities_after_optimize_cond(thd, join,
- hash_sj_engine->semi_join_conds,
- cond_value))
- DBUG_RETURN(TRUE);
+ List_iterator<Item> li(*hash_sj_engine->semi_join_conds->argument_list());
+ Item *item;
+ while ((item=li++))
+ eq_list.push_back(item, thd->mem_root);
}
table->table->maybe_null= MY_TEST(join->mixed_implicit_grouping);
}
-
if ((nested_join= table->nested_join))
{
- if (setup_jtbm_semi_joins(join, &nested_join->join_list,
- join_where, cond_value))
+ if (setup_jtbm_semi_joins(join, &nested_join->join_list, eq_list))
DBUG_RETURN(TRUE);
}
}
@@ -6543,9 +6510,9 @@ Item *Item_field::in_subq_field_transformer_for_having(THD *thd, uchar *arg)
of the left part of IN subquery
*/
void grouping_fields_in_the_in_subq_left_part(THD *thd,
- st_select_lex *sel,
- List<In_subq_field> *fields,
- ORDER *grouping_list)
+ st_select_lex *sel,
+ List<In_subq_field> *fields,
+ ORDER *grouping_list)
{
sel->grouping_tmp_fields.empty();
List_iterator<In_subq_field> it(*fields);
@@ -6556,12 +6523,11 @@ void grouping_fields_in_the_in_subq_left_part(THD *thd,
{
if ((*ord->item)->eq(item->right_it, 0))
{
- Field *field=
- ((Item_field *)(item->left_it->real_item()))->field;
- Grouping_tmp_field *grouping_tmp_field=
- new Grouping_tmp_field(field,
- item->right_it);
- sel->grouping_tmp_fields.push_back(grouping_tmp_field);
+ Field *field=
+ ((Item_field *)(item->left_it->real_item()))->field;
+ Grouping_tmp_field *grouping_tmp_field=
+ new Grouping_tmp_field(field, item->right_it);
+ sel->grouping_tmp_fields.push_back(grouping_tmp_field);
}
}
}
@@ -6596,11 +6562,11 @@ void grouping_fields_in_the_in_subq_left_part(THD *thd,
The implementation scheme:
- 1. It extracts the condition extr from condition cond depending only on
+ 1. It extracts the condition extr from condition cond that depends only on
the fields of the left part of the IN subquery (left_part).
2. Finds fields F_group in the right part of the IN subquery (right_part)
that are used in the GROUP BY.
- 3. Extracts from the extr condition cond_where depending only on the
+ 3. Extracts from the extr condition cond_where that depends only on the
those fields from the left_part that stay at the same places in the left_part
(have the same indexes) as the F_group fields in the projection of the
right_part.
@@ -6629,7 +6595,7 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
/*
Create the list of In_subq_field items for this IN subquery:
- it consists of pairs of fields from the left part of the IN subquery
+ it consists of the pairs of fields from the left part of the IN subquery
'left_part' and the respective fields from the right part of the
IN subquery (fields from the projections list of the select of the right
part of the IN subquery 'right_part' that stay on the same places in
@@ -6650,7 +6616,7 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
}
/*
- Build the new condition from the cond that can be pushed in sel
+ Build the new condition from the cond that can be pushed into sel
*/
Item *extracted_cond;
cond->check_pushable_cond(0, this);
@@ -6697,19 +6663,19 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
}
/*
- Check what can be pushed in the WHERE clause of the sel from the
+ Checks what can be pushed into the WHERE clause of the sel from the
extracted condition
*/
Item *cond_over_grouping_fields;
grouping_fields_in_the_in_subq_left_part(thd, sel, &comparable_fields,
- sel->group_list.first);
+ sel->group_list.first);
sel->check_cond_extraction_for_grouping_fields(extracted_cond);
cond_over_grouping_fields=
sel->build_cond_for_grouping_fields(thd, extracted_cond, true);
/*
- Transform the references to the left_part fields so they can be pushed
- into the sel WHERE clause.
+ Transforms the references to the left_part fields so they can be pushed
+ into the sel of the WHERE clause.
*/
if (cond_over_grouping_fields)
cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
@@ -6719,7 +6685,7 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
if (cond_over_grouping_fields)
{
/*
- Remove from extracted_cond all parts that can be pushed in WHERE clause
+ Removes from extracted_cond all parts that can be pushed into the WHERE clause
*/
extracted_cond= remove_pushed_top_conjuncts(thd, extracted_cond);
@@ -6731,8 +6697,8 @@ bool Item_in_subselect::pushdown_cond_for_in_subquery(THD *thd, Item *cond)
goto exit;
}
/*
- Transform the references to the left_part fields so they can be pushed in
- the sel HAVING clause
+ Transforms the references to the left_part fields so they can be pushed into
+ the sel of the HAVING clause
*/
extracted_cond= extracted_cond->transform(thd,
&Item::in_subq_field_transformer_for_having,
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index 70cf47f..e116fdf 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -26,17 +26,13 @@ int check_and_do_in_subquery_rewrites(JOIN *join);
bool convert_join_subqueries_to_semijoins(JOIN *join);
int pull_out_semijoin_tables(JOIN *join);
bool optimize_semijoin_nests(JOIN *join, table_map all_table_map);
-bool setup_degenerated_jtbm_semi_join(THD *thd, JOIN *join,
- TABLE_LIST *table,
- Item **join_where,
- Item_in_subselect *subq_pred,
- Item::cond_result *cond_value);
+bool join_equalities_after_optimize_cond(JOIN *join,
+ List<Item> &eq_list);
+bool setup_degenerate_jtbm_semi_joins(JOIN *join,
+ List<TABLE_LIST> *join_list,
+ List<Item> &eq_list);
bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
- Item **join_where, Item::cond_result *cond_value);
-bool setup_degenerated_semi_joins_before_optimize_cond(JOIN *join,
- List<TABLE_LIST> *join_list,
- Item **join_where,
- Item::cond_result *cond_value);
+ List<Item> &eq_list);
void cleanup_empty_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list);
// used by Loose_scan_opt
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 97b2ccc..5a342c8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1730,10 +1730,27 @@ JOIN::optimize_inner()
thd->restore_active_arena(arena, &backup);
}
- if (setup_degenerated_semi_joins_before_optimize_cond(this, join_list,
- &conds, &cond_value))
+ List<Item> eq_list;
+
+ if (setup_degenerate_jtbm_semi_joins(this, join_list, eq_list))
DBUG_RETURN(1);
+ if (eq_list.elements != 0)
+ {
+ Item *new_cond;
+
+ if (eq_list.elements == 1)
+ new_cond= eq_list.pop();
+ else
+ new_cond= new (thd->mem_root) Item_cond_and(thd, eq_list);
+
+ if (new_cond &&
+ (new_cond->fix_fields(thd, &new_cond) ||
+ !(conds= and_items(thd, conds, new_cond)) ||
+ conds->fix_fields(thd, &conds)))
+ DBUG_RETURN(TRUE);
+ }
+
if (select_lex->cond_pushed_into_where)
{
conds= and_conds(thd, conds, select_lex->cond_pushed_into_where);
@@ -1768,9 +1785,16 @@ JOIN::optimize_inner()
}
}
- if (setup_jtbm_semi_joins(this, join_list, &conds, &cond_value))
+ if (setup_jtbm_semi_joins(this, join_list, eq_list))
DBUG_RETURN(1);
+ if (eq_list.elements != 0)
+ {
+ if (join_equalities_after_optimize_cond(this, eq_list))
+ DBUG_RETURN(TRUE);
+ conds= conds->remove_eq_conds(thd, &cond_value, true);
+ }
+
if (thd->lex->sql_command == SQLCOM_SELECT &&
optimizer_flag(thd, OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED))
{
diff --git a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
index 1dcb1ee..9d9fb4c 100644
--- a/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
+++ b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result
@@ -1,7 +1,7 @@
drop table if exists t;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
create table t (a int not null, b int not null, c int not null, d int not null, primary key(a,b), key(c,a)) engine=tokudb;
insert into t values (0,0,0,0),(0,1,0,1);
explain select c,a,b from t where c=0 and a=0 and b=1;
1
0

[Commits] 78e4215: Fix compile on windows: O_SYNC is not available, use a my_sync() call instead.
by psergey@askmonty.org 13 Apr '18
by psergey@askmonty.org 13 Apr '18
13 Apr '18
revision-id: 78e42153b51d6166b916a5bdb39e8726913c263e
parent(s): 5545753b0b21b98fbdd2d8b894bc141d1ed558b3
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-04-13 20:26:40 +0300
message:
Fix compile on windows: O_SYNC is not available, use a my_sync() call instead.
---
storage/rocksdb/rdb_utils.cc | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/storage/rocksdb/rdb_utils.cc b/storage/rocksdb/rdb_utils.cc
index 19469d0..723e079 100644
--- a/storage/rocksdb/rdb_utils.cc
+++ b/storage/rocksdb/rdb_utils.cc
@@ -358,7 +358,8 @@ bool rdb_check_rocksdb_corruption() {
void rdb_persist_corruption_marker() {
const std::string &fileName(myrocks::rdb_corruption_marker_file_name());
- int fd = my_open(fileName.c_str(), O_CREAT | O_SYNC, MYF(MY_WME));
+ /* O_SYNC is not supported on windows */
+ int fd = my_open(fileName.c_str(), O_CREAT | IF_WIN(0, O_SYNC), MYF(MY_WME));
if (fd < 0) {
sql_print_error("RocksDB: Can't create file %s to mark rocksdb as "
"corrupted.",
@@ -370,6 +371,12 @@ void rdb_persist_corruption_marker() {
fileName.c_str());
}
+#ifdef _WIN32
+ /* A replacement for O_SYNC flag above */
+ if (fd >= 0)
+ my_sync(fd, MYF(0));
+#endif
+
int ret = my_close(fd, MYF(MY_WME));
if (ret) {
// NO_LINT_DEBUG
1
0

[Commits] 2c233f3dca8: MDEV-14551 Can't find record in table on multi-table update with ORDER BY
by serg@mariadb.org 13 Apr '18
by serg@mariadb.org 13 Apr '18
13 Apr '18
revision-id: 2c233f3dca8d4a12bd96b072aa358784fda5f28c (mariadb-10.3.5-153-g2c233f3dca8)
parent(s): 95811f01f34705ea026e4b7bbebe2e00f7061f88
author: Sergei Golubchik
committer: Sergei Golubchik
timestamp: 2018-04-13 19:13:48 +0200
message:
MDEV-14551 Can't find record in table on multi-table update with ORDER BY
preserve positions if the multi-update join is using tmp table:
* introduce Item_temptable_rowid() that is used to store
table->file->position() in the temporary table record
* store positions in the tmp table if needed
JOIN::add_fields_for_current_rowid()
* take positions from the tmp table, not from file->position():
multi_update::prepare2()
---
mysql-test/main/multi_update.result | 72 +++++++++++++++++++++++
mysql-test/main/multi_update.test | 46 +++++++++++++++
sql/item.cc | 5 ++
sql/item.h | 3 +-
sql/item_func.h | 2 +-
sql/item_strfunc.cc | 20 +++++++
sql/item_strfunc.h | 22 +++++++-
sql/sql_class.h | 7 ++-
sql/sql_insert.cc | 2 +-
sql/sql_select.cc | 45 +++++++++++----
sql/sql_select.h | 6 ++
sql/sql_union.cc | 4 +-
sql/sql_update.cc | 110 ++++++++++++++++++++++--------------
13 files changed, 283 insertions(+), 61 deletions(-)
diff --git a/mysql-test/main/multi_update.result b/mysql-test/main/multi_update.result
index 45239f6e090..c40de47668a 100644
--- a/mysql-test/main/multi_update.result
+++ b/mysql-test/main/multi_update.result
@@ -968,3 +968,75 @@ NULL 6
7 7
8 8
drop table t1, t2;
+create table t1 (i int) engine=memory;
+insert t1 values (1),(2);
+create table t2 (f int) engine=myisam;
+insert t2 values (1),(2);
+explain update t1, t2 set f = 126 order by f limit 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+update t1, t2 set f = 126 order by f limit 2;
+select * from t2;
+f
+126
+2
+drop table t1, t2;
+create table t0(a int);
+insert t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int, key(a));
+insert t1 select a,a,a from t0;
+create table t2 as select * from t1;
+create table t3 as select * from t1;
+select * from t1, t2 where t1.a=t2.a and t1.b in (select b from t3 where t3.c<=t2.c) order by t2.c, t1.c limit 5;
+a b c a b c
+0 0 0 0 0 0
+1 1 1 1 1 1
+2 2 2 2 2 2
+3 3 3 3 3 3
+4 4 4 4 4 4
+set optimizer_switch='firstmatch=off';
+explain update t1, t2 set t2.c=1 where t1.a=t2.a and t1.b in (select b from t3 where t3.c< t2.c) order by t2.c, t1.c limit 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+1 PRIMARY t1 ALL a NULL NULL NULL 10 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 10 Using where; Start temporary; End temporary
+update t1, t2 set t2.c=1 where t1.a=t2.a and t1.b in (select b from t3 where t3.c<=t2.c) order by t2.c, t1.c limit 5;
+select * from t2;
+a b c
+0 0 1
+1 1 1
+2 2 1
+3 3 1
+4 4 1
+5 5 5
+6 6 6
+7 7 7
+8 8 8
+9 9 9
+set optimizer_switch=default;
+drop table t0,t1,t2,t3;
+create table t0 (x int);
+create table t1 (a int);
+create table t2 (b int, c int default 0);
+insert t0 (x) values (0),(10);
+insert t1 (a) values (1), (2);
+insert t2 (b) values (1), (2);
+create view v1 as select t2.b,t2.c from t1, t2
+where t1.a=t2.b and t2.b < 3 with check option;
+select * from t0 join v1 on (x=c);
+x b c
+0 1 0
+0 2 0
+explain update v1,t0 set c=1 where b=1 and x=c order by x,b limit 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t0 ALL NULL NULL NULL NULL 2 Using where
+update v1,t0 set c=1 where b<3 and x=c order by x,b limit 1;
+select * from v1;
+b c
+1 1
+2 0
+drop view v1;
+drop table t0, t1,t2;
diff --git a/mysql-test/main/multi_update.test b/mysql-test/main/multi_update.test
index 5feebe87a5a..42e34d1e4a1 100644
--- a/mysql-test/main/multi_update.test
+++ b/mysql-test/main/multi_update.test
@@ -914,3 +914,49 @@ update t1 set c1=NULL;
update t1, t2 set t1.c1=t2.c3 where t1.c3=t2.c3 order by t1.c3 desc limit 2;
select * from t1;
drop table t1, t2;
+
+#
+# MDEV-14551 Can't find record in table on multi-table update with ORDER BY
+#
+
+# simple test with multi-update and Using temporary:
+create table t1 (i int) engine=memory;
+insert t1 values (1),(2);
+create table t2 (f int) engine=myisam;
+insert t2 values (1),(2);
+explain update t1, t2 set f = 126 order by f limit 2;
+update t1, t2 set f = 126 order by f limit 2;
+select * from t2;
+drop table t1, t2;
+
+# test with DuplicateElimination
+# (so that keep_current_rowid is set for DuplicateElimination too)
+create table t0(a int);
+insert t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int, key(a));
+insert t1 select a,a,a from t0;
+create table t2 as select * from t1;
+create table t3 as select * from t1;
+select * from t1, t2 where t1.a=t2.a and t1.b in (select b from t3 where t3.c<=t2.c) order by t2.c, t1.c limit 5;
+set optimizer_switch='firstmatch=off';
+explain update t1, t2 set t2.c=1 where t1.a=t2.a and t1.b in (select b from t3 where t3.c< t2.c) order by t2.c, t1.c limit 10;
+update t1, t2 set t2.c=1 where t1.a=t2.a and t1.b in (select b from t3 where t3.c<=t2.c) order by t2.c, t1.c limit 5;
+select * from t2;
+set optimizer_switch=default;
+drop table t0,t1,t2,t3;
+
+# test WITH CHECK OPTION
+create table t0 (x int);
+create table t1 (a int);
+create table t2 (b int, c int default 0);
+insert t0 (x) values (0),(10);
+insert t1 (a) values (1), (2);
+insert t2 (b) values (1), (2);
+create view v1 as select t2.b,t2.c from t1, t2
+ where t1.a=t2.b and t2.b < 3 with check option;
+select * from t0 join v1 on (x=c);
+explain update v1,t0 set c=1 where b=1 and x=c order by x,b limit 1;
+update v1,t0 set c=1 where b<3 and x=c order by x,b limit 1;
+select * from v1;
+drop view v1;
+drop table t0, t1,t2;
diff --git a/sql/item.cc b/sql/item.cc
index 56af69be427..f1695b67ca1 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -6846,6 +6846,11 @@ fast_field_copier Item_field::setup_fast_field_copier(Field *to)
return to->get_fast_field_copier(field);
}
+void Item_field::save_in_result_field(bool no_conversions)
+{
+ bool unused;
+ save_field_in_field(field, &unused, result_field, no_conversions);
+}
/**
Set a field's value from a item.
diff --git a/sql/item.h b/sql/item.h
index 9574bdc63bf..30e7eb1f1cb 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2996,8 +2996,7 @@ class Item_field :public Item_ident,
cond_equal_ref);
}
bool is_result_field() { return false; }
- void set_result_field(Field *field_arg) {}
- void save_in_result_field(bool no_conversions) { }
+ void save_in_result_field(bool no_conversions);
Item *get_tmp_table_item(THD *thd);
bool collect_item_field_processor(void * arg);
bool add_field_to_set_processor(void * arg);
diff --git a/sql/item_func.h b/sql/item_func.h
index 4b4f94df329..8ed911c725c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -70,7 +70,7 @@ class Item_func :public Item_func_or_sum
SP_CONTAINS_FUNC,SP_OVERLAPS_FUNC,
SP_STARTPOINT,SP_ENDPOINT,SP_EXTERIORRING,
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_RELATE_FUNC,
- NOT_FUNC, NOT_ALL_FUNC,
+ NOT_FUNC, NOT_ALL_FUNC, TEMPTABLE_ROWID,
NOW_FUNC, NOW_UTC_FUNC, SYSDATE_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 85e578f4595..12081a0cd9e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -5204,3 +5204,23 @@ String *Item_func_dyncol_list::val_str(String *str)
my_free(names);
return NULL;
}
+
+Item_temptable_rowid::Item_temptable_rowid(TABLE *table_arg)
+ : Item_str_func(table_arg->in_use), table(table_arg)
+{
+ max_length= table->file->ref_length;
+}
+
+void Item_temptable_rowid::fix_length_and_dec()
+{
+ used_tables_cache= table->map;
+ const_item_cache= false;
+}
+
+String *Item_temptable_rowid::val_str(String *str)
+{
+ if (!((null_value= table->null_row)))
+ table->file->position(table->record[0]);
+ str_value.set((char*)(table->file->ref), max_length, &my_charset_bin);
+ return &str_value;
+}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index cff9fdee072..c368d9336c4 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1750,5 +1750,25 @@ class Item_func_dyncol_list: public Item_str_func
{ return get_item_copy<Item_func_dyncol_list>(thd, this); }
};
-#endif /* ITEM_STRFUNC_INCLUDED */
+/*
+ this is used by JOIN_TAB::keep_current_rowid
+ and stores handler::position().
+ It has nothing to do with _rowid pseudo-column, that the parser supports.
+*/
+class Item_temptable_rowid :public Item_str_func
+{
+public:
+ TABLE *table;
+ Item_temptable_rowid(TABLE *table_arg);
+ const Type_handler *type_handler() const { return &type_handler_string; }
+ Field *create_tmp_field(bool group, TABLE *table)
+ { return create_table_field_from_handler(table); }
+ String *val_str(String *str);
+ enum Functype functype() const { return TEMPTABLE_ROWID; }
+ const char *func_name() const { return "<rowid>"; }
+ void fix_length_and_dec();
+ Item *get_copy(THD *thd)
+ { return get_item_copy<Item_temptable_rowid>(thd, this); }
+};
+#endif /* ITEM_STRFUNC_INCLUDED */
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a7c33cbc504..ddde591793d 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4907,7 +4907,7 @@ class select_result :public select_result_sink
unit= u;
return 0;
}
- virtual int prepare2(void) { return 0; }
+ virtual int prepare2(JOIN *join) { return 0; }
/*
Because of peculiarities of prepared statements protocol
we need to know number of columns in the result set (if
@@ -5151,7 +5151,7 @@ class select_insert :public select_result_interceptor {
enum_duplicates duplic, bool ignore);
~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
- virtual int prepare2(void);
+ virtual int prepare2(JOIN *join);
virtual int send_data(List<Item> &items);
virtual void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; }
@@ -5203,7 +5203,7 @@ class select_create: public select_insert {
// Needed for access from local class MY_HOOKS in prepare(), since thd is proteted.
const THD *get_thd(void) { return thd; }
const HA_CREATE_INFO *get_create_info() { return create_info; };
- int prepare2(void) { return 0; }
+ int prepare2(JOIN *join) { return 0; }
private:
TABLE *create_table_from_items(THD *thd,
@@ -5887,6 +5887,7 @@ class multi_update :public select_result_interceptor
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
int send_data(List<Item> &items);
bool initialize_tables (JOIN *join);
+ int prepare2(JOIN *join);
int do_updates();
bool send_eof();
inline ha_rows num_found() const { return found; }
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 392aa52825e..f1b438e8305 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3781,7 +3781,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
0 OK
*/
-int select_insert::prepare2(void)
+int select_insert::prepare2(JOIN *)
{
DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT &&
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 796ea569e64..2511cff82a5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2650,6 +2650,25 @@ bool JOIN::add_having_as_table_cond(JOIN_TAB *tab)
}
+bool JOIN::add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *table_fields)
+{
+ /*
+ this will not walk into semi-join materialization nests but this is ok
+ because we will never need to save current rowids for those.
+ */
+ for (JOIN_TAB *tab=join_tab; tab < cur; tab++)
+ {
+ if (!tab->keep_current_rowid)
+ continue;
+ Item *item= new (thd->mem_root) Item_temptable_rowid(tab->table);
+ item->fix_fields(thd, 0);
+ table_fields->push_back(item, thd->mem_root);
+ cur->tmp_table_param->func_count++;
+ }
+ return 0;
+}
+
+
/**
Set info for aggregation tables
@@ -3258,6 +3277,8 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param)))
DBUG_RETURN(true);
+ if (tmp_table_keep_current_rowid)
+ add_fields_for_current_rowid(tab, table_fields);
tab->tmp_table_param->skip_create_table= true;
TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields,
table_group, distinct,
@@ -3652,7 +3673,7 @@ bool JOIN::prepare_result(List<Item> **columns_list)
select_lex->handle_derived(thd->lex, DT_CREATE))
goto err;
- if (result->prepare2())
+ if (result->prepare2(this))
goto err;
if ((select_lex->options & OPTION_SCHEMA_TABLE) &&
@@ -3789,7 +3810,7 @@ void JOIN::exec_inner()
}
columns_list= &procedure_fields_list;
}
- if (result->prepare2())
+ if (result->prepare2(this))
DBUG_VOID_RETURN;
if (!tables_list && (table_count || !select_lex->with_sum_func) &&
@@ -23365,13 +23386,10 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables,
calc how big buffer we need for comparing group entries.
*/
-static void
-calc_group_buffer(JOIN *join,ORDER *group)
+void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group)
{
uint key_length=0, parts=0, null_parts=0;
- if (group)
- join->group= 1;
for (; group ; group=group->next)
{
Item *group_item= *group->item;
@@ -23441,9 +23459,16 @@ calc_group_buffer(JOIN *join,ORDER *group)
if (group_item->maybe_null)
null_parts++;
}
- join->tmp_table_param.group_length=key_length+null_parts;
- join->tmp_table_param.group_parts=parts;
- join->tmp_table_param.group_null_parts=null_parts;
+ param->group_length= key_length + null_parts;
+ param->group_parts= parts;
+ param->group_null_parts= null_parts;
+}
+
+static void calc_group_buffer(JOIN *join, ORDER *group)
+{
+ if (group)
+ join->group= 1;
+ calc_group_buffer(&join->tmp_table_param, group);
}
@@ -26184,7 +26209,7 @@ bool JOIN::change_result(select_result *new_result, select_result *old_result)
{
result= new_result;
if (result->prepare(fields_list, select_lex->master_unit()) ||
- result->prepare2())
+ result->prepare2(this))
DBUG_RETURN(true); /* purecov: inspected */
DBUG_RETURN(false);
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index f8911fbba01..1da87bb9d50 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1438,6 +1438,9 @@ class JOIN :public Sql_alloc
enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE, QEP_DELETED} have_query_plan;
+ // if keep_current_rowid=true, whether they should be saved in temporary table
+ bool tmp_table_keep_current_rowid;
+
/*
Additional WHERE and HAVING predicates to be considered for IN=>EXISTS
subquery transformation of a JOIN object.
@@ -1543,6 +1546,7 @@ class JOIN :public Sql_alloc
pushdown_query= 0;
original_join_tab= 0;
explain= NULL;
+ tmp_table_keep_current_rowid= 0;
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
@@ -1767,6 +1771,7 @@ class JOIN :public Sql_alloc
void cleanup_item_list(List<Item> &items) const;
bool add_having_as_table_cond(JOIN_TAB *tab);
bool make_aggr_tables_info();
+ bool add_fields_for_current_rowid(JOIN_TAB *cur, List<Item> *fields);
};
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
@@ -2373,6 +2378,7 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table,
#define RATIO_TO_PACK_ROWS 2
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
+void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 0149c2848c2..f9e4414f13a 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -507,14 +507,14 @@ void select_union_recursive::cleanup()
bool select_union_direct::change_result(select_result *new_result)
{
result= new_result;
- return (result->prepare(unit->types, unit) || result->prepare2());
+ return (result->prepare(unit->types, unit) || result->prepare2(NULL));
}
bool select_union_direct::postponed_prepare(List<Item> &types)
{
if (result != NULL)
- return (result->prepare(types, unit) || result->prepare2());
+ return (result->prepare(types, unit) || result->prepare2(NULL));
else
return false;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 38638d3aa1d..82fef617815 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -2164,22 +2164,12 @@ multi_update::initialize_tables(JOIN *join)
tbl->prepare_for_position();
join->map2table[tbl->tablenr]->keep_current_rowid= true;
- Field_string *field= new Field_string(tbl->file->ref_length, 0,
- &field_name,
- &my_charset_bin);
- if (!field)
- DBUG_RETURN(1);
- field->init(tbl);
- /*
- The field will be converted to varstring when creating tmp table if
- table to be updated was created by mysql 4.1. Deny this.
- */
- field->can_alter_field_type= 0;
- Item_field *ifield= new (thd->mem_root) Item_field(join->thd, (Field *) field);
- if (!ifield)
+ Item_temptable_rowid *item=
+ new (thd->mem_root) Item_temptable_rowid(tbl);
+ if (!item)
DBUG_RETURN(1);
- ifield->maybe_null= 0;
- if (temp_fields.push_back(ifield, thd->mem_root))
+ item->fix_fields(thd, 0);
+ if (temp_fields.push_back(item, thd->mem_root))
DBUG_RETURN(1);
} while ((tbl= tbl_it++));
@@ -2190,10 +2180,10 @@ multi_update::initialize_tables(JOIN *join)
group.direction= ORDER::ORDER_ASC;
group.item= (Item**) temp_fields.head_ref();
- tmp_param->quick_group=1;
- tmp_param->field_count=temp_fields.elements;
- tmp_param->group_parts=1;
- tmp_param->group_length= table->file->ref_length;
+ tmp_param->quick_group= 1;
+ tmp_param->field_count= temp_fields.elements;
+ tmp_param->func_count= temp_fields.elements - 1;
+ calc_group_buffer(tmp_param, &group);
/* small table, ignore SQL_BIG_TABLES */
my_bool save_big_tables= thd->variables.big_tables;
thd->variables.big_tables= FALSE;
@@ -2205,10 +2195,66 @@ multi_update::initialize_tables(JOIN *join)
DBUG_RETURN(1);
tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE);
}
+ join->tmp_table_keep_current_rowid= TRUE;
DBUG_RETURN(0);
}
+static TABLE *item_rowid_table(Item *item)
+{
+ if (item->type() != Item::FUNC_ITEM)
+ return NULL;
+ Item_func *func= (Item_func *)item;
+ if (func->functype() != Item_func::TEMPTABLE_ROWID)
+ return NULL;
+ Item_temptable_rowid *itr= (Item_temptable_rowid *)func;
+ return itr->table;
+}
+
+
+/*
+ multi_update stores a rowid and new field values for every updated row in a
+ temporary table (one temporary table per updated table). These rowids are
+ obtained via Item_temptable_rowid's by calling handler::position(). But if
+ the join is resolved via a temp table, rowids cannot be obtained from
+ handler::position() in the multi_update::send_data(). So, they're stored in
+ the join's temp table (JOIN::add_fields_for_current_rowid()) and here we
+ replace Item_temptable_rowid's (that would've done handler::position()) with
+ Item_field's (that will simply take the corresponding field value from the
+ temp table).
+*/
+int multi_update::prepare2(JOIN *join)
+{
+ if (!join->need_tmp || !join->tmp_table_keep_current_rowid)
+ return 0;
+
+ // there cannot be many tmp tables in multi-update
+ JOIN_TAB *tmptab= join->join_tab + join->exec_join_tab_cnt();
+
+ for (Item **it= tmptab->tmp_table_param->items_to_copy; *it ; it++)
+ {
+ TABLE *tbl= item_rowid_table(*it);
+ if (!tbl)
+ continue;
+ for (uint i= 0; i < table_count; i++)
+ {
+ for (Item **it2= tmp_table_param[i].items_to_copy; *it2; it2++)
+ {
+ if (item_rowid_table(*it2) != tbl)
+ continue;
+ Item *fld= new (thd->mem_root)
+ Item_field(thd, (*it)->get_tmp_table_field());
+ if (!fld)
+ return 1;
+ fld->set_result_field((*it2)->get_tmp_table_field());
+ *it2= fld;
+ }
+ }
+ }
+ return 0;
+}
+
+
multi_update::~multi_update()
{
TABLE_LIST *table;
@@ -2380,29 +2426,11 @@ int multi_update::send_data(List<Item> ¬_used_values)
{
int error;
TABLE *tmp_table= tmp_tables[offset];
- /*
- For updatable VIEW store rowid of the updated table and
- rowids of tables used in the CHECK OPTION condition.
- */
- uint field_num= 0;
- List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
- /* Set first tbl = table and then tbl to tables from tbl_it */
- TABLE *tbl= table;
- do
- {
- tbl->file->position(tbl->record[0]);
- memcpy((char*) tmp_table->field[field_num]->ptr,
- (char*) tbl->file->ref, tbl->file->ref_length);
- /*
- For outer joins a rowid field may have no NOT_NULL_FLAG,
- so we have to reset NULL bit for this field.
- (set_notnull() resets NULL bit only if available).
- */
- tmp_table->field[field_num]->set_notnull();
- field_num++;
- } while ((tbl= tbl_it++));
-
+ if (copy_funcs(tmp_table_param[offset].items_to_copy, thd))
+ DBUG_RETURN(1);
/* Store regular updated fields in the row. */
+ DBUG_ASSERT(1 + unupdated_check_opt_tables.elements ==
+ tmp_table_param[offset].func_count);
fill_record(thd, tmp_table,
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
*values_for_table[offset], TRUE, FALSE);
1
0

[Commits] 93b3a484364: MDEV-15672: encryption.innodb_encryption_filekeys - typo in I_S column name: ENCRYPTION_SHCEME
by jan 13 Apr '18
by jan 13 Apr '18
13 Apr '18
revision-id: 93b3a484364067a883dc838adbbcdef6ec12e07f (mariadb-10.3.5-151-g93b3a484364)
parent(s): 71ceed75232952a77dfb7722440cbb1123935e76
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-04-13 12:50:03 +0300
message:
MDEV-15672: encryption.innodb_encryption_filekeys - typo in I_S column name: ENCRYPTION_SHCEME
Fixed typo on select that is executed only when something unexpected
happens.
---
mysql-test/suite/encryption/t/innodb_encryption_filekeys.test | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
index a087635fc99..03447bbcfa6 100644
--- a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
+++ b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test
@@ -52,7 +52,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
@@ -82,7 +82,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
@@ -111,7 +111,7 @@ while ($cnt)
}
if (!$success)
{
- SELECT NAME,ENCRYPTION_SHCEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
+ SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION;
SHOW STATUS LIKE 'innodb_encryption%';
-- die Timeout waiting for encryption threads
}
1
0

[Commits] f638c37abe1: MDEV-12632: Source and destination overlap in memcpy, encryption.innodb-discard-import-change fails in buildbot with valgrind
by jan 12 Apr '18
by jan 12 Apr '18
12 Apr '18
revision-id: f638c37abe1ab2e84746829a05144528b8953432 (mariadb-10.2.14-43-gf638c37abe1)
parent(s): e341da4711d80a8150ac26b2fe1ed4b035c13754
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-04-13 09:44:28 +0300
message:
MDEV-12632: Source and destination overlap in memcpy, encryption.innodb-discard-import-change fails in buildbot with valgrind
Use block->page.offset for checking page number.
---
storage/innobase/row/row0import.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index dad16c1f54e..c699b2117be 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3464,7 +3464,7 @@ fil_iterate(
/* When tablespace is encrypted or compressed its
first page (i.e. page 0) is not encrypted or
compressed and there is no need to copy frame. */
- if (encrypted && i != 0) {
+ if (encrypted && block->page.id.page_no() != 0) {
byte *local_frame = callback.get_frame(block);
ut_ad((writeptr + (i * size)) != local_frame);
memcpy((writeptr + (i * size)), local_frame, size);
1
0