diff options
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 214 |
1 files changed, 102 insertions, 112 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 7bf8fd676d4..50f7446f38a 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1,4 +1,5 @@ /* Copyright (C) 2009 MySQL AB + Copyright (c) 2019, 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 @@ inline 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; } @@ -1047,7 +1046,6 @@ public: my_bitmap_map *old_map; 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]; @@ -1063,7 +1061,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); } @@ -1074,7 +1072,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); } @@ -1254,7 +1252,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); @@ -1286,7 +1284,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(); @@ -1329,8 +1327,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; } @@ -1814,16 +1812,13 @@ public: bool is_partial_fields_present; Index_prefix_calc(THD *thd, TABLE *table, KEY *key_info) - : index_table(table), index_info(key_info) + : index_table(table), index_info(key_info), prefixes(0), empty(true), + calc_state(NULL), is_single_comp_pk(false), is_partial_fields_present(false) { uint i; Prefix_calc_state *state; uint key_parts= table->actual_n_key_parts(key_info); - empty= TRUE; - prefixes= 0; - LINT_INIT_STRUCT(calc_state); - is_partial_fields_present= is_single_comp_pk= FALSE; uint pk= table->s->primary_key; if ((uint) (table->key_info - key_info) == pk && table->key_info[pk].user_defined_key_parts == 1) @@ -1975,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; @@ -2044,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; @@ -2518,7 +2513,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; @@ -2776,11 +2771,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++) { @@ -3164,7 +3155,7 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) TABLE_SHARE *table_share= tl->table->s; if (table_share && table_share->table_category != TABLE_CATEGORY_USER - && is_stat_table(tl->db, tl->alias)) + && is_stat_table(&tl->db, &tl->alias)) return FALSE; } } @@ -3357,7 +3348,7 @@ int read_statistics_for_tables_if_needed(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; @@ -3595,8 +3586,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; @@ -3604,7 +3595,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)) @@ -4078,15 +4068,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; } } |