Skip to content

Commit 505a850

Browse files
committed
Merge branch 'main' of github.com:dolthub/go-mysql-server
2 parents e22aa12 + f73a318 commit 505a850

19 files changed

+381
-122
lines changed

enginetest/queries/information_schema_queries.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,18 @@ var InfoSchemaScripts = []ScriptTest{
874874
},
875875
},
876876
},
877+
{
878+
Name: "issue 8930: connect to info schema",
879+
SetUpScript: []string{
880+
"use information_schema",
881+
},
882+
Assertions: []ScriptTestAssertion{
883+
{
884+
Query: "SELECT C.COLUMN_NAME AS label, 'connection.column' as \"type\", C.TABLE_NAME AS \"table\", C.DATA_TYPE AS \"dataType\", CAST(C.CHARACTER_MAXIMUM_LENGTH AS UNSIGNED) AS size, CAST(UPPER( CONCAT( C.DATA_TYPE, CASE WHEN C.DATA_TYPE = 'text' THEN '' ELSE ( CASE WHEN C.CHARACTER_MAXIMUM_LENGTH > 0 THEN ( CONCAT('(', C.CHARACTER_MAXIMUM_LENGTH, ')') ) ELSE '' END ) END ) ) AS CHAR CHARACTER SET utf8) AS \"detail\", C.TABLE_CATALOG AS \"catalog\", C.TABLE_SCHEMA AS \"database\", C.TABLE_SCHEMA AS \"schema\", C.COLUMN_DEFAULT AS \"defaultValue\", C.IS_NULLABLE AS \"isNullable\", (CASE WHEN C.COLUMN_KEY = 'PRI' THEN 1 ELSE 0 END) AS \"isPk\", (CASE WHEN KCU.REFERENCED_COLUMN_NAME IS NULL THEN 0 ELSE 1 END) AS \"isFk\" FROM INFORMATION_SCHEMA.COLUMNS AS C LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU ON ( C.TABLE_NAME = KCU.TABLE_NAME AND C.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND C.TABLE_CATALOG = KCU.TABLE_CATALOG AND C.COLUMN_NAME = KCU.COLUMN_NAME ) JOIN INFORMATION_SCHEMA.TABLES AS T ON C.TABLE_NAME = T.TABLE_NAME AND C.TABLE_SCHEMA = T.TABLE_SCHEMA AND C.TABLE_CATALOG = T.TABLE_CATALOG WHERE C.TABLE_SCHEMA = 'dev' AND C.TABLE_NAME = 'countries' AND C.TABLE_CATALOG = 'def' ORDER BY C.TABLE_NAME, C.ORDINAL_POSITION",
885+
Expected: []sql.Row{},
886+
},
887+
},
888+
},
877889
{
878890
Name: "query does not use optimization rule on LIKE clause because info_schema db charset is utf8mb3",
879891
SetUpScript: []string{

enginetest/queries/query_plans.go

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

enginetest/queries/trigger_queries.go

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3421,6 +3421,135 @@ end;
34213421
},
34223422
},
34233423
},
3424+
3425+
{
3426+
Name: "insert trigger with stored procedure with deletes",
3427+
SetUpScript: []string{
3428+
"create table t (i int);",
3429+
"create table t1 (j int);",
3430+
"insert into t1 values (1);",
3431+
"create table t2 (k int);",
3432+
"insert into t2 values (1);",
3433+
"create table t3 (l int);",
3434+
"insert into t3 values (1);",
3435+
"create table t4 (m int);",
3436+
`
3437+
create procedure proc(x int)
3438+
begin
3439+
delete from t2 where k = (select j from t1 where j = x);
3440+
update t3 set l = 10 where l = x;
3441+
insert into t4 values (x);
3442+
end;
3443+
`,
3444+
`
3445+
create trigger trig before insert on t
3446+
for each row
3447+
begin
3448+
call proc(new.i);
3449+
end;
3450+
`,
3451+
},
3452+
Assertions: []ScriptTestAssertion{
3453+
{
3454+
Query: "insert into t values (1);",
3455+
Expected: []sql.Row{
3456+
{types.NewOkResult(1)},
3457+
},
3458+
},
3459+
{
3460+
Query: "select * from t;",
3461+
Expected: []sql.Row{
3462+
{1},
3463+
},
3464+
},
3465+
{
3466+
Query: "select * from t1;",
3467+
Expected: []sql.Row{
3468+
{1},
3469+
},
3470+
},
3471+
{
3472+
Query: "select * from t2;",
3473+
Expected: []sql.Row{},
3474+
},
3475+
{
3476+
Query: "select * from t3;",
3477+
Expected: []sql.Row{
3478+
{10},
3479+
},
3480+
},
3481+
{
3482+
Query: "select * from t4;",
3483+
Expected: []sql.Row{
3484+
{1},
3485+
},
3486+
},
3487+
},
3488+
},
3489+
3490+
{
3491+
Name: "delete trigger with stored procedure with deletes",
3492+
SetUpScript: []string{
3493+
"create table t (i int);",
3494+
"insert into t values (1)",
3495+
"create table t1 (j int);",
3496+
"insert into t1 values (1);",
3497+
"create table t2 (k int);",
3498+
"insert into t2 values (1);",
3499+
"create table t3 (l int);",
3500+
"insert into t3 values (1);",
3501+
"create table t4 (m int);",
3502+
`
3503+
create procedure proc(x int)
3504+
begin
3505+
delete from t2 where k = (select j from t1 where j = x);
3506+
update t3 set l = 10 where l = x;
3507+
insert into t4 values (x);
3508+
end;
3509+
`,
3510+
`
3511+
create trigger trig before delete on t
3512+
for each row
3513+
begin
3514+
call proc(old.i);
3515+
end;
3516+
`,
3517+
},
3518+
Assertions: []ScriptTestAssertion{
3519+
{
3520+
Query: "delete from t where i = 1;",
3521+
Expected: []sql.Row{
3522+
{types.NewOkResult(1)},
3523+
},
3524+
},
3525+
{
3526+
Query: "select * from t;",
3527+
Expected: []sql.Row{},
3528+
},
3529+
{
3530+
Query: "select * from t1;",
3531+
Expected: []sql.Row{
3532+
{1},
3533+
},
3534+
},
3535+
{
3536+
Query: "select * from t2;",
3537+
Expected: []sql.Row{},
3538+
},
3539+
{
3540+
Query: "select * from t3;",
3541+
Expected: []sql.Row{
3542+
{10},
3543+
},
3544+
},
3545+
{
3546+
Query: "select * from t4;",
3547+
Expected: []sql.Row{
3548+
{1},
3549+
},
3550+
},
3551+
},
3552+
},
34243553
}
34253554

