Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong result when update multiple columns with CTE #43645

Closed
harry1129 opened this issue May 9, 2023 · 4 comments · Fixed by #43759
Closed

Wrong result when update multiple columns with CTE #43645

harry1129 opened this issue May 9, 2023 · 4 comments · Fixed by #43759

Comments

@harry1129
Copy link

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

DROP TABLE t1,t2;
CREATE TABLE t1(id int,col1 varchar(10),col2 varchar(10),col3 varchar(10));
CREATE TABLE t2(id int,col1 varchar(10),col2 varchar(10),col3 varchar(10));

INSERT INTO t1 values(1,NULL,NULL,null),(2,NULL,NULL,null),(3,NULL,NULL,null);
INSERT INTO t2 values(1,'a','aa','aaa'),(2,'b','bb','bbb'),(3,'c','cc','ccc');


WITH tmp AS (SELECT t2.* FROM t2)
UPDATE t1 SET
t1.col1=(SELECT tmp.col1 FROM tmp WHERE tmp.id=t1.id ),
t1.col2=(SELECT tmp.col2 FROM tmp WHERE tmp.id=t1.id ),
t1.col3=(SELECT tmp.col3 FROM tmp WHERE tmp.id=t1.id )
;

2. What did you expect to see? (Required)

MySQL [test]> select * from t1;
+------+------+------+------+
| id   | col1 | col2 | col3 |
+------+------+------+------+
|    1 | a    | aa   | aaa  |
|    2 | b    | bb   | bbb  |
|    3 | c    | cc   | ccc  |
+------+------+------+------+
3 rows in set (0.00 sec)

3. What did you see instead (Required)

mysql> select * from t1;
+------+------+------+------+
| id   | col1 | col2 | col3 |
+------+------+------+------+
|    1 | a    | NULL | NULL |
|    2 | b    | NULL | NULL |
|    3 | c    | cc   | ccc  |
+------+------+------+------+
3 rows in set (0.00 sec)

4. What is your TiDB version? (Required)

This problem can be reproduced in v6.1.6 and v6.5.2.

MySQL [test]> select tidb_version()\G
*************************** 1. row ***************************
tidb_version(): Release Version: v6.5.2
Edition: Community
Git Commit Hash: 29116c0256c52b224da2b34d712c1063d171c0ad
Git Branch: heads/refs/tags/v6.5.2
UTC Build Time: 2023-04-19 10:52:06
GoVersion: go1.19.8
Race Enabled: false
TiKV Min Version: 6.2.0-alpha
Check Table Before Drop: false
Store: tikv
1 row in set (0.00 sec)
mysql> select tidb_version()\G
*************************** 1. row ***************************
tidb_version(): Release Version: v6.1.6
Edition: Community
Git Commit Hash: 705abbd2e2f00c3386bf284654c746521ab26444
Git Branch: heads/refs/tags/v6.1.6
UTC Build Time: 2023-04-06 10:20:29
GoVersion: go1.19.7
Race Enabled: false
TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306
Check Table Before Drop: false
1 row in set (0.00 sec)
@harry1129 harry1129 added the type/bug The issue is confirmed as a bug. label May 9, 2023
@ti-chi-bot ti-chi-bot bot added may-affects-5.1 This bug maybe affects 5.1.x versions. may-affects-5.2 This bug maybe affects 5.2.x versions. may-affects-5.3 This bug maybe affects 5.3.x versions. may-affects-5.4 This bug maybe affects 5.4.x versions. may-affects-6.1 may-affects-6.5 may-affects-7.1 labels May 10, 2023
@seiya-annie seiya-annie added the sig/execution SIG execution label May 10, 2023
@windtalker
Copy link
Contributor

Seems related to CTE

mysql>  select (SELECT tmp.col1 FROM t2 tmp WHERE tmp.id=t1.id ) col1, (SELECT tmp.col2 FROM t2 tmp WHERE tmp.id=t1.id ) col2, (SELECT tmp.col3 FROM t2 tmp WHERE tmp.id=t1.id ) col3 from t1;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| a    | aa   | aaa  |
| b    | bb   | bbb  |
| c    | cc   | ccc  |
+------+------+------+
3 rows in set (0.01 sec)

