summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-11-25 18:17:28 +0100
committerSergei Golubchik <sergii@pisem.net>2010-11-25 18:17:28 +0100
commit65ca700def99289cc31a7040537f5aa6e12bf485 (patch)
tree97b3a07299b626c519da0e80c122b5b79b933914 /sql/sql_update.cc
parent2ab57de38d13d927ddff2d51aed4af34e13998f5 (diff)
parent6e5bcca7935d3c62f84bb640e5357664a210ee12 (diff)
downloadmariadb-git-65ca700def99289cc31a7040537f5aa6e12bf485.tar.gz
merge.
checkpoint. does not compile.
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc117
1 files changed, 73 insertions, 44 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 68440f6623a..76c90e40b17 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -46,12 +46,12 @@
bool compare_record(TABLE *table)
{
- if (table->s->blob_fields + table->s->varchar_fields == 0)
+ if (table->s->can_cmp_whole_record)
return cmp_record(table,record[1]);
/* Compare null bits */
if (memcmp(table->null_flags,
table->null_flags+table->s->rec_buff_length,
- table->s->null_bytes))
+ table->s->null_bytes_for_compare))
return TRUE; // Diff in NULL value
/* Compare updated fields */
for (Field **ptr= table->field ; *ptr ; ptr++)
@@ -160,7 +160,7 @@ static void prepare_record_for_error_message(int error, TABLE *table)
/* Tell the engine about the new set. */
table->file->column_bitmaps_signal();
/* Read record that is identified by table->file->ref. */
- (void) table->file->rnd_pos(table->record[1], table->file->ref);
+ (void) table->file->ha_rnd_pos(table->record[1], table->file->ref);
/* Copy the newly read columns into the new record. */
for (field_p= table->field; (field= *field_p); field_p++)
if (bitmap_is_set(&unique_map, field->field_index))
@@ -285,8 +285,7 @@ int mysql_update(THD *thd,
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
else
{
- if (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)
+ if (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE)
bitmap_set_bit(table->write_set,
table->timestamp_field->field_index);
}
@@ -320,10 +319,8 @@ int mysql_update(THD *thd,
update force the table handler to retrieve write-only fields to be able
to compare records and detect data change.
*/
- if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
- table->timestamp_field &&
- (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
+ (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE))
bitmap_union(table->read_set, table->write_set);
// Don't count on usage of 'only index' when calculating which key to use
table->covering_keys.clear_all();
@@ -467,7 +464,10 @@ int mysql_update(THD *thd,
*/
if (used_index == MAX_KEY || (select && select->quick))
- init_read_record(&info, thd, table, select, 0, 1, FALSE);
+ {
+ if (init_read_record(&info, thd, table, select, 0, 1, FALSE))
+ goto err;
+ }
else
init_read_record_idx(&info, thd, table, 1, used_index, reverse);
@@ -476,15 +476,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
+ update_virtual_fields(thd, table);
thd->examined_row_count++;
- bool skip_record= FALSE;
- if (select && select->skip_record(thd, &skip_record))
- {
- error= 1;
- table->file->unlock_row();
- break;
- }
- if (!skip_record)
+ if (!select || (error= select->skip_record(thd)) > 0)
{
if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */
@@ -503,7 +497,15 @@ int mysql_update(THD *thd,
}
}
else
+ {
table->file->unlock_row();
+ if (error < 0)
+ {
+ /* Fatal error from select->skip_record() */
+ error= 1;
+ break;
+ }
+ }
}
if (thd->killed && !error)
error= 1; // Aborted
@@ -541,7 +543,8 @@ int mysql_update(THD *thd,
if (select && select->quick && select->quick->reset())
goto err;
table->file->try_semi_consistent_read(1);
- init_read_record(&info, thd, table, select, 0, 1, FALSE);
+ if (init_read_record(&info, thd, table, select, 0, 1, FALSE))
+ goto err;
updated= found= 0;
/*
@@ -590,9 +593,9 @@ int mysql_update(THD *thd,
while (!(error=info.read_record(&info)) && !thd->killed)
{
+ update_virtual_fields(thd, table);
thd->examined_row_count++;
- bool skip_record;
- if (!select || (!select->skip_record(thd, &skip_record) && !skip_record))
+ if (!select || select->skip_record(thd) > 0)
{
if (table->file->was_semi_consistent_read())
continue; /* repeat the read of the same row if it still exists */
@@ -860,7 +863,7 @@ int mysql_update(THD *thd,
err:
delete select;
free_underlaid_joins(thd, select_lex);
- table->set_keyread(FALSE);
+ table->disable_keyread();
thd->abort_on_warning= 0;
DBUG_RETURN(1);
}
@@ -1277,10 +1280,9 @@ int multi_update::prepare(List<Item> &not_used_values,
update force the table handler to retrieve write-only fields to be able
to compare records and detect data change.
*/
- if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
- table->timestamp_field &&
- (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
+ if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
+ (((uint) table->timestamp_field_type) &
+ TIMESTAMP_AUTO_SET_ON_UPDATE))
bitmap_union(table->read_set, table->write_set);
}
}
@@ -1765,15 +1767,17 @@ bool multi_update::send_data(List<Item> &not_used_values)
/* Store regular updated fields in the row. */
fill_record(thd,
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
- *values_for_table[offset], 1);
+ *values_for_table[offset], TRUE, FALSE);
/* Write row, ignoring duplicated updates to a row */
error= tmp_table->file->ha_write_row(tmp_table->record[0]);
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
- create_myisam_from_heap(thd, tmp_table,
- tmp_table_param + offset, error, 1))
+ create_internal_tmp_table_from_heap(thd, tmp_table,
+ tmp_table_param[offset].start_recinfo,
+ &tmp_table_param[offset].recinfo,
+ error, 1))
{
do_update= 0;
DBUG_RETURN(1); // Not a table_is_full error
@@ -1851,7 +1855,7 @@ int multi_update::do_updates()
TABLE_LIST *cur_table;
int local_error= 0;
ha_rows org_updated;
- TABLE *table, *tmp_table;
+ TABLE *table, *tmp_table, *err_table;
List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables);
DBUG_ENTER("multi_update::do_updates");
@@ -1869,14 +1873,21 @@ int multi_update::do_updates()
org_updated= updated;
tmp_table= tmp_tables[cur_table->shared];
tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache
- (void) table->file->ha_rnd_init(0);
+ if ((local_error= table->file->ha_rnd_init(0)))
+ {
+ err_table= table;
+ goto err;
+ }
table->file->extra(HA_EXTRA_NO_CACHE);
check_opt_it.rewind();
while(TABLE *tbl= check_opt_it++)
{
- if (tbl->file->ha_rnd_init(1))
+ if ((local_error= tbl->file->ha_rnd_init(1)))
+ {
+ err_table= tbl;
goto err;
+ }
tbl->file->extra(HA_EXTRA_CACHE);
}
@@ -1884,9 +1895,11 @@ int multi_update::do_updates()
Setup copy functions to copy fields from temporary table
*/
List_iterator_fast<Item> field_it(*fields_for_table[offset]);
- Field **field= tmp_table->field +
- 1 + unupdated_check_opt_tables.elements; // Skip row pointers
+ Field **field;
Copy_field *copy_field_ptr= copy_field, *copy_field_end;
+
+ /* Skip row pointers */
+ field= tmp_table->field + 1 + unupdated_check_opt_tables.elements;
for ( ; *field ; field++)
{
Item_field *item= (Item_field* ) field_it++;
@@ -1894,8 +1907,11 @@ int multi_update::do_updates()
}
copy_field_end=copy_field_ptr;
- if ((local_error = tmp_table->file->ha_rnd_init(1)))
+ if ((local_error= tmp_table->file->ha_rnd_init(1)))
+ {
+ err_table= tmp_table;
goto err;
+ }
can_compare_record= (!(table->file->ha_table_flags() &
HA_PARTIAL_COLUMN_READ) ||
@@ -1905,13 +1921,17 @@ int multi_update::do_updates()
for (;;)
{
if (thd->killed && trans_safe)
- goto err;
- if ((local_error=tmp_table->file->rnd_next(tmp_table->record[0])))
+ {
+ thd->fatal_error();
+ goto err2;
+ }
+ if ((local_error= tmp_table->file->ha_rnd_next(tmp_table->record[0])))
{
if (local_error == HA_ERR_END_OF_FILE)
break;
if (local_error == HA_ERR_RECORD_DELETED)
continue; // May happen on dup key
+ err_table= tmp_table;
goto err;
}
@@ -1921,12 +1941,15 @@ int multi_update::do_updates()
uint field_num= 0;
do
{
- if((local_error=
- tbl->file->rnd_pos(tbl->record[0],
- (uchar *) tmp_table->field[field_num]->ptr)))
+ if ((local_error=
+ tbl->file->ha_rnd_pos(tbl->record[0],
+ (uchar*) tmp_table->field[field_num]->ptr)))
+ {
+ err_table= tbl;
goto err;
+ }
field_num++;
- } while((tbl= check_opt_it++));
+ } while ((tbl= check_opt_it++));
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
@@ -1951,7 +1974,10 @@ int multi_update::do_updates()
if (error == VIEW_CHECK_SKIP)
continue;
else if (error == VIEW_CHECK_ERROR)
- goto err;
+ {
+ thd->fatal_error();
+ goto err2;
+ }
}
if ((local_error=table->file->ha_update_row(table->record[1],
table->record[0])) &&
@@ -1959,7 +1985,10 @@ int multi_update::do_updates()
{
if (!ignore ||
table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY))
+ {
+ err_table= table;
goto err;
+ }
}
if (local_error != HA_ERR_RECORD_IS_THE_SAME)
updated++;
@@ -1994,8 +2023,8 @@ int multi_update::do_updates()
err:
{
- prepare_record_for_error_message(local_error, table);
- table->file->print_error(local_error,MYF(ME_FATALERROR));
+ prepare_record_for_error_message(local_error, err_table);
+ err_table->file->print_error(local_error,MYF(ME_FATALERROR));
}
err2: