executor: fix wrong result of delete multiple tables using left join (#33055)
close pingcap/tidb#31321
This commit is contained in:
@ -159,6 +159,9 @@ func (e *DeleteExec) doBatchDelete(ctx context.Context) error {
|
||||
func (e *DeleteExec) composeTblRowMap(tblRowMap tableRowMapType, colPosInfos []plannercore.TblColPosInfo, joinedRow []types.Datum) error {
|
||||
// iterate all the joined tables, and got the copresonding rows in joinedRow.
|
||||
for _, info := range colPosInfos {
|
||||
if unmatchedOuterRow(info, joinedRow) {
|
||||
continue
|
||||
}
|
||||
if tblRowMap[info.TblID] == nil {
|
||||
tblRowMap[info.TblID] = kv.NewHandleMap()
|
||||
}
|
||||
|
||||
@ -8521,3 +8521,33 @@ func (s *testSuite1) TestBitColumnIn(c *C) {
|
||||
tk.MustExec("insert into t values (65)")
|
||||
tk.MustQuery("select * from t where id not in (-1,2)").Check(testkit.Rows("\x00A"))
|
||||
}
|
||||
|
||||
func (s *testSuite) TestDeleteWithMulTbl(c *C) {
|
||||
tk := testkit.NewTestKit(c, s.store)
|
||||
|
||||
// Delete multiple tables from left joined table.
|
||||
// The result of left join is (3, null, null).
|
||||
// Because rows in t2 are not matched, so no row will be deleted in t2.
|
||||
// But row in t1 is matched, so it should be deleted.
|
||||
tk.MustExec("use test;")
|
||||
tk.MustExec("drop table if exists t1, t2;")
|
||||
tk.MustExec("create table t1 (c1 int);")
|
||||
tk.MustExec("create table t2 (c1 int primary key, c2 int);")
|
||||
tk.MustExec("insert into t1 values(3);")
|
||||
tk.MustExec("insert into t2 values(2, 2);")
|
||||
tk.MustExec("insert into t2 values(0, 0);")
|
||||
tk.MustExec("delete from t1, t2 using t1 left join t2 on t1.c1 = t2.c2;")
|
||||
tk.MustQuery("select * from t1 order by c1;").Check(testkit.Rows())
|
||||
tk.MustQuery("select * from t2 order by c1;").Check(testkit.Rows("0 0", "2 2"))
|
||||
|
||||
// Rows in both t1 and t2 are matched, so will be deleted even if it's null.
|
||||
// NOTE: The null values are not generated by join.
|
||||
tk.MustExec("drop table if exists t1, t2;")
|
||||
tk.MustExec("create table t1 (c1 int);")
|
||||
tk.MustExec("create table t2 (c2 int);")
|
||||
tk.MustExec("insert into t1 values(null);")
|
||||
tk.MustExec("insert into t2 values(null);")
|
||||
tk.MustExec("delete from t1, t2 using t1 join t2 where t1.c1 is null;")
|
||||
tk.MustQuery("select * from t1;").Check(testkit.Rows())
|
||||
tk.MustQuery("select * from t2;").Check(testkit.Rows())
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ func (e *UpdateExec) prepare(row []types.Datum) (err error) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if e.unmatchedOuterRow(content, row) {
|
||||
if unmatchedOuterRow(content, row) {
|
||||
updatable = false
|
||||
}
|
||||
e.tableUpdatable = append(e.tableUpdatable, updatable)
|
||||
@ -211,7 +211,7 @@ func (e *UpdateExec) exec(ctx context.Context, schema *expression.Schema, row, n
|
||||
// the inner handle field is filled with a NULL value.
|
||||
//
|
||||
// This fixes: https://github.com/pingcap/tidb/issues/7176.
|
||||
func (e *UpdateExec) unmatchedOuterRow(tblPos plannercore.TblColPosInfo, waitUpdateRow []types.Datum) bool {
|
||||
func unmatchedOuterRow(tblPos plannercore.TblColPosInfo, waitUpdateRow []types.Datum) bool {
|
||||
firstHandleIdx := tblPos.HandleCols.GetCol(0)
|
||||
return waitUpdateRow[firstHandleIdx.Index].IsNull()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user