diff --git a/pkg/planner/core/operator/logicalop/hash64_equals_generated.go b/pkg/planner/core/operator/logicalop/hash64_equals_generated.go index 99444d045048e..a86a4f92b3bd4 100644 --- a/pkg/planner/core/operator/logicalop/hash64_equals_generated.go +++ b/pkg/planner/core/operator/logicalop/hash64_equals_generated.go @@ -452,6 +452,7 @@ func (op *LogicalLimit) Equals(other any) bool { // Hash64 implements the Hash64Equals interface. func (op *LogicalMaxOneRow) Hash64(h base.Hasher) { h.HashString(plancodec.TypeMaxOneRow) + op.BaseLogicalPlan.Hash64(h) } // Equals implements the Hash64Equals interface, only receive *LogicalMaxOneRow pointer. @@ -466,7 +467,9 @@ func (op *LogicalMaxOneRow) Equals(other any) bool { if op2 == nil { return false } - _ = op2 + if !op.BaseLogicalPlan.Equals(&op2.BaseLogicalPlan) { + return false + } return true } diff --git a/pkg/planner/core/operator/logicalop/logical_max_one_row.go b/pkg/planner/core/operator/logicalop/logical_max_one_row.go index 200a8ac51750d..686d461da0364 100644 --- a/pkg/planner/core/operator/logicalop/logical_max_one_row.go +++ b/pkg/planner/core/operator/logicalop/logical_max_one_row.go @@ -26,7 +26,8 @@ import ( // LogicalMaxOneRow checks if a query returns no more than one row. type LogicalMaxOneRow struct { - BaseLogicalPlan + // logical max one row, doesn't have any other attribute to distinguish, use plan id inside. + BaseLogicalPlan `hash64-equals:"true"` } // Init initializes LogicalMaxOneRow. diff --git a/pkg/planner/core/operator/logicalop/logicalop_test/hash64_equals_test.go b/pkg/planner/core/operator/logicalop/logicalop_test/hash64_equals_test.go index 8e56fd9bfb950..33533b1ef2ea1 100644 --- a/pkg/planner/core/operator/logicalop/logicalop_test/hash64_equals_test.go +++ b/pkg/planner/core/operator/logicalop/logicalop_test/hash64_equals_test.go @@ -278,14 +278,21 @@ func TestLogicalSchemaProducerHash64Equals(t *testing.T) { } func TestLogicalMaxOneRowHash64Equals(t *testing.T) { - m1 := &logicalop.LogicalMaxOneRow{} - m2 := &logicalop.LogicalMaxOneRow{} + ctx := mock.NewContext() + m1 := logicalop.LogicalMaxOneRow{}.Init(ctx, 1) + m2 := logicalop.LogicalMaxOneRow{}.Init(ctx, 1) // since logical max one row doesn't have any elements, they are always indicate // that they are equal. hasher1 := base.NewHashEqualer() hasher2 := base.NewHashEqualer() m1.Hash64(hasher1) m2.Hash64(hasher2) + require.NotEqual(t, hasher1.Sum64(), hasher2.Sum64()) + require.False(t, m1.Equals(m2)) + + m2.SetID(m1.ID()) + hasher2.Reset() + m2.Hash64(hasher2) require.Equal(t, hasher1.Sum64(), hasher2.Sum64()) require.True(t, m1.Equals(m2)) }