Skip to content

Commit

Permalink
planner: fix name ambiguous check when building natural join without …
Browse files Browse the repository at this point in the history
…filter (#36012) (#50904)

close #32044
  • Loading branch information
ti-chi-bot authored Feb 19, 2024
1 parent 081ea9a commit d686efd
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pkg/executor/test/jointest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ go_test(
],
flaky = True,
race = "on",
shard_count = 13,
shard_count = 14,
deps = [
"//pkg/config",
"//pkg/meta/autoid",
Expand Down
25 changes: 25 additions & 0 deletions pkg/executor/test/jointest/join_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,31 @@ import (
"github.com/stretchr/testify/require"
)

func TestIssue30244(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("use test;")
tk.MustExec("drop table if exists t1,t2,t3,t4;")
tk.MustExec("create table t1 (c int, b int);")
tk.MustExec("create table t2 (a int, b int);")
tk.MustExec("create table t3 (b int, c int);")
tk.MustExec("create table t4 (y int, c int);")

err := tk.ExecToErr("select * from t1 natural join (t3 cross join t4);")
require.NotNil(t, err)
require.Equal(t, err.Error(), "[planner:1052]Column 'c' in from clause is ambiguous")
err = tk.ExecToErr("select * from (t3 cross join t4) natural join t1;")
require.NotNil(t, err)
require.Equal(t, err.Error(), "[planner:1052]Column 'c' in from clause is ambiguous")
err = tk.ExecToErr("select * from (t1 join t2 on t1.b=t2.b) natural join (t3 natural join t4);")
require.NotNil(t, err)
require.Equal(t, err.Error(), "[planner:1052]Column 'b' in from clause is ambiguous")
err = tk.ExecToErr("select * from (t3 natural join t4) natural join (t1 join t2 on t1.b=t2.b);")
require.NotNil(t, err)
require.Equal(t, err.Error(), "[planner:1052]Column 'b' in from clause is ambiguous")
}

func TestJoinInDisk(t *testing.T) {
origin := config.RestoreFunc()
defer origin()
Expand Down
46 changes: 46 additions & 0 deletions pkg/planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,52 @@ func (b *PlanBuilder) coalesceCommonColumns(p *LogicalJoin, leftPlan, rightPlan
if err != nil {
return err
}
} else {
// Even with no using filter, we still should check the checkAmbiguous name before we try to find the common column from both side.
// (t3 cross join t4) natural join t1
// t1 natural join (t3 cross join t4)
// t3 and t4 may generate the same name column from cross join.
// for every common column of natural join, the name from right or left should be exactly one.
commonNames := make([]string, 0, len(lNames))
lNameMap := make(map[string]int, len(lNames))
rNameMap := make(map[string]int, len(rNames))
for _, name := range lNames {
// Natural join should ignore _tidb_rowid
if name.ColName.L == "_tidb_rowid" {
continue
}
// record left map
if cnt, ok := lNameMap[name.ColName.L]; ok {
lNameMap[name.ColName.L] = cnt + 1
} else {
lNameMap[name.ColName.L] = 1
}
}
for _, name := range rNames {
// Natural join should ignore _tidb_rowid
if name.ColName.L == "_tidb_rowid" {
continue
}
// record right map
if cnt, ok := rNameMap[name.ColName.L]; ok {
rNameMap[name.ColName.L] = cnt + 1
} else {
rNameMap[name.ColName.L] = 1
}
// check left map
if cnt, ok := lNameMap[name.ColName.L]; ok {
if cnt > 1 {
return ErrAmbiguous.GenWithStackByArgs(name.ColName.L, "from clause")
}
commonNames = append(commonNames, name.ColName.L)
}
}
// check right map
for _, commonName := range commonNames {
if rNameMap[commonName] > 1 {
return ErrAmbiguous.GenWithStackByArgs(commonName, "from clause")
}
}
}

// Find out all the common columns and put them ahead.
Expand Down

0 comments on commit d686efd

Please sign in to comment.