mirror of
https://github.com/MariaDB/server.git
synced 2025-11-09 11:41:36 +03:00
MDEV-24726 Assertion on compressed varstring as key field in optimizer
temporary table Compressed field cannot be part of a key by its nature: there is no data to order, only the compressed data. For optimizer temporary table we create uncompressed substitute. In all other cases (MDEV-16808) we don't use key: add_keyuse() is skipped by !field->compression_method() condition.
This commit is contained in:
@@ -2978,4 +2978,60 @@ SELECT GROUP_CONCAT( b, a ORDER BY 2 ) AS f FROM t1;
|
|||||||
f
|
f
|
||||||
nc,mmmmmmmmmmd
|
nc,mmmmmmmmmmd
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-24726 Assertion `0' failed in Field_varstring_compressed::key_cmp
|
||||||
|
#
|
||||||
|
# VARCHAR
|
||||||
|
create table t1 (a varchar(8) compressed) character set utf8mb4;
|
||||||
|
create algorithm=temptable view v1 as select * from t1;
|
||||||
|
insert into t1 values ('foo'),('bar'),('foo');
|
||||||
|
select * from v1 where a in (select a from t1);
|
||||||
|
a
|
||||||
|
foo
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (f1 varchar(8)) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t1 values ('');
|
||||||
|
create table t2 (f2 varchar(8) compressed) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t2 values ('a'),('b');
|
||||||
|
select t1.* from t1 left join (select distinct f2 from t2) sq on sq.f2 = t1.f1;
|
||||||
|
f1
|
||||||
|
|
||||||
|
drop table t1, t2;
|
||||||
|
# BLOB
|
||||||
|
create table t1 (a text compressed) character set utf8mb4;
|
||||||
|
create algorithm=temptable view v1 as select * from t1;
|
||||||
|
insert into t1 values ('foo'),('bar'),('foo');
|
||||||
|
select * from v1 where a in (select a from t1);
|
||||||
|
a
|
||||||
|
foo
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
create table t1 (f1 text) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t1 values ('');
|
||||||
|
create table t2 (f2 text compressed) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t2 values ('a'),('b');
|
||||||
|
select t1.* from t1 left join (select distinct f2 from t2) sq on sq.f2 = t1.f1;
|
||||||
|
f1
|
||||||
|
|
||||||
|
drop table t1, t2;
|
||||||
|
#
|
||||||
|
# MDEV-16808 Assertion on compressed blob as key field
|
||||||
|
#
|
||||||
|
set join_cache_level= 3;
|
||||||
|
create table t1 (col_blob text) engine=innodb;
|
||||||
|
create table t2 (col_blob text compressed) engine=innodb;
|
||||||
|
select * from t1 join t2 using ( col_blob );
|
||||||
|
col_blob
|
||||||
|
drop tables t1, t2;
|
||||||
|
create table t (a text compressed,b text) engine=innodb;
|
||||||
|
create table t4 like t;
|
||||||
|
set session join_cache_level=3;
|
||||||
|
select * from (select * from t) as t natural join (select * from t) as t1;
|
||||||
|
a b
|
||||||
|
drop tables t, t4;
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
|
|||||||
@@ -519,4 +519,57 @@ INSERT INTO t1 VALUES ('c','n'),('d','mmmmmmmmmm');
|
|||||||
SELECT GROUP_CONCAT( b, a ORDER BY 2 ) AS f FROM t1;
|
SELECT GROUP_CONCAT( b, a ORDER BY 2 ) AS f FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24726 Assertion `0' failed in Field_varstring_compressed::key_cmp
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo # VARCHAR
|
||||||
|
create table t1 (a varchar(8) compressed) character set utf8mb4;
|
||||||
|
create algorithm=temptable view v1 as select * from t1;
|
||||||
|
insert into t1 values ('foo'),('bar'),('foo');
|
||||||
|
select * from v1 where a in (select a from t1);
|
||||||
|
# cleanup
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1 (f1 varchar(8)) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t1 values ('');
|
||||||
|
create table t2 (f2 varchar(8) compressed) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t2 values ('a'),('b');
|
||||||
|
select t1.* from t1 left join (select distinct f2 from t2) sq on sq.f2 = t1.f1;
|
||||||
|
# cleanup
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
|
--echo # BLOB
|
||||||
|
create table t1 (a text compressed) character set utf8mb4;
|
||||||
|
create algorithm=temptable view v1 as select * from t1;
|
||||||
|
insert into t1 values ('foo'),('bar'),('foo');
|
||||||
|
select * from v1 where a in (select a from t1);
|
||||||
|
# cleanup
|
||||||
|
drop view v1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
create table t1 (f1 text) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t1 values ('');
|
||||||
|
create table t2 (f2 text compressed) charset=eucjpms collate=eucjpms_nopad_bin;
|
||||||
|
insert into t2 values ('a'),('b');
|
||||||
|
select t1.* from t1 left join (select distinct f2 from t2) sq on sq.f2 = t1.f1;
|
||||||
|
# cleanup
|
||||||
|
drop table t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-16808 Assertion on compressed blob as key field
|
||||||
|
--echo #
|
||||||
|
set join_cache_level= 3;
|
||||||
|
create table t1 (col_blob text) engine=innodb;
|
||||||
|
create table t2 (col_blob text compressed) engine=innodb;
|
||||||
|
select * from t1 join t2 using ( col_blob );
|
||||||
|
drop tables t1, t2;
|
||||||
|
|
||||||
|
create table t (a text compressed,b text) engine=innodb;
|
||||||
|
create table t4 like t;
|
||||||
|
set session join_cache_level=3;
|
||||||
|
select * from (select * from t) as t natural join (select * from t) as t1;
|
||||||
|
drop tables t, t4;
|
||||||
|
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
|
|||||||
53
sql/field.cc
53
sql/field.cc
@@ -8374,6 +8374,59 @@ Field *Field_varstring::make_new_field(MEM_ROOT *root, TABLE *new_table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Field_varstring_compressed::make_new_field(MEM_ROOT *root, TABLE *new_table,
|
||||||
|
bool keep_type)
|
||||||
|
{
|
||||||
|
Field_varstring *res;
|
||||||
|
if (new_table->s->is_optimizer_tmp_table())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Compressed field cannot be part of a key. For optimizer temporary
|
||||||
|
table we create uncompressed substitute.
|
||||||
|
*/
|
||||||
|
res= new (root) Field_varstring(ptr, field_length, length_bytes, null_ptr,
|
||||||
|
null_bit, Field::NONE, &field_name,
|
||||||
|
new_table->s, charset());
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
res->init_for_make_new_field(new_table, orig_table);
|
||||||
|
/* See Column_definition::create_length_to_internal_length_string() */
|
||||||
|
res->field_length--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res= (Field_varstring*) Field::make_new_field(root, new_table, keep_type);
|
||||||
|
if (res)
|
||||||
|
res->length_bytes= length_bytes;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field *Field_blob_compressed::make_new_field(MEM_ROOT *root, TABLE *new_table,
|
||||||
|
bool keep_type)
|
||||||
|
{
|
||||||
|
Field_blob *res;
|
||||||
|
if (new_table->s->is_optimizer_tmp_table())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Compressed field cannot be part of a key. For optimizer temporary
|
||||||
|
table we create uncompressed substitute.
|
||||||
|
*/
|
||||||
|
res= new (root) Field_blob(ptr, null_ptr, null_bit, Field::NONE, &field_name,
|
||||||
|
new_table->s, packlength, charset());
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
res->init_for_make_new_field(new_table, orig_table);
|
||||||
|
/* See Column_definition::create_length_to_internal_length_string() */
|
||||||
|
res->field_length--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res= (Field_blob *) Field::make_new_field(root, new_table, keep_type);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
|
Field *Field_varstring::new_key_field(MEM_ROOT *root, TABLE *new_table,
|
||||||
uchar *new_ptr, uint32 length,
|
uchar *new_ptr, uint32 length,
|
||||||
uchar *new_null_ptr, uint new_null_bit)
|
uchar *new_null_ptr, uint new_null_bit)
|
||||||
|
|||||||
@@ -4309,6 +4309,7 @@ private:
|
|||||||
{ DBUG_ASSERT(0); return 0; }
|
{ DBUG_ASSERT(0); return 0; }
|
||||||
using Field_varstring::key_cmp;
|
using Field_varstring::key_cmp;
|
||||||
Binlog_type_info binlog_type_info() const override;
|
Binlog_type_info binlog_type_info() const override;
|
||||||
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -4750,6 +4751,7 @@ private:
|
|||||||
override
|
override
|
||||||
{ DBUG_ASSERT(0); return 0; }
|
{ DBUG_ASSERT(0); return 0; }
|
||||||
Binlog_type_info binlog_type_info() const override;
|
Binlog_type_info binlog_type_info() const override;
|
||||||
|
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7082,7 +7082,13 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (field->hash_join_is_possible() &&
|
/*
|
||||||
|
Compressed field cannot be part of a key. For optimizer temporary table
|
||||||
|
compressed fields are replaced by uncompressed, see
|
||||||
|
is_optimizer_tmp_table() and Field_*_compressed::make_new_field().
|
||||||
|
*/
|
||||||
|
if (!field->compression_method() &&
|
||||||
|
field->hash_join_is_possible() &&
|
||||||
(key_field->optimize & KEY_OPTIMIZE_EQ) &&
|
(key_field->optimize & KEY_OPTIMIZE_EQ) &&
|
||||||
key_field->val->used_tables())
|
key_field->val->used_tables())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1092,6 +1092,11 @@ struct TABLE_SHARE
|
|||||||
return (tmp_table == SYSTEM_TMP_TABLE) ? 0 : table_map_id;
|
return (tmp_table == SYSTEM_TMP_TABLE) ? 0 : table_map_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_optimizer_tmp_table()
|
||||||
|
{
|
||||||
|
return tmp_table == INTERNAL_TMP_TABLE && !db.length && table_name.length;
|
||||||
|
}
|
||||||
|
|
||||||
bool visit_subgraph(Wait_for_flush *waiting_ticket,
|
bool visit_subgraph(Wait_for_flush *waiting_ticket,
|
||||||
MDL_wait_for_graph_visitor *gvisitor);
|
MDL_wait_for_graph_visitor *gvisitor);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user