diff options
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 211 |
1 files changed, 101 insertions, 110 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index b63172045e6..dfce00f08a9 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1,4 +1,5 @@ /* Copyright (C) 2009 MySQL AB + Copyright (c) 2019, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +24,7 @@ @{ */ -#include <my_global.h> +#include "mariadb.h" #include "sql_base.h" #include "key.h" #include "sql_statistics.h" @@ -66,16 +67,13 @@ static const uint STATISTICS_TABLES= 3; The names of the statistical tables in this array must correspond the definitions of the tables in the file ../scripts/mysql_system_tables.sql */ -static const LEX_STRING stat_table_name[STATISTICS_TABLES]= +static const LEX_CSTRING stat_table_name[STATISTICS_TABLES]= { - { C_STRING_WITH_LEN("table_stats") }, - { C_STRING_WITH_LEN("column_stats") }, - { C_STRING_WITH_LEN("index_stats") } + { STRING_WITH_LEN("table_stats") }, + { STRING_WITH_LEN("column_stats") }, + { STRING_WITH_LEN("index_stats") } }; -/* Name of database to which the statistical tables belong */ -static const LEX_STRING stat_tables_db_name= { C_STRING_WITH_LEN("mysql") }; - /** @details @@ -94,10 +92,9 @@ inline void init_table_list_for_stat_tables(TABLE_LIST *tables, bool for_write) for (i= 0; i < STATISTICS_TABLES; i++) { - tables[i].db= stat_tables_db_name.str; - tables[i].db_length= stat_tables_db_name.length; - tables[i].alias= tables[i].table_name= stat_table_name[i].str; - tables[i].table_name_length= stat_table_name[i].length; + tables[i].db= MYSQL_SCHEMA_NAME; + tables[i].table_name= stat_table_name[i]; + tables[i].alias= stat_table_name[i]; tables[i].lock_type= for_write ? TL_WRITE : TL_READ; if (i < STATISTICS_TABLES - 1) tables[i].next_global= tables[i].next_local= @@ -116,17 +113,16 @@ inline void init_table_list_for_stat_tables(TABLE_LIST *tables, bool for_write) otherwise it is set to TL_WRITE. */ -static -inline void init_table_list_for_single_stat_table(TABLE_LIST *tbl, - const LEX_STRING *stat_tab_name, - bool for_write) +static inline +void init_table_list_for_single_stat_table(TABLE_LIST *tbl, + const LEX_CSTRING *stat_tab_name, + bool for_write) { memset((char *) tbl, 0, sizeof(TABLE_LIST)); - tbl->db= stat_tables_db_name.str; - tbl->db_length= stat_tables_db_name.length; - tbl->alias= tbl->table_name= stat_tab_name->str; - tbl->table_name_length= stat_tab_name->length; + tbl->db= MYSQL_SCHEMA_NAME; + tbl->table_name= *stat_tab_name; + tbl->alias= *stat_tab_name; tbl->lock_type= for_write ? TL_WRITE : TL_READ; } @@ -137,18 +133,18 @@ static const TABLE_FIELD_TYPE table_stat_fields[TABLE_STAT_N_FIELDS] = { { - { C_STRING_WITH_LEN("db_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("db_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("table_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("table_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("cardinality") }, - { C_STRING_WITH_LEN("bigint(21)") }, + { STRING_WITH_LEN("cardinality") }, + { STRING_WITH_LEN("bigint(21)") }, { NULL, 0 } }, }; @@ -160,58 +156,58 @@ static const TABLE_FIELD_TYPE column_stat_fields[COLUMN_STAT_N_FIELDS] = { { - { C_STRING_WITH_LEN("db_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("db_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("table_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("table_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("column_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("column_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("min_value") }, - { C_STRING_WITH_LEN("varbinary(255)") }, + { STRING_WITH_LEN("min_value") }, + { STRING_WITH_LEN("varbinary(255)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("max_value") }, - { C_STRING_WITH_LEN("varbinary(255)") }, + { STRING_WITH_LEN("max_value") }, + { STRING_WITH_LEN("varbinary(255)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("nulls_ratio") }, - { C_STRING_WITH_LEN("decimal(12,4)") }, + { STRING_WITH_LEN("nulls_ratio") }, + { STRING_WITH_LEN("decimal(12,4)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("avg_length") }, - { C_STRING_WITH_LEN("decimal(12,4)") }, + { STRING_WITH_LEN("avg_length") }, + { STRING_WITH_LEN("decimal(12,4)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("avg_frequency") }, - { C_STRING_WITH_LEN("decimal(12,4)") }, + { STRING_WITH_LEN("avg_frequency") }, + { STRING_WITH_LEN("decimal(12,4)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("hist_size") }, - { C_STRING_WITH_LEN("tinyint(3)") }, + { STRING_WITH_LEN("hist_size") }, + { STRING_WITH_LEN("tinyint(3)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("hist_type") }, - { C_STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB')") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("hist_type") }, + { STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB')") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("histogram") }, - { C_STRING_WITH_LEN("varbinary(255)") }, + { STRING_WITH_LEN("histogram") }, + { STRING_WITH_LEN("varbinary(255)") }, { NULL, 0 } } }; @@ -223,28 +219,28 @@ static const TABLE_FIELD_TYPE index_stat_fields[INDEX_STAT_N_FIELDS] = { { - { C_STRING_WITH_LEN("db_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("db_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("table_name") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("table_name") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("index") }, - { C_STRING_WITH_LEN("varchar(64)") }, - { C_STRING_WITH_LEN("utf8") } + { STRING_WITH_LEN("index") }, + { STRING_WITH_LEN("varchar(64)") }, + { STRING_WITH_LEN("utf8") } }, { - { C_STRING_WITH_LEN("prefix_arity") }, - { C_STRING_WITH_LEN("int(11)") }, + { STRING_WITH_LEN("prefix_arity") }, + { STRING_WITH_LEN("int(11)") }, { NULL, 0 } }, { - { C_STRING_WITH_LEN("avg_frequency") }, - { C_STRING_WITH_LEN("decimal(12,4)") }, + { STRING_WITH_LEN("avg_frequency") }, + { STRING_WITH_LEN("decimal(12,4)") }, { NULL, 0 } } }; @@ -295,7 +291,7 @@ static int open_stat_tables(THD *thd, TABLE_LIST *tables, */ static inline int open_single_stat_table(THD *thd, TABLE_LIST *table, - const LEX_STRING *stat_tab_name, + const LEX_CSTRING *stat_tab_name, Open_tables_backup *backup, bool for_write) { @@ -472,9 +468,9 @@ protected: /* Table for which statistical data is read / updated */ TABLE *table; - TABLE_SHARE *table_share; /* Table share for 'table */ - LEX_STRING *db_name; /* Name of the database containing 'table' */ - LEX_STRING *table_name; /* Name of the table 'table' */ + TABLE_SHARE *table_share; /* Table share for 'table */ + const LEX_CSTRING *db_name; /* Name of the database containing 'table' */ + const LEX_CSTRING *table_name; /* Name of the table 'table' */ void store_record_for_update() { @@ -529,12 +525,10 @@ public: by the database name 'db' and the table name 'tab'. */ - Stat_table(TABLE *stat, LEX_STRING *db, LEX_STRING *tab) - :stat_table(stat), table_share(NULL) + Stat_table(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab) + :stat_table(stat), table_share(NULL),db_name(db), table_name(tab) { common_init_stat_table(); - db_name= db; - table_name= tab; } @@ -554,7 +548,7 @@ public: The method is called by the update_table_name_key_parts function. */ - virtual void change_full_table_name(LEX_STRING *db, LEX_STRING *tab)= 0; + virtual void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab)= 0; /** @@ -667,16 +661,22 @@ public: { if (find_stat()) { + bool res; store_record_for_update(); store_stat_fields(); - return update_record(); + res= update_record(); + DBUG_ASSERT(res == 0); + return res; } else { int err; store_stat_fields(); if ((err= stat_file->ha_write_row(record[0]))) + { + DBUG_ASSERT(0); return TRUE; + } /* Make change permanent and avoid 'table is marked as crashed' errors */ stat_file->extra(HA_EXTRA_FLUSH); } @@ -704,7 +704,7 @@ public: to store the new names in the record buffer used for updates. */ - bool update_table_name_key_parts(LEX_STRING *db, LEX_STRING *tab) + bool update_table_name_key_parts(const LEX_CSTRING *db, const LEX_CSTRING *tab) { store_record_for_update(); change_full_table_name(db, tab); @@ -766,7 +766,7 @@ private: table_name_field= stat_table->field[TABLE_STAT_TABLE_NAME]; } - void change_full_table_name(LEX_STRING *db, LEX_STRING *tab) + void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab) { db_name_field->store(db->str, db->length, system_charset_info); table_name_field->store(tab->str, tab->length, system_charset_info); @@ -796,7 +796,7 @@ public: from the database 'db'. */ - Table_stat(TABLE *stat, LEX_STRING *db, LEX_STRING *tab) + Table_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab) :Stat_table(stat, db, tab) { common_init_table_stat(); @@ -910,7 +910,7 @@ private: column_name_field= stat_table->field[COLUMN_STAT_COLUMN_NAME]; } - void change_full_table_name(LEX_STRING *db, LEX_STRING *tab) + void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab) { db_name_field->store(db->str, db->length, system_charset_info); table_name_field->store(tab->str, tab->length, system_charset_info); @@ -940,7 +940,7 @@ public: from the database 'db'. */ - Column_stat(TABLE *stat, LEX_STRING *db, LEX_STRING *tab) + Column_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab) :Stat_table(stat, db, tab) { common_init_column_stat_table(); @@ -984,8 +984,7 @@ public: void set_key_fields(Field *col) { set_full_table_name(); - const char *column_name= col->field_name; - column_name_field->store(column_name, strlen(column_name), + column_name_field->store(col->field_name.str, col->field_name.length, system_charset_info); table_field= col; } @@ -1046,7 +1045,6 @@ public: String val(buff, sizeof(buff), &my_charset_bin); MY_BITMAP *old_map= dbug_tmp_use_all_columns(stat_table, &stat_table->read_set); - for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HISTOGRAM; i++) { Field *stat_field= stat_table->field[i]; @@ -1062,7 +1060,7 @@ public: else { table_field->collected_stats->min_value->val_str(&val); - uint32 length= Well_formed_prefix(val.charset(), val.ptr(), + size_t length= Well_formed_prefix(val.charset(), val.ptr(), MY_MIN(val.length(), stat_field->field_length)).length(); stat_field->store(val.ptr(), length, &my_charset_bin); } @@ -1073,7 +1071,7 @@ public: else { table_field->collected_stats->max_value->val_str(&val); - uint32 length= Well_formed_prefix(val.charset(), val.ptr(), + size_t length= Well_formed_prefix(val.charset(), val.ptr(), MY_MIN(val.length(), stat_field->field_length)).length(); stat_field->store(val.ptr(), length, &my_charset_bin); } @@ -1253,7 +1251,7 @@ private: prefix_arity_field= stat_table->field[INDEX_STAT_PREFIX_ARITY]; } - void change_full_table_name(LEX_STRING *db, LEX_STRING *tab) + void change_full_table_name(const LEX_CSTRING *db, const LEX_CSTRING *tab) { db_name_field->store(db->str, db->length, system_charset_info); table_name_field->store(tab->str, tab->length, system_charset_info); @@ -1285,7 +1283,7 @@ public: from the database 'db'. */ - Index_stat(TABLE *stat, LEX_STRING *db, LEX_STRING *tab) + Index_stat(TABLE *stat, const LEX_CSTRING *db, const LEX_CSTRING *tab) :Stat_table(stat, db, tab) { common_init_index_stat_table(); @@ -1328,8 +1326,8 @@ public: void set_index_prefix_key_fields(KEY *index_info) { set_full_table_name(); - char *index_name= index_info->name; - index_name_field->store(index_name, strlen(index_name), + const char *index_name= index_info->name.str; + index_name_field->store(index_name, index_info->name.length, system_charset_info); table_key_info= index_info; } @@ -1972,7 +1970,7 @@ void create_min_max_statistical_fields_for_table(TABLE *table) for (uint i=0; i < 2; i++, record+= rec_buff_length) { - for (Field **field_ptr= table->field; *field_ptr; field_ptr++) + for (Field **field_ptr= table->field; *field_ptr; field_ptr++) { Field *fld; Field *table_field= *field_ptr; @@ -2041,7 +2039,7 @@ void create_min_max_statistical_fields_for_table_share(THD *thd, for (uint i=0; i < 2; i++, record+= rec_buff_length) { - for (Field **field_ptr= table_share->field; *field_ptr; field_ptr++) + for (Field **field_ptr= table_share->field; *field_ptr; field_ptr++) { Field *fld; Field *table_field= *field_ptr; @@ -2362,7 +2360,7 @@ bool Column_statistics_collected::add(ha_rows rowno) set_not_null(COLUMN_STAT_MIN_VALUE); if (max_value && column->update_max(max_value, rowno == nulls)) set_not_null(COLUMN_STAT_MAX_VALUE); - if (count_distinct) + if (count_distinct) err= count_distinct->add(); } return err; @@ -2620,11 +2618,7 @@ int collect_statistics_for_table(THD *thd, TABLE *table) break; if (rc) - { - if (rc == HA_ERR_RECORD_DELETED) - continue; break; - } for (field_ptr= table->field; *field_ptr; field_ptr++) { @@ -2840,7 +2834,6 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) Field **field_ptr; KEY *key_info, *key_info_end; TABLE_SHARE *table_share= table->s; - enum_check_fields old_check_level= thd->count_cuted_fields; DBUG_ENTER("read_statistics_for_table"); DEBUG_SYNC(thd, "statistics_mem_alloc_start1"); @@ -2856,7 +2849,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) } /* Don't write warnings for internal field conversions */ - thd->count_cuted_fields= CHECK_FIELD_IGNORE; + Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE); /* Read statistics from the statistical table table_stats */ Table_statistics *read_stats= table_share->stats_cb.table_stats; @@ -2938,7 +2931,6 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) } } - thd->count_cuted_fields= old_check_level; table_share->stats_cb.end_stats_load(); DBUG_RETURN(0); } @@ -3138,7 +3130,7 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables) } statistics_for_tables_is_needed= true; } - else if (is_stat_table(tl->db, tl->alias)) + else if (is_stat_table(&tl->db, &tl->alias)) found_stat_table= true; } } @@ -3205,7 +3197,7 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables) The function is called when executing the statement DROP TABLE 'tab'. */ -int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab) +int delete_statistics_for_table(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab) { int err; enum_binlog_format save_binlog_format; @@ -3443,8 +3435,8 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info, The function is called when executing any statement that renames a table */ -int rename_table_in_stat_tables(THD *thd, LEX_STRING *db, LEX_STRING *tab, - LEX_STRING *new_db, LEX_STRING *new_tab) +int rename_table_in_stat_tables(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *tab, + const LEX_CSTRING *new_db, const LEX_CSTRING *new_tab) { int err; enum_binlog_format save_binlog_format; @@ -3452,7 +3444,6 @@ int rename_table_in_stat_tables(THD *thd, LEX_STRING *db, LEX_STRING *tab, TABLE_LIST tables[STATISTICS_TABLES]; Open_tables_backup open_tables_backup; int rc= 0; - DBUG_ENTER("rename_table_in_stat_tables"); if (open_stat_tables(thd, tables, &open_tables_backup, TRUE)) @@ -3926,15 +3917,15 @@ double Histogram::point_selectivity(double pos, double avg_sel) /* Check whether the table is one of the persistent statistical tables. */ -bool is_stat_table(const char *db, const char *table) +bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table) { - DBUG_ASSERT(db && table); + DBUG_ASSERT(db->str && table->str); - if (!my_strcasecmp(table_alias_charset, db, stat_tables_db_name.str)) + if (!my_strcasecmp(table_alias_charset, db->str, MYSQL_SCHEMA_NAME.str)) { for (uint i= 0; i < STATISTICS_TABLES; i ++) { - if (!my_strcasecmp(table_alias_charset, table, stat_table_name[i].str)) + if (!my_strcasecmp(table_alias_charset, table->str, stat_table_name[i].str)) return true; } } |