Skip to content

Commit a1183bc

Browse files
authored
planner: fix select lock don't have Hash64 and Equals methods itself in next-gen mode. (pingcap#63227)
close pingcap#63229
1 parent b854521 commit a1183bc

File tree

12 files changed

+133
-27
lines changed

12 files changed

+133
-27
lines changed

pkg/parser/ast/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ go_library(
2828
"//pkg/parser/terror",
2929
"//pkg/parser/tidb",
3030
"//pkg/parser/types",
31+
"//pkg/parser/util",
3132
"@com_github_pingcap_errors//:errors",
3233
"@com_github_pingcap_failpoint//:failpoint",
3334
],

pkg/parser/ast/dml.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
package ast
1515

1616
import (
17+
"reflect"
1718
"strings"
1819

1920
"github.com/pingcap/errors"
2021
"github.com/pingcap/tidb/pkg/parser/auth"
2122
"github.com/pingcap/tidb/pkg/parser/format"
2223
"github.com/pingcap/tidb/pkg/parser/mysql"
24+
"github.com/pingcap/tidb/pkg/parser/util"
2325
)
2426

2527
var (
@@ -632,6 +634,45 @@ type SelectLockInfo struct {
632634
Tables []*TableName
633635
}
634636

637+
// Hash64 implements the cascades/base.Hasher.<0th> interface.
638+
func (n *SelectLockInfo) Hash64(h util.IHasher) {
639+
h.HashInt(int(n.LockType))
640+
h.HashUint64(n.WaitSec)
641+
h.HashInt(len(n.Tables))
642+
for _, one := range n.Tables {
643+
// to make it simple, we just use lockInfo's addr.
644+
h.HashUint64(uint64(reflect.ValueOf(one).Pointer()))
645+
}
646+
}
647+
648+
// Equals implements the cascades/base.Hasher.<1th> interface.
649+
func (n *SelectLockInfo) Equals(other any) bool {
650+
n2, ok := other.(*SelectLockInfo)
651+
if !ok {
652+
return false
653+
}
654+
if n == nil {
655+
return n2 == nil
656+
}
657+
if other == nil {
658+
return false
659+
}
660+
ok = n.LockType == n2.LockType &&
661+
n.WaitSec == n2.WaitSec
662+
if !ok {
663+
return false
664+
}
665+
if len(n.Tables) != len(n2.Tables) {
666+
return false
667+
}
668+
for i, one := range n.Tables {
669+
if one != n2.Tables[i] {
670+
return false
671+
}
672+
}
673+
return true
674+
}
675+
635676
// String implements fmt.Stringer.
636677
func (n SelectLockType) String() string {
637678
switch n {

pkg/parser/ast/model.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"unsafe"
2020

2121
"github.com/pingcap/errors"
22-
"github.com/pingcap/tidb/pkg/parser/types"
22+
"github.com/pingcap/tidb/pkg/parser/util"
2323
)
2424

2525
// TableLockType is the type of the table lock.
@@ -272,7 +272,7 @@ type CIStr struct {
272272
}
273273

274274
// Hash64 implements HashEquals interface.
275-
func (cis *CIStr) Hash64(h types.IHasher) {
275+
func (cis *CIStr) Hash64(h util.IHasher) {
276276
h.HashString(cis.L)
277277
}
278278

pkg/parser/types/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ go_library(
1414
"//pkg/parser/format",
1515
"//pkg/parser/mysql",
1616
"//pkg/parser/terror",
17+
"//pkg/parser/util",
1718
],
1819
)
1920

pkg/parser/types/field_type.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/pingcap/tidb/pkg/parser/charset"
2525
"github.com/pingcap/tidb/pkg/parser/format"
2626
"github.com/pingcap/tidb/pkg/parser/mysql"
27+
"github.com/pingcap/tidb/pkg/parser/util"
2728
)
2829

2930
// UnspecifiedLength is unspecified length.
@@ -39,21 +40,6 @@ var (
3940
TiDBStrictIntegerDisplayWidth bool
4041
)
4142

42-
// IHasher is internal usage represent cascades/base.Hasher
43-
type IHasher interface {
44-
HashBool(val bool)
45-
HashInt(val int)
46-
HashInt64(val int64)
47-
HashUint64(val uint64)
48-
HashFloat64(val float64)
49-
HashRune(val rune)
50-
HashString(val string)
51-
HashByte(val byte)
52-
HashBytes(val []byte)
53-
Reset()
54-
Sum64() uint64
55-
}
56-
5743
// FieldType records field type information.
5844
type FieldType struct {
5945
// tp is type of the field
@@ -101,7 +87,7 @@ func (ft *FieldType) DeepCopy() *FieldType {
10187
}
10288

10389
// Hash64 implements the cascades/base.Hasher.<0th> interface.
104-
func (ft *FieldType) Hash64(h IHasher) {
90+
func (ft *FieldType) Hash64(h util.IHasher) {
10591
h.HashByte(ft.tp)
10692
h.HashUint64(uint64(ft.flag))
10793
h.HashInt(ft.flen)

pkg/parser/util/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "util",
5+
srcs = ["hash64.go"],
6+
importpath = "github.com/pingcap/tidb/pkg/parser/util",
7+
visibility = ["//visibility:public"],
8+
)

pkg/parser/util/hash64.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2025 The ql Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSES/QL-LICENSE file.
4+
5+
// Copyright 2015 PingCAP, Inc.
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
package util
19+
20+
// IHasher is internal usage represent cascades/base.Hasher
21+
type IHasher interface {
22+
HashBool(val bool)
23+
HashInt(val int)
24+
HashInt64(val int64)
25+
HashUint64(val uint64)
26+
HashFloat64(val float64)
27+
HashRune(val rune)
28+
HashString(val string)
29+
HashByte(val byte)
30+
HashBytes(val []byte)
31+
Reset()
32+
Sum64() uint64
33+
}

pkg/planner/core/generator/hash64_equals/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ go_library(
66
importpath = "github.com/pingcap/tidb/pkg/planner/core/generator/hash64_equals",
77
visibility = ["//visibility:private"],
88
deps = [
9-
"//pkg/parser/types",
9+
"//pkg/parser/util",
1010
"//pkg/planner/cascades/base",
1111
"//pkg/planner/core/operator/logicalop",
1212
],

pkg/planner/core/generator/hash64_equals/hash64_equals_generator.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"reflect"
2424
"strings"
2525

26-
"github.com/pingcap/tidb/pkg/parser/types"
26+
"github.com/pingcap/tidb/pkg/parser/util"
2727
"github.com/pingcap/tidb/pkg/planner/cascades/base"
2828
"github.com/pingcap/tidb/pkg/planner/core/operator/logicalop"
2929
)
@@ -40,7 +40,8 @@ func GenHash64Equals4LogicalOps() ([]byte, error) {
4040
logicalop.LogicalExpand{}, logicalop.LogicalLimit{}, logicalop.LogicalMaxOneRow{}, logicalop.DataSource{},
4141
logicalop.LogicalMemTable{}, logicalop.LogicalUnionAll{}, logicalop.LogicalPartitionUnionAll{}, logicalop.LogicalProjection{},
4242
logicalop.LogicalSelection{}, logicalop.LogicalSequence{}, logicalop.LogicalShow{}, logicalop.LogicalShowDDLJobs{},
43-
logicalop.LogicalSort{}, logicalop.LogicalTableDual{}, logicalop.LogicalTopN{}, logicalop.LogicalUnionScan{}, logicalop.LogicalWindow{},
43+
logicalop.LogicalSort{}, logicalop.LogicalTableDual{}, logicalop.LogicalTopN{}, logicalop.LogicalUnionScan{},
44+
logicalop.LogicalWindow{}, logicalop.LogicalLock{},
4445
}
4546
c := new(cc)
4647
c.write(codeGenHash64EqualsPrefix)
@@ -56,7 +57,7 @@ func GenHash64Equals4LogicalOps() ([]byte, error) {
5657

5758
// IHashEquals is the interface for hash64 and equals inside parser pkg.
5859
type IHashEquals interface {
59-
Hash64(h types.IHasher)
60+
Hash64(h util.IHasher)
6061
Equals(other any) bool
6162
}
6263

@@ -155,6 +156,8 @@ func logicalOpName2PlanCodecString(name string) string {
155156
return "plancodec.TypeUnionScan"
156157
case "LogicalWindow":
157158
return "plancodec.TypeWindow"
159+
case "LogicalLock":
160+
return "plancodec.TypeLock"
158161
default:
159162
return ""
160163
}

pkg/planner/core/operator/logicalop/base_logical_plan.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ type BaseLogicalPlan struct {
6969

7070
// Hash64 implements HashEquals.<0th> interface.
7171
func (p *BaseLogicalPlan) Hash64(h base2.Hasher) {
72-
_, ok1 := p.self.(*LogicalSequence)
73-
_, ok2 := p.self.(*LogicalMaxOneRow)
74-
if !ok1 && !ok2 {
72+
switch p.self.(type) {
73+
case *LogicalSequence, *LogicalMaxOneRow, *LogicalLock:
74+
default:
7575
intest.Assert(false, "Hash64 should not be called directly")
7676
}
7777
h.HashInt(p.ID())

0 commit comments

Comments
 (0)