summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-10-30 11:15:30 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-10-30 11:15:30 +0200
commit898521e2dd8a4a6706cba01b6ef0a7cea4114fd0 (patch)
tree4ef9a6ddc4298574bb75db673c2412f83c107c5b /sql/sql_show.cc
parent571bcf9aaaf59b84e24bbfb809738dea25495d78 (diff)
parent199863d72b7cccaa4c75641c50c45a83b568ab8c (diff)
downloadmariadb-git-898521e2dd8a4a6706cba01b6ef0a7cea4114fd0.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc170
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());