summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/april.(none)>2006-12-20 20:01:31 +0400
committerunknown <svoj@mysql.com/april.(none)>2006-12-20 20:01:31 +0400
commit2efb6576008acd580680849e1e618da021b57c7e (patch)
tree07b49f1420b38586b00555274fbede619a469630 /sql/sql_update.cc
parent76da582ca5f8a93ae5ff7e7fdea1991d47658196 (diff)
parent9d094c56bc6f15d16f51d4b0bcf9de3cd4674d7f (diff)
downloadmariadb-git-2efb6576008acd580680849e1e618da021b57c7e.tar.gz
Merge mysql.com:/home/svoj/devel/mysql/BUG21310/mysql-4.1-engines
into mysql.com:/home/svoj/devel/mysql/BUG21310/mysql-5.0-engines sql/lock.cc: Use local. mysql-test/r/myisam.result: Manual merge. mysql-test/t/myisam.test: Manual merge. sql/sql_update.cc: Manual merge.
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc138
1 files changed, 62 insertions, 76 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 3b6aa5f1aa2..5b7b7f594da 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -25,8 +25,6 @@
#include "sp_head.h"
#include "sql_trigger.h"
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
-
/* Return 0 if row hasn't changed */
static bool compare_record(TABLE *table, query_id_t query_id)
@@ -1041,27 +1039,72 @@ int multi_update::prepare(List<Item> &not_used_values,
for (i=0 ; i < table_count ; i++)
set_if_bigger(max_fields, fields_for_table[i]->elements);
copy_field= new Copy_field[max_fields];
+ DBUG_RETURN(thd->is_fatal_error != 0);
+}
- /*
- Mark all copies of tables that are updates to ensure that
- init_read_record() will not try to enable a cache on them
- The problem is that for queries like
+/*
+ Check if table is safe to update on fly
- UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a;
+ SYNOPSIS
+ safe_update_on_fly()
+ thd Thread handler
+ join_tab How table is used in join
+ all_tables List of tables
+ fields Fields that are updated
- the row buffer may contain things that doesn't match what is on disk
- which will cause an error when reading a row.
- (This issue is mostly relevent for MyISAM tables)
- */
- for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
- {
- TABLE *table=table_ref->table;
- if ((tables_to_update & table->map) &&
- unique_table(thd, table_ref, update_tables))
- table->no_cache= 1; // Disable row cache
+ NOTES
+ We can update the first table in join on the fly if we know that
+ a row in this table will never be read twice. This is true under
+ the following conditions:
+
+ - We are doing a table scan and the data is in a separate file (MyISAM) or
+ if we don't update a clustered key.
+
+ - We are doing a range scan and we don't update the scan key or
+ the primary key for a clustered table handler.
+
+ - Table is not joined to itself.
+
+ When checking for above cases we also should take into account that
+ BEFORE UPDATE trigger potentially may change value of any field in row
+ being updated.
+
+ WARNING
+ This code is a bit dependent of how make_join_readinfo() works.
+
+ RETURN
+ 0 Not safe to update
+ 1 Safe to update
+*/
+
+static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
+ TABLE_LIST *all_tables, List<Item> *fields)
+{
+ TABLE *table= join_tab->table;
+ if (unique_table(thd, table, all_tables))
+ return 0;
+ switch (join_tab->type) {
+ case JT_SYSTEM:
+ case JT_CONST:
+ case JT_EQ_REF:
+ return TRUE; // At most one matching row
+ case JT_REF:
+ case JT_REF_OR_NULL:
+ return !is_key_used(table, join_tab->ref.key, *fields);
+ case JT_ALL:
+ /* If range search on index */
+ if (join_tab->quick)
+ return !join_tab->quick->is_keys_used(fields);
+ /* If scanning in clustered key */
+ if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
+ table->s->primary_key < MAX_KEY)
+ return !is_key_used(table, table->s->primary_key, *fields);
+ return TRUE;
+ default:
+ break; // Avoid compler warning
}
- DBUG_RETURN(thd->is_fatal_error != 0);
+ return FALSE;
}
@@ -1099,7 +1142,7 @@ multi_update::initialize_tables(JOIN *join)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (table == main_table) // First table in join
{
- if (safe_update_on_fly(join->join_tab, &temp_fields))
+ if (safe_update_on_fly(thd, join->join_tab, all_tables, &temp_fields))
{
table_to_update= main_table; // Update table on the fly
continue;
@@ -1150,63 +1193,6 @@ multi_update::initialize_tables(JOIN *join)
DBUG_RETURN(0);
}
-/*
- Check if table is safe to update on fly
-
- SYNOPSIS
- safe_update_on_fly
- join_tab How table is used in join
- fields Fields that are updated
-
- NOTES
- We can update the first table in join on the fly if we know that
- a row in this table will never be read twice. This is true under
- the following conditions:
-
- - We are doing a table scan and the data is in a separate file (MyISAM) or
- if we don't update a clustered key.
-
- - We are doing a range scan and we don't update the scan key or
- the primary key for a clustered table handler.
-
- When checking for above cases we also should take into account that
- BEFORE UPDATE trigger potentially may change value of any field in row
- being updated.
-
- WARNING
- This code is a bit dependent of how make_join_readinfo() works.
-
- RETURN
- 0 Not safe to update
- 1 Safe to update
-*/
-
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
-{
- TABLE *table= join_tab->table;
- switch (join_tab->type) {
- case JT_SYSTEM:
- case JT_CONST:
- case JT_EQ_REF:
- return TRUE; // At most one matching row
- case JT_REF:
- case JT_REF_OR_NULL:
- return !is_key_used(table, join_tab->ref.key, *fields);
- case JT_ALL:
- /* If range search on index */
- if (join_tab->quick)
- return !join_tab->quick->is_keys_used(fields);
- /* If scanning in clustered key */
- if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
- table->s->primary_key < MAX_KEY)
- return !is_key_used(table, table->s->primary_key, *fields);
- return TRUE;
- default:
- break; // Avoid compler warning
- }
- return FALSE;
-}
-
multi_update::~multi_update()
{