diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-10-30 11:15:30 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-10-30 11:15:30 +0200 |
commit | 898521e2dd8a4a6706cba01b6ef0a7cea4114fd0 (patch) | |
tree | 4ef9a6ddc4298574bb75db673c2412f83c107c5b /sql/sql_show.cc | |
parent | 571bcf9aaaf59b84e24bbfb809738dea25495d78 (diff) | |
parent | 199863d72b7cccaa4c75641c50c45a83b568ab8c (diff) | |
download | mariadb-git-898521e2dd8a4a6706cba01b6ef0a7cea4114fd0.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 170 |
1 files changed, 83 insertions, 87 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 794589b234c..c00476871e4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3675,8 +3675,6 @@ static bool show_status_array(THD *thd, const char *wild, CHARSET_INFO *charset= system_charset_info; DBUG_ENTER("show_status_array"); - thd->count_cuted_fields= CHECK_FIELD_WARN; - prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1); if (*prefix) *prefix_end++= '_'; @@ -3776,6 +3774,8 @@ static bool show_status_array(THD *thd, const char *wild, pos= get_one_variable(thd, var, scope, show_type, status_var, &charset, buff, &length); + if (table->field[1]->field_length) + thd->count_cuted_fields= CHECK_FIELD_WARN; table->field[1]->store(pos, (uint32) length, charset); thd->count_cuted_fields= CHECK_FIELD_IGNORE; table->field[1]->set_notnull(); @@ -8046,51 +8046,6 @@ ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx) return &schema_tables[schema_table_idx]; } -static void -mark_all_fields_used_in_query(THD *thd, - ST_FIELD_INFO *schema_fields, - MY_BITMAP *bitmap, - Item *all_items) -{ - Item *item; - DBUG_ENTER("mark_all_fields_used_in_query"); - - /* If not SELECT command, return all columns */ - if (thd->lex->sql_command != SQLCOM_SELECT && - thd->lex->sql_command != SQLCOM_SET_OPTION) - { - bitmap_set_all(bitmap); - DBUG_VOID_RETURN; - } - - for (item= all_items ; item ; item= item->next) - { - if (item->type() == Item::FIELD_ITEM) - { - ST_FIELD_INFO *fields= schema_fields; - uint count; - Item_field *item_field= (Item_field*) item; - - /* item_field can be '*' as this function is called before fix_fields */ - if (item_field->field_name.str == star_clex_str.str) - { - bitmap_set_all(bitmap); - break; - } - for (count=0; !fields->end_marker(); fields++, count++) - { - if (!my_strcasecmp(system_charset_info, fields->name().str, - item_field->field_name.str)) - { - bitmap_set_bit(bitmap, count); - break; - } - } - } - } - DBUG_VOID_RETURN; -} - /** Create information_schema table using schema_table data. @@ -8103,7 +8058,7 @@ mark_all_fields_used_in_query(THD *thd, 0<decimals<10 and 0<=length<100 . @param - thd thread handler + thd thread handler @param table_list Used to pass I_S table information(fields info, tables parameters etc) and table name. @@ -8114,32 +8069,16 @@ mark_all_fields_used_in_query(THD *thd, TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) { - uint field_count; - Item *all_items; + uint field_count= 0; TABLE *table; ST_SCHEMA_TABLE *schema_table= table_list->schema_table; - ST_FIELD_INFO *fields_info= schema_table->fields_info; - ST_FIELD_INFO *fields; - MY_BITMAP bitmap; - my_bitmap_map *buf; + ST_FIELD_INFO *fields= schema_table->fields_info; + bool need_all_fieds= table_list->schema_table_reformed || // SHOW command + thd->lex->only_view_structure(); // need table structure DBUG_ENTER("create_schema_table"); - for (field_count= 0, fields= fields_info; !fields->end_marker(); fields++) + for (; !fields->end_marker(); fields++) field_count++; - if (!(buf= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)))) - DBUG_RETURN(NULL); - my_bitmap_init(&bitmap, buf, field_count, 0); - - if (!thd->stmt_arena->is_conventional() && - thd->mem_root != thd->stmt_arena->mem_root) - all_items= thd->stmt_arena->free_list; - else - all_items= thd->free_list; - - if (table_list->part_of_natural_join) - bitmap_set_all(&bitmap); - else - mark_all_fields_used_in_query(thd, fields_info, &bitmap, all_items); TMP_TABLE_PARAM *tmp_table_param = new (thd->mem_root) TMP_TABLE_PARAM; tmp_table_param->init(); @@ -8148,13 +8087,9 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) tmp_table_param->schema_table= 1; SELECT_LEX *select_lex= table_list->select_lex; bool keep_row_order= is_show_command(thd); - if (!(table= create_tmp_table_for_schema(thd, tmp_table_param, - *schema_table, bitmap, - (select_lex->options | - thd->variables.option_bits | - TMP_TABLE_ALL_COLUMNS), - table_list->alias, - keep_row_order))) + if (!(table= create_tmp_table_for_schema(thd, tmp_table_param, *schema_table, + (select_lex->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS), + table_list->alias, !need_all_fieds, keep_row_order))) DBUG_RETURN(0); my_bitmap_map* bitmaps= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); @@ -8546,6 +8481,68 @@ end: } +static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list) +{ + TABLE *table= table_list->table; + THD *thd=table->in_use; + 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); + + // XXX HACK HACK HACK: in a stored function, RETURN (SELECT ...) + // enables warnings (in THD::sp_eval_expr) for the whole val_xxx/store pair, + // while the intention is to warn only for store(). Until this is + // fixed let's avoid data truncation warnings in I_S->fill_table() + if (thd->count_cuted_fields == CHECK_FIELD_IGNORE) + { + + 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; + } // XXX end of HACK HACK HACK + + // 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; +} + + /* This is the optimizer part of get_schema_tables_result(). */ @@ -8566,6 +8563,9 @@ 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; @@ -8588,10 +8588,10 @@ bool optimize_schema_tables_reads(JOIN *join) cond= tab->cache_select->cond; } if (optimize_for_get_all_tables(thd, table_list, cond)) - DBUG_RETURN(TRUE); // Handle OOM + DBUG_RETURN(1); // Handle OOM } } - DBUG_RETURN(FALSE); + DBUG_RETURN(0); } @@ -8656,13 +8656,10 @@ bool get_schema_tables_result(JOIN *join, continue; /* - If schema table is already processed and - the statement is not a subselect then - we don't need to fill this table again. - If schema table is already processed and - schema_table_state != executed_place then - table is already processed and - we should skip second data processing. + If schema table is already processed and the statement is not a + subselect then we don't need to fill this table again. If schema table + is already processed and schema_table_state != executed_place then + table is already processed and we should skip second data processing. */ if (table_list->schema_table_state && (!is_subselect || table_list->schema_table_state != executed_place)) @@ -8724,8 +8721,7 @@ bool get_schema_tables_result(JOIN *join, It also means that an audit plugin cannot process the error correctly either. See also thd->clear_error() */ - thd->get_stmt_da()->push_warning(thd, - thd->get_stmt_da()->sql_errno(), + thd->get_stmt_da()->push_warning(thd, thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->get_sqlstate(), Sql_condition::WARN_LEVEL_ERROR, thd->get_stmt_da()->message()); |