| 249 | */ |
| 250 | |
| 251 | static void prepare_record_for_error_message(int error, TABLE *table) |
| 252 | { |
| 253 | Field **field_p; |
| 254 | Field *field; |
| 255 | uint keynr; |
| 256 | MY_BITMAP unique_map; /* Fields in offended unique. */ |
| 257 | my_bitmap_map unique_map_buf[bitmap_buffer_size(MAX_FIELDS)/sizeof(my_bitmap_map)]; |
| 258 | DBUG_ENTER("prepare_record_for_error_message"); |
| 259 | |
| 260 | /* |
| 261 | Only duplicate key errors print the key value. |
| 262 | If storage engine does always read all columns, we have the value already. |
| 263 | */ |
| 264 | if ((error != HA_ERR_FOUND_DUPP_KEY) || |
| 265 | !(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)) |
| 266 | DBUG_VOID_RETURN; |
| 267 | |
| 268 | /* |
| 269 | Get the number of the offended index. |
| 270 | We will see MAX_KEY if the engine cannot determine the affected index. |
| 271 | */ |
| 272 | if (unlikely((keynr= table->file->get_dup_key(error)) >= MAX_KEY)) |
| 273 | DBUG_VOID_RETURN; |
| 274 | |
| 275 | /* Create unique_map with all fields used by that index. */ |
| 276 | my_bitmap_init(&unique_map, unique_map_buf, table->s->fields); |
| 277 | table->mark_index_columns(keynr, &unique_map); |
| 278 | |
| 279 | /* Subtract read_set and write_set. */ |
| 280 | bitmap_subtract(&unique_map, table->read_set); |
| 281 | bitmap_subtract(&unique_map, table->write_set); |
| 282 | |
| 283 | /* |
| 284 | If the unique index uses columns that are neither in read_set |
| 285 | nor in write_set, we must re-read the record. |
| 286 | Otherwise no need to do anything. |
| 287 | */ |
| 288 | if (bitmap_is_clear_all(&unique_map)) |
| 289 | DBUG_VOID_RETURN; |
| 290 | |
| 291 | /* Get identifier of last read record into table->file->ref. */ |
| 292 | table->file->position(table->record[0]); |
| 293 | /* Add all fields used by unique index to read_set. */ |
| 294 | bitmap_union(table->read_set, &unique_map); |
| 295 | /* Tell the engine about the new set. */ |
| 296 | table->file->column_bitmaps_signal(false); |
| 297 | |
| 298 | if ((error= table->file->ha_index_or_rnd_end()) || |
| 299 | (error= table->file->ha_rnd_init(0))) |
| 300 | { |
| 301 | table->file->print_error(error, MYF(0)); |
| 302 | DBUG_VOID_RETURN; |
| 303 | } |
| 304 | |
| 305 | /* Read record that is identified by table->file->ref. */ |
| 306 | (void) table->file->ha_rnd_pos(table->record[1], table->file->ref); |
| 307 | /* Copy the newly read columns into the new record. */ |
| 308 | for (field_p= table->field; (field= *field_p); field_p++) |
no test coverage detected