summaryrefslogtreecommitdiff
path: root/sql/sql_statistics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r--sql/sql_statistics.cc211
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;
}
}