Repository: pingcap/tidb (go)

Issue:
flaky assert "assert failed, TS used in import should in [now-1d, now]"
## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

<!-- a step by step guide for reproducing the bug. -->
in real-tikv test, the clock might out of sync between tidb and pd, so this check fails
```
[2024/12/20 10:33:01.029 +00:00] [ERROR] [wait_group_wrapper.go:246] ["panic in error group"] [recover="assert failed, TS used in import should in [now-1d, now], but got 454738780250439970"]


454738780250439970 is 2024-12-20 18:33:01.595000
```

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

### 3. What did you see instead (Required)

### 4. What is your TiDB version? (Required)
master
<!-- Paste the output of SELECT tidb_version() -->



Pull request:
lightning: adjust TS assertion range between TiDB and PD
<!--

Thank you for contributing to TiDB!

PR Title Format:
1. pkg [, pkg2, pkg3]: what's changed
2. *: what's changed

-->

### What problem does this PR solve?
<!--

Please create an issue first to describe the problem.

There MUST be one line starting with "Issue Number:  " and
linking the relevant issues via the "close" or "ref".

For more info, check https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/contribute-code.html#referring-to-an-issue.

-->

Issue Number: close #58449
Problem Summary:

Timestamp assertion was flaky due to minor clock drift between TiDB and PD.



### What changed and how does it work?

Expanded the range to tolerate minor differences, allowing timestamps up to 1 hour in the future and 24 hours in the past.

### Check List

Tests <!-- At least one of them must be included. -->

- [ ] Unit test
- [ ] Integration test
- [ ] Manual test (add detailed scripts or steps below)
- [x] No need to test
  > - [ ] I checked and no code files have been changed.
  > <!-- Or your custom  "No need to test" reasons -->

I’d greatly appreciate it if you could suggest a good place to add tests, if needed!

Side effects

- [ ] Performance regression: Consumes more CPU
- [ ] Performance regression: Consumes more Memory
- [ ] Breaking backward compatibility

Documentation

- [ ] Affects user behaviors
- [ ] Contains syntax changes
- [ ] Contains variable changes
- [ ] Contains experimental features
- [ ] Changes MySQL compatibility

### Release note

<!-- compatibility change, improvement, bugfix, and new feature need a release note -->

