diff options
author | unknown <tomas@poseidon.ndb.mysql.com> | 2006-07-04 11:43:06 +0200 |
---|---|---|
committer | unknown <tomas@poseidon.ndb.mysql.com> | 2006-07-04 11:43:06 +0200 |
commit | 8597f663482b125736e34f77a19d35fa26e309fe (patch) | |
tree | a204ffab993ad6cc9a81aea8c74c6ac44b80b5c0 /sql | |
parent | c8ddbe6d2fad3d268bfadfd295f8bb7e7041097e (diff) | |
download | mariadb-git-8597f663482b125736e34f77a19d35fa26e309fe.tar.gz |
Bug #20784 Uninitialized memory in update on table with PK not on first column
- partial backport of code from 5.1, do cot compare_record for engines that do not read all columns during update
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_ndbcluster.cc | 3 | ||||
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/sql_update.cc | 25 |
3 files changed, 25 insertions, 4 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e4ff39797ca..280b23fc73f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -4575,7 +4575,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_NO_PREFIX_CHAR_KEYS | HA_NEED_READ_RANGE_BUFFER | HA_CAN_GEOMETRY | - HA_CAN_BIT_FIELD), + HA_CAN_BIT_FIELD | + HA_PARTIAL_COLUMN_READ), m_share(0), m_use_write(FALSE), m_ignore_dup_key(FALSE), diff --git a/sql/handler.h b/sql/handler.h index 31aac075a5e..aada647e071 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -57,6 +57,7 @@ see mi_rsame/heap_rsame/myrg_rsame */ #define HA_READ_RND_SAME (1 << 0) +#define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */ #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */ #define HA_REC_NOT_IN_SEQ (1 << 3) /* ha_info don't return recnumber; It returns a position to ha_r_rnd */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c2b7624c9e7..5237b3a1c05 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -120,6 +120,7 @@ int mysql_update(THD *thd, bool using_limit= limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table; + bool can_compare_record; int res; int error; uint used_index= MAX_KEY; @@ -433,6 +434,13 @@ int mysql_update(THD *thd, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))); + /* + We can use compare_record() to optimize away updates if + the table handler is returning all columns + */ + can_compare_record= !(table->file->table_flags() & + HA_PARTIAL_COLUMN_READ); + while (!(error=info.read_record(&info)) && !thd->killed) { if (!(select && select->skip_record())) @@ -445,7 +453,7 @@ int mysql_update(THD *thd, found++; - if (compare_record(table, query_id)) + if (!can_compare_record || compare_record(table, query_id)) { if ((res= table_list->view_check_option(thd, ignore)) != VIEW_CHECK_OK) @@ -1248,8 +1256,15 @@ bool multi_update::send_data(List<Item> ¬_used_values) uint offset= cur_table->shared; table->file->position(table->record[0]); + /* + We can use compare_record() to optimize away updates if + the table handler is returning all columns + */ if (table == table_to_update) { + bool can_compare_record; + can_compare_record= !(table->file->table_flags() & + HA_PARTIAL_COLUMN_READ); table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset], @@ -1259,7 +1274,7 @@ bool multi_update::send_data(List<Item> ¬_used_values) DBUG_RETURN(1); found++; - if (compare_record(table, thd->query_id)) + if (!can_compare_record || compare_record(table, thd->query_id)) { int error; if ((error= cur_table->view_check_option(thd, ignore)) != @@ -1376,6 +1391,7 @@ int multi_update::do_updates(bool from_send_error) for (cur_table= update_tables; cur_table; cur_table= cur_table->next_local) { byte *ref_pos; + bool can_compare_record; table = cur_table->table; if (table == table_to_update) @@ -1402,6 +1418,9 @@ int multi_update::do_updates(bool from_send_error) if ((local_error = tmp_table->file->ha_rnd_init(1))) goto err; + can_compare_record= !(table->file->table_flags() & + HA_PARTIAL_COLUMN_READ); + ref_pos= (byte*) tmp_table->field[0]->ptr; for (;;) { @@ -1431,7 +1450,7 @@ int multi_update::do_updates(bool from_send_error) TRG_ACTION_BEFORE, TRUE)) goto err2; - if (compare_record(table, thd->query_id)) + if (!can_compare_record || compare_record(table, thd->query_id)) { if ((local_error=table->file->update_row(table->record[1], table->record[0]))) |