Details
- 
    
Bug
 - 
    Status: Open (View Workflow)
 - 
    
Major
 - 
    Resolution: Unresolved
 - 
    10.11.4
 - 
    None
 
Description
Performing an ordered multi-table update uses values from unrelated rows for the assignment.
Setup:
					MariaDB [test]> CREATE TABLE x (id INT PRIMARY KEY AUTO_INCREMENT, filter INT, INDEX filter(filter));  | 
		
					Query OK, 0 rows affected (0.022 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> CREATE TABLE y (id INT PRIMARY KEY AUTO_INCREMENT, x_id INT REFERENCES x(id), val FLOAT);  | 
		
					Query OK, 0 rows affected (0.028 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> INSERT INTO x VALUES (1,1), (2,2), (3,3);  | 
		
					Query OK, 3 rows affected (0.009 sec)  | 
		
					Records: 3  Duplicates: 0  Warnings: 0
			 | 
		
| 
					 | 
		
					MariaDB [test]> INSERT INTO y VALUES (1,1,123), (2,2,234), (3,3,345);  | 
		
					Query OK, 3 rows affected (0.001 sec)  | 
		
					Records: 3  Duplicates: 0  Warnings: 0
			 | 
		
Working version, without `ORDER BY`:
					MariaDB [test]> BEGIN;  | 
		
					Query OK, 0 rows affected (0.000 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> SELECT * FROM y;  | 
		
					+----+------+------+  | 
		
					| id | x_id | val  |
			 | 
		
					+----+------+------+  | 
		
					|  1 |    1 |  123 |
			 | 
		
					|  2 |    2 |  234 |
			 | 
		
					|  3 |    3 |  345 |
			 | 
		
					+----+------+------+  | 
		
					3 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> EXPLAIN UPDATE y INNER JOIN x ON x.id = y.x_id SET y.val = y.val / 100 WHERE x.filter = 2;  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+-------------+  | 
		
					| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+-------------+  | 
		
					| 1 | SIMPLE | x | ref | PRIMARY,filter | filter | 5 | const | 1 | Using index |  | 
		
					| 1 | SIMPLE | y | ALL | x_id | NULL | NULL | NULL | 3 | Using where |  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+-------------+  | 
		
					2 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> UPDATE y INNER JOIN x ON x.id = y.x_id SET y.val = y.val / 100 WHERE x.filter = 2;  | 
		
					Query OK, 1 row affected (0.001 sec)
			 | 
		
					Rows matched: 1 Changed: 1 Warnings: 0  | 
		
| 
					 | 
		
					MariaDB [test]> SELECT * FROM y;  | 
		
					+----+------+------+  | 
		
					| id | x_id | val  |
			 | 
		
					+----+------+------+  | 
		
					|  1 |    1 |  123 |
			 | 
		
					|  2 |    2 | 2.34 |
			 | 
		
					|  3 |    3 |  345 |
			 | 
		
					+----+------+------+  | 
		
					3 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> ROLLBACK;  | 
		
					Query OK, 0 rows affected (0.001 sec)  | 
		
Broken version, with `ORDER BY`:
					MariaDB [test]> BEGIN;  | 
		
					Query OK, 0 rows affected (0.000 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> SELECT * FROM y;  | 
		
					+----+------+------+  | 
		
					| id | x_id | val  |
			 | 
		
					+----+------+------+  | 
		
					|  1 |    1 |  123 |
			 | 
		
					|  2 |    2 |  234 |
			 | 
		
					|  3 |    3 |  345 |
			 | 
		
					+----+------+------+  | 
		
					3 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> EXPLAIN UPDATE y INNER JOIN x ON x.id = y.x_id SET y.val = y.val / 100 WHERE x.filter = 2 ORDER BY y.val;  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+----------------------------------------------+  | 
		
					| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+----------------------------------------------+  | 
		
					| 1 | SIMPLE | x | ref | PRIMARY,filter | filter | 5 | const | 1 | Using index; Using temporary; Using filesort |  | 
		
					| 1 | SIMPLE | y | ALL | x_id | NULL | NULL | NULL | 3 | Using where |  | 
		
					+------+-------------+-------+------+----------------+--------+---------+-------+------+----------------------------------------------+  | 
		
					2 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> UPDATE y INNER JOIN x ON x.id = y.x_id SET y.val = y.val / 100 WHERE x.filter = 2 ORDER BY y.val;  | 
		
					Query OK, 1 row affected (0.001 sec)
			 | 
		
					Rows matched: 1 Changed: 1 Warnings: 0  | 
		
| 
					 | 
		
					MariaDB [test]> SELECT * FROM y;  | 
		
					+----+------+------+  | 
		
					| id | x_id | val  |
			 | 
		
					+----+------+------+  | 
		
					|  1 |    1 |  123 |
			 | 
		
					|  2 |    2 | 3.45 |
			 | 
		
					|  3 |    3 |  345 |
			 | 
		
					+----+------+------+  | 
		
					3 rows in set (0.001 sec)  | 
		
| 
					 | 
		
					MariaDB [test]> ROLLBACK;  | 
		
					Query OK, 0 rows affected (0.000 sec)  | 
		
Notice how the update including the `ORDER BY` clause updates the `val` for the row with id 2 using the `val` from the row with id 3, which, to my understanding, should not be included in the query at all given the filter conditions in the `WHERE` and `ON` clauses.
Attachments
Issue Links
- relates to
 - 
                    
MDEV-24961 Multi-table UPDATE does not consider ORDER BY clause
-         
 - Closed
 
 -