MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns
I_S tables were materialized too late, an attempt to use table statistics before the table was created caused a crash. Let's move table creation up. it only needs read_set to be calculated properly, this happens in JOIN::optimize_inner(), after semijoin transformation. Note that tables are not populated at that point, so most of the statistics would make no sense anyway. But at least field sizes will be correct. And it won't crash.
This commit is contained in:
parent
61feb568bb
commit
4e503aec7f
@ -2282,5 +2282,14 @@ create table t2 (n int);
|
||||
insert into t1 set n = (select table_rows from information_schema.tables where table_name='t2');
|
||||
drop table t1, t2;
|
||||
#
|
||||
# MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns
|
||||
#
|
||||
create table t1 (f varchar(64) primary key);
|
||||
select f from information_schema.columns i
|
||||
inner join t1 on f=i.column_name
|
||||
group by f;
|
||||
f
|
||||
drop table t1;
|
||||
#
|
||||
# End of 10.3 tests
|
||||
#
|
||||
|
@ -2007,6 +2007,16 @@ create table t2 (n int);
|
||||
insert into t1 set n = (select table_rows from information_schema.tables where table_name='t2');
|
||||
drop table t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-24593 Signal 11 when group by primary key of table joined to information_schema.columns
|
||||
--echo #
|
||||
create table t1 (f varchar(64) primary key);
|
||||
select f from information_schema.columns i
|
||||
inner join t1 on f=i.column_name
|
||||
group by f;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.3 tests
|
||||
--echo #
|
||||
|
@ -1556,7 +1556,7 @@ int JOIN::init_join_caches()
|
||||
int
|
||||
JOIN::optimize_inner()
|
||||
{
|
||||
DBUG_ENTER("JOIN::optimize");
|
||||
DBUG_ENTER("JOIN::optimize_inner");
|
||||
subq_exit_fl= false;
|
||||
do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
|
||||
|
||||
@ -1624,6 +1624,10 @@ JOIN::optimize_inner()
|
||||
|
||||
table_count= select_lex->leaf_tables.elements;
|
||||
|
||||
if (select_lex->options & OPTION_SCHEMA_TABLE &&
|
||||
optimize_schema_tables_memory_usage(select_lex->leaf_tables))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
|
102
sql/sql_show.cc
102
sql/sql_show.cc
@ -8658,55 +8658,64 @@ end:
|
||||
}
|
||||
|
||||
|
||||
static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list)
|
||||
bool optimize_schema_tables_memory_usage(List<TABLE_LIST> &tables)
|
||||
{
|
||||
TABLE *table= table_list->table;
|
||||
THD *thd=table->in_use;
|
||||
if (!table->is_created())
|
||||
List_iterator<TABLE_LIST> tli(tables);
|
||||
|
||||
while (TABLE_LIST *table_list= tli++)
|
||||
{
|
||||
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);
|
||||
TABLE *table= table_list->table;
|
||||
THD *thd=table->in_use;
|
||||
|
||||
uchar *cur= table->field[0]->ptr;
|
||||
/* first recinfo could be a NULL bitmap, not an actual Field */
|
||||
from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]);
|
||||
for (uint i=0; i < table->s->fields; i++, from_recinfo++)
|
||||
{
|
||||
Field *field= table->field[i];
|
||||
DBUG_ASSERT(field->vcol_info == 0);
|
||||
DBUG_ASSERT(from_recinfo->length);
|
||||
DBUG_ASSERT(from_recinfo->length == field->pack_length_in_rec());
|
||||
if (bitmap_is_set(table->read_set, i))
|
||||
{
|
||||
field->move_field(cur);
|
||||
*to_recinfo++= *from_recinfo;
|
||||
cur+= from_recinfo->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
field= new (thd->mem_root) Field_string(cur, 0, field->null_ptr,
|
||||
field->null_bit, Field::NONE,
|
||||
&field->field_name, field->dtcollation());
|
||||
field->init(table);
|
||||
field->field_index= i;
|
||||
DBUG_ASSERT(field->pack_length_in_rec() == 0);
|
||||
table->field[i]= field;
|
||||
}
|
||||
}
|
||||
if ((table->s->reclength= (ulong)(cur - table->record[0])) == 0)
|
||||
{
|
||||
/* all fields were optimized away. Force a non-0-length row */
|
||||
table->s->reclength= to_recinfo->length= 1;
|
||||
to_recinfo++;
|
||||
}
|
||||
p->recinfo= to_recinfo;
|
||||
if (!table_list->schema_table || !thd->fill_information_schema_tables())
|
||||
continue;
|
||||
|
||||
// TODO switch from Aria to Memory if all blobs were optimized away?
|
||||
if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo,
|
||||
table_list->select_lex->options | thd->variables.option_bits))
|
||||
return 1;
|
||||
if (!table->is_created())
|
||||
{
|
||||
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 */
|
||||
from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]);
|
||||
for (uint i=0; i < table->s->fields; i++, from_recinfo++)
|
||||
{
|
||||
Field *field= table->field[i];
|
||||
DBUG_ASSERT(field->vcol_info == 0);
|
||||
DBUG_ASSERT(from_recinfo->length);
|
||||
DBUG_ASSERT(from_recinfo->length == field->pack_length_in_rec());
|
||||
if (bitmap_is_set(table->read_set, i))
|
||||
{
|
||||
field->move_field(cur);
|
||||
*to_recinfo++= *from_recinfo;
|
||||
cur+= from_recinfo->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
field= new (thd->mem_root) Field_string(cur, 0, field->null_ptr,
|
||||
field->null_bit, Field::NONE,
|
||||
&field->field_name, field->dtcollation());
|
||||
field->init(table);
|
||||
field->field_index= i;
|
||||
DBUG_ASSERT(field->pack_length_in_rec() == 0);
|
||||
table->field[i]= field;
|
||||
}
|
||||
}
|
||||
if ((table->s->reclength= (ulong)(cur - table->record[0])) == 0)
|
||||
{
|
||||
/* all fields were optimized away. Force a non-0-length row */
|
||||
table->s->reclength= to_recinfo->length= 1;
|
||||
to_recinfo++;
|
||||
}
|
||||
p->recinfo= to_recinfo;
|
||||
|
||||
// TODO switch from Aria to Memory if all blobs were optimized away?
|
||||
if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo,
|
||||
table_list->select_lex->options | thd->variables.option_bits))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -8732,9 +8741,6 @@ bool optimize_schema_tables_reads(JOIN *join)
|
||||
TABLE_LIST *table_list= tab->table->pos_in_table_list;
|
||||
if (table_list->schema_table && thd->fill_information_schema_tables())
|
||||
{
|
||||
if (optimize_schema_tables_memory_usage(table_list))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* A value of 0 indicates a dummy implementation */
|
||||
if (table_list->schema_table->fill_table == 0)
|
||||
continue;
|
||||
|
@ -238,6 +238,7 @@ public:
|
||||
};
|
||||
|
||||
bool optimize_schema_tables_reads(JOIN *join);
|
||||
bool optimize_schema_tables_memory_usage(List<TABLE_LIST> &tables);
|
||||
|
||||
/* Handle the ignored database directories list for SHOW/I_S. */
|
||||
bool ignore_db_dirs_init();
|
||||
|
@ -363,9 +363,6 @@ int ha_heap::info(uint flag)
|
||||
{
|
||||
HEAPINFO hp_info;
|
||||
|
||||
if (!table)
|
||||
return 0;
|
||||
|
||||
(void) heap_info(file,&hp_info,flag);
|
||||
|
||||
errkey= hp_info.errkey;
|
||||
|
@ -2440,9 +2440,6 @@ int ha_maria::info(uint flag)
|
||||
MARIA_INFO maria_info;
|
||||
char name_buff[FN_REFLEN];
|
||||
|
||||
if (!table)
|
||||
return 0;
|
||||
|
||||
(void) maria_status(file, &maria_info, flag);
|
||||
if (flag & HA_STATUS_VARIABLE)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user