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.cc214
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;
}
}