maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #09268
Re: [Commits] 841c317: MDEV-7122: Assertion `0' failed in subselect_hash_sj_engine::init
Hi Vicentiu,
Please find some cosmetic feedback below. Ok to push after it is addressed.
On Tue, Feb 09, 2016 at 04:02:58PM +0200, Vicentiu Ciorbaru wrote:
> revision-id: 841c317d237453f3e6c253e2a884cad73622b59a (mariadb-5.5.47-33-g841c317)
> parent(s): ad94790f468bacb2cd62d02d3a6e7f012ca72e65
> author: Vicențiu Ciorbaru
> committer: Vicențiu Ciorbaru
> timestamp: 2016-02-09 16:00:18 +0200
> message:
>
> MDEV-7122: Assertion `0' failed in subselect_hash_sj_engine::init
>
> The select mentioned in the bug attempted to create a temporary table
> using the maria storage engine. The table needs to have primary keys such that
> duplicates can be removed. Unfortunately this use case has a longer
> than allowed key and the tmp table got created without a temporary key.
> We must not allow materialization for the subquery if the total key
> length and key parts is greater than what the storage engine supports.
>
> ---
> mysql-test/r/subselect.result | 12 ++++++++++++
> mysql-test/r/subselect_no_mat.result | 12 ++++++++++++
> mysql-test/r/subselect_no_opts.result | 12 ++++++++++++
> mysql-test/r/subselect_no_scache.result | 12 ++++++++++++
> mysql-test/r/subselect_no_semijoin.result | 12 ++++++++++++
> mysql-test/t/subselect.test | 9 +++++++++
> sql/opt_subselect.cc | 10 ++++++++++
> sql/sql_select.cc | 25 +++++++++++++++++++++++++
> 8 files changed, 104 insertions(+)
>
> diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
> index ba52fd9..27e8eaa 100644
> --- a/mysql-test/r/subselect.result
> +++ b/mysql-test/r/subselect.result
> @@ -7081,3 +7081,15 @@ sq
> NULL
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +# MDEV-7122
> +# Assertion `0' failed in subselect_hash_sj_engine::init
> +#
> +SET SESSION big_tables=1;
Please unset the variable back at the end of this testcase. We don't want the
rest of the test to run with non-standard settings.
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +a
> +0
> +0
> +0
> +DROP TABLE t1;
> diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
> index d8d5c4e..4727f9f 100644
> --- a/mysql-test/r/subselect_no_mat.result
> +++ b/mysql-test/r/subselect_no_mat.result
> @@ -7078,6 +7078,18 @@ sq
> NULL
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +# MDEV-7122
> +# Assertion `0' failed in subselect_hash_sj_engine::init
> +#
> +SET SESSION big_tables=1;
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +a
> +0
> +0
> +0
> +DROP TABLE t1;
> set optimizer_switch=default;
> select @@optimizer_switch like '%materialization=on%';
> @@optimizer_switch like '%materialization=on%'
> diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
> index 78908bc..7c542dd 100644
> --- a/mysql-test/r/subselect_no_opts.result
> +++ b/mysql-test/r/subselect_no_opts.result
> @@ -7076,4 +7076,16 @@ sq
> NULL
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +# MDEV-7122
> +# Assertion `0' failed in subselect_hash_sj_engine::init
> +#
> +SET SESSION big_tables=1;
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +a
> +0
> +0
> +0
> +DROP TABLE t1;
> set @optimizer_switch_for_subselect_test=null;
> diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
> index d1de4b8..3b58b3c 100644
> --- a/mysql-test/r/subselect_no_scache.result
> +++ b/mysql-test/r/subselect_no_scache.result
> @@ -7087,6 +7087,18 @@ sq
> NULL
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +# MDEV-7122
> +# Assertion `0' failed in subselect_hash_sj_engine::init
> +#
> +SET SESSION big_tables=1;
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +a
> +0
> +0
> +0
> +DROP TABLE t1;
> set optimizer_switch=default;
> select @@optimizer_switch like '%subquery_cache=on%';
> @@optimizer_switch like '%subquery_cache=on%'
> diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
> index 524a5dd..9246ffb 100644
> --- a/mysql-test/r/subselect_no_semijoin.result
> +++ b/mysql-test/r/subselect_no_semijoin.result
> @@ -7076,5 +7076,17 @@ sq
> NULL
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +# MDEV-7122
> +# Assertion `0' failed in subselect_hash_sj_engine::init
> +#
> +SET SESSION big_tables=1;
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +a
> +0
> +0
> +0
> +DROP TABLE t1;
> set @optimizer_switch_for_subselect_test=null;
> set @join_cache_level_for_subselect_test=NULL;
> diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
> index 67eac0d..5ca21ea 100644
> --- a/mysql-test/t/subselect.test
> +++ b/mysql-test/t/subselect.test
> @@ -5964,3 +5964,12 @@ EXECUTE stmt;
>
> deallocate prepare stmt;
> drop table t1,t2,t3,t4;
> +
> +--echo # MDEV-7122
> +--echo # Assertion `0' failed in subselect_hash_sj_engine::init
> +--echo #
> +SET SESSION big_tables=1;
> +CREATE TABLE t1(a char(255) DEFAULT '', KEY(a(10))) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
> +INSERT INTO t1 VALUES(0),(0),(0);
> +SELECT * FROM t1 WHERE a IN(SELECT MIN(a) FROM t1);
> +DROP TABLE t1;
> diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
> index 827290f..a39e04b 100644
> --- a/sql/opt_subselect.cc
> +++ b/sql/opt_subselect.cc
> @@ -830,12 +830,14 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
> in_subs->sjm_scan_allowed= FALSE;
>
> bool all_are_fields= TRUE;
> + uint32 total_key_length = 0;
> for (uint i= 0; i < elements; i++)
> {
> Item *outer= in_subs->left_expr->element_index(i);
> Item *inner= it++;
> all_are_fields &= (outer->real_item()->type() == Item::FIELD_ITEM &&
> inner->real_item()->type() == Item::FIELD_ITEM);
> + total_key_length += inner->max_length;
> if (outer->cmp_type() != inner->cmp_type())
> DBUG_RETURN(FALSE);
> switch (outer->cmp_type()) {
> @@ -866,6 +868,14 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
> }
> }
>
> + /*
> + Make sure that create_tmp_table will not fail due to too long keys.
> + See MDEV-7122. This check is performed inside create_tmp_table also and
> + we must do it so that we know the table has keys created.
> + */
> + if (total_key_length > HA_MAX_KEY_LENGTH || elements > HA_MAX_KEY_SEG)
> + DBUG_RETURN(FALSE);
> +
> in_subs->types_allow_materialization= TRUE;
> in_subs->sjm_scan_allowed= all_are_fields;
> DBUG_PRINT("info",("subquery_types_allow_materialization: ok, allowed"));
> diff --git a/sql/sql_select.cc b/sql/sql_select.cc
> index f43f506..218a4ce 100644
> --- a/sql/sql_select.cc
> +++ b/sql/sql_select.cc
> @@ -15307,6 +15307,13 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
> if (!table->file)
> goto err;
>
> + /*
> + Temporary table storage engines must allow keys of at least
> + HA_MAX_KEY_LENGT and at least HA_MAX_KEY_SEG key parts.
psergey: typo. ^^^^^^^^^^^
> + */
> + DBUG_ASSERT(table->file->max_key_length() >= HA_MAX_KEY_LENGTH &&
> + table->file->max_key_parts() >= HA_MAX_KEY_SEG);
> +
> if (!using_unique_constraint)
> reclength+= group_null_items; // null flag is stored separately
>
> @@ -15940,6 +15947,12 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
> goto err;
>
> bzero(seg, sizeof(*seg) * keyinfo->key_parts);
> + /*
> + Note that a simillar check is performed during
typo ^^^^^^^^^
> + subquery_types_allow_materialization. See MDEV-7122 for more details as
> + to why. Whenever this changes, it must be updated there as well, for
> + all tmp_table engines.
> + */
> if (keyinfo->key_length > table->file->max_key_length() ||
> keyinfo->key_parts > table->file->max_key_parts() ||
> share->uniques)
> @@ -16126,6 +16139,12 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
> goto err;
>
> bzero(seg, sizeof(*seg) * keyinfo->key_parts);
> + /*
> + Note that a simillar check is performed during
typo ^^^^^^^^^
> + subquery_types_allow_materialization. See MDEV-7122 for more details as
> + to why. Whenever this changes, it must be updated there as well, for
> + all tmp_table engines.
> + */
> if (keyinfo->key_length > table->file->max_key_length() ||
> keyinfo->key_parts > table->file->max_key_parts() ||
> share->uniques)
> @@ -16286,6 +16305,12 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
> if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
> new_table.s->db_type())))
> DBUG_RETURN(1); // End of memory
> + /*
> + Temporary table storage engines must allow keys of at least
> + HA_MAX_KEY_LENGTH and at least HA_MAX_KEY_SEG key parts.
> + */
> + DBUG_ASSERT(new_table.file->max_key_length() >= HA_MAX_KEY_LENGTH &&
> + new_table.file->max_key_parts() >= HA_MAX_KEY_SEG);
>
> save_proc_info=thd->proc_info;
> thd_proc_info(thd, proc_info);
> _______________________________________________
> commits mailing list
> commits@xxxxxxxxxxx
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
--
BR
Sergei
--
Sergei Petrunia, Software Developer
MariaDB Corporation | Skype: sergefp | Blog: http://s.petrunia.net/blog