Skip to content

Commit cce3ea1

Browse files
committed
Merge branch 'main' into max/stats-iter-change
2 parents 49ce035 + 9a6edfc commit cce3ea1

25 files changed

+22952
-23952
lines changed

enginetest/join_planning_tests.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ type JoinPlanTest struct {
4343
skipOld bool
4444
}
4545

46-
var JoinPlanningTests = []struct {
46+
type joinPlanScript struct {
4747
name string
4848
setup []string
4949
tests []JoinPlanTest
50-
}{
50+
}
51+
52+
var JoinPlanningTests = []joinPlanScript{
5153
{
5254
name: "filter pushdown through join uppercase name",
5355
setup: []string{
@@ -78,6 +80,43 @@ var JoinPlanningTests = []struct {
7880
},
7981
},
8082
},
83+
{
84+
name: "block merge join",
85+
setup: []string{
86+
"CREATE table xy (x int primary key, y int, unique index y_idx(y));",
87+
"CREATE table ab (a int primary key, b int);",
88+
"insert into xy values (1,0), (2,1), (0,2), (3,3);",
89+
"insert into ab values (0,2), (1,2), (2,2), (3,1);",
90+
`analyze table xy update histogram on x using data '{"row_count":1000000}'`,
91+
`analyze table ab update histogram on a using data '{"row_count":1000000}'`,
92+
},
93+
tests: []JoinPlanTest{
94+
{
95+
q: "select /*+ JOIN_ORDER(ab, xy) MERGE_JOIN(ab, xy)*/ * from ab join xy on y = a order by 1, 3",
96+
types: []plan.JoinType{plan.JoinTypeMerge},
97+
exp: []sql.Row{{0, 2, 1, 0}, {1, 2, 2, 1}, {2, 2, 0, 2}, {3, 1, 3, 3}},
98+
},
99+
{
100+
q: "select * from ab join xy on x = a and y = a order by 1, 3",
101+
types: []plan.JoinType{plan.JoinTypeMerge},
102+
exp: []sql.Row{{3, 1, 3, 3}},
103+
},
104+
{
105+
q: "set @@SESSION.disable_merge_join = 1",
106+
exp: []sql.Row{{}},
107+
},
108+
{
109+
q: "select /*+ JOIN_ORDER(ab, xy) MERGE_JOIN(ab, xy)*/ * from ab join xy on y = a order by 1, 3",
110+
types: []plan.JoinType{plan.JoinTypeLookup},
111+
exp: []sql.Row{{0, 2, 1, 0}, {1, 2, 2, 1}, {2, 2, 0, 2}, {3, 1, 3, 3}},
112+
},
113+
{
114+
q: "select * from ab join xy on x = a and y = a order by 1, 3",
115+
types: []plan.JoinType{plan.JoinTypeLookup},
116+
exp: []sql.Row{{3, 1, 3, 3}},
117+
},
118+
},
119+
},
81120
{
82121
name: "merge join unary index",
83122
setup: []string{
@@ -1725,8 +1764,17 @@ join uv d on d.u = c.x`,
17251764
}
17261765

17271766
func TestJoinPlanning(t *testing.T, harness Harness) {
1728-
for _, tt := range JoinPlanningTests {
1767+
runJoinPlanningTests(t, harness, JoinPlanningTests)
1768+
}
1769+
1770+
func runJoinPlanningTests(t *testing.T, harness Harness, tests []joinPlanScript) {
1771+
for _, tt := range tests {
17291772
t.Run(tt.name, func(t *testing.T) {
1773+
if sh, ok := harness.(SkippingHarness); ok {
1774+
if sh.SkipQueryTest(tt.name) {
1775+
t.Skip(tt.name)
1776+
}
1777+
}
17301778
harness.Setup([]setup.SetupScript{setup.MydbData[0], tt.setup})
17311779
e := mustNewEngine(t, harness)
17321780
defer e.Close()
@@ -1750,7 +1798,6 @@ func TestJoinPlanning(t *testing.T, harness Harness) {
17501798
})
17511799
}
17521800
}
1753-
17541801
func evalJoinTypeTest(t *testing.T, harness Harness, e QueryEngine, query string, types []plan.JoinType, skipOld bool) {
17551802
t.Run(query+" join types", func(t *testing.T) {
17561803
if skipOld {

enginetest/join_stats_tests.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,8 @@ var JoinStatTests = []struct {
135135
{
136136
// b is smallest table, bxc is smallest b-connected join
137137
// due to b < 0 filter and positive c skew
138-
q: "select /*+ LEFT_DEEP */ count(*) from u0 b join `u-15` a on a.b = b.b join `u+15` c on a.b = c.b where b.b < -2",
139-
order: [][]string{{"b", "c", "a"}},
140-
},
141-
{
142138
q: "select /*+ LEFT_DEEP */ count(*) from u0 b join `u-15` a on a.b = b.b join `u+15` c on a.b = c.b where b.b < -2",
143-
order: [][]string{{"b", "c", "a"}},
139+
order: [][]string{{"b", "c", "a"}, {"a", "c", "b"}},
144140
},
145141
{
146142
// b is smallest table, bxa is smallest b-connected join

enginetest/memory_engine_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ func TestLateralJoin(t *testing.T) {
111111

112112
// TestJoinPlanning runs join-specific tests for merge
113113
func TestJoinPlanning(t *testing.T) {
114-
enginetest.TestJoinPlanning(t, enginetest.NewDefaultMemoryHarness())
114+
harness := enginetest.NewDefaultMemoryHarness()
115+
if harness.IsUsingServer() {
116+
harness.QueriesToSkip("block merge join")
117+
}
118+
enginetest.TestJoinPlanning(t, harness)
115119
}
116120

117121
// TestJoinOps runs join-specific tests for merge

enginetest/queries/imdb_plans.go

Lines changed: 22664 additions & 23880 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enginetest/queries/integration_plans.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/dolthub/go-mysql-server
33
require (
44
github.com/cespare/xxhash/v2 v2.2.0
55
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
6-
github.com/dolthub/go-icu-regex v0.0.0-20250303123116-549b8d7cad00
6+
github.com/dolthub/go-icu-regex v0.0.0-20250319212010-451ea8d003fa
77
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71
88
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81
99
github.com/dolthub/vitess v0.0.0-20250304211657-920ca9ec2b9a

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1G
5454
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2/go.mod h1:mIEZOHnFx4ZMQeawhw9rhsj+0zwQj7adVsnBX7t+eKY=
5555
github.com/dolthub/go-icu-regex v0.0.0-20250303123116-549b8d7cad00 h1:rh2ij2yTYKJWlX+c8XRg4H5OzqPewbU1lPK8pcfVmx8=
5656
github.com/dolthub/go-icu-regex v0.0.0-20250303123116-549b8d7cad00/go.mod h1:ylU4XjUpsMcvl/BKeRRMXSH7e7WBrPXdSLvnRJYrxEA=
57+
github.com/dolthub/go-icu-regex v0.0.0-20250319212010-451ea8d003fa h1:NFbzJ4wjWRz32nz2EimbrHpRx1Xt6k+IaR8N+j4x62k=
58+
github.com/dolthub/go-icu-regex v0.0.0-20250319212010-451ea8d003fa/go.mod h1:ylU4XjUpsMcvl/BKeRRMXSH7e7WBrPXdSLvnRJYrxEA=
5759
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71 h1:bMGS25NWAGTEtT5tOBsCuCrlYnLRKpbJVJkDbrTRhwQ=
5860
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71/go.mod h1:2/2zjLQ/JOOSbbSboojeg+cAwcRV0fDLzIiWch/lhqI=
5961
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9XGFa6q5Ap4Z/OhNkAMBaK5YeuEzwJt+NZdhiE=

sql/analyzer/fix_exec_indexes.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,10 @@ func (s *idxScope) visitSelf(n sql.Node) error {
494494
newCheck.Expr = newE
495495
s.checks = append(s.checks, &newCheck)
496496
}
497+
for _, r := range n.Returning {
498+
newE := fixExprToScope(r, dstScope)
499+
s.expressions = append(s.expressions, newE)
500+
}
497501
case *plan.Update:
498502
newScope := s.copy()
499503
srcScope := s.childScopes[0]
@@ -543,7 +547,8 @@ func (s *idxScope) finalizeSelf(n sql.Node) (sql.Node, error) {
543547
nn := *n
544548
nn.Source = s.children[0]
545549
nn.Destination = s.children[1]
546-
nn.OnDupExprs = s.expressions
550+
nn.OnDupExprs = s.expressions[:len(n.OnDupExprs)]
551+
nn.Returning = s.expressions[len(n.OnDupExprs):]
547552
return nn.WithChecks(s.checks), nil
548553
default:
549554
s.ids = columnIdsForNode(n)

sql/analyzer/indexed_joins.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ func replanJoin(ctx *sql.Context, n *plan.JoinNode, a *Analyzer, scope *plan.Sco
200200
return nil, err
201201
}
202202

203+
m.SetDefaultHints()
203204
hints := memo.ExtractJoinHint(n)
204205
for _, h := range hints {
205206
// this should probably happen earlier, but the root is not
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2025 Dolthub, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package function
16+
17+
import (
18+
regex "github.com/dolthub/go-icu-regex"
19+
"github.com/sirupsen/logrus"
20+
)
21+
22+
func init() {
23+
// By default, the dolthub/go-icu-regex package will panic if a regex object is
24+
// finalized without having the Dispose() method called. Instead of panicing, we
25+
// add a RegexLeakHandler to log an error.
26+
regex.SetRegexLeakHandler(func() {
27+
logrus.Error("Detected leaked go-icu-regex.Regex instance")
28+
})
29+
}

0 commit comments

Comments
 (0)