diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-11-25 18:17:28 +0100 |
commit | 65ca700def99289cc31a7040537f5aa6e12bf485 (patch) | |
tree | 97b3a07299b626c519da0e80c122b5b79b933914 /sql/sql_update.cc | |
parent | 2ab57de38d13d927ddff2d51aed4af34e13998f5 (diff) | |
parent | 6e5bcca7935d3c62f84bb640e5357664a210ee12 (diff) | |
download | mariadb-git-65ca700def99289cc31a7040537f5aa6e12bf485.tar.gz |
merge.
checkpoint.
does not compile.
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r-- | sql/sql_update.cc | 117 |
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> ¬_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> ¬_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: |