mysql>  WITH tmp AS (SELECT t2.* FROM t2) select (SELECT tmp.col1 FROM tmp WHERE tmp.id=t1.id ) col1, (SELECT tmp.col2 FROM tmp WHERE tmp.id=t1.id ) col2, (SELECT tmp.col3 FROM tmp WHERE tmp.id=t1.id ) col3 from t1;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
| a    | aa   | aaa  |
| NULL | NULL | NULL |
| NULL | NULL | NULL |
+------+------+------+
3 rows in set (0.01 sec)

@seiya-annie seiya-annie added sig/sql-infra SIG: SQL Infra and removed sig/execution SIG execution labels May 10, 2023
@pcqz
Copy link

pcqz commented May 10, 2023

May introduced by #33158

@guo-shaoge
Copy link
Collaborator

guo-shaoge commented May 11, 2023

Although Selection_17 in CTE_0 is correlated, but CTE_0 will only execute once. Because there are correlated cols in Selection_17, but we miss updating cte.IsInApply when push down Selection to CTE. /cc @wjhuang2016

MySQL [test]> explain WITH tmp AS (SELECT t2.* FROM t2)
    -> UPDATE t1 SET
    -> t1.col1=(SELECT tmp.col1 FROM tmp WHERE tmp.id=t1.id ),
    -> t1.col2=(SELECT tmp.col2 FROM tmp WHERE tmp.id=t1.id );
+-----------------------------------+-------------+-----------+---------------+------------------------------------------------------------+
| id                                | estRows     | task      | access object | operator info                                              |
+-----------------------------------+-------------+-----------+---------------+------------------------------------------------------------+
| Update_15                         | N/A         | root      |               | N/A                                                        |
| └─Apply_22                        | 10000.00    | root      |               | CARTESIAN left outer join                                  |
|   ├─Apply_24(Build)               | 10000.00    | root      |               | CARTESIAN left outer join                                  |
|   │ ├─TableReader_27(Build)       | 10000.00    | root      |               | data:TableFullScan_26                                      |
|   │ │ └─TableFullScan_26          | 10000.00    | cop[tikv] | table:t1      | keep order:false, stats:pseudo                             |
|   │ └─MaxOneRow_28(Probe)         | 10000.00    | root      |               |                                                            |
|   │   └─Projection_29             | 20000.00    | root      |               | test.t2.col1                                               |
|   │     └─Selection_30            | 20000.00    | root      |               | eq(test.t2.id, test.t1.id)                                 |
|   │       └─CTEFullScan_31        | 80000000.00 | root      | CTE:tmp       | data:CTE_0                                                 |
|   └─MaxOneRow_32(Probe)           | 10000.00    | root      |               |                                                            |
|     └─Projection_33               | 20000.00    | root      |               | test.t2.col2                                               |
|       └─Selection_34              | 20000.00    | root      |               | eq(test.t2.id, test.t1.id)                                 |
|         └─CTEFullScan_35          | 80000000.00 | root      | CTE:tmp       | data:CTE_0                                                 |
| CTE_0                             | 8000.00     | root      |               | Non-Recursive CTE                                          |
| └─Selection_17(Seed Part)         | 8000.00     | root      |               | or(eq(test.t2.id, test.t1.id), eq(test.t2.id, test.t1.id)) |
|   └─TableReader_20                | 10000.00    | root      |               | data:TableFullScan_19                                      |
|     └─TableFullScan_19            | 10000.00    | cop[tikv] | table:t2      | keep order:false, stats:pseudo                             |
+-----------------------------------+-------------+-----------+---------------+------------------------------------------------------------+
17 rows in set (0.003 sec)

@guo-shaoge
Copy link
Collaborator

Also the correlated column in Selection_17 is wrong, it should point to the result row of Apply_24 instead of the result of TableReader_27

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants