summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2012-05-22 20:55:07 -0700
committerIgor Babaev <igor@askmonty.org>2012-05-22 20:55:07 -0700
commit055477ae522b805d3b2e890af9fe520cc1e3290d (patch)
tree6f45830161e7fa5f2a690046fc6f118f9331b3b2 /sql
parent2a1afc29f252fb189f6e93a2e0d3a1939f8220d5 (diff)
downloadmariadb-git-055477ae522b805d3b2e890af9fe520cc1e3290d.tar.gz
Support of the extended syntax for ANALYZE.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_admin.cc68
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_statistics.cc27
-rw-r--r--sql/sql_yacc.yy89
5 files changed, 172 insertions, 16 deletions
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index c2d06a149e8..4e2581b885c 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -27,6 +27,7 @@
#include "sql_acl.h" // *_ACL
#include "sp.h" // Sroutine_hash_entry
#include "sql_parse.h" // check_table_access
+#include "strfunc.h"
#include "sql_admin.h"
/* Prepare, run and cleanup for mysql_recreate_table() */
@@ -628,16 +629,75 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
}
}
- result_code= compl_result_code= 0;
- if (operator_func != &handler::ha_analyze ||
- thd->variables.optimizer_use_stat_tables < 3)
+ result_code= compl_result_code= HA_ADMIN_OK;
+
+ if (operator_func == &handler::ha_analyze)
+ {
+ TABLE *tab= table->table;
+ Field **field_ptr= tab->field;
+
+ if (!lex->column_list)
+ {
+ uint fields= 0;
+ for ( ; *field_ptr; field_ptr++, fields++) ;
+ bitmap_set_prefix(tab->read_set, fields);
+ }
+ else
+ {
+ int pos;
+ LEX_STRING *column_name;
+ List_iterator_fast<LEX_STRING> it(*lex->column_list);
+
+ bitmap_clear_all(tab->read_set);
+ while ((column_name= it++))
+ {
+ if (tab->s->fieldnames.type_names == 0 ||
+ (pos= find_type(&tab->s->fieldnames, column_name->str,
+ column_name->length, 1)) <= 0)
+ {
+ compl_result_code= result_code= HA_ADMIN_INVALID;
+ break;
+ }
+ bitmap_set_bit(tab->read_set, --pos);
+ }
+ }
+
+ if (!lex->index_list)
+ {
+ tab->keys_in_use_for_query.init(tab->s->keys);
+ }
+ else
+ {
+ int pos;
+ LEX_STRING *index_name;
+ List_iterator_fast<LEX_STRING> it(*lex->index_list);
+
+ tab->keys_in_use_for_query.clear_all();
+ while ((index_name= it++))
+ {
+ if (tab->s->keynames.type_names == 0 ||
+ (pos= find_type(&tab->s->keynames, index_name->str,
+ index_name->length, 1)) <= 0)
+ {
+ compl_result_code= result_code= HA_ADMIN_INVALID;
+ break;
+ }
+ tab->keys_in_use_for_query.set_bit(--pos);
+ }
+ }
+ }
+
+ if (result_code == HA_ADMIN_OK &&
+ (operator_func != &handler::ha_analyze ||
+ thd->variables.optimizer_use_stat_tables < 3))
{
DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
result_code = (table->table->file->*operator_func)(thd, check_opt);
DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
}
- if (operator_func == &handler::ha_analyze && opt_with_stat_tables &&
+ if (compl_result_code == HA_ADMIN_OK &&
+ operator_func == &handler::ha_analyze && opt_with_stat_tables &&
thd->variables.optimizer_use_stat_tables > 0)
{
if (!(compl_result_code=
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 246f03a7754..bff3ebb3450 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -456,6 +456,8 @@ void lex_start(THD *thd)
lex->set_var_list.empty();
lex->param_list.empty();
lex->view_list.empty();
+ lex->column_list= NULL;
+ lex->index_list= NULL;
lex->prepared_stmt_params.empty();
lex->auxiliary_table_list.empty();
lex->unit.next= lex->unit.master=
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index f1ee6cf22ec..70c97613f55 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2383,6 +2383,8 @@ struct LEX: public Query_tables_list
List<Item_func_set_user_var> set_var_list; // in-query assignment list
List<Item_param> param_list;
List<LEX_STRING> view_list; // view list (list of field names in view)
+ List<LEX_STRING> *column_list; // list of column names (in ANALYZE)
+ List<LEX_STRING> *index_list; // list of index names (in ANALYZE)
/*
A stack of name resolution contexts for the query. This stack is used
at parse time to set local name resolution contexts for various parts
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 44f25115f00..aeaecf537cb 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -1289,6 +1289,8 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
{
table_field= *field_ptr;
uint max_heap_table_size= thd->variables.max_heap_table_size;
+ if (!bitmap_is_set(table->read_set, table_field->field_index))
+ continue;
set_nulls_for_write_column_stat_values(table_field);
table_field->nulls= 0;
table_field->column_total_length= 0;
@@ -1306,8 +1308,6 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
table_field->count_distinct= NULL;
}
- bitmap_set_all(table->read_set);
-
/* Perform a full table scan to collect statistics on 'table's columns */
if (!(rc= file->ha_rnd_init(TRUE)))
{
@@ -1319,6 +1319,8 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
table_field= *field_ptr;
+ if (!bitmap_is_set(table->read_set, table_field->field_index))
+ continue;
if (table_field->is_null())
table_field->nulls++;
else
@@ -1357,6 +1359,8 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
table_field= *field_ptr;
+ if (!bitmap_is_set(table->read_set, table_field->field_index))
+ continue;
table_field->write_stat.nulls_ratio= (double) table_field->nulls/rows;
table_field->write_stat.avg_length=
(double) table_field->column_total_length / (rows-table_field->nulls);
@@ -1380,12 +1384,13 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
if (!rc)
{
- uint keys= table->s->keys ;
-
+ uint key;
+ key_map::Iterator it(table->keys_in_use_for_query);
+
/* Collect statistics for indexes */
- for (uint i= 0; i < keys; i++)
+ while ((key= it++) != key_map::Iterator::BITMAP_END)
{
- if ((rc= collect_statistics_for_index(table, i)))
+ if ((rc= collect_statistics_for_index(table, key)))
break;
}
}
@@ -1439,7 +1444,6 @@ int update_statistics_for_table(THD *thd, TABLE *table)
int err;
int rc= 0;
TABLE *stat_table;
- uint keys= table->s->keys;
DBUG_ENTER("update_statistics_for_table");
@@ -1466,6 +1470,8 @@ int update_statistics_for_table(THD *thd, TABLE *table)
for (Field **field_ptr= table->field; *field_ptr; field_ptr++)
{
Field *table_field= *field_ptr;
+ if (!bitmap_is_set(table->read_set, table_field->field_index))
+ continue;
restore_record(stat_table, s->default_values);
column_stat.set_key_fields(table_field);
err= column_stat.update_stat();
@@ -1475,12 +1481,13 @@ int update_statistics_for_table(THD *thd, TABLE *table)
/* Update the statistical table index_stat */
stat_table= tables[INDEX_STAT].table;
+ uint key;
+ key_map::Iterator it(table->keys_in_use_for_query);
Index_stat index_stat(stat_table, table);
- KEY *key_info, *key_info_end;
- for (key_info= table->key_info, key_info_end= table->key_info+keys;
- key_info < key_info_end; key_info++)
+ while ((key= it++) != key_map::Iterator::BITMAP_END)
{
+ KEY *key_info= table->key_info+key;
uint key_parts= table->actual_n_key_parts(key_info);
for (i= 0; i < key_parts; i++)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 34e015e1f9b..ff72d27647d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1593,7 +1593,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
show describe load alter optimize keycache preload flush
reset purge begin commit rollback savepoint release
slave master_def master_defs master_file_def slave_until_opts
- repair analyze check start checksum
+ repair analyze
+ analyze_table_list analyze_table_elem_spec
+ opt_persistent_stat_clause persistent_stat_spec
+ persistent_column_stat_spec persistent_index_stat_spec
+ table_column_list table_index_list
+ check start checksum
field_list field_list_item field_spec kill column_def key_def
keycache_list keycache_list_or_parts assign_to_keycache
assign_to_keycache_parts
@@ -7212,7 +7217,7 @@ analyze:
/* Will be overriden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
- table_list
+ analyze_table_list
{
THD *thd= YYTHD;
LEX* lex= thd->lex;
@@ -7223,6 +7228,86 @@ analyze:
}
;
+analyze_table_list:
+ analyze_table_elem_spec
+ | analyze_table_list ',' analyze_table_elem_spec
+ ;
+
+analyze_table_elem_spec:
+ table_name opt_persistent_stat_clause
+ ;
+
+opt_persistent_stat_clause:
+ /* empty */
+ {}
+ | PERSISTENT_SYM FOR_SYM persistent_stat_spec
+ {}
+ ;
+
+persistent_stat_spec:
+ ALL
+ {}
+ | COLUMNS persistent_column_stat_spec INDEXES persistent_index_stat_spec
+ {}
+
+persistent_column_stat_spec:
+ ALL {}
+ | '('
+ {
+ THD *thd= YYTHD;
+ LEX* lex= thd->lex;
+ lex->column_list= new List<LEX_STRING>;
+ if (lex->column_list == NULL)
+ MYSQL_YYABORT;
+ }
+ table_column_list
+ ')'
+ ;
+
+persistent_index_stat_spec:
+ ALL {}
+ | '('
+ {
+ THD *thd= YYTHD;
+ LEX* lex= thd->lex;
+ lex->index_list= new List<LEX_STRING>;
+ if (lex->index_list == NULL)
+ MYSQL_YYABORT;
+ }
+ table_index_list
+ ')'
+ ;
+
+table_column_list:
+ /* empty */
+ {}
+ | ident
+ {
+ Lex->column_list->push_back((LEX_STRING*)
+ sql_memdup(&$1, sizeof(LEX_STRING)));
+ }
+ | table_column_list ',' ident
+ {
+ Lex->column_list->push_back((LEX_STRING*)
+ sql_memdup(&$3, sizeof(LEX_STRING)));
+ }
+ ;
+
+table_index_list:
+ /* empty */
+ {}
+ | ident
+ {
+ Lex->index_list->push_back((LEX_STRING*)
+ sql_memdup(&$1, sizeof(LEX_STRING)));
+ }
+ | table_index_list ',' ident
+ {
+ Lex->index_list->push_back((LEX_STRING*)
+ sql_memdup(&$3, sizeof(LEX_STRING)));
+ }
+ ;
+
binlog_base64_event:
BINLOG_SYM TEXT_STRING_sys
{