Please refer to [Release Notes Language Style Guide](https://pingcap.github.io/tidb-dev-guide/contribute-to-tidb/release-notes-style-guide.html) to write a quality release note.

```release-note
Fix flaky assert by adjusting the TS range
```


Patch:
diff --git a/.bazelrc b/.bazelrc
index a8227f6e53..778350123b 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -19,6 +19,7 @@ test:ci --verbose_failures --test_verbose_timeout_warnings
 test:ci --test_env=GO_TEST_WRAP_TESTV=1
 test:ci --experimental_ui_max_stdouterr_bytes=268435456
 test:ci --test_timeout=150,300,900,3600
+test:ci --flaky_test_attempts=5
 test:race --test_timeout=1200,6000,18000,72000
 
 try-import /data/bazel
diff --git a/WORKSPACE b/WORKSPACE
index e3ffd55d8c..39aad92a63 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -37,12 +37,12 @@ versions.check(minimum_bazel_version = "6.0.0")
 
 http_archive(
     name = "io_bazel_rules_go",
-    sha256 = "f4a9314518ca6acfa16cc4ab43b0b8ce1e4ea64b81c38d8a3772883f153346b8",
+    sha256 = "0936c9bc3c4321ee372cb8f66dd972d368cb940ed01a9ba9fd7debcf0093f09b",
     urls = [
-        "http://bazel-cache.pingcap.net:8080/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
-        "http://ats.apps.svc/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
-        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
-        "https://github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
+        "http://bazel-cache.pingcap.net:8080/bazelbuild/rules_go/releases/download/v0.51.0/rules_go-v0.51.0.zip",
+        "http://ats.apps.svc/bazelbuild/rules_go/releases/download/v0.51.0/rules_go-v0.51.0.zip",
+        "https://cache.hawkingrei.com/bazelbuild/rules_go/releases/download/v0.51.0/rules_go-v0.51.0.zip",
+        "https://github.com/bazelbuild/rules_go/releases/download/v0.51.0/rules_go-v0.51.0.zip",
     ],
 )
 
diff --git a/br/pkg/rtree/rtree.go b/br/pkg/rtree/rtree.go
index aefa1343d4..688c7c2382 100644
--- a/br/pkg/rtree/rtree.go
+++ b/br/pkg/rtree/rtree.go
@@ -278,7 +278,9 @@ func (rangeTree *RangeTree) GetIncompleteRange(
 	if len(startKey) != 0 && bytes.Equal(startKey, endKey) {
 		return []Range{}
 	}
-	incomplete := make([]Range, 0, 64)
+	// Don't use a large buffer, because it will cause memory issue.
+	// And the number of missing ranges is usually small.
+	incomplete := make([]Range, 0, 1)
 	requestRange := Range{StartKey: startKey, EndKey: endKey}
 	lastEndKey := startKey
 	pviot := &Range{StartKey: startKey}
diff --git a/pkg/ddl/partition.go b/pkg/ddl/partition.go
index 42313a931b..aff25aae73 100644
--- a/pkg/ddl/partition.go
+++ b/pkg/ddl/partition.go
@@ -445,11 +445,7 @@ func checkPartitionReplica(replicaCount uint64, addingDefinitions []model.Partit
 		// For every region in the partition, if it has some corresponding peers and
 		// no pending peers, that means the replication has completed.
 		for _, region := range regions {
-			regionState, err := pdCli.GetRegionByID(ctx, region.Meta.Id)
-			if err != nil {
-				return needWait, errors.Trace(err)
-			}
-			tiflashPeerAtLeastOne := checkTiFlashPeerStoreAtLeastOne(stores, regionState.Meta.Peers)
+			tiflashPeerAtLeastOne := checkTiFlashPeerStoreAtLeastOne(stores, region.Meta.Peers)
 			failpoint.Inject("ForceTiflashNotAvailable", func(v failpoint.Value) {
 				tiflashPeerAtLeastOne = v.(bool)
 			})
diff --git a/pkg/domain/domain.go b/pkg/domain/domain.go
index 174c2cb22d..adf850f6a7 100644
--- a/pkg/domain/domain.go
+++ b/pkg/domain/domain.go
@@ -146,7 +146,7 @@ type Domain struct {
 	store           kv.Storage
 	infoCache       *infoschema.InfoCache
 	privHandle      *privileges.Handle
-	bindHandle      bindinfo.GlobalBindingHandle
+	bindHandle      atomic.Value
 	statsHandle     atomic.Pointer[handle.Handle]
 	statsLease      time.Duration
 	ddl             ddl.DDL
@@ -2080,13 +2080,17 @@ func (do *Domain) PrivilegeHandle() *privileges.Handle {
 
 // BindHandle returns domain's bindHandle.
 func (do *Domain) BindHandle() bindinfo.GlobalBindingHandle {
-	return do.bindHandle
+	v := do.bindHandle.Load()
+	if v == nil {
+		return nil
+	}
+	return v.(bindinfo.GlobalBindingHandle)
 }
 
 // InitBindingHandle create a goroutine loads BindInfo in a loop, it should
 // be called only once in BootstrapSession.
 func (do *Domain) InitBindingHandle() error {
-	do.bindHandle = bindinfo.NewGlobalBindingHandle(do.sysSessionPool)
+	do.bindHandle.Store(bindinfo.NewGlobalBindingHandle(do.sysSessionPool))
 	err := do.BindHandle().LoadFromStorageToCache(true)
 	if err != nil || bindinfo.Lease == 0 {
 		return err
diff --git a/pkg/domain/domainctx.go b/pkg/domain/domainctx.go
index 55e96cd48d..18ec7769ee 100644
--- a/pkg/domain/domainctx.go
+++ b/pkg/domain/domainctx.go
@@ -18,26 +18,11 @@ import (
 	contextutil "github.com/pingcap/tidb/pkg/util/context"
 )
 
-// domainKeyType is a dummy type to avoid naming collision in context.
-type domainKeyType int
-
-// String defines a Stringer function for debugging and pretty printing.
-func (domainKeyType) String() string {
-	return "domain"
-}
-
-const domainKey domainKeyType = 0
-
-// BindDomain binds domain to context.
-func BindDomain(ctx contextutil.ValueStoreContext, domain *Domain) {
-	ctx.SetValue(domainKey, domain)
-}
-
 // GetDomain gets domain from context.
 func GetDomain(ctx contextutil.ValueStoreContext) *Domain {
-	v, ok := ctx.Value(domainKey).(*Domain)
-	if !ok {
-		return nil
+	v, ok := ctx.GetDomain().(*Domain)
+	if ok {
+		return v
 	}
-	return v
+	return nil
 }
diff --git a/pkg/lightning/backend/local/region_job.go b/pkg/lightning/backend/local/region_job.go
index f6bb92990d..67b0e83b42 100644
--- a/pkg/lightning/backend/local/region_job.go
+++ b/pkg/lightning/backend/local/region_job.go
@@ -440,14 +440,14 @@ func (local *Backend) doWrite(ctx context.Context, j *regionJob) error {
 	intest.AssertFunc(func() bool {
 		timeOfTS := oracle.GetTimeFromTS(dataCommitTS)
 		now := time.Now()
-		if timeOfTS.After(now) {
+		if timeOfTS.Sub(now) > time.Hour {
 			return false
 		}
 		if now.Sub(timeOfTS) > 24*time.Hour {
 			return false
 		}
 		return true
-	}, "TS used in import should in [now-1d, now], but got %d", dataCommitTS)
+	}, "TS used in import should in [now-1d, now+1h], but got %d", dataCommitTS)
 	if dataCommitTS == 0 {
 		return errors.New("data commitTS is 0")
 	}
diff --git a/pkg/planner/core/exhaust_physical_plans.go b/pkg/planner/core/exhaust_physical_plans.go
index 866428e413..1434536817 100644
--- a/pkg/planner/core/exhaust_physical_plans.go
+++ b/pkg/planner/core/exhaust_physical_plans.go
@@ -442,10 +442,8 @@ func getHashJoins(p *logicalop.LogicalJoin, prop *property.PhysicalProperty) (jo
 		if p.SCtx().GetSessionVars().UseHashJoinV2 && joinversion.IsHashJoinV2Supported() && canUseHashJoinV2(p.JoinType, leftJoinKeys, isNullEQ, leftNAJoinKeys) {
 			if !forceLeftToBuild {
 				joins = append(joins, getHashJoin(p, prop, 1, false))
-			} else if !forceRightToBuild {
-				joins = append(joins, getHashJoin(p, prop, 1, true))
-			} else {
-				joins = append(joins, getHashJoin(p, prop, 1, false))
+			}
+			if !forceRightToBuild {
 				joins = append(joins, getHashJoin(p, prop, 1, true))
 			}
 		} else {
diff --git a/pkg/planner/core/mock.go b/pkg/planner/core/mock.go
index 8fee1721bc..122741adc8 100644
--- a/pkg/planner/core/mock.go
+++ b/pkg/planner/core/mock.go
@@ -429,7 +429,7 @@ func MockContext() *mock.Context {
 	if err := do.CreateStatsHandle(ctx, initStatsCtx); err != nil {
 		panic(fmt.Sprintf("create mock context panic: %+v", err))
 	}
-	domain.BindDomain(ctx, do)
+	ctx.BindDomain(do)
 	return ctx
 }
 
diff --git a/pkg/session/session.go b/pkg/session/session.go
index 8fe917b358..2d173bb2dc 100644
--- a/pkg/session/session.go
+++ b/pkg/session/session.go
@@ -182,6 +182,8 @@ type session struct {
 	currentCtx  context.Context // only use for runtime.trace, Please NEVER use it.
 	currentPlan base.Plan
 
+	// dom is *domain.Domain, use `any` to avoid import cycle.
+	dom   any
 	store kv.Storage
 
 	sessionPlanCache sessionctx.SessionPlanCache
@@ -3789,6 +3791,7 @@ func createSessionWithOpt(store kv.Storage, opt *Opt) (*session, error) {
 		return nil, err
 	}
 	s := &session{
+		dom:                   dom,
 		store:                 store,
 		ddlOwnerManager:       dom.DDL().OwnerManager(),
 		client:                store.GetClient(),
@@ -3808,7 +3811,6 @@ func createSessionWithOpt(store kv.Storage, opt *Opt) (*session, error) {
 	s.lockedTables = make(map[int64]model.TableLockTpInfo)
 	s.advisoryLocks = make(map[string]*advisoryLock)
 
-	domain.BindDomain(s, dom)
 	// session implements variable.GlobalVarAccessor. Bind it to ctx.
 	s.sessionVars.GlobalVarsAccessor = s
 	s.txn.init()
@@ -3852,6 +3854,7 @@ func detachStatsCollector(s *session) *session {
 // a lock context, which cause we can't call createSession directly.
 func CreateSessionWithDomain(store kv.Storage, dom *domain.Domain) (*session, error) {
 	s := &session{
+		dom:                   dom,
 		store:                 store,
 		sessionVars:           variable.NewSessionVars(nil),
 		client:                store.GetClient(),
@@ -3864,7 +3867,6 @@ func CreateSessionWithDomain(store kv.Storage, dom *domain.Domain) (*session, er
 	s.tblctx = tblsession.NewMutateContext(s)
 	s.mu.values = make(map[fmt.Stringer]any)
 	s.lockedTables = make(map[int64]model.TableLockTpInfo)
-	domain.BindDomain(s, dom)
 	// session implements variable.GlobalVarAccessor. Bind it to ctx.
 	s.sessionVars.GlobalVarsAccessor = s
 	s.txn.init()
@@ -4674,3 +4676,8 @@ func (s *session) GetCursorTracker() cursor.Tracker {
 func (s *session) GetCommitWaitGroup() *sync.WaitGroup {
 	return &s.commitWaitGroup
 }
+
+// GetDomain get domain from session.
+func (s *session) GetDomain() any {
+	return s.dom
+}
diff --git a/pkg/util/context/context.go b/pkg/util/context/context.go
index 8c265c43cd..6d0ea1d6f7 100644
--- a/pkg/util/context/context.go
+++ b/pkg/util/context/context.go
@@ -29,6 +29,9 @@ type ValueStoreContext interface {
 
 	// ClearValue clears the value associated with this context for key.
 	ClearValue(key fmt.Stringer)
+
+	// GetDomain returns the domain.
+	GetDomain() any
 }
 
 var contextIDGenerator atomic.Uint64
diff --git a/pkg/util/mock/context.go b/pkg/util/mock/context.go
index ba79e99375..14ed7fc40e 100644
--- a/pkg/util/mock/context.go
+++ b/pkg/util/mock/context.go
@@ -66,7 +66,8 @@ var (
 type Context struct {
 	planctx.EmptyPlanContextExtended
 	*sessionexpr.ExprContext
-	txn           wrapTxn    // mock global variable
+	txn           wrapTxn // mock global variable
+	dom           any
 	Store         kv.Storage // mock global variable
 	ctx           context.Context
 	sm            util.SessionManager
@@ -639,6 +640,16 @@ func (*Context) GetCommitWaitGroup() *sync.WaitGroup {
 	return nil
 }
 
+// BindDomain bind domain into ctx.
+func (c *Context) BindDomain(dom any) {
+	c.dom = dom
+}
+
+// GetDomain get domain from ctx.
+func (c *Context) GetDomain() any {
+	return c.dom
+}
+
 // NewContextDeprecated creates a new mocked sessionctx.Context.
 // Deprecated: This method is only used for some legacy code.
 // DO NOT use mock.Context in new production code, and use the real Context instead.


Test patch:
diff --git a/pkg/domain/domainctx_test.go b/pkg/domain/domainctx_test.go
index 0efd628665..21d1963cbb 100644
--- a/pkg/domain/domainctx_test.go
+++ b/pkg/domain/domainctx_test.go
@@ -23,13 +23,11 @@ import (
 
 func TestDomainCtx(t *testing.T) {
 	ctx := mock.NewContext()
-	require.NotEqual(t, "", domainKey.String())
-
-	BindDomain(ctx, nil)
+	ctx.BindDomain(nil)
 	v := GetDomain(ctx)
 	require.Nil(t, v)
 
-	ctx.ClearValue(domainKey)
+	ctx.BindDomain(&Domain{})
 	v = GetDomain(ctx)
-	require.Nil(t, v)
+	require.NotNil(t, v)
 }
diff --git a/pkg/executor/executor_pkg_test.go b/pkg/executor/executor_pkg_test.go
index ec0c15fa7e..6582d91c77 100644
--- a/pkg/executor/executor_pkg_test.go
+++ b/pkg/executor/executor_pkg_test.go
@@ -332,7 +332,7 @@ func TestFilterTemporaryTableKeys(t *testing.T) {
 
 func TestErrLevelsForResetStmtContext(t *testing.T) {
 	ctx := mock.NewContext()
-	domain.BindDomain(ctx, &domain.Domain{})
+	ctx.BindDomain(&domain.Domain{})
 
 	cases := []struct {
 		name    string
diff --git a/pkg/executor/executor_required_rows_test.go b/pkg/executor/executor_required_rows_test.go
index a81dda7e15..ec32ea1f6c 100644
--- a/pkg/executor/executor_required_rows_test.go
+++ b/pkg/executor/executor_required_rows_test.go
@@ -215,7 +215,7 @@ func defaultCtx() sessionctx.Context {
 	ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, ctx.GetSessionVars().MemQuotaQuery)
 	ctx.GetSessionVars().StmtCtx.DiskTracker = disk.NewTracker(-1, -1)
 	ctx.GetSessionVars().SnapshotTS = uint64(1)
-	domain.BindDomain(ctx, domain.NewMockDomain())
+	ctx.BindDomain(domain.NewMockDomain())
 	return ctx
 }
 
diff --git a/pkg/executor/join/joiner_test.go b/pkg/executor/join/joiner_test.go
index 796f1b17ec..92a3aab004 100644
--- a/pkg/executor/join/joiner_test.go
+++ b/pkg/executor/join/joiner_test.go
@@ -38,7 +38,7 @@ func defaultCtx() sessionctx.Context {
 	ctx.GetSessionVars().StmtCtx.MemTracker = memory.NewTracker(-1, ctx.GetSessionVars().MemQuotaQuery)
 	ctx.GetSessionVars().StmtCtx.DiskTracker = disk.NewTracker(-1, -1)
 	ctx.GetSessionVars().SnapshotTS = uint64(1)
-	domain.BindDomain(ctx, domain.NewMockDomain())
+	ctx.BindDomain(domain.NewMockDomain())
 	return ctx
 }
 
diff --git a/pkg/executor/select_test.go b/pkg/executor/select_test.go
index faa342c3b2..c6dd909beb 100644
--- a/pkg/executor/select_test.go
+++ b/pkg/executor/select_test.go
@@ -26,7 +26,7 @@ import (
 func BenchmarkResetContextOfStmt(b *testing.B) {
 	stmt := &ast.SelectStmt{}
 	ctx := mock.NewContext()
-	domain.BindDomain(ctx, &domain.Domain{})
+	ctx.BindDomain(&domain.Domain{})
 	for i := 0; i < b.N; i++ {
 		executor.ResetContextOfStmt(ctx, stmt)
 	}
diff --git a/pkg/planner/core/casetest/enforcempp/testdata/enforce_mpp_suite_out.json b/pkg/planner/core/casetest/enforcempp/testdata/enforce_mpp_suite_out.json
index 01cfd9e26b..1e8cf370aa 100644
--- a/pkg/planner/core/casetest/enforcempp/testdata/enforce_mpp_suite_out.json
+++ b/pkg/planner/core/casetest/enforcempp/testdata/enforce_mpp_suite_out.json
@@ -649,11 +649,11 @@
       {
         "SQL": "explain select a from t where t.a not in (select a from s where t.a<1); -- 9. non left join has left conditions",
         "Plan": [
-          "MergeJoin_10 8000.00 root  anti semi join, left side:TableReader_23, left key:test.t.a, right key:test.s.a, left cond:lt(test.t.a, 1)",
-          "├─TableReader_26(Build) 10000.00 root  data:TableFullScan_25",
-          "│ └─TableFullScan_25 10000.00 cop[tikv] table:s keep order:true, stats:pseudo",
-          "└─TableReader_23(Probe) 10000.00 root  data:TableFullScan_22",
-          "  └─TableFullScan_22 10000.00 cop[tikv] table:t keep order:true, stats:pseudo"
+          "MergeJoin_10 8000.00 root  anti semi join, left side:TableReader_24, left key:test.t.a, right key:test.s.a, left cond:lt(test.t.a, 1)",
+          "├─TableReader_27(Build) 10000.00 root  data:TableFullScan_26",
+          "│ └─TableFullScan_26 10000.00 cop[tikv] table:s keep order:true, stats:pseudo",
+          "└─TableReader_24(Probe) 10000.00 root  data:TableFullScan_23",
+          "  └─TableFullScan_23 10000.00 cop[tikv] table:t keep order:true, stats:pseudo"
         ],
         "Warn": [
           "MPP mode may be blocked because there is a join that is not `left join` but has left conditions, which is not supported by mpp now, see github.com/pingcap/tidb/issues/26090 for more information.",
diff --git a/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json
index 4ee0330d58..5ab80ad009 100644
--- a/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json
+++ b/pkg/planner/core/casetest/physicalplantest/testdata/plan_suite_out.json
@@ -1577,15 +1577,15 @@
       {
         "SQL": "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)",
         "Plan": [
-          "TableReader_36 0.80 root  MppVersion: 2, data:ExchangeSender_35",
-          "└─ExchangeSender_35 0.80 mpp[tiflash]  ExchangeType: PassThrough",
-          "  └─HashJoin_34 0.80 mpp[tiflash]  semi join, left side:Selection_13, equal:[eq(test.t1.a, test.t2.b)]",
-          "    ├─ExchangeReceiver_17(Build) 8.00 mpp[tiflash]  ",
-          "    │ └─ExchangeSender_16 8.00 mpp[tiflash]  ExchangeType: Broadcast, Compression: FAST",
-          "    │   └─Selection_15 8.00 mpp[tiflash]  not(isnull(test.t2.b))",
-          "    │     └─TableFullScan_14 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false",
-          "    └─Selection_13(Probe) 1.00 mpp[tiflash]  not(isnull(test.t1.a))",
-          "      └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false"
+          "TableReader_37 0.80 root  MppVersion: 2, data:ExchangeSender_36",
+          "└─ExchangeSender_36 0.80 mpp[tiflash]  ExchangeType: PassThrough",
+          "  └─HashJoin_35 0.80 mpp[tiflash]  semi join, left side:Selection_14, equal:[eq(test.t1.a, test.t2.b)]",
+          "    ├─ExchangeReceiver_18(Build) 8.00 mpp[tiflash]  ",
+          "    │ └─ExchangeSender_17 8.00 mpp[tiflash]  ExchangeType: Broadcast, Compression: FAST",
+          "    │   └─Selection_16 8.00 mpp[tiflash]  not(isnull(test.t2.b))",
+          "    │     └─TableFullScan_15 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false",
+          "    └─Selection_14(Probe) 1.00 mpp[tiflash]  not(isnull(test.t1.a))",
+          "      └─TableFullScan_13 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false"
         ],
         "Warn": null
       },
@@ -1607,17 +1607,17 @@
       {
         "SQL": "explain select * from t1 where exists (select * from t2 where t1.a=t2.b)",
         "Plan": [
-          "TableReader_38 0.80 root  MppVersion: 2, data:ExchangeSender_37",
-          "└─ExchangeSender_37 0.80 mpp[tiflash]  ExchangeType: PassThrough",
-          "  └─HashJoin_36 0.80 mpp[tiflash]  semi join, left side:ExchangeReceiver_15, equal:[eq(test.t1.a, test.t2.b)]",
-          "    ├─ExchangeReceiver_15(Build) 1.00 mpp[tiflash]  ",
-          "    │ └─ExchangeSender_14 1.00 mpp[tiflash]  ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]",
-          "    │   └─Selection_13 1.00 mpp[tiflash]  not(isnull(test.t1.a))",
-          "    │     └─TableFullScan_12 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false",
-          "    └─ExchangeReceiver_19(Probe) 8.00 mpp[tiflash]  ",
-          "      └─ExchangeSender_18 8.00 mpp[tiflash]  ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]",
-          "        └─Selection_17 8.00 mpp[tiflash]  not(isnull(test.t2.b))",
-          "          └─TableFullScan_16 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false"
+          "TableReader_39 0.80 root  MppVersion: 2, data:ExchangeSender_38",
+          "└─ExchangeSender_38 0.80 mpp[tiflash]  ExchangeType: PassThrough",
+          "  └─HashJoin_37 0.80 mpp[tiflash]  semi join, left side:ExchangeReceiver_16, equal:[eq(test.t1.a, test.t2.b)]",
+          "    ├─ExchangeReceiver_16(Build) 1.00 mpp[tiflash]  ",
+          "    │ └─ExchangeSender_15 1.00 mpp[tiflash]  ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]",
+          "    │   └─Selection_14 1.00 mpp[tiflash]  not(isnull(test.t1.a))",
+          "    │     └─TableFullScan_13 1.00 mpp[tiflash] table:t1 pushed down filter:empty, keep order:false",
+          "    └─ExchangeReceiver_20(Probe) 8.00 mpp[tiflash]  ",
+          "      └─ExchangeSender_19 8.00 mpp[tiflash]  ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]",
+          "        └─Selection_18 8.00 mpp[tiflash]  not(isnull(test.t2.b))",
+          "          └─TableFullScan_17 8.00 mpp[tiflash] table:t2 pushed down filter:empty, keep order:false"
         ],
         "Warn": null
       }
diff --git a/pkg/planner/core/logical_plans_test.go b/pkg/planner/core/logical_plans_test.go
index b10abfd47f..1df812f693 100644
--- a/pkg/planner/core/logical_plans_test.go
+++ b/pkg/planner/core/logical_plans_test.go
@@ -118,7 +118,7 @@ func createPlannerSuite() (s *plannerSuite) {
 	if err := do.CreateStatsHandle(ctx, initStatsCtx); err != nil {
 		panic(fmt.Sprintf("create mock context panic: %+v", err))
 	}
-	domain.BindDomain(ctx, do)
+	ctx.BindDomain(do)
 	ctx.SetInfoSchema(s.is)
 	s.ctx = ctx
 	s.sctx = ctx
diff --git a/pkg/session/bootstrap_test.go b/pkg/session/bootstrap_test.go
index db58b3c5f1..7bf76aebf7 100644
--- a/pkg/session/bootstrap_test.go
+++ b/pkg/session/bootstrap_test.go
@@ -178,7 +178,7 @@ func TestBootstrapWithError(t *testing.T) {
 		dom, err := domap.Get(store)
 		require.NoError(t, err)
 		require.NoError(t, dom.Start(ddl.Bootstrap))
-		domain.BindDomain(se, dom)
+		se.dom = dom
 		b, err := checkBootstrapped(se)
 		require.False(t, b)
 		require.NoError(t, err)
@@ -2409,7 +2409,7 @@ func TestTiDBUpgradeToVer211(t *testing.T) {
 	require.NoError(t, err)
 	require.Less(t, int64(ver210), ver)
 
-	domain.BindDomain(seV210, dom)
+	seV210.(*session).dom = dom
 	r := MustExecToRecodeSet(t, seV210, "select count(summary) from mysql.tidb_background_subtask_history;")
 	req := r.NewChunk(nil)
 	err = r.Next(ctx, req)
diff --git a/tests/integrationtest/r/cte.result b/tests/integrationtest/r/cte.result
index 1c9505bae8..4c9e1c8005 100644
--- a/tests/integrationtest/r/cte.result
+++ b/tests/integrationtest/r/cte.result
@@ -581,13 +581,13 @@ c1	c2
 insert into t1 values(2, 3);
 explain select * from t1 where exists(with cte1 as (select c1 from t2 where t2.c2 = t1.c2) select c1 from cte1);
 id	estRows	task	access object	operator info
-HashJoin_14	7992.00	root		semi join, left side:TableReader_17, equal:[eq(cte.t1.c2, cte.t2.c2)]
-├─TableReader_20(Build)	9990.00	root		data:Selection_19
-│ └─Selection_19	9990.00	cop[tikv]		not(isnull(cte.t2.c2))
-│   └─TableFullScan_18	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
-└─TableReader_17(Probe)	9990.00	root		data:Selection_16
-  └─Selection_16	9990.00	cop[tikv]		not(isnull(cte.t1.c2))
-    └─TableFullScan_15	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
+HashJoin_14	7992.00	root		semi join, left side:TableReader_18, equal:[eq(cte.t1.c2, cte.t2.c2)]
+├─TableReader_21(Build)	9990.00	root		data:Selection_20
+│ └─Selection_20	9990.00	cop[tikv]		not(isnull(cte.t2.c2))
+│   └─TableFullScan_19	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
+└─TableReader_18(Probe)	9990.00	root		data:Selection_17
+  └─Selection_17	9990.00	cop[tikv]		not(isnull(cte.t1.c2))
+    └─TableFullScan_16	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
 select * from t1 where exists(with cte1 as (select c1 from t2 where t2.c2 = t1.c2) select c1 from cte1);
 c1	c2
 2	1
@@ -1118,23 +1118,23 @@ SELECT col_4
 FROM product_detail
 ) a;
 id	estRows	task	access object	operator info
-Union_210	199600.20	root		
-├─Projection_211	99800.10	root		cte1.table_c.col_4->Column#418
-│ └─CTEFullScan_212	99800.10	root	CTE:product_detail	data:CTE_4
-└─Projection_213	99800.10	root		cte1.table_c.col_4->Column#418
-  └─CTEFullScan_214	99800.10	root	CTE:product_detail	data:CTE_4
+Union_212	199600.20	root		
+├─Projection_213	99800.10	root		cte1.table_c.col_4->Column#418
+│ └─CTEFullScan_214	99800.10	root	CTE:product_detail	data:CTE_4
+└─Projection_215	99800.10	root		cte1.table_c.col_4->Column#418
+  └─CTEFullScan_216	99800.10	root	CTE:product_detail	data:CTE_4
 CTE_4	99800.10	root		Non-Recursive CTE
-└─Projection_172(Seed Part)	99800.10	root		cte1.table_c.col_4, 3集合->Column#413
-  └─HashJoin_188	99800.10	root		left outer join, left side:HashJoin_190, equal:[eq(cte1.table_c.col_4, cte1.table_c.col_4) eq(Column#390, cte1.table_c.col_1)]
-    ├─TableReader_204(Build)	9980.01	root		data:Selection_203
-    │ └─Selection_203	9980.01	cop[tikv]		not(isnull(cte1.table_c.col_1)), not(isnull(cte1.table_c.col_4))
-    │   └─TableFullScan_202	10000.00	cop[tikv]	table:a	keep order:false, stats:pseudo
-    └─HashJoin_190(Probe)	80000.00	root		CARTESIAN left outer join, left side:HashAgg_196
-      ├─CTEFullScan_200(Build)	10.00	root	CTE:date_table AS dt	data:CTE_0
-      └─HashAgg_196(Probe)	8000.00	root		group by:cte1.table_c.col_3, cte1.table_c.col_4, funcs:firstrow(cte1.table_c.col_4)->cte1.table_c.col_4
-        └─TableReader_197	8000.00	root		data:HashAgg_192
-          └─HashAgg_192	8000.00	cop[tikv]		group by:cte1.table_c.col_3, cte1.table_c.col_4, 
-            └─TableFullScan_195	10000.00	cop[tikv]	table:t	keep order:false, stats:pseudo
+└─Projection_174(Seed Part)	99800.10	root		cte1.table_c.col_4, 3集合->Column#413
+  └─HashJoin_190	99800.10	root		left outer join, left side:HashJoin_192, equal:[eq(cte1.table_c.col_4, cte1.table_c.col_4) eq(Column#390, cte1.table_c.col_1)]
+    ├─TableReader_206(Build)	9980.01	root		data:Selection_205
+    │ └─Selection_205	9980.01	cop[tikv]		not(isnull(cte1.table_c.col_1)), not(isnull(cte1.table_c.col_4))
+    │   └─TableFullScan_204	10000.00	cop[tikv]	table:a	keep order:false, stats:pseudo
+    └─HashJoin_192(Probe)	80000.00	root		CARTESIAN left outer join, left side:HashAgg_198
+      ├─CTEFullScan_202(Build)	10.00	root	CTE:date_table AS dt	data:CTE_0
+      └─HashAgg_198(Probe)	8000.00	root		group by:cte1.table_c.col_3, cte1.table_c.col_4, funcs:firstrow(cte1.table_c.col_4)->cte1.table_c.col_4
+        └─TableReader_199	8000.00	root		data:HashAgg_194
+          └─HashAgg_194	8000.00	cop[tikv]		group by:cte1.table_c.col_3, cte1.table_c.col_4, 
+            └─TableFullScan_197	10000.00	cop[tikv]	table:t	keep order:false, stats:pseudo
 CTE_0	10.00	root		Non-Recursive CTE
 └─Apply_95(Seed Part)	10.00	root		CARTESIAN left outer join, left side:Apply_97
   ├─Apply_97(Build)	10.00	root		CARTESIAN left outer join, left side:Apply_99
@@ -1145,38 +1145,38 @@ CTE_0	10.00	root		Non-Recursive CTE
   │ │ │ │   └─TableFullScan_102	10000.00	cop[tikv]	table:d	keep order:false, stats:pseudo
   │ │ │ └─StreamAgg_106(Probe)	10.00	root		funcs:max(cte1.table_c.col_1)->Column#159
   │ │ │   └─TopN_109	10.00	root		cte1.table_c.col_1:desc, offset:0, count:1
-  │ │ │     └─HashJoin_114	63936.00	root		semi join, left side:Projection_115, equal:[eq(Column#423, Column#424)]
-  │ │ │       ├─Projection_119(Build)	80000.00	root		cast(cte1.table_d.col_1, double BINARY)->Column#424
-  │ │ │       │ └─TableReader_122	80000.00	root		data:Selection_121
-  │ │ │       │   └─Selection_121	80000.00	cop[tikv]		eq(cast(cte1.table_d.col_2, double BINARY), 1)
-  │ │ │       │     └─TableFullScan_120	100000.00	cop[tikv]	table:d	keep order:false, stats:pseudo
-  │ │ │       └─Projection_115(Probe)	79920.00	root		cte1.table_c.col_1, cast(cte1.table_c.col_1, double BINARY)->Column#423
-  │ │ │         └─IndexReader_118	79920.00	root		index:Selection_117
-  │ │ │           └─Selection_117	79920.00	cop[tikv]		le(cte1.table_c.col_1, concat(cast(year(cast(date_sub(cte1.table_d.col_1, 1, "YEAR"), datetime(6) BINARY)), var_string(20)), "1231"))
-  │ │ │             └─IndexFullScan_116	99900.00	cop[tikv]	table:a, index:index_col_1_3(col_1, col_3)	keep order:false, stats:pseudo
-  │ │ └─StreamAgg_124(Probe)	10.00	root		funcs:max(cte1.table_a.col_1)->Column#208
-  │ │   └─TopN_127	10.00	root		cte1.table_a.col_1:desc, offset:0, count:1
-  │ │     └─HashJoin_132	63936.00	root		semi join, left side:Projection_133, equal:[eq(Column#429, Column#430)]
-  │ │       ├─Projection_137(Build)	80000.00	root		cast(cte1.table_d.col_1, double BINARY)->Column#430
-  │ │       │ └─TableReader_140	80000.00	root		data:Selection_139
-  │ │       │   └─Selection_139	80000.00	cop[tikv]		eq(cast(cte1.table_d.col_2, double BINARY), 1)
-  │ │       │     └─TableFullScan_138	100000.00	cop[tikv]	table:d	keep order:false, stats:pseudo
-  │ │       └─Projection_133(Probe)	79920.00	root		cte1.table_a.col_1, cast(cte1.table_a.col_1, double BINARY)->Column#429
-  │ │         └─IndexReader_136	79920.00	root		index:Selection_135
-  │ │           └─Selection_135	79920.00	cop[tikv]		le(cte1.table_a.col_1, concat(cast(year(cast(date_sub(cte1.table_d.col_1, 1, "YEAR"), datetime(6) BINARY)), var_string(20)), "1231"))
-  │ │             └─IndexFullScan_134	99900.00	cop[tikv]	table:a, index:index_col_1(col_1)	keep order:false, stats:pseudo
-  │ └─StreamAgg_142(Probe)	10.00	root		funcs:max(cte1.table_c.col_1)->Column#230
-  │   └─Limit_146	10.00	root		offset:0, count:1
-  │     └─IndexReader_155	10.00	root		index:Limit_154
-  │       └─Limit_154	10.00	cop[tikv]		offset:0, count:1
-  │         └─Selection_153	10.00	cop[tikv]		le(cast(cte1.table_c.col_1, double BINARY), cast(cte1.table_d.col_1, double BINARY))
-  │           └─IndexFullScan_152	12.50	cop[tikv]	table:table_c, index:index_col_1_3(col_1, col_3)	keep order:true, desc, stats:pseudo
-  └─StreamAgg_157(Probe)	10.00	root		funcs:max(cte1.table_a.col_1)->Column#254
-    └─Limit_161	10.00	root		offset:0, count:1
-      └─IndexReader_170	10.00	root		index:Limit_169
-        └─Limit_169	10.00	cop[tikv]		offset:0, count:1
-          └─Selection_168	10.00	cop[tikv]		le(cast(cte1.table_a.col_1, double BINARY), cast(cte1.table_d.col_1, double BINARY))
-            └─IndexFullScan_167	12.50	cop[tikv]	table:table_a, index:index_col_1(col_1)	keep order:true, desc, stats:pseudo
+  │ │ │     └─HashJoin_114	63936.00	root		semi join, left side:Projection_116, equal:[eq(Column#423, Column#424)]
+  │ │ │       ├─Projection_120(Build)	80000.00	root		cast(cte1.table_d.col_1, double BINARY)->Column#424
+  │ │ │       │ └─TableReader_123	80000.00	root		data:Selection_122
+  │ │ │       │   └─Selection_122	80000.00	cop[tikv]		eq(cast(cte1.table_d.col_2, double BINARY), 1)
+  │ │ │       │     └─TableFullScan_121	100000.00	cop[tikv]	table:d	keep order:false, stats:pseudo
+  │ │ │       └─Projection_116(Probe)	79920.00	root		cte1.table_c.col_1, cast(cte1.table_c.col_1, double BINARY)->Column#423
+  │ │ │         └─IndexReader_119	79920.00	root		index:Selection_118
+  │ │ │           └─Selection_118	79920.00	cop[tikv]		le(cte1.table_c.col_1, concat(cast(year(cast(date_sub(cte1.table_d.col_1, 1, "YEAR"), datetime(6) BINARY)), var_string(20)), "1231"))
+  │ │ │             └─IndexFullScan_117	99900.00	cop[tikv]	table:a, index:index_col_1_3(col_1, col_3)	keep order:false, stats:pseudo
+  │ │ └─StreamAgg_125(Probe)	10.00	root		funcs:max(cte1.table_a.col_1)->Column#208
+  │ │   └─TopN_128	10.00	root		cte1.table_a.col_1:desc, offset:0, count:1
+  │ │     └─HashJoin_133	63936.00	root		semi join, left side:Projection_135, equal:[eq(Column#429, Column#430)]
+  │ │       ├─Projection_139(Build)	80000.00	root		cast(cte1.table_d.col_1, double BINARY)->Column#430
+  │ │       │ └─TableReader_142	80000.00	root		data:Selection_141
+  │ │       │   └─Selection_141	80000.00	cop[tikv]		eq(cast(cte1.table_d.col_2, double BINARY), 1)
+  │ │       │     └─TableFullScan_140	100000.00	cop[tikv]	table:d	keep order:false, stats:pseudo
+  │ │       └─Projection_135(Probe)	79920.00	root		cte1.table_a.col_1, cast(cte1.table_a.col_1, double BINARY)->Column#429
+  │ │         └─IndexReader_138	79920.00	root		index:Selection_137
+  │ │           └─Selection_137	79920.00	cop[tikv]		le(cte1.table_a.col_1, concat(cast(year(cast(date_sub(cte1.table_d.col_1, 1, "YEAR"), datetime(6) BINARY)), var_string(20)), "1231"))
+  │ │             └─IndexFullScan_136	99900.00	cop[tikv]	table:a, index:index_col_1(col_1)	keep order:false, stats:pseudo
+  │ └─StreamAgg_144(Probe)	10.00	root		funcs:max(cte1.table_c.col_1)->Column#230
+  │   └─Limit_148	10.00	root		offset:0, count:1
+  │     └─IndexReader_157	10.00	root		index:Limit_156
+  │       └─Limit_156	10.00	cop[tikv]		offset:0, count:1
+  │         └─Selection_155	10.00	cop[tikv]		le(cast(cte1.table_c.col_1, double BINARY), cast(cte1.table_d.col_1, double BINARY))
+  │           └─IndexFullScan_154	12.50	cop[tikv]	table:table_c, index:index_col_1_3(col_1, col_3)	keep order:true, desc, stats:pseudo
+  └─StreamAgg_159(Probe)	10.00	root		funcs:max(cte1.table_a.col_1)->Column#254
+    └─Limit_163	10.00	root		offset:0, count:1
+      └─IndexReader_172	10.00	root		index:Limit_171
+        └─Limit_171	10.00	cop[tikv]		offset:0, count:1
+          └─Selection_170	10.00	cop[tikv]		le(cast(cte1.table_a.col_1, double BINARY), cast(cte1.table_d.col_1, double BINARY))
+            └─IndexFullScan_169	12.50	cop[tikv]	table:table_a, index:index_col_1(col_1)	keep order:true, desc, stats:pseudo
 WITH date_table AS (
 SELECT
 d.col_1 AS date,
diff --git a/tests/integrationtest/r/naaj.result b/tests/integrationtest/r/naaj.result
index 2be21d9576..60f452a36d 100644
--- a/tests/integrationtest/r/naaj.result
+++ b/tests/integrationtest/r/naaj.result
@@ -404,9 +404,9 @@ HashJoin_9	10000.00	root		anti left outer semi join, left side:TableReader_11, e
   └─TableFullScan_10	10000.00	cop[tikv]	table:naaj_A	keep order:false, stats:pseudo
 explain select * from naaj_A where (a+1,b*2) not in (select a, b=1 from naaj_B where naaj_A.a = naaj_B.a);
 id	estRows	task	access object	operator info
-HashJoin_9	8000.00	root		anti semi join, left side:TableReader_11, equal:[eq(naaj.naaj_a.a, naaj.naaj_b.a)], other cond:eq(mul(naaj.naaj_a.b, 2), eq(naaj.naaj_b.b, 1)), eq(plus(naaj.naaj_a.a, 1), naaj.naaj_b.a)
-├─TableReader_13(Build)	10000.00	root		data:TableFullScan_12
-│ └─TableFullScan_12	10000.00	cop[tikv]	table:naaj_B	keep order:false, stats:pseudo
-└─TableReader_11(Probe)	10000.00	root		data:TableFullScan_10
-  └─TableFullScan_10	10000.00	cop[tikv]	table:naaj_A	keep order:false, stats:pseudo
+HashJoin_9	8000.00	root		anti semi join, left side:TableReader_12, equal:[eq(naaj.naaj_a.a, naaj.naaj_b.a)], other cond:eq(mul(naaj.naaj_a.b, 2), eq(naaj.naaj_b.b, 1)), eq(plus(naaj.naaj_a.a, 1), naaj.naaj_b.a)
+├─TableReader_14(Build)	10000.00	root		data:TableFullScan_13
+│ └─TableFullScan_13	10000.00	cop[tikv]	table:naaj_B	keep order:false, stats:pseudo
+└─TableReader_12(Probe)	10000.00	root		data:TableFullScan_11
+  └─TableFullScan_11	10000.00	cop[tikv]	table:naaj_A	keep order:false, stats:pseudo
 set @@session.tidb_enable_null_aware_anti_join=0;
diff --git a/tests/integrationtest/r/planner/core/casetest/integration.result b/tests/integrationtest/r/planner/core/casetest/integration.result
index 84f5a0b9ef..12f9555254 100644
--- a/tests/integrationtest/r/planner/core/casetest/integration.result
+++ b/tests/integrationtest/r/planner/core/casetest/integration.result
@@ -1423,27 +1423,27 @@ set @@tidb_skip_missing_partition_stats = off;
 set @@tidb_opt_fix_control = "";
 explain select /*+ TIDB_INLJ(t2_part@sel_2) */ * from t1 where t1.b<10 and not exists (select 1 from t2_part where t1.a=t2_part.a and t2_part.b<20);
 id	estRows	task	access object	operator info
-HashJoin_19	2658.67	root		anti semi join, left side:TableReader_22, equal:[eq(planner__core__casetest__integration.t1.a, planner__core__casetest__integration.t2_part.a)]
-├─PartitionUnion_23(Build)	13293.33	root		
-│ ├─TableReader_31	3323.33	root		data:Projection_25
-│ │ └─Projection_25	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
-│ │   └─Selection_30	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
-│ │     └─TableFullScan_29	10000.00	cop[tikv]	table:t2_part, partition:p0	keep order:false, stats:pseudo
-│ ├─TableReader_39	3323.33	root		data:Projection_33
-│ │ └─Projection_33	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
-│ │   └─Selection_38	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
-│ │     └─TableFullScan_37	10000.00	cop[tikv]	table:t2_part, partition:p1	keep order:false, stats:pseudo
-│ ├─TableReader_47	3323.33	root		data:Projection_41
-│ │ └─Projection_41	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
-│ │   └─Selection_46	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
-│ │     └─TableFullScan_45	10000.00	cop[tikv]	table:t2_part, partition:p2	keep order:false, stats:pseudo
-│ └─TableReader_55	3323.33	root		data:Projection_49
-│   └─Projection_49	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
-│     └─Selection_54	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
-│       └─TableFullScan_53	10000.00	cop[tikv]	table:t2_part, partition:p3	keep order:false, stats:pseudo
-└─TableReader_22(Probe)	3323.33	root		data:Selection_21
-  └─Selection_21	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t1.b, 10)
-    └─TableFullScan_20	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
+HashJoin_19	2658.67	root		anti semi join, left side:TableReader_23, equal:[eq(planner__core__casetest__integration.t1.a, planner__core__casetest__integration.t2_part.a)]
+├─PartitionUnion_24(Build)	13293.33	root		
+│ ├─TableReader_32	3323.33	root		data:Projection_26
+│ │ └─Projection_26	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
+│ │   └─Selection_31	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
+│ │     └─TableFullScan_30	10000.00	cop[tikv]	table:t2_part, partition:p0	keep order:false, stats:pseudo
+│ ├─TableReader_40	3323.33	root		data:Projection_34
+│ │ └─Projection_34	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
+│ │   └─Selection_39	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
+│ │     └─TableFullScan_38	10000.00	cop[tikv]	table:t2_part, partition:p1	keep order:false, stats:pseudo
+│ ├─TableReader_48	3323.33	root		data:Projection_42
+│ │ └─Projection_42	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
+│ │   └─Selection_47	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
+│ │     └─TableFullScan_46	10000.00	cop[tikv]	table:t2_part, partition:p2	keep order:false, stats:pseudo
+│ └─TableReader_56	3323.33	root		data:Projection_50
+│   └─Projection_50	3323.33	cop[tikv]		planner__core__casetest__integration.t2_part.a
+│     └─Selection_55	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t2_part.b, 20)
+│       └─TableFullScan_54	10000.00	cop[tikv]	table:t2_part, partition:p3	keep order:false, stats:pseudo
+└─TableReader_23(Probe)	3323.33	root		data:Selection_22
+  └─Selection_22	3323.33	cop[tikv]		lt(planner__core__casetest__integration.t1.b, 10)
+    └─TableFullScan_21	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
 Level	Code	Message
 Warning	1105	disable dynamic pruning due to t2_part has no global stats
 Warning	1815	Optimizer Hint /*+ INL_JOIN(t2_part) */ or /*+ TIDB_INLJ(t2_part) */ is inapplicable
diff --git a/tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result b/tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result
index d4d06658a4..4438e56437 100644
--- a/tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result
+++ b/tests/integrationtest/r/planner/core/casetest/physicalplantest/physical_plan.result
@@ -2909,12 +2909,12 @@ Warning	1815	NO_DECORRELATE() and SEMI_JOIN_REWRITE() are in conflict. Both will
 explain format = 'brief' select t1.a from t1 where t1.a in (select t2.b from t2 where t2.a = t1.b);
 id	estRows	task	access object	operator info
 HashJoin	7984.01	root		semi join, left side:TableReader, equal:[eq(planner__core__casetest__physicalplantest__physical_plan.t1.b, planner__core__casetest__physicalplantest__physical_plan.t2.a) eq(planner__core__casetest__physicalplantest__physical_plan.t1.a, planner__core__casetest__physicalplantest__physical_plan.t2.b)]
-├─TableReader(Build)	9990.00	root		data:Selection
-│ └─Selection	9990.00	cop[tikv]		not(isnull(planner__core__casetest__physicalplantest__physical_plan.t2.b))
-│   └─TableFullScan	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
-└─TableReader(Probe)	9980.01	root		data:Selection
-  └─Selection	9980.01	cop[tikv]		not(isnull(planner__core__casetest__physicalplantest__physical_plan.t1.a)), not(isnull(planner__core__casetest__physicalplantest__physical_plan.t1.b))
-    └─TableFullScan	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
+├─TableReader(Build)	9980.01	root		data:Selection
+│ └─Selection	9980.01	cop[tikv]		not(isnull(planner__core__casetest__physicalplantest__physical_plan.t1.a)), not(isnull(planner__core__casetest__physicalplantest__physical_plan.t1.b))
+│   └─TableFullScan	10000.00	cop[tikv]	table:t1	keep order:false, stats:pseudo
+└─TableReader(Probe)	9990.00	root		data:Selection
+  └─Selection	9990.00	cop[tikv]		not(isnull(planner__core__casetest__physicalplantest__physical_plan.t2.b))
+    └─TableFullScan	10000.00	cop[tikv]	table:t2	keep order:false, stats:pseudo
 select t1.a from t1 where t1.a in (select t2.b from t2 where t2.a = t1.b);
 a
 1
diff --git a/tests/integrationtest/r/tpch.result b/tests/integrationtest/r/tpch.result
index 905849349a..cb9d2891d2 100644
--- a/tests/integrationtest/r/tpch.result
+++ b/tests/integrationtest/r/tpch.result
@@ -1294,8 +1294,8 @@ Sort	1.00	root		Column#31
   └─HashAgg	1.00	root		group by:Column#36, funcs:count(1)->Column#32, funcs:sum(Column#35)->Column#33, funcs:firstrow(Column#36)->Column#31
     └─Projection	0.64	root		tpch50.customer.c_acctbal->Column#35, substring(tpch50.customer.c_phone, 1, 2)->Column#36
       └─HashJoin	0.64	root		anti semi join, left side:TableReader, equal:[eq(tpch50.customer.c_custkey, tpch50.orders.o_custkey)]
-        ├─TableReader(Build)	75000000.00	root		data:TableFullScan
-        │ └─TableFullScan	75000000.00	cop[tikv]	table:orders	keep order:false
-        └─TableReader(Probe)	0.80	root		data:Selection
-          └─Selection	0.80	cop[tikv]		gt(tpch50.customer.c_acctbal, NULL), in(substring(tpch50.customer.c_phone, 1, 2), "20", "40", "22", "30", "39", "42", "21")
-            └─TableFullScan	7500000.00	cop[tikv]	table:customer	keep order:false
+        ├─TableReader(Build)	0.80	root		data:Selection
+        │ └─Selection	0.80	cop[tikv]		gt(tpch50.customer.c_acctbal, NULL), in(substring(tpch50.customer.c_phone, 1, 2), "20", "40", "22", "30", "39", "42", "21")
+        │   └─TableFullScan	7500000.00	cop[tikv]	table:customer	keep order:false
+        └─TableReader(Probe)	75000000.00	root		data:TableFullScan
+          └─TableFullScan	75000000.00	cop[tikv]	table:orders	keep order:false