Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't turn on multiStatements when using memory driver #2314

Closed
seanlaff opened this issue Feb 5, 2024 · 2 comments
Closed

Can't turn on multiStatements when using memory driver #2314

seanlaff opened this issue Feb 5, 2024 · 2 comments

Comments

@seanlaff
Copy link

seanlaff commented Feb 5, 2024

If I create an in-memory server and supply multiStatements=true in the connection dsn, mutli statements work. However, I have not been able to find a way to reproduce this behavior when using the the in-memory driver directly- is that an expected limitation?

My usecase: I have tests that depend on mysql and I'm interested in running an in-memory go-mysql-server in such a way that I wouldn't have to worry about port coordination. I thought I could use the driver directly to avoid the networking stack, but maybe I misunderstand the abstractions.

I copied the example from driver/example (Im using main d5876b4)

import (
	"database/sql"
	"testing"

	"github.com/dolthub/go-mysql-server/driver"
	"github.com/dolthub/go-mysql-server/memory"
	msql "github.com/dolthub/go-mysql-server/sql"
)

var provider = memory.NewDBProvider(memory.NewDatabase("mydb"))

type factory struct{}

func (factory) Resolve(name string, options *driver.Options) (string, msql.DatabaseProvider, error) {
	return name, provider, nil
}

func TestMultiStatement(t *testing.T) {
	sql.Register("sqle", driver.New(factory{}, nil))
	db, err := sql.Open("sqle", "")
	if err != nil {
		panic(err)
	}

	_, err = db.Exec("USE mydb")
	if err != nil {
		panic(err)
	}
	const createTwoTables = `CREATE TABLE table1 (id int); CREATE TABLE table2 (id int);`
	_, err = db.Exec(createTwoTables)
	if err != nil {
		panic(err)
	}
	res, err := db.Query("show tables")
	if err != nil {
		panic(err)
	}

	tables := []string{}
	for res.Next() {
		var table string
		res.Scan(&table)
		tables = append(tables, table)
	}
	if len(tables) != 2 {
		t.Fatalf("didn't find both tables, tables: %s", tables)
	}
}

This test fails- which I assume is expected since I have yet to supply the multiStatements flag. I tried a few variations:

Building a conn from the driver, supplying the multiStatements flag, no luck:

	drv := driver.New(factory{}, nil)
	conn, err := drv.OpenConnector("/mydb?multiStatements=true")
        if err != nil {
		panic(err)
	}
	db := sql.OpenDB(conn)

Also tried having my factory implement SessionBuilder, and then supplying the raw Capabilities bit flag directly

func (factory) NewSession(ctx context.Context, id uint32, conn *driver.Connector) (msql.Session, error) {
	sess := msql.NewBaseSessionWithClientServer(conn.Server(), msql.Client{
		Address:      "",
		Capabilities: 1 << 16, // copied from "vitess.io/vitess/go/mysql".CapabilityClientMultiStatements
	}, id)
	return memory.NewSession(sess, provider), nil
}

also no luck.

Would anyone be able to point me in the right direction? I am also happy to make a PR if needed. (I have a mysqldump of my db schema which I'm trying to load, as a precursor to tests).

@seanlaff
Copy link
Author

seanlaff commented Feb 5, 2024

Looking further, it seems like the driver dir is a separate implementation from the main server. Perhaps I'd be better off trying something like https://pkg.go.dev/google.golang.org/grpc/test/bufconn as a way to avoid using the host's networking stack- though I'm not sure if I'll be able to thread that through as Handler is all private

@seanlaff
Copy link
Author

seanlaff commented Feb 6, 2024

Closing in favor of #2319, which seems like a better approach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants