Skip to content

Commit b3edbf2

Browse files
committed
MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_table
The code in create_internal_tmp_table() didn't take into account that now temporary (derived) tables may have multiple indexes: - one index due to duplicate removal = In this example created by conversion of big-IN(...) into subquery = this index might be converted into a "unique constraint" if the key length is too large. - one index added by derived_with_keys optimization. Make create_internal_tmp_table() handle multiple indexes. Before this patch, use of a unique constraint was indicated in TABLE_SHARE::uniques. This was ok as unique constraint was the only index in the table. Now it's no longer the case so TABLE_SHARE::uniques is removed and replaced with an in-memory-only flag HA_UNIQUE_HASH. This patch is based on Monty's patch. Co-Author: Monty <monty@mariadb.org>
1 parent 63df43a commit b3edbf2

File tree

9 files changed

+195
-105
lines changed

9 files changed

+195
-105
lines changed

include/my_base.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ enum ha_key_alg {
104104
HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */
105105
HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */
106106
HA_KEY_ALG_FULLTEXT= 4, /* FULLTEXT (MyISAM tables) */
107-
HA_KEY_ALG_LONG_HASH= 5 /* long BLOB keys */
107+
HA_KEY_ALG_LONG_HASH= 5, /* long BLOB keys */
108+
HA_KEY_ALG_UNIQUE_HASH= 6 /* Internal UNIQUE hash (Aria) */
108109
};
109110

110111
/* Storage media types */
@@ -276,11 +277,17 @@ enum ha_base_keytype {
276277
#define HA_SPATIAL 1024U /* For spatial search */
277278
#define HA_NULL_ARE_EQUAL 2048U /* NULL in key are cmp as equal */
278279
#define HA_GENERATED_KEY 8192U /* Automatically generated key */
280+
/*
281+
Part of unique hash key. Used only for temporary (work) tables so is not
282+
written to .frm files.
283+
*/
284+
#define HA_UNIQUE_HASH 262144U
279285

280286
/* The combination of the above can be used for key type comparison. */
281287
#define HA_KEYFLAG_MASK (HA_NOSAME | HA_AUTO_KEY | \
282288
HA_FULLTEXT | HA_UNIQUE_CHECK | \
283-
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
289+
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY | \
290+
HA_UNIQUE_HASH)
284291

285292
/*
286293
Key contains partial segments.

mysql-test/main/derived.result

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,5 +1499,33 @@ a
14991499
2
15001500
drop table t1;
15011501
#
1502+
# MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_table
1503+
# keydef incorrectly allocated on the stack in create_internal_tmp_table()
1504+
#
1505+
CREATE TABLE t1 (c CHAR(1) NULL) ENGINE=MyISAM;
1506+
INSERT INTO t1 (c) VALUES (1);
1507+
SET statement
1508+
optimizer_where_cost=1,
1509+
big_tables=1,
1510+
in_predicate_conversion_threshold=2
1511+
FOR
1512+
SELECT * FROM t1 WHERE c IN ('','');
1513+
c
1514+
Warnings:
1515+
Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
1516+
Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
1517+
SET statement
1518+
optimizer_where_cost=1,
1519+
big_tables=1,
1520+
in_predicate_conversion_threshold=2,
1521+
sql_mode=''
1522+
FOR
1523+
SELECT * FROM t1 WHERE c IN ('','');
1524+
c
1525+
Warnings:
1526+
Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
1527+
Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
1528+
DROP TABLE t1;
1529+
#
15021530
# End of 11.0 tests
15031531
#

mysql-test/main/derived.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,30 @@ SET IN_PREDICATE_CONVERSION_THRESHOLD=100;
12731273
SELECT a FROM t1 WHERE a IN ( 1, 1, 2, 194 );
12741274
drop table t1;
12751275

1276+
--echo #
1277+
--echo # MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_table
1278+
--echo # keydef incorrectly allocated on the stack in create_internal_tmp_table()
1279+
--echo #
1280+
1281+
CREATE TABLE t1 (c CHAR(1) NULL) ENGINE=MyISAM;
1282+
INSERT INTO t1 (c) VALUES (1);
1283+
SET statement
1284+
optimizer_where_cost=1,
1285+
big_tables=1,
1286+
in_predicate_conversion_threshold=2
1287+
FOR
1288+
SELECT * FROM t1 WHERE c IN ('','');
1289+
1290+
SET statement
1291+
optimizer_where_cost=1,
1292+
big_tables=1,
1293+
in_predicate_conversion_threshold=2,
1294+
sql_mode=''
1295+
FOR
1296+
SELECT * FROM t1 WHERE c IN ('','');
1297+
1298+
DROP TABLE t1;
1299+
12761300
--echo #
12771301
--echo # End of 11.0 tests
12781302
--echo #

sql/item_subselect.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5266,7 +5266,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
52665266
//fprintf(stderr, "Q: %s\n", current_thd->query());
52675267
DBUG_ASSERT(0);
52685268
DBUG_ASSERT(
5269-
tmp_table->s->uniques ||
5269+
(tmp_table->key_info->flags & HA_UNIQUE_HASH) ||
52705270
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
52715271
tmp_table->key_info->user_defined_key_parts >
52725272
tmp_table->file->max_key_parts());

sql/opt_subselect.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4903,11 +4903,13 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
49034903
{
49044904
DBUG_PRINT("info",("Creating group key in temporary table"));
49054905
share->keys=1;
4906-
share->uniques= MY_TEST(using_unique_constraint);
49074906
table->key_info= share->key_info= keyinfo;
49084907
keyinfo->key_part=key_part_info;
4909-
keyinfo->flags=HA_NOSAME;
4908+
keyinfo->flags= HA_NOSAME | (using_unique_constraint ? HA_UNIQUE_HASH : 0);
4909+
keyinfo->ext_key_flags= keyinfo->flags;
49104910
keyinfo->usable_key_parts= keyinfo->user_defined_key_parts= 1;
4911+
keyinfo->ext_key_parts= 1;
4912+
share->key_parts= 1;
49114913
keyinfo->key_length=0;
49124914
keyinfo->rec_per_key=0;
49134915
keyinfo->algorithm= HA_KEY_ALG_UNDEF;

0 commit comments

Comments
 (0)