If one row is updated through two different aliases and the first update physically moves the row, the second update will error because the row is no longer located where expected. This function checks if the multiple-table update is about to do that and if so returns with an error. The following update operations physically moves rows: 1) Update of a column in a clustered primary k
| 1493 | false otherwise. |
| 1494 | */ |
| 1495 | static |
| 1496 | bool unsafe_key_update(List<TABLE_LIST> leaves, table_map tables_for_update) |
| 1497 | { |
| 1498 | List_iterator_fast<TABLE_LIST> it(leaves), it2(leaves); |
| 1499 | TABLE_LIST *tl, *tl2; |
| 1500 | |
| 1501 | while ((tl= it++)) |
| 1502 | { |
| 1503 | if (!tl->is_jtbm() && (tl->table->map & tables_for_update)) |
| 1504 | { |
| 1505 | TABLE *table1= tl->table; |
| 1506 | bool primkey_clustered= (table1->file-> |
| 1507 | pk_is_clustering_key(table1->s->primary_key)); |
| 1508 | |
| 1509 | bool table_partitioned= false; |
| 1510 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
| 1511 | table_partitioned= (table1->part_info != NULL); |
| 1512 | #endif |
| 1513 | |
| 1514 | if (!table_partitioned && !primkey_clustered) |
| 1515 | continue; |
| 1516 | |
| 1517 | it2.rewind(); |
| 1518 | while ((tl2= it2++)) |
| 1519 | { |
| 1520 | if (tl2->is_jtbm()) |
| 1521 | continue; |
| 1522 | /* |
| 1523 | Look at "next" tables only since all previous tables have |
| 1524 | already been checked |
| 1525 | */ |
| 1526 | TABLE *table2= tl2->table; |
| 1527 | if (tl2 != tl && |
| 1528 | table2->map & tables_for_update && table1->s == table2->s) |
| 1529 | { |
| 1530 | // A table is updated through two aliases |
| 1531 | if (table_partitioned && |
| 1532 | (partition_key_modified(table1, table1->write_set) || |
| 1533 | partition_key_modified(table2, table2->write_set))) |
| 1534 | { |
| 1535 | // Partitioned key is updated |
| 1536 | my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0), |
| 1537 | tl->top_table()->alias.str, |
| 1538 | tl2->top_table()->alias.str); |
| 1539 | return true; |
| 1540 | } |
| 1541 | |
| 1542 | if (primkey_clustered) |
| 1543 | { |
| 1544 | // The primary key can cover multiple columns |
| 1545 | KEY key_info= table1->key_info[table1->s->primary_key]; |
| 1546 | KEY_PART_INFO *key_part= key_info.key_part; |
| 1547 | KEY_PART_INFO *key_part_end= key_part + key_info.user_defined_key_parts; |
| 1548 | |
| 1549 | for (;key_part != key_part_end; ++key_part) |
| 1550 | { |
| 1551 | if (bitmap_is_set(table1->write_set, key_part->fieldnr-1) || |
| 1552 | bitmap_is_set(table2->write_set, key_part->fieldnr-1)) |
no test coverage detected