MCPcopy Create free account
hub / github.com/MariaDB/server / unsafe_key_update

Function unsafe_key_update

sql/sql_update.cc:1495–1567  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

1493 false otherwise.
1494*/
1495static
1496bool 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))

Callers 1

handle_endMethod · 0.85

Calls 6

partition_key_modifiedFunction · 0.85
my_errorFunction · 0.85
bitmap_is_setFunction · 0.85
is_jtbmMethod · 0.80
top_tableMethod · 0.80
rewindMethod · 0.45

Tested by

no test coverage detected