Skip to content

Commit 022ae5b

Browse files
authored
planner/core: fix wrong results caused by rule_project_eliminate for queries with Apply (#67231)
close #67138
1 parent 27f439f commit 022ae5b

3 files changed

Lines changed: 42 additions & 18 deletions

File tree

pkg/planner/core/casetest/rule/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ go_test(
2020
],
2121
data = glob(["testdata/**"]),
2222
flaky = True,
23-
shard_count = 24,
23+
shard_count = 25,
2424
deps = [
2525
"//pkg/config",
2626
"//pkg/domain",

pkg/planner/core/casetest/rule/rule_eliminate_projection_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,52 @@
1515
package rule
1616

1717
import (
18+
"fmt"
19+
"strings"
1820
"testing"
1921

2022
"github.com/pingcap/tidb/pkg/config"
2123
"github.com/pingcap/tidb/pkg/testkit"
24+
"github.com/stretchr/testify/require"
2225
)
2326

27+
func TestWithApply(t *testing.T) {
28+
store := testkit.CreateMockStore(t)
29+
tk := testkit.NewTestKit(t, store)
30+
tk.MustExec("use test")
31+
32+
tk.MustExec("drop table if exists t11, t22")
33+
tk.MustExec("create table t11(id int, name varchar(20))")
34+
tk.MustExec("create table t22(id int, name varchar(20))")
35+
tk.MustExec("insert into t11(id, name) values(1, 'test')")
36+
tk.MustExec("insert into t22(id, name) values(1, 'test')")
37+
38+
sqls := []string{
39+
`with temp as (
40+
select id from t22 order by name
41+
)
42+
select (select name from t11 where id = (case when temp.id = 1 then temp.id else temp.id end)) = 'test'
43+
from temp where id = 1`,
44+
`with temp as (
45+
select id from t22
46+
)
47+
select (select name from t11 where id = (case when temp.id = 1 then temp.id else temp.id end)) = 'test'
48+
from temp where id = 1`,
49+
}
50+
for _, sql := range sqls {
51+
tk.MustQuery(sql).Check(testkit.Rows("1"))
52+
planRows := tk.MustQuery("explain " + sql).Rows()
53+
hasApply := false
54+
for _, row := range planRows {
55+
if strings.Contains(fmt.Sprintf("%v", row), "Apply") {
56+
hasApply = true
57+
break
58+
}
59+
}
60+
require.True(t, hasApply, "plan should contain Apply, sql: %s", sql)
61+
}
62+
}
63+
2464
func TestElinimateProjectionWithExpressionIndex(t *testing.T) {
2565
originCfg := config.GetGlobalConfig()
2666
newCfg := *originCfg

pkg/planner/core/rule_eliminate_projection.go

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -183,23 +183,7 @@ func (pe *ProjectionEliminator) eliminate(p base.LogicalPlan, replace map[string
183183
}
184184
}
185185

186-
// Filter replace map first to make sure the replaced columns
187-
// exist in the child output.
188-
newReplace := make(map[string]*expression.Column, len(replace))
189-
for code, expr := range replace {
190-
childloop:
191-
for _, child := range p.Children() {
192-
for _, schemaCol := range child.Schema().Columns {
193-
if schemaCol.Equal(nil, expr) {
194-
newReplace[code] = expr
195-
break childloop
196-
}
197-
}
198-
}
199-
}
200-
if len(newReplace) > 0 {
201-
p.ReplaceExprColumns(newReplace)
202-
}
186+
p.ReplaceExprColumns(replace)
203187

204188
// eliminate duplicate projection: projection with child projection
205189
if isProj {

0 commit comments

Comments
 (0)