summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <sergey@mariadb.com>2023-05-03 15:15:37 +0300
committerSergei Petrunia <sergey@mariadb.com>2023-05-09 10:12:27 +0300
commitb3edbf25a1f3bb4c8d7e9824096fc0538c04a977 (patch)
tree03ec8f43b0a2a5383ac50d1baeeb74c12632df04
parent63df43a0e830c6b54178574e4f72f21d19ed765e (diff)
downloadmariadb-git-b3edbf25a1f3bb4c8d7e9824096fc0538c04a977.tar.gz
MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_tablebb-11.0-MDEV-31022-variant4
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>
-rw-r--r--include/my_base.h11
-rw-r--r--mysql-test/main/derived.result28
-rw-r--r--mysql-test/main/derived.test24
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/opt_subselect.cc6
-rw-r--r--sql/sql_select.cc212
-rw-r--r--sql/sql_show.cc1
-rw-r--r--sql/table.h13
-rw-r--r--storage/maria/ha_maria.cc3
9 files changed, 195 insertions, 105 deletions
diff --git a/include/my_base.h b/include/my_base.h
index 22f1ea0a5df..05b3b56359e 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -104,7 +104,8 @@ enum ha_key_alg {
HA_KEY_ALG_RTREE= 2, /* R-tree, for spatial searches */
HA_KEY_ALG_HASH= 3, /* HASH keys (HEAP tables) */
HA_KEY_ALG_FULLTEXT= 4, /* FULLTEXT (MyISAM tables) */
- HA_KEY_ALG_LONG_HASH= 5 /* long BLOB keys */
+ HA_KEY_ALG_LONG_HASH= 5, /* long BLOB keys */
+ HA_KEY_ALG_UNIQUE_HASH= 6 /* Internal UNIQUE hash (Aria) */
};
/* Storage media types */
@@ -276,11 +277,17 @@ enum ha_base_keytype {
#define HA_SPATIAL 1024U /* For spatial search */
#define HA_NULL_ARE_EQUAL 2048U /* NULL in key are cmp as equal */
#define HA_GENERATED_KEY 8192U /* Automatically generated key */
+/*
+ Part of unique hash key. Used only for temporary (work) tables so is not
+ written to .frm files.
+*/
+#define HA_UNIQUE_HASH 262144U
/* The combination of the above can be used for key type comparison. */
#define HA_KEYFLAG_MASK (HA_NOSAME | HA_AUTO_KEY | \
HA_FULLTEXT | HA_UNIQUE_CHECK | \
- HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
+ HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY | \
+ HA_UNIQUE_HASH)
/*
Key contains partial segments.
diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result
index e15be3aecc4..091ca13d579 100644
--- a/mysql-test/main/derived.result
+++ b/mysql-test/main/derived.result
@@ -1499,5 +1499,33 @@ a
2
drop table t1;
#
+# MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_table
+# keydef incorrectly allocated on the stack in create_internal_tmp_table()
+#
+CREATE TABLE t1 (c CHAR(1) NULL) ENGINE=MyISAM;
+INSERT INTO t1 (c) VALUES (1);
+SET statement
+optimizer_where_cost=1,
+big_tables=1,
+in_predicate_conversion_threshold=2
+FOR
+SELECT * FROM t1 WHERE c IN ('','');
+c
+Warnings:
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+SET statement
+optimizer_where_cost=1,
+big_tables=1,
+in_predicate_conversion_threshold=2,
+sql_mode=''
+FOR
+SELECT * FROM t1 WHERE c IN ('','');
+c
+Warnings:
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+Warning 1287 '@@big_tables' is deprecated and will be removed in a future release
+DROP TABLE t1;
+#
# End of 11.0 tests
#
diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test
index 83de98c5d89..78ccba0b362 100644
--- a/mysql-test/main/derived.test
+++ b/mysql-test/main/derived.test
@@ -1274,5 +1274,29 @@ SELECT a FROM t1 WHERE a IN ( 1, 1, 2, 194 );
drop table t1;
--echo #
+--echo # MDEV-31022: SIGSEGV in maria_create from create_internal_tmp_table
+--echo # keydef incorrectly allocated on the stack in create_internal_tmp_table()
+--echo #
+
+CREATE TABLE t1 (c CHAR(1) NULL) ENGINE=MyISAM;
+INSERT INTO t1 (c) VALUES (1);
+SET statement
+ optimizer_where_cost=1,
+ big_tables=1,
+ in_predicate_conversion_threshold=2
+FOR
+SELECT * FROM t1 WHERE c IN ('','');
+
+SET statement
+ optimizer_where_cost=1,
+ big_tables=1,
+ in_predicate_conversion_threshold=2,
+ sql_mode=''
+FOR
+SELECT * FROM t1 WHERE c IN ('','');
+
+DROP TABLE t1;
+
+--echo #
--echo # End of 11.0 tests
--echo #
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 80228917210..3adc65008e0 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -5266,7 +5266,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
//fprintf(stderr, "Q: %s\n", current_thd->query());
DBUG_ASSERT(0);
DBUG_ASSERT(
- tmp_table->s->uniques ||
+ (tmp_table->key_info->flags & HA_UNIQUE_HASH) ||
tmp_table->key_info->key_length >= tmp_table->file->max_key_length() ||
tmp_table->key_info->user_defined_key_parts >
tmp_table->file->max_key_parts());
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 1d0b1ff1874..94adae02a17 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4903,11 +4903,13 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
{
DBUG_PRINT("info",("Creating group key in temporary table"));
share->keys=1;
- share->uniques= MY_TEST(using_unique_constraint);
table->key_info= share->key_info= keyinfo;
keyinfo->key_part=key_part_info;
- keyinfo->flags=HA_NOSAME;
+ keyinfo->flags= HA_NOSAME | (using_unique_constraint ? HA_UNIQUE_HASH : 0);
+ keyinfo->ext_key_flags= keyinfo->flags;
keyinfo->usable_key_parts= keyinfo->user_defined_key_parts= 1;
+ keyinfo->ext_key_parts= 1;
+ share->key_parts= 1;
keyinfo->key_length=0;
keyinfo->rec_per_key=0;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9c665bf5df0..048f101c046 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -21410,12 +21410,13 @@ bool Create_tmp_table::finalize(THD *thd,
table->group= m_group; /* Table is grouped by key */
param->group_buff= m_group_buff;
share->keys=1;
- share->uniques= MY_TEST(m_using_unique_constraint);
table->key_info= table->s->key_info= keyinfo;
table->keys_in_use_for_query.set_bit(0);
share->keys_in_use.set_bit(0);
keyinfo->key_part= m_key_part_info;
keyinfo->flags=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ if (m_using_unique_constraint)
+ keyinfo->flags|= HA_UNIQUE_HASH;
keyinfo->ext_key_flags= keyinfo->flags;
keyinfo->usable_key_parts=keyinfo->user_defined_key_parts=
param->group_parts;
@@ -21514,6 +21515,7 @@ bool Create_tmp_table::finalize(THD *thd,
*/
DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
+ keyinfo->flags= 0;
if (m_blobs_count[distinct])
{
/*
@@ -21521,10 +21523,11 @@ bool Create_tmp_table::finalize(THD *thd,
indexes on blobs with arbitrary length. Such indexes cannot be
used for lookups.
*/
- share->uniques= 1;
+ keyinfo->flags|= HA_UNIQUE_HASH;
}
keyinfo->user_defined_key_parts= m_field_count[distinct] +
- (share->uniques ? MY_TEST(null_pack_length[distinct]) : 0);
+ ((keyinfo->flags & HA_UNIQUE_HASH) ?
+ MY_TEST(null_pack_length[distinct]) : 0);
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
keyinfo->usable_key_parts= keyinfo->user_defined_key_parts;
table->distinct= 1;
@@ -21539,7 +21542,8 @@ bool Create_tmp_table::finalize(THD *thd,
share->keys_in_use.set_bit(0);
table->key_info= table->s->key_info= keyinfo;
keyinfo->key_part= m_key_part_info;
- keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ keyinfo->flags|= (HA_NOSAME | HA_NULL_ARE_EQUAL | HA_BINARY_PACK_KEY |
+ HA_PACK_KEY);
keyinfo->ext_key_flags= keyinfo->flags;
keyinfo->key_length= 0; // Will compute the sum of the parts below.
keyinfo->name= distinct_key;
@@ -21568,7 +21572,7 @@ bool Create_tmp_table::finalize(THD *thd,
blobs can distinguish NULL from 0. This extra field is not needed
when we do not use UNIQUE indexes for blobs.
*/
- if (null_pack_length[distinct] && share->uniques)
+ if (null_pack_length[distinct] && (keyinfo->flags & HA_UNIQUE_HASH))
{
m_key_part_info->null_bit=0;
m_key_part_info->offset= null_pack_base[distinct];
@@ -21986,113 +21990,125 @@ bool open_tmp_table(TABLE *table)
*/
-bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+bool create_internal_tmp_table(TABLE *table, KEY *org_keyinfo,
TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options)
{
int error;
- MARIA_KEYDEF keydef;
+ MARIA_KEYDEF *keydefs= 0, *keydef;
MARIA_UNIQUEDEF uniquedef;
TABLE_SHARE *share= table->s;
MARIA_CREATE_INFO create_info;
+ bool use_unique= false;
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
{ // Get keys for ni_create
- bool using_unique_constraint=0;
- HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
- sizeof(*seg) * keyinfo->user_defined_key_parts);
- if (!seg)
- goto err;
+ HA_KEYSEG *seg;
+ DBUG_ASSERT(share->key_parts);
- bzero(seg, sizeof(*seg) * keyinfo->user_defined_key_parts);
- /*
- Note that a similar check is performed during
- 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->user_defined_key_parts > table->file->max_key_parts() ||
- share->uniques)
- {
- if (!share->uniques && !(keyinfo->flags & HA_NOSAME))
- {
- my_error(ER_INTERNAL_ERROR, MYF(0),
- "Using too big key for internal temp tables");
- DBUG_RETURN(1);
- }
-
- /* Can't create a key; Make a unique constraint instead of a key */
- share->keys= 0;
- share->key_parts= share->ext_key_parts= 0;
- share->uniques= 1;
- using_unique_constraint=1;
- bzero((char*) &uniquedef,sizeof(uniquedef));
- uniquedef.keysegs=keyinfo->user_defined_key_parts;
- uniquedef.seg=seg;
- uniquedef.null_are_equal=1;
+ if (!(multi_alloc_root(&table->mem_root,
+ &seg, sizeof(*seg) * share->key_parts,
+ &keydefs, sizeof(*keydefs) * share->keys,
+ NullS)))
+ goto err;
+ keydef= keydefs;
- /* Create extra column for hash value */
- bzero((uchar*) *recinfo,sizeof(**recinfo));
- (*recinfo)->type= FIELD_CHECK;
- (*recinfo)->length= MARIA_UNIQUE_HASH_LENGTH;
- (*recinfo)++;
+ bzero(seg, sizeof(*seg) * share->key_parts);
- /* Avoid warnings from valgrind */
- bzero(table->record[0]+ share->reclength, MARIA_UNIQUE_HASH_LENGTH);
- bzero(share->default_values+ share->reclength, MARIA_UNIQUE_HASH_LENGTH);
- share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
- }
- else
- {
- /* Create a key */
- bzero((char*) &keydef,sizeof(keydef));
- keydef.flag= keyinfo->flags & HA_NOSAME;
- keydef.keysegs= keyinfo->user_defined_key_parts;
- keydef.seg= seg;
- }
- for (uint i=0; i < keyinfo->user_defined_key_parts ; i++,seg++)
+ /* Note that share->keys may change in the loop ! */
+ for (KEY *keyinfo= org_keyinfo, *end_keyinfo= keyinfo + share->keys;
+ keyinfo < end_keyinfo ;
+ keyinfo++)
{
- Field *field=keyinfo->key_part[i].field;
- seg->flag= 0;
- seg->language= field->charset()->number;
- seg->length= keyinfo->key_part[i].length;
- seg->start= keyinfo->key_part[i].offset;
- if (field->flags & BLOB_FLAG)
+ /*
+ Note that a similar check is performed during
+ 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->user_defined_key_parts > table->file->max_key_parts() ||
+ (keyinfo->flags & HA_UNIQUE_HASH))
{
- seg->type=
- ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
- HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
- seg->bit_start= (uint8)(field->pack_length() -
- portable_sizeof_char_ptr);
- seg->flag= HA_BLOB_PART;
- seg->length=0; // Whole blob in unique constraint
+ if (!(keyinfo->flags & (HA_NOSAME | HA_UNIQUE_HASH)))
+ {
+ my_error(ER_INTERNAL_ERROR, MYF(0),
+ "Using too big key for internal temp tables");
+ DBUG_RETURN(1);
+ }
+ /* Can't create a key; Make a unique constraint instead of a key */
+ share->keys--;
+ share->key_parts-= keyinfo->user_defined_key_parts;
+ share->ext_key_parts-= keyinfo->ext_key_parts;
+ use_unique= true;
+ bzero((char*) &uniquedef,sizeof(uniquedef));
+ uniquedef.keysegs= keyinfo->user_defined_key_parts;
+ uniquedef.seg=seg;
+ uniquedef.null_are_equal=1;
+ keyinfo->flags|= HA_UNIQUE_HASH;
+ keyinfo->algorithm= HA_KEY_ALG_UNIQUE_HASH;
+
+ /* Create extra column for hash value */
+ bzero((uchar*) *recinfo,sizeof(**recinfo));
+ (*recinfo)->type= FIELD_CHECK;
+ (*recinfo)->length= MARIA_UNIQUE_HASH_LENGTH;
+ (*recinfo)++;
+
+ /* Avoid warnings from valgrind */
+ bzero(table->record[0]+ share->reclength, MARIA_UNIQUE_HASH_LENGTH);
+ bzero(share->default_values+ share->reclength,
+ MARIA_UNIQUE_HASH_LENGTH);
+ share->reclength+= MARIA_UNIQUE_HASH_LENGTH;
}
else
{
- seg->type= keyinfo->key_part[i].type;
- /* Tell handler if it can do suffic space compression */
- if (field->real_type() == MYSQL_TYPE_STRING &&
- keyinfo->key_part[i].length > 32)
- seg->flag|= HA_SPACE_PACK;
- }
- if (!(field->flags & NOT_NULL_FLAG))
- {
- seg->null_bit= field->null_bit;
- seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
- /*
- We are using a GROUP BY on something that contains NULL
- In this case we have to tell Aria that two NULL should
- on INSERT be regarded at the same value
- */
- if (!using_unique_constraint)
- keydef.flag|= HA_NULL_ARE_EQUAL;
+ /* Create a key */
+ bzero((char*) keydef,sizeof(*keydef));
+ /*
+ We are using a GROUP BY on something that contains NULL
+ In this case we have to tell Aria that two NULL should
+ on INSERT be regarded at the same value.
+ */
+ keydef->flag= (keyinfo->flags & HA_NOSAME) | HA_NULL_ARE_EQUAL;
+ keydef->keysegs= keyinfo->user_defined_key_parts;
+ keydef->seg= seg;
+ keydef++;
+ }
+ for (uint i=0; i < keyinfo->user_defined_key_parts ; i++,seg++)
+ {
+ Field *field=keyinfo->key_part[i].field;
+ seg->flag= 0;
+ seg->language= field->charset()->number;
+ seg->length= keyinfo->key_part[i].length;
+ seg->start= keyinfo->key_part[i].offset;
+ if (field->flags & BLOB_FLAG)
+ {
+ seg->type=
+ ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
+ HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
+ seg->bit_start= (uint8)(field->pack_length() -
+ portable_sizeof_char_ptr);
+ seg->flag= HA_BLOB_PART;
+ seg->length=0; // Whole blob in unique constraint
+ }
+ else
+ {
+ seg->type= keyinfo->key_part[i].type;
+ /* Tell handler if it can do suffic space compression */
+ if (field->real_type() == MYSQL_TYPE_STRING &&
+ keyinfo->key_part[i].length > 32)
+ seg->flag|= HA_SPACE_PACK;
+ }
+ if (!(field->flags & NOT_NULL_FLAG))
+ {
+ seg->null_bit= field->null_bit;
+ seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
+ }
}
- }
- if (share->keys)
keyinfo->index_flags= table->file->index_flags(0, 0, 1);
+ }
}
bzero((char*) &create_info,sizeof(create_info));
create_info.data_file_length= table->in_use->variables.tmp_disk_table_size;
@@ -22138,8 +22154,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
if (unlikely((error= maria_create(share->path.str, file_type, share->keys,
- &keydef, (uint) (*recinfo-start_recinfo),
- start_recinfo, share->uniques, &uniquedef,
+ keydefs, (uint) (*recinfo-start_recinfo),
+ start_recinfo, use_unique, &uniquedef,
&create_info, create_flags))))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
@@ -22191,7 +22207,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
/* Create internal MyISAM temporary table */
-bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
+bool create_internal_tmp_table(TABLE *table, KEY *org_keyinfo,
TMP_ENGINE_COLUMNDEF *start_recinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options)
@@ -22206,11 +22222,12 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
{ // Get keys for ni_create
bool using_unique_constraint=0;
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
- sizeof(*seg) * keyinfo->user_defined_key_parts);
+ sizeof(*seg) *
+ share->user_defined_key_parts);
if (!seg)
goto err;
- bzero(seg, sizeof(*seg) * keyinfo->user_defined_key_parts);
+ bzero(seg, sizeof(*seg) * share->user_defined_key_parts);
/*
Note that a similar check is performed during
subquery_types_allow_materialization. See MDEV-7122 for more details as
@@ -22546,7 +22563,7 @@ void set_postjoin_aggr_write_func(JOIN_TAB *tab)
Note for MyISAM tmp tables: if uniques is true keys won't be
created.
*/
- if (table->s->keys && !table->s->uniques)
+ if (table->s->keys && !table->s->have_unique_constraint())
{
DBUG_PRINT("info",("Using end_update"));
aggr->set_write_func(end_update);
@@ -22856,6 +22873,8 @@ bool instantiate_tmp_table(TABLE *table, KEY *keyinfo,
TMP_ENGINE_COLUMNDEF **recinfo,
ulonglong options)
{
+ DBUG_ASSERT(table->s->keys == 0 || table->key_info == keyinfo);
+ DBUG_ASSERT(table->s->keys <= 1);
if (table->s->db_type() == TMP_ENGINE_HTON)
{
/*
@@ -24768,7 +24787,6 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
if (is_duplicate)
goto end;
- table->s->uniques=0; // To ensure rows are the same
}
if (++join_tab->send_records >=
join_tab->tmp_table_param->end_write_records &&
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1a99f6f0bae..fa95aa66b0f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -8841,7 +8841,6 @@ bool optimize_schema_tables_memory_usage(List<TABLE_LIST> &tables)
TMP_TABLE_PARAM *p= table_list->schema_table_param;
TMP_ENGINE_COLUMNDEF *from_recinfo, *to_recinfo;
DBUG_ASSERT(table->s->keys == 0);
- DBUG_ASSERT(table->s->uniques == 0);
uchar *cur= table->field[0]->ptr;
/* first recinfo could be a NULL bitmap, not an actual Field */
diff --git a/sql/table.h b/sql/table.h
index c67a5783c89..3874ccacb9a 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -853,7 +853,18 @@ struct TABLE_SHARE
uint keys, key_parts;
uint ext_key_parts; /* Total number of key parts in extended keys */
uint max_key_length, max_unique_length;
- uint uniques; /* Number of UNIQUE index */
+
+ /*
+ Older versions had TABLE_SHARE::uniques but now it is replaced with
+ per-index HA_UNIQUE_HASH flag
+ */
+ bool have_unique_constraint() const
+ {
+ for (uint i=0; i < keys; i++)
+ if (key_info[i].flags & HA_UNIQUE_HASH)
+ return true;
+ return false;
+ }
uint db_create_options; /* Create options from database */
uint db_options_in_use; /* Options in use */
uint db_record_offset; /* if HA_REC_IN_SEQ */
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 08e2b34a90e..2f58110cb91 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1082,7 +1082,8 @@ const char *ha_maria::index_type(uint key_number)
ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const
{
ulong flags;
- if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+ if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT ||
+ table_share->key_info[inx].algorithm == HA_KEY_ALG_UNIQUE_HASH)
flags= 0;
else
if ((table_share->key_info[inx].flags & HA_SPATIAL ||