summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/federated/federated_maybe_16324629.result1
-rw-r--r--mysql-test/suite/vcol/r/update.result11
-rw-r--r--mysql-test/suite/vcol/t/update.test10
-rw-r--r--sql/sql_class.h20
-rw-r--r--sql/sql_delete.cc11
-rw-r--r--sql/sql_lex.cc9
-rw-r--r--sql/sql_select.cc1
-rw-r--r--sql/sql_update.cc17
8 files changed, 63 insertions, 17 deletions
diff --git a/mysql-test/suite/federated/federated_maybe_16324629.result b/mysql-test/suite/federated/federated_maybe_16324629.result
index 0417b5c0659..e16e4dd101d 100644
--- a/mysql-test/suite/federated/federated_maybe_16324629.result
+++ b/mysql-test/suite/federated/federated_maybe_16324629.result
@@ -13,7 +13,6 @@ insert into t1 values (3, 3), (7, 7);
delete t1 from t1 where a = 3;
select * from t1;
a b
-3 3
7 7
drop table t1;
connection slave;
diff --git a/mysql-test/suite/vcol/r/update.result b/mysql-test/suite/vcol/r/update.result
index dd864e4a7e2..e88502492cb 100644
--- a/mysql-test/suite/vcol/r/update.result
+++ b/mysql-test/suite/vcol/r/update.result
@@ -43,3 +43,14 @@ select * from t1;
a b c
b 2 b
drop table t1;
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t;
+Table Op Msg_type Msg_text
+test.t check status OK
+select * from t;
+a b c
+9 10 10
+drop table t, t2;
diff --git a/mysql-test/suite/vcol/t/update.test b/mysql-test/suite/vcol/t/update.test
index f840c277cd1..8be5872a26b 100644
--- a/mysql-test/suite/vcol/t/update.test
+++ b/mysql-test/suite/vcol/t/update.test
@@ -55,3 +55,13 @@ replace t1 set a = 'a',b =1;
insert t1 (a,b) values ('a', 1) on duplicate key update a='b', b=2;
select * from t1;
drop table t1;
+
+#
+# multi-UPDATE and const tables
+#
+create table t (a int primary key, b int, c int as (b), index (c));
+insert t (a,b) values (9,0);
+create table t2 select * from t;
+update t, t2 set t.b=10 where t.a=t2.a;
+check table t; select * from t;
+drop table t, t2;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 0434f5485cf..507fadedac1 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4455,6 +4455,9 @@ public:
#endif
virtual void update_used_tables() {}
+ /* this method is called just before the first row of the table can be read */
+ virtual void prepare_to_read_rows() {}
+
void reset_offset_limit()
{
unit->offset_limit_cnt= 0;
@@ -5301,11 +5304,9 @@ public:
int do_deletes();
int do_table_deletes(TABLE *table, SORT_INFO *sort_info, bool ignore);
bool send_eof();
- inline ha_rows num_deleted()
- {
- return deleted;
- }
+ inline ha_rows num_deleted() const { return deleted; }
virtual void abort_result_set();
+ void prepare_to_read_rows();
};
@@ -5349,16 +5350,11 @@ public:
bool initialize_tables (JOIN *join);
int do_updates();
bool send_eof();
- inline ha_rows num_found()
- {
- return found;
- }
- inline ha_rows num_updated()
- {
- return updated;
- }
+ inline ha_rows num_found() const { return found; }
+ inline ha_rows num_updated() const { return updated; }
virtual void abort_result_set();
void update_used_tables();
+ void prepare_to_read_rows();
};
class my_var : public Sql_alloc {
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 46491a832b3..e9a3be30060 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -924,6 +924,15 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_RETURN(0);
}
+void multi_delete::prepare_to_read_rows()
+{
+ /* see multi_update::prepare_to_read_rows() */
+ for (TABLE_LIST *walk= delete_tables; walk; walk= walk->next_local)
+ {
+ TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
+ tbl->table->mark_columns_needed_for_delete();
+ }
+}
bool
multi_delete::initialize_tables(JOIN *join)
@@ -953,7 +962,6 @@ multi_delete::initialize_tables(JOIN *join)
}
}
-
walk= delete_tables;
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS,
@@ -977,7 +985,6 @@ multi_delete::initialize_tables(JOIN *join)
normal_tables= 1;
tbl->prepare_triggers_for_delete_stmt_or_event();
tbl->prepare_for_position();
- tbl->mark_columns_needed_for_delete();
}
else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) &&
walk == delete_tables)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index bea3b14e607..634b6d1a3b8 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4122,6 +4122,15 @@ void SELECT_LEX::update_used_tables()
TABLE *tab= tl->table;
tab->covering_keys= tab->s->keys_for_keyread;
tab->covering_keys.intersect(tab->keys_in_use_for_query);
+ /*
+ View/derived was merged. Need to recalculate read_set/vcol_set
+ bitmaps here. For example:
+ CREATE VIEW v1 AS SELECT f1,f2,f3 FROM t1;
+ SELECT f1 FROM v1;
+ Initially, the view definition will put all f1,f2,f3 in the
+ read_set for t1. But after the view is merged, only f1 should
+ be in the read_set.
+ */
bitmap_clear_all(tab->read_set);
if (tab->vcol_set)
bitmap_clear_all(tab->vcol_set);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index efeee4085ff..89a9eeb1e32 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1466,6 +1466,7 @@ JOIN::optimize_inner()
/* Calculate how to do the join */
THD_STAGE_INFO(thd, stage_statistics);
+ result->prepare_to_read_rows();
if (make_join_statistics(this, select_lex->leaf_tables, &keyuse) ||
thd->is_fatal_error)
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index da0e6cd2116..05f7080609a 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1800,6 +1800,21 @@ void multi_update::update_used_tables()
}
}
+void multi_update::prepare_to_read_rows()
+{
+ /*
+ update column maps now. it cannot be done in ::prepare() before the
+ optimizer, because the optimize might reset them (in
+ SELECT_LEX::update_used_tables()), it cannot be done in
+ ::initialize_tables() after the optimizer, because the optimizer
+ might read rows from const tables
+ */
+
+ for (TABLE_LIST *tl= update_tables; tl; tl= tl->next_local)
+ tl->table->mark_columns_needed_for_update();
+}
+
+
/*
Check if table is safe to update on fly
@@ -1916,12 +1931,10 @@ multi_update::initialize_tables(JOIN *join)
{
if (safe_update_on_fly(thd, join->join_tab, table_ref, all_tables))
{
- table->mark_columns_needed_for_update();
table_to_update= table; // Update table on the fly
continue;
}
}
- table->mark_columns_needed_for_update();
table->prepare_for_position();
/*