diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-10-22 17:33:42 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-12-12 20:27:38 +0100 |
commit | 0e401bf7bfe4a14609e25c4335b9d4e0619e35ec (patch) | |
tree | a79fa574ae3b42d7cb28188cd449f02c28a8ec5d | |
parent | b8f51c04d31e15570c53dc2e61258304ee49047a (diff) | |
download | mariadb-git-0e401bf7bfe4a14609e25c4335b9d4e0619e35ec.tar.gz |
bugfix: move vcol calculations down into the handler
This fixes a bug where handler::read_range_first (for example)
needed to compare vcol values that were not calculated yet.
As a bonus it fixes few cases where vcols were calculated twice
-rw-r--r-- | mysql-test/suite/vcol/r/mrr.result | 25 | ||||
-rw-r--r-- | mysql-test/suite/vcol/t/mrr.test | 13 | ||||
-rw-r--r-- | sql/filesort.cc | 6 | ||||
-rw-r--r-- | sql/handler.cc | 32 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_handler.cc | 3 | ||||
-rw-r--r-- | sql/sql_join_cache.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 7 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 |
9 files changed, 72 insertions, 25 deletions
diff --git a/mysql-test/suite/vcol/r/mrr.result b/mysql-test/suite/vcol/r/mrr.result new file mode 100644 index 00000000000..39337f32963 --- /dev/null +++ b/mysql-test/suite/vcol/r/mrr.result @@ -0,0 +1,25 @@ +CREATE TABLE t1 ( +pk INT AUTO_INCREMENT PRIMARY KEY, +col_int_nokey INT NULL, +col_int_key INT AS (col_int_nokey) VIRTUAL, +KEY (col_int_key) +); +INSERT INTO t1 (col_int_nokey) +VALUES (0), (5), (4), (3), (7), (42), (5), (0), (3); +SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1; +pk col_int_nokey col_int_key +3 4 4 +4 3 3 +9 3 3 +set optimizer_switch='index_condition_pushdown=off'; +SELECT * FROM t1 WHERE col_int_key IN (3, 4) ORDER BY 1; +pk col_int_nokey col_int_key +3 4 4 +4 3 3 +9 3 3 +SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1; +pk col_int_nokey col_int_key +3 4 4 +4 3 3 +9 3 3 +DROP TABLE t1; diff --git a/mysql-test/suite/vcol/t/mrr.test b/mysql-test/suite/vcol/t/mrr.test new file mode 100644 index 00000000000..d7772ba5a78 --- /dev/null +++ b/mysql-test/suite/vcol/t/mrr.test @@ -0,0 +1,13 @@ +CREATE TABLE t1 ( + pk INT AUTO_INCREMENT PRIMARY KEY, + col_int_nokey INT NULL, + col_int_key INT AS (col_int_nokey) VIRTUAL, + KEY (col_int_key) +); +INSERT INTO t1 (col_int_nokey) +VALUES (0), (5), (4), (3), (7), (42), (5), (0), (3); +SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1; +set optimizer_switch='index_condition_pushdown=off'; +SELECT * FROM t1 WHERE col_int_key IN (3, 4) ORDER BY 1; +SELECT * FROM t1 WHERE col_int_key IN (3, 4) AND col_int_key <= 83 ORDER BY 1; +DROP TABLE t1; diff --git a/sql/filesort.cc b/sql/filesort.cc index e2f18f99135..a82f4871045 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -31,7 +31,7 @@ #include <m_ctype.h> #include "sql_sort.h" #include "probes_mysql.h" -#include "sql_base.h" // update_virtual_fields +#include "sql_base.h" #include "sql_test.h" // TEST_filesort #include "opt_range.h" // SQL_SELECT #include "bounded_queue.h" @@ -784,8 +784,6 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, { if ((error= select->quick->get_next())) break; - if (!error && sort_form->vfield) - sort_form->update_virtual_fields(VCOL_UPDATE_FOR_READ); file->position(sort_form->record[0]); DBUG_EXECUTE_IF("debug_filesort", dbug_print_record(sort_form, TRUE);); } @@ -793,8 +791,6 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select, { { error= file->ha_rnd_next(sort_form->record[0]); - if (!error && sort_form->vfield) - sort_form->update_virtual_fields(VCOL_UPDATE_FOR_READ); if (!flag) { my_store_ptr(ref_pos,ref_length,record); // Position to row diff --git a/sql/handler.cc b/sql/handler.cc index ede0bfad5ce..4155057ebe8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2579,6 +2579,8 @@ int handler::ha_rnd_next(uchar *buf) if (!result) { update_rows_read(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); increment_statistics(&SSV::ha_read_rnd_next_count); } else if (result == HA_ERR_RECORD_DELETED) @@ -2603,7 +2605,11 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos) { result= rnd_pos(buf, pos); }) increment_statistics(&SSV::ha_read_rnd_count); if (!result) + { update_rows_read(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; DBUG_RETURN(result); } @@ -2622,7 +2628,11 @@ int handler::ha_index_read_map(uchar *buf, const uchar *key, { result= index_read_map(buf, key, keypart_map, find_flag); }) increment_statistics(&SSV::ha_read_key_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; DBUG_RETURN(result); } @@ -2649,6 +2659,8 @@ int handler::ha_index_read_idx_map(uchar *buf, uint index, const uchar *key, { update_rows_read(); index_rows_read[index]++; + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); } table->status=result ? STATUS_NOT_FOUND: 0; return result; @@ -2666,7 +2678,11 @@ int handler::ha_index_next(uchar * buf) { result= index_next(buf); }) increment_statistics(&SSV::ha_read_next_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; DBUG_RETURN(result); } @@ -2683,7 +2699,11 @@ int handler::ha_index_prev(uchar * buf) { result= index_prev(buf); }) increment_statistics(&SSV::ha_read_prev_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; DBUG_RETURN(result); } @@ -2699,7 +2719,11 @@ int handler::ha_index_first(uchar * buf) { result= index_first(buf); }) increment_statistics(&SSV::ha_read_first_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; return result; } @@ -2715,7 +2739,11 @@ int handler::ha_index_last(uchar * buf) { result= index_last(buf); }) increment_statistics(&SSV::ha_read_last_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; return result; } @@ -2731,7 +2759,11 @@ int handler::ha_index_next_same(uchar *buf, const uchar *key, uint keylen) { result= index_next_same(buf, key, keylen); }) increment_statistics(&SSV::ha_read_next_count); if (!result) + { update_index_statistics(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(VCOL_UPDATE_FOR_READ); + } table->status=result ? STATUS_NOT_FOUND: 0; return result; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index d0da7f9dc2d..46491a832b3 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -561,7 +561,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { explain->tracker.on_record_read(); if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ_WRITE); + table->update_virtual_fields(VCOL_UPDATE_FOR_WRITE); thd->inc_examined_row_count(1); // thd->is_error() is tested to disallow delete row on error if (!select || select->skip_record(thd) > 0) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index bab33919e03..735adeadb11 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -929,9 +929,6 @@ retry: } goto ok; } - /* Generate values for virtual fields */ - if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ); if (cond && !cond->val_int()) { if (thd->is_error()) diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 7c134aba551..b9d7f660a5a 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -3371,7 +3371,6 @@ int JOIN_TAB_SCAN::next() int skip_rc; READ_RECORD *info= &join_tab->read_record; SQL_SELECT *select= join_tab->cache_select; - TABLE *table= join_tab->table; THD *thd= join->thd; if (is_first_record) @@ -3382,8 +3381,6 @@ int JOIN_TAB_SCAN::next() if (!err) { join_tab->tracker->r_rows++; - if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ); } while (!err && select && (skip_rc= select->skip_record(thd)) <= 0) @@ -3398,8 +3395,6 @@ int JOIN_TAB_SCAN::next() if (!err) { join_tab->tracker->r_rows++; - if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ); } } @@ -3923,8 +3918,6 @@ int JOIN_TAB_SCAN_MRR::next() DBUG_ASSERT(cache->buff <= (uchar *) (*ptr) && (uchar *) (*ptr) <= cache->end_pos); */ - if (join_tab->table->vfield) - join_tab->table->update_virtual_fields(VCOL_UPDATE_FOR_READ); } return rc; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5eda6e9bbbb..efeee4085ff 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -18442,9 +18442,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, join_tab->tracker->r_rows++; - if (join_tab->table->vfield) - join_tab->table->update_virtual_fields(VCOL_UPDATE_FOR_READ); - if (select_cond) { select_cond_result= MY_TEST(select_cond->val_int()); @@ -18895,8 +18892,6 @@ join_read_system(JOIN_TAB *tab) empty_record(table); // Make empty record return -1; } - if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ); store_record(table,record[1]); } else if (!table->status) // Only happens with left join @@ -18942,8 +18937,6 @@ join_read_const(JOIN_TAB *tab) return report_error(table, error); return -1; } - if (table->vfield) - table->update_virtual_fields(VCOL_UPDATE_FOR_READ); store_record(table,record[1]); } else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7b18322662a..16c8214438b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9803,8 +9803,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, error= 1; break; } - if (from->vfield) - from->update_virtual_fields(VCOL_UPDATE_FOR_READ); if (++thd->progress.counter >= time_to_report_progress) { time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10; |