1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
1
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3
3
This program is free software; you can redistribute it and/or modify
4
4
it under the terms of the GNU General Public License as published by
25
25
#include "sql_trigger.h"
26
26
#include "debug_sync.h"
28
/* Return 0 if row hasn't changed */
30
bool compare_record(TABLE *table)
30
True if the table's input and output record buffers are comparable using
31
compare_records(TABLE*).
33
bool records_are_comparable(const TABLE *table) {
34
return ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) == 0) ||
35
bitmap_is_subset(table->write_set, table->read_set);
40
Compares the input and outbut record buffers of the table to see if a row
41
has changed. The algorithm iterates over updated columns and if they are
42
nullable compares NULL bits in the buffer before comparing actual
43
data. Special care must be taken to compare only the relevant NULL bits and
44
mask out all others as they may be undefined. The storage engine will not
45
and should not touch them.
47
@param table The table to evaluate.
49
@return true if row has changed.
50
@return false otherwise.
52
bool compare_records(const TABLE *table)
54
DBUG_ASSERT(records_are_comparable(table));
56
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) != 0)
59
Storage engine may not have read all columns of the record. Fields
60
(including NULL bits) not in the write_set may not have been read and
61
can therefore not be compared.
63
for (Field **ptr= table->field ; *ptr != NULL; ptr++)
66
if (bitmap_is_set(table->write_set, field->field_index))
68
if (field->real_maybe_null())
70
uchar null_byte_index= field->null_ptr - table->record[0];
72
if (((table->record[0][null_byte_index]) & field->null_bit) !=
73
((table->record[1][null_byte_index]) & field->null_bit))
76
if (field->cmp_binary_offset(table->s->rec_buff_length))
84
The storage engine has read all columns, so it's safe to compare all bits
85
including those not in the write_set. This is cheaper than the field-by-field
86
comparison done above.
32
88
if (table->s->blob_fields + table->s->varchar_fields == 0)
89
// Fixed-size record: do bitwise comparison of the records
33
90
return cmp_record(table,record[1]);
34
91
/* Compare null bits */
35
92
if (memcmp(table->null_flags,
186
243
bool using_limit= limit != HA_POS_ERROR;
187
244
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
188
245
bool used_key_is_modified, transactional_table, will_batch;
189
bool can_compare_record;
191
247
int error, loc_error;
192
248
uint used_index= MAX_KEY, dup_key_found;
473
529
while (!(error=info.read_record(&info)) && !thd->killed)
475
531
thd->examined_row_count++;
476
if (!(select && select->skip_record()))
532
bool skip_record= FALSE;
533
if (select && select->skip_record(thd, &skip_record))
536
table->file->unlock_row();
478
541
if (table->file->was_semi_consistent_read())
479
542
continue; /* repeat the read of the same row if it still exists */
568
631
if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
569
632
table->prepare_for_position();
572
We can use compare_record() to optimize away updates if
573
the table handler is returning all columns OR if
574
if all updated columns are read
576
can_compare_record= (!(table->file->ha_table_flags() &
577
HA_PARTIAL_COLUMN_READ) ||
578
bitmap_is_subset(table->write_set, table->read_set));
580
634
while (!(error=info.read_record(&info)) && !thd->killed)
582
636
thd->examined_row_count++;
583
if (!(select && select->skip_record()))
638
if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
585
640
if (table->file->was_semi_consistent_read())
586
641
continue; /* repeat the read of the same row if it still exists */
1195
Implementation of the safe update options during UPDATE IGNORE. This syntax
1196
causes an UPDATE statement to ignore all errors. In safe update mode,
1197
however, we must never ignore the ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE. There
1198
is a special hook in my_message_sql that will otherwise delete all errors
1199
when the IGNORE option is specified.
1201
In the future, all IGNORE handling should be used with this class and all
1202
traces of the hack outlined below should be removed.
1204
- The parser detects IGNORE option and sets thd->lex->ignore= 1
1206
- In JOIN::optimize, if this is set, then
1207
thd->lex->current_select->no_error gets set.
1209
- In my_message_sql(), if the flag above is set then any error is
1210
unconditionally converted to a warning.
1212
We are moving in the direction of using Internal_error_handler subclasses
1213
to do all such error tweaking, please continue this effort if new bugs
1216
class Safe_dml_handler : public Internal_error_handler {
1219
bool m_handled_error;
1222
explicit Safe_dml_handler() : m_handled_error(FALSE) {}
1224
bool handle_error(uint sql_errno,
1225
const char *message,
1226
MYSQL_ERROR::enum_warning_level level,
1229
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR &&
1230
sql_errno == ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE)
1233
thd->main_da.set_error_status(thd, sql_errno, message);
1234
m_handled_error= TRUE;
1240
bool handled_error() { return m_handled_error; }
1245
1250
Setup multi-update handling and call SELECT to do the join
1271
1276
List<Item> total_list;
1273
Safe_dml_handler handler;
1274
bool using_handler= thd->options & OPTION_SAFE_UPDATES;
1276
thd->push_internal_handler(&handler);
1278
1278
res= mysql_select(thd, &select_lex->ref_pointer_array,
1279
1279
table_list, select_lex->with_wild,
1284
1284
OPTION_SETUP_TABLES_DONE,
1285
1285
result, unit, select_lex);
1289
Internal_error_handler *top_handler;
1290
top_handler= thd->pop_internal_handler();
1291
DBUG_ASSERT(&handler == top_handler);
1294
1287
DBUG_PRINT("info",("res: %d report_error: %d", res, (int) thd->is_error()));
1295
1288
res|= thd->is_error();
1297
Todo: remove below code and make Safe_dml_handler do error processing
1298
instead. That way we can return the actual error instead of
1301
if (unlikely(res) && (!using_handler || !handler.handled_error()))
1303
1291
/* If we had a another error reported earlier then this will be ignored */
1304
1292
result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
1754
1742
if (table->status & (STATUS_NULL_ROW | STATUS_UPDATED))
1758
We can use compare_record() to optimize away updates if
1759
the table handler is returning all columns OR if
1760
if all updated columns are read
1762
1745
if (table == table_to_update)
1764
bool can_compare_record;
1765
can_compare_record= (!(table->file->ha_table_flags() &
1766
HA_PARTIAL_COLUMN_READ) ||
1767
bitmap_is_subset(table->write_set,
1769
1747
table->status|= STATUS_UPDATED;
1770
1748
store_record(table,record[1]);
1771
1749
if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset],
1781
1759
table->auto_increment_field_not_null= FALSE;
1783
if (!can_compare_record || compare_record(table))
1761
if (!records_are_comparable(table) || compare_records(table))
1786
1764
if ((error= cur_table->view_check_option(thd, ignore)) !=
2004
1981
if ((local_error = tmp_table->file->ha_rnd_init(1)))
2007
can_compare_record= (!(table->file->ha_table_flags() &
2008
HA_PARTIAL_COLUMN_READ) ||
2009
bitmap_is_subset(table->write_set,
2014
1986
if (thd->killed && trans_safe)
2049
2021
TRG_ACTION_BEFORE, TRUE))
2052
if (!can_compare_record || compare_record(table))
2024
if (!records_are_comparable(table) || compare_records(table))
2055
2027
if ((error= cur_table->view_check_option(thd, ignore)) !=