Skip to content

Commit

Permalink
executor: fix wrong result of delete multiple tables using left join (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
guo-shaoge authored Mar 16, 2022
1 parent ef8c858 commit 2dd0074
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
3 changes: 3 additions & 0 deletions executor/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
30 changes: 30 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
4 changes: 2 additions & 2 deletions executor/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
}
Expand Down

0 comments on commit 2dd0074

Please sign in to comment.