34263555
var TriggerCreateInSubroutineTests = []ScriptTest{

enginetest/server_engine_test.go

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ type serverScriptTestAssertion struct {
8383
expectedRows []any
8484

8585
// can't avoid writing custom comparator because of how gosql.Rows.Scan() works
86-
checkRows func(rows *gosql.Rows, expectedRows []any) (bool, error)
86+
checkRows func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error)
8787
}
8888

8989
type serverScriptTest struct {
@@ -108,7 +108,7 @@ func TestServerPreparedStatements(t *testing.T) {
108108
expectedRows: []any{
109109
[]float64{321.4},
110110
},
111-
checkRows: func(rows *gosql.Rows, expectedRows []any) (bool, error) {
111+
checkRows: func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error) {
112112
var i float64
113113
var rowNum int
114114
for rows.Next() {
@@ -133,7 +133,7 @@ func TestServerPreparedStatements(t *testing.T) {
133133
[]float64{213.4},
134134
[]float64{213.4},
135135
},
136-
checkRows: func(rows *gosql.Rows, expectedRows []any) (bool, error) {
136+
checkRows: func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error) {
137137
var i float64
138138
var rowNum int
139139
for rows.Next() {
@@ -197,7 +197,7 @@ func TestServerPreparedStatements(t *testing.T) {
197197
[]uint64{uint64(math.MaxInt64 + 1)},
198198
[]uint64{uint64(math.MaxUint64)},
199199
},
200-
checkRows: func(rows *gosql.Rows, expectedRows []any) (bool, error) {
200+
checkRows: func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error) {
201201
var i uint64
202202
var rowNum int
203203
for rows.Next() {
@@ -247,7 +247,7 @@ func TestServerPreparedStatements(t *testing.T) {
247247
[]int64{int64(-1)},
248248
[]int64{int64(math.MaxInt64)},
249249
},
250-
checkRows: func(rows *gosql.Rows, expectedRows []any) (bool, error) {
250+
checkRows: func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error) {
251251
var i int64
252252
var rowNum int
253253
for rows.Next() {
@@ -267,6 +267,51 @@ func TestServerPreparedStatements(t *testing.T) {
267267
},
268268
},
269269
},
270+
{
271+
name: "regression test for incorrectly setting QFlagMax1Row flag",
272+
setup: []string{
273+
"create table test(c0 int not null, c1 int not null, pk int primary key, key (c0, c1));",
274+
"insert into test values (2, 3, 1), (5, 6, 4), (2, 3, 7);",
275+
},
276+
assertions: []serverScriptTestAssertion{
277+
{
278+
query: "select * from test where c0 = 2 and c1 = 3 order by pk;",
279+
expectedRows: []any{
280+
[]uint64{uint64(2), uint64(3), uint64(1)},
281+
[]uint64{uint64(2), uint64(3), uint64(7)},
282+
},
283+
checkRows: func(t *testing.T, rows *gosql.Rows, expectedRows []any) (bool, error) {
284+
var c0, c1, pk uint64
285+
var rowNum int
286+
for rows.Next() {
287+
err := rows.Scan(&c0, &c1, &pk)
288+
require.NoError(t, err)
289+
if err != nil {
290+
return false, err
291+
}
292+
require.Less(t, rowNum, len(expectedRows))
293+
if rowNum >= len(expectedRows) {
294+
return false, nil
295+
}
296+
require.Equal(t, c0, expectedRows[rowNum].([]uint64)[0])
297+
if c0 != expectedRows[rowNum].([]uint64)[0] {
298+
return false, nil
299+
}
300+
require.Equal(t, c1, expectedRows[rowNum].([]uint64)[1])
301+
if c1 != expectedRows[rowNum].([]uint64)[1] {
302+
return false, nil
303+
}
304+
require.Equal(t, pk, expectedRows[rowNum].([]uint64)[2])
305+
if pk != expectedRows[rowNum].([]uint64)[2] {
306+
return false, nil
307+
}
308+
rowNum++
309+
}
310+
return true, nil
311+
},
312+
},
313+
},
314+
},
270315
}
271316

272317
port, perr := findEmptyPort()
@@ -315,8 +360,10 @@ func TestServerPreparedStatements(t *testing.T) {
315360
if assertion.expectErr {
316361
require.Error(t, err)
317362
return
363+
} else {
364+
require.NoError(t, err)
318365
}
319-
ok, err := assertion.checkRows(rows, assertion.expectedRows)
366+
ok, err := assertion.checkRows(t, rows, assertion.expectedRows)
320367
require.NoError(t, err)
321368
require.True(t, ok)
322369
})

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
github.com/dolthub/go-icu-regex v0.0.0-20250303123116-549b8d7cad00
77
github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71
88
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81
9-
github.com/dolthub/vitess v0.0.0-20250228011932-c4f6bba87730
9+
github.com/dolthub/vitess v0.0.0-20250304211657-920ca9ec2b9a
1010
github.com/go-kit/kit v0.10.0
1111
github.com/go-sql-driver/mysql v1.7.2-0.20231213112541-0004702b931d
1212
github.com/gocraft/dbr/v2 v2.7.2

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9X
6060
github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY=
6161
github.com/dolthub/vitess v0.0.0-20250228011932-c4f6bba87730 h1:GtlMVB7+Z7fZZj7BHRFd2rzxZ574dJ8cB/EHWdq1kbY=
6262
github.com/dolthub/vitess v0.0.0-20250228011932-c4f6bba87730/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
63+
github.com/dolthub/vitess v0.0.0-20250303224041-5cc89c183bc4 h1:wtS9ZWEyEeYzLCcqdGUo+7i3hAV5MWuY9Z7tYbQa65A=
64+
github.com/dolthub/vitess v0.0.0-20250303224041-5cc89c183bc4/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
65+
github.com/dolthub/vitess v0.0.0-20250304211657-920ca9ec2b9a h1:HIH9g4z+yXr4DIFyT6L5qOIEGJ1zVtlj6baPyHAG4Yw=
66+
github.com/dolthub/vitess v0.0.0-20250304211657-920ca9ec2b9a/go.mod h1:1gQZs/byeHLMSul3Lvl3MzioMtOW1je79QYGyi2fd70=
6367
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
6468
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
6569
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=

server/context.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ type SessionManager struct {
4949
connections map[uint32]*mysql.Conn
5050
lastPid uint64
5151
ctxFactory sql.ContextFactory
52+
// Implements WaitForClosedConnections(), which is only used
53+
// at server shutdown to allow the integrator to ensure that
54+
// no connections are being handled by handlers.
55+
wg sync.WaitGroup
5256
}
5357

5458
// NewSessionManager creates a SessionManager with the given SessionBuilder.
@@ -82,6 +86,13 @@ func (s *SessionManager) nextPid() uint64 {
8286
return s.lastPid
8387
}
8488

89+
// Block the calling thread until all known connections are closed. It
90+
// is an error to call this concurrently while the server might still
91+
// be accepting new connections.
92+
func (s *SessionManager) WaitForClosedConnections() {
93+
s.wg.Wait()
94+
}
95+
8596
// AddConn adds a connection to be tracked by the SessionManager. Should be called as
8697
// soon as possible after the server has accepted the connection. Results in
8798
// the connection being tracked by ProcessList and being available through
@@ -93,6 +104,7 @@ func (s *SessionManager) AddConn(conn *mysql.Conn) {
93104
defer s.mu.Unlock()
94105
s.connections[conn.ConnectionID] = conn
95106
s.processlist.AddConnection(conn.ConnectionID, conn.RemoteAddr().String())
107+
s.wg.Add(1)
96108
}
97109

98110
// NewSession creates a Session for the given connection and saves it to the session pool.
@@ -270,6 +282,7 @@ func (s *SessionManager) KillConnection(connID uint32) error {
270282
func (s *SessionManager) RemoveConn(conn *mysql.Conn) {
271283
s.mu.Lock()
272284
defer s.mu.Unlock()
285+
s.wg.Done()
273286
if cur, ok := s.sessions[conn.ConnectionID]; ok {
274287
sql.SessionEnd(cur)
275288
}

0 commit comments

Comments
 (0)