diff --git a/pkg/planner/core/generator/hash64_equals/hash64_equals_generator.go b/pkg/planner/core/generator/hash64_equals/hash64_equals_generator.go index 6414284ac0ab7..9877937bc5198 100644 --- a/pkg/planner/core/generator/hash64_equals/hash64_equals_generator.go +++ b/pkg/planner/core/generator/hash64_equals/hash64_equals_generator.go @@ -17,6 +17,7 @@ package main import ( "bytes" "fmt" + "github.com/pingcap/tidb/pkg/parser/types" "go/format" "log" "os" @@ -49,7 +50,14 @@ func GenHash64Equals4LogicalOps() ([]byte, error) { return c.format() } +// IHashEquals is the interface for hash64 and equals inside parser pkg. +type IHashEquals interface { + Hash64(h types.IHasher) + Equals(other any) bool +} + var hashEqualsType = reflect.TypeOf((*base.HashEquals)(nil)).Elem() +var iHashEqualsType = reflect.TypeOf((*IHashEquals)(nil)).Elem() func genHash64EqualsForLogicalOps(x any) ([]byte, error) { c := new(cc) @@ -152,7 +160,8 @@ func (c *cc) EqualsElement(fType reflect.Type, lhs, rhs string, i string) { reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: c.write("if %v != %v {return false}", lhs, rhs) default: - if fType.Implements(hashEqualsType) || reflect.PtrTo(fType).Implements(hashEqualsType) { + if fType.Implements(hashEqualsType) || fType.Implements(iHashEqualsType) || + reflect.PtrTo(fType).Implements(hashEqualsType) || reflect.PtrTo(fType).Implements(iHashEqualsType) { if fType.Kind() == reflect.Struct { rhs = "&" + rhs } @@ -186,7 +195,8 @@ func (c *cc) Hash64Element(fType reflect.Type, callName string) { case reflect.Float32, reflect.Float64: c.write("h.HashFloat64(float64(%v))", callName) default: - if fType.Implements(hashEqualsType) || reflect.PtrTo(fType).Implements(hashEqualsType) { + if fType.Implements(hashEqualsType) || fType.Implements(iHashEqualsType) || + reflect.PtrTo(fType).Implements(hashEqualsType) || reflect.PtrTo(fType).Implements(iHashEqualsType) { c.write("%v.Hash64(h)", callName) } else { panic("doesn't support element type" + fType.Kind().String()) diff --git a/pkg/planner/core/operator/logicalop/hash64_equals_generated.go b/pkg/planner/core/operator/logicalop/hash64_equals_generated.go index 906706d37de3c..3c0b68a68df78 100644 --- a/pkg/planner/core/operator/logicalop/hash64_equals_generated.go +++ b/pkg/planner/core/operator/logicalop/hash64_equals_generated.go @@ -464,6 +464,12 @@ func (op *DataSource) Hash64(h base.Hasher) { h.HashByte(base.NotNilFlag) op.TableInfo.Hash64(h) } + if op.TableAsName == nil { + h.HashByte(base.NilFlag) + } else { + h.HashByte(base.NotNilFlag) + op.TableAsName.Hash64(h) + } if op.PushedDownConds == nil { h.HashByte(base.NilFlag) } else { @@ -504,6 +510,9 @@ func (op *DataSource) Equals(other any) bool { if !op.TableInfo.Equals(op2.TableInfo) { return false } + if !op.TableAsName.Equals(op2.TableAsName) { + return false + } if (op.PushedDownConds == nil && op2.PushedDownConds != nil) || (op.PushedDownConds != nil && op2.PushedDownConds == nil) || len(op.PushedDownConds) != len(op2.PushedDownConds) { return false } diff --git a/pkg/planner/core/operator/logicalop/logical_datasource.go b/pkg/planner/core/operator/logicalop/logical_datasource.go index 5f6b95c9b47db..f77bf4ffdf7d6 100644 --- a/pkg/planner/core/operator/logicalop/logical_datasource.go +++ b/pkg/planner/core/operator/logicalop/logical_datasource.go @@ -56,7 +56,7 @@ type DataSource struct { Columns []*model.ColumnInfo DBName pmodel.CIStr - TableAsName *pmodel.CIStr + TableAsName *pmodel.CIStr `hash64-equals:"true"` // IndexMergeHints are the hint for indexmerge. IndexMergeHints []h.HintedIndex // PushedDownConds are the conditions that will be pushed down to coprocessor.