diff --git a/pkg/executor/join/joinversion/join_version.go b/pkg/executor/join/joinversion/join_version.go index 903d365e8c60f..ff59a57c0e7e4 100644 --- a/pkg/executor/join/joinversion/join_version.go +++ b/pkg/executor/join/joinversion/join_version.go @@ -25,6 +25,20 @@ const ( HashJoinVersionOptimized = "optimized" ) +var ( + // UseHashJoinV2ForNonGAJoin is added because Hash join contains a lots of types(like inner join, outer join, semi join, nullaware semi join, etc) + // we want to GA these different kind of joins step by step, but don't want to add a new session variable for each of the join, + // so we add this variable to control whether to use hash join v2 for nonGA joins(enable it for test, disable it in a release version). + // PhysicalHashJoin.isGAForHashJoinV2() defines whether the join is GA for hash join v2, we can make each join GA separately by updating + // this function one by one + UseHashJoinV2ForNonGAJoin = false +) + +func init() { + // This variable is set to true for test, need to be set back to false in release version + UseHashJoinV2ForNonGAJoin = true +} + // IsOptimizedVersion returns true if hashJoinVersion equals to HashJoinVersionOptimized func IsOptimizedVersion(hashJoinVersion string) bool { return strings.ToLower(hashJoinVersion) == HashJoinVersionOptimized diff --git a/pkg/planner/core/BUILD.bazel b/pkg/planner/core/BUILD.bazel index 32e0016f1e833..dc158bb1b93d8 100644 --- a/pkg/planner/core/BUILD.bazel +++ b/pkg/planner/core/BUILD.bazel @@ -96,6 +96,7 @@ go_library( "//pkg/distsql", "//pkg/domain", "//pkg/errctx", + "//pkg/executor/join/joinversion", "//pkg/expression", "//pkg/expression/aggregation", "//pkg/expression/exprctx", diff --git a/pkg/planner/core/physical_plans.go b/pkg/planner/core/physical_plans.go index e7c5585e3d93c..c50fd060c7b5c 100644 --- a/pkg/planner/core/physical_plans.go +++ b/pkg/planner/core/physical_plans.go @@ -21,6 +21,7 @@ import ( "unsafe" "github.com/pingcap/errors" + "github.com/pingcap/tidb/pkg/executor/join/joinversion" "github.com/pingcap/tidb/pkg/expression" "github.com/pingcap/tidb/pkg/expression/aggregation" "github.com/pingcap/tidb/pkg/kv" @@ -1472,8 +1473,34 @@ type PhysicalHashJoin struct { runtimeFilterList []*RuntimeFilter `plan-cache-clone:"must-nil"` // plan with runtime filter is not cached } +func (p *PhysicalHashJoin) isGAForHashJoinV2() bool { + // nullaware join + if len(p.LeftNAJoinKeys) > 0 { + return false + } + // cross join + if len(p.LeftJoinKeys) == 0 { + return false + } + // join with null equal condition + for _, value := range p.IsNullEQ { + if value { + return false + } + } + switch p.JoinType { + case logicalop.LeftOuterJoin, logicalop.RightOuterJoin, logicalop.InnerJoin: + return true + default: + return false + } +} + // CanUseHashJoinV2 returns true if current join is supported by hash join v2 func (p *PhysicalHashJoin) CanUseHashJoinV2() bool { + if !p.isGAForHashJoinV2() && !joinversion.UseHashJoinV2ForNonGAJoin { + return false + } switch p.JoinType { case logicalop.LeftOuterJoin, logicalop.RightOuterJoin, logicalop.InnerJoin: // null aware join is not supported yet