Commit c6be7445 authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-6398: ANALYZE UPDATE does not populate r_rows

- In print_explain_row(), do not forget to print r_rows.
- Switch Explain_update from using its own counters to re-using
  Table_access_tracker.
- Make ANALYZE UPDATE code structure uniform with ANALYZE DELETE.
parent a787edd7
...@@ -16,7 +16,7 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f ...@@ -16,7 +16,7 @@ id select_type table type possible_keys key key_len ref rows r_rows filtered r_f
# ANALYZE DELETE will delete rows: # ANALYZE DELETE will delete rows:
analyze delete from t1 where a in (2,3,4); analyze delete from t1 where a in (2,3,4);
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 NULL 100.00 30.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 30.00 Using where
select * from t1; select * from t1;
a a
0 0
...@@ -32,7 +32,7 @@ create table t1(a int, b int); ...@@ -32,7 +32,7 @@ create table t1(a int, b int);
insert into t1 select a,a from t0; insert into t1 select a,a from t0;
analyze update t1 set b=100+b where a in (6,7,8); analyze update t1 set b=100+b where a in (6,7,8);
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 NULL 100.00 30.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 30.00 Using where
select * from t1; select * from t1;
a b a b
0 0 0 0
...@@ -233,3 +233,12 @@ analyze update t1 set b=12345 where a > 30 and a < 10; ...@@ -233,3 +233,12 @@ analyze update t1 set b=12345 where a > 30 and a < 10;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
drop table t1; drop table t1;
#
# MDEV-6398: ANALYZE UPDATE does not populate r_rows
#
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
analyze update t1 set i=8;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 4 100.00 100.00
drop table t1;
...@@ -183,4 +183,11 @@ analyze update t1 set b=12345 where 1 > 2; ...@@ -183,4 +183,11 @@ analyze update t1 set b=12345 where 1 > 2;
analyze update t1 set b=12345 where a > 30 and a < 10; analyze update t1 set b=12345 where a > 30 and a < 10;
drop table t1; drop table t1;
--echo #
--echo # MDEV-6398: ANALYZE UPDATE does not populate r_rows
--echo #
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
analyze update t1 set i=8;
drop table t1;
...@@ -539,10 +539,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -539,10 +539,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
} }
explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan(); explain= (Explain_delete*)thd->lex->explain->get_upd_del_plan();
explain->tracker.on_scan_init();
while (!(error=info.read_record(&info)) && !thd->killed && while (!(error=info.read_record(&info)) && !thd->killed &&
! thd->is_error()) ! thd->is_error())
{ {
explain->on_record_read(); explain->tracker.on_record_read();
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table,
table->triggers ? VCOL_UPDATE_ALL : table->triggers ? VCOL_UPDATE_ALL :
...@@ -551,7 +553,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -551,7 +553,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
// thd->is_error() is tested to disallow delete row on error // thd->is_error() is tested to disallow delete row on error
if (!select || select->skip_record(thd) > 0) if (!select || select->skip_record(thd) > 0)
{ {
explain->on_record_after_where(); explain->tracker.on_record_after_where();
if (table->triggers && if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE)) TRG_ACTION_BEFORE, FALSE))
......
...@@ -957,7 +957,8 @@ int Explain_update::print_explain(Explain_query *query, ...@@ -957,7 +957,8 @@ int Explain_update::print_explain(Explain_query *query,
Single-table DELETE commands do not do "Using temporary". Single-table DELETE commands do not do "Using temporary".
"Using index condition" is also not possible (which is an unjustified limitation) "Using index condition" is also not possible (which is an unjustified limitation)
*/ */
double r_filtered= 100 * (r_rows?((double)r_rows_after_where/r_rows):1.0); double r_filtered= 100 * tracker.get_filtered_after_where();
ha_rows r_rows= tracker.get_avg_rows();
print_explain_row(output, explain_flags, is_analyze, print_explain_row(output, explain_flags, is_analyze,
1, /* id */ 1, /* id */
...@@ -970,7 +971,7 @@ int Explain_update::print_explain(Explain_query *query, ...@@ -970,7 +971,7 @@ int Explain_update::print_explain(Explain_query *query,
key_len_buf.length() ? key_len_buf.c_ptr() : NULL, key_len_buf.length() ? key_len_buf.c_ptr() : NULL,
NULL, /* 'ref' is always NULL in single-table EXPLAIN DELETE */ NULL, /* 'ref' is always NULL in single-table EXPLAIN DELETE */
&rows, &rows,
&r_rows, tracker.has_scans()? &r_rows : NULL,
r_filtered, r_filtered,
extra_str.c_ptr_safe()); extra_str.c_ptr_safe());
......
...@@ -44,6 +44,10 @@ public: ...@@ -44,6 +44,10 @@ public:
return r_filtered; return r_filtered;
} }
inline void on_scan_init() { r_scans++; }
inline void on_record_read() { r_rows++; }
inline void on_record_after_where() { r_rows_after_where++; }
}; };
...@@ -576,14 +580,8 @@ public: ...@@ -576,14 +580,8 @@ public:
bool using_io_buffer; bool using_io_buffer;
/* ANALYZE members and methods */ /* ANALYZE members and methods */
ha_rows r_rows; Table_access_tracker tracker;
ha_rows r_rows_after_where;
inline void on_record_read() { r_rows++; }
inline void on_record_after_where() { r_rows_after_where++; }
Explain_update() :
r_rows(0), r_rows_after_where(0)
{}
virtual int print_explain(Explain_query *query, select_result_sink *output, virtual int print_explain(Explain_query *query, select_result_sink *output,
uint8 explain_flags, bool is_analyze); uint8 explain_flags, bool is_analyze);
}; };
......
...@@ -23131,7 +23131,15 @@ int print_explain_row(select_result_sink *result, ...@@ -23131,7 +23131,15 @@ int print_explain_row(select_result_sink *result,
/* 'r_rows' */ /* 'r_rows' */
if (is_analyze) if (is_analyze)
{
if (r_rows)
{
item_list.push_back(new Item_int(*r_rows,
MY_INT64_NUM_DECIMAL_DIGITS));
}
else
item_list.push_back(item_null); item_list.push_back(item_null);
}
/* 'filtered' */ /* 'filtered' */
const double filtered=100.0; const double filtered=100.0;
......
...@@ -725,9 +725,11 @@ int mysql_update(THD *thd, ...@@ -725,9 +725,11 @@ int mysql_update(THD *thd,
if all updated columns are read if all updated columns are read
*/ */
can_compare_record= records_are_comparable(table); can_compare_record= records_are_comparable(table);
explain->tracker.on_scan_init();
while (!(error=info.read_record(&info)) && !thd->killed) while (!(error=info.read_record(&info)) && !thd->killed)
{ {
explain->on_record_read(); explain->tracker.on_record_read();
if (table->vfield) if (table->vfield)
update_virtual_fields(thd, table, update_virtual_fields(thd, table,
table->triggers ? VCOL_UPDATE_ALL : table->triggers ? VCOL_UPDATE_ALL :
...@@ -738,7 +740,7 @@ int mysql_update(THD *thd, ...@@ -738,7 +740,7 @@ int mysql_update(THD *thd,
if (table->file->was_semi_consistent_read()) if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */ continue; /* repeat the read of the same row if it still exists */
explain->on_record_after_where(); explain->tracker.on_record_after_where();
store_record(table,record[1]); store_record(table,record[1]);
if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0, if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
TRG_EVENT_UPDATE)) TRG_EVENT_UPDATE))
...@@ -947,6 +949,7 @@ int mysql_update(THD *thd, ...@@ -947,6 +949,7 @@ int mysql_update(THD *thd,
end_read_record(&info); end_read_record(&info);
delete select; delete select;
select= NULL;
THD_STAGE_INFO(thd, stage_end); THD_STAGE_INFO(thd, stage_end);
(void) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); (void) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
...@@ -996,11 +999,7 @@ int mysql_update(THD *thd, ...@@ -996,11 +999,7 @@ int mysql_update(THD *thd,
id= thd->arg_of_last_insert_id_function ? id= thd->arg_of_last_insert_id_function ?
thd->first_successful_insert_id_in_prev_stmt : 0; thd->first_successful_insert_id_in_prev_stmt : 0;
if (thd->lex->analyze_stmt) if (error < 0 && !thd->lex->analyze_stmt)
{
error= thd->lex->explain->send_explain(thd);
}
else if (error < 0)
{ {
char buff[MYSQL_ERRMSG_SIZE]; char buff[MYSQL_ERRMSG_SIZE];
my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
...@@ -1019,10 +1018,14 @@ int mysql_update(THD *thd, ...@@ -1019,10 +1018,14 @@ int mysql_update(THD *thd,
} }
*found_return= found; *found_return= found;
*updated_return= updated; *updated_return= updated;
if (thd->lex->analyze_stmt)
goto emit_explain_and_leave;
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0); DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
err: err:
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
table->disable_keyread(); table->disable_keyread();
...@@ -1036,6 +1039,7 @@ produce_explain_and_leave: ...@@ -1036,6 +1039,7 @@ produce_explain_and_leave:
*/ */
query_plan.save_explain_data(thd->lex->explain); query_plan.save_explain_data(thd->lex->explain);
emit_explain_and_leave:
int err2= thd->lex->explain->send_explain(thd); int err2= thd->lex->explain->send_explain(thd);
delete select; delete select;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment