Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4b0176c
First pass at ViewProvider interface
zachmu Oct 13, 2021
f4fd9d6
Fixed errors from interface change:
zachmu Oct 13, 2021
6e57370
Fix remaining broken tests
zachmu Oct 13, 2021
85d6b4f
Updated create and drop view to use either the registry or the provid…
zachmu Oct 13, 2021
daa260e
Added view storage to memory database, pruned view registry interface
zachmu Oct 14, 2021
3b8b9fc
Fixed create and drop view tests
zachmu Oct 14, 2021
b2fa665
Fixed tests for create view
zachmu Oct 14, 2021
dfb5e4c
Added native tests to drop view
zachmu Oct 14, 2021
72c0383
Further fleshed out interface and fixed tests
zachmu Oct 15, 2021
2dd79b5
Cleaned up context construction
zachmu Oct 15, 2021
2557e83
Moving view and index registries out of context, into session
zachmu Oct 15, 2021
ed76569
Moving registries out of context
zachmu Oct 15, 2021
f0de1a5
Fixed more tests
zachmu Oct 15, 2021
71a9222
Fixed all but two tests
zachmu Oct 15, 2021
9c6f151
Fixed last test
zachmu Oct 15, 2021
9a728f8
[ga-format-pr] Run ./format_repo.sh to fix formatting
zachmu Oct 15, 2021
f5f68e4
Consolidated view functions into a single interface. Fixed the way in…
zachmu Oct 18, 2021
6399960
Merge branch 'zachmu/views' of github.com:dolthub/go-mysql-server int…
zachmu Oct 18, 2021
c2f89fc
Fixed bug in in-memory view initiatlization for engine test
zachmu Oct 18, 2021
199d7e2
Fix change that breaks everything
zachmu Oct 18, 2021
9f4beb6
Added missing context arg to new interface, committing ritual seppuku…
zachmu Oct 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions auth/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import (

const port = 33336

func authEngine(au auth.Auth) (*sqle.Engine, *sql.IndexRegistry, error) {
func authEngine(au auth.Auth) (*sqle.Engine, error) {

tblName := "test"
table := memory.NewTable(tblName, sql.Schema{
Expand All @@ -44,18 +44,17 @@ func authEngine(au auth.Auth) (*sqle.Engine, *sql.IndexRegistry, error) {
db.AddTable(tblName, table)

pro := memory.NewMemoryDBProvider(db)
idxReg := sql.NewIndexRegistry()

a := analyzer.NewBuilder(pro).Build()
config := &sqle.Config{Auth: au}

return sqle.New(a, config), idxReg, nil
return sqle.New(a, config), nil
}

func authServer(a auth.Auth) (*server.Server, *sql.IndexRegistry, error) {
engine, idxReg, err := authEngine(a)
func authServer(a auth.Auth) (*server.Server, error) {
engine, err := authEngine(a)
if err != nil {
return nil, nil, err
return nil, err
}

config := server.Config{
Expand All @@ -67,12 +66,12 @@ func authServer(a auth.Auth) (*server.Server, *sql.IndexRegistry, error) {

s, err := server.NewDefaultServer(config, engine)
if err != nil {
return nil, nil, err
return nil, err
}

go s.Start()

return s, idxReg, nil
return s, nil
}

func connString(user, password string) string {
Expand All @@ -94,7 +93,7 @@ func testAuthentication(
t.Helper()
req := require.New(t)

s, _, err := authServer(a)
s, err := authServer(a)
req.NoError(err)

for _, c := range tests {
Expand Down Expand Up @@ -150,7 +149,7 @@ func testAuthorization(
t.Helper()
req := require.New(t)

e, idxReg, err := authEngine(a)
e, err := authEngine(a)
req.NoError(err)

for i, c := range tests {
Expand All @@ -160,9 +159,7 @@ func testAuthorization(
session := sql.NewSession("localhost", sql.Client{Address: "client", User: c.user}, uint32(i))
ctx := sql.NewContext(context.TODO(),
sql.WithSession(session),
sql.WithPid(uint64(i)),
sql.WithIndexRegistry(idxReg),
sql.WithViewRegistry(sql.NewViewRegistry())).WithCurrentDB("test")
sql.WithPid(uint64(i))).WithCurrentDB("test")

_, _, err := e.Query(ctx, c.query)

Expand Down Expand Up @@ -190,7 +187,7 @@ func testAudit(
t.Helper()
req := require.New(t)

s, _, err := authServer(a)
s, err := authServer(a)
req.NoError(err)

for _, c := range tests {
Expand Down
4 changes: 1 addition & 3 deletions driver/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ func (c *Conn) newContextWithQuery(ctx context.Context, query string) (*sql.Cont
sql.WithQuery(query),
sql.WithPid(c.dbConn.nextProcessID()),
sql.WithMemoryManager(c.dbConn.engine.MemoryManager),
sql.WithProcessList(c.dbConn.engine.ProcessList),
sql.WithIndexRegistry(c.indexes),
sql.WithViewRegistry(c.views))
sql.WithProcessList(c.dbConn.engine.ProcessList))
}

type fakeTransaction struct{}
Expand Down
77 changes: 22 additions & 55 deletions enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ var infoSchemaTables = []string{
// TestInfoSchema runs tests of the information_schema database
func TestInfoSchema(t *testing.T, harness Harness) {
dbs := CreateSubsetTestData(t, harness, infoSchemaTables)
engine := NewEngineWithDbs(t, harness, dbs, nil)
engine := NewEngineWithDbs(t, harness, dbs)
createIndexes(t, harness, engine)
createForeignKeys(t, harness, engine)

Expand Down Expand Up @@ -122,7 +122,7 @@ func TestReadOnlyDatabases(t *testing.T, harness Harness) {
}
dbs := createReadOnlyDatabases(ro)
dbs = createSubsetTestData(t, harness, nil, dbs[0], dbs[1])
engine := NewEngineWithDbs(t, harness, dbs, nil)
engine := NewEngineWithDbs(t, harness, dbs)

for _, querySet := range [][]QueryTest{
QueryTests,
Expand Down Expand Up @@ -939,13 +939,7 @@ func TestScript(t *testing.T, harness Harness, script ScriptTest) bool {
return t.Run(script.Name, func(t *testing.T) {
myDb := harness.NewDatabase("mydb")
databases := []sql.Database{myDb}

var idxDriver sql.IndexDriver
if ih, ok := harness.(IndexDriverHarness); ok {
idxDriver = ih.IndexDriver(databases)
}
e := NewEngineWithDbs(t, harness, databases, idxDriver)

e := NewEngineWithDbs(t, harness, databases)
TestScriptWithEngine(t, e, harness, script)
})
}
Expand Down Expand Up @@ -1000,14 +994,7 @@ func TestTransactionScripts(t *testing.T, harness Harness) {
func TestTransactionScript(t *testing.T, harness Harness, script TransactionTest) bool {
return t.Run(script.Name, func(t *testing.T) {
myDb := harness.NewDatabase("mydb")
databases := []sql.Database{myDb}

var idxDriver sql.IndexDriver
if ih, ok := harness.(IndexDriverHarness); ok {
idxDriver = ih.IndexDriver(databases)
}
e := NewEngineWithDbs(t, harness, databases, idxDriver)

e := NewEngineWithDbs(t, harness, []sql.Database{myDb})
TestTransactionScriptWithEngine(t, e, harness, script)
})
}
Expand Down Expand Up @@ -1060,10 +1047,6 @@ func getClient(query string) string {
return strings.TrimSpace(strings.TrimPrefix(query, "client"))
}

// This method is the only place we can reliably test newly created views, because view definitions live in the
// context, as opposed to being defined by integrators with a ViewDatabase interface, and we lose that context with
// our standard method of using a new context object per query.
// TODO: fix this by introducing sql.ViewDatabase
func TestViews(t *testing.T, harness Harness) {
e := NewEngine(t, harness)
ctx := NewContext(harness)
Expand Down Expand Up @@ -2909,8 +2892,7 @@ func TestTracing(t *testing.T, harness Harness) {

tracer := new(test.MemTracer)

ctx := sql.NewContext(context.Background(),
sql.WithTracer(tracer), sql.WithViewRegistry(sql.NewViewRegistry())).WithCurrentDB("mydb")
ctx := sql.NewContext(context.Background(), sql.WithTracer(tracer)).WithCurrentDB("mydb")

_, iter, err := e.Query(ctx, `SELECT DISTINCT i
FROM mytable
Expand Down Expand Up @@ -2950,7 +2932,7 @@ func TestTracing(t *testing.T, harness Harness) {
// Runs tests on SHOW TABLE STATUS queries.
func TestShowTableStatus(t *testing.T, harness Harness) {
dbs := CreateSubsetTestData(t, harness, infoSchemaTables)
engine := NewEngineWithDbs(t, harness, dbs, nil)
engine := NewEngineWithDbs(t, harness, dbs)
createIndexes(t, harness, engine)
createForeignKeys(t, harness, engine)

Expand Down Expand Up @@ -3531,13 +3513,14 @@ var pid uint64

func NewContext(harness Harness) *sql.Context {
ctx := harness.NewContext()
currentDB := ctx.GetCurrentDatabase()
if currentDB == "" {
currentDB = "mydb"
ctx.WithCurrentDB(currentDB)

// Select a current database if there isn't one yet
if ctx.GetCurrentDatabase() == "" {
ctx.SetCurrentDatabase("mydb")
}

_ = ctx.ViewRegistry.Register(currentDB,
// Add our in-session view to the context
_ = ctx.GetViewRegistry().Register("mydb",
plan.NewSubqueryAlias(
"myview",
"SELECT * FROM mytable",
Expand All @@ -3562,7 +3545,7 @@ func NewSession(harness Harness) *sql.Context {
ctx.WithCurrentDB(currentDB)
}

_ = ctx.ViewRegistry.Register(currentDB,
_ = ctx.GetViewRegistry().Register(currentDB,
plan.NewSubqueryAlias(
"myview",
"SELECT * FROM mytable",
Expand All @@ -3574,42 +3557,26 @@ func NewSession(harness Harness) *sql.Context {
return ctx
}

// Returns a new BaseSession compatible with these tests. Most tests will work with any session implementation, but for
// full compatibility use a session based on this one.
// NewBaseSession returns a new BaseSession compatible with these tests. Most tests will work with any session
// implementation, but for full compatibility use a session based on this one.
func NewBaseSession() sql.Session {
return sql.NewSession("address", sql.Client{Address: "client", User: "user"}, 1)
}

func NewContextWithEngine(harness Harness, engine *sqle.Engine) *sql.Context {
ctx := NewContext(harness)

// TODO: move index driver back out of context, into catalog, make this unnecessary
if idh, ok := harness.(IndexDriverHarness); ok {
driver := idh.IndexDriver(engine.Analyzer.Catalog.AllDatabases())
if driver != nil {
ctx.IndexRegistry.RegisterIndexDriver(driver)
ctx.IndexRegistry.LoadIndexes(ctx, engine.Analyzer.Catalog.AllDatabases())
}
}

return ctx
return NewContext(harness)
}

// NewEngine creates test data and returns an engine using the harness provided.
func NewEngine(t *testing.T, harness Harness) *sqle.Engine {
dbs := CreateTestData(t, harness)
var idxDriver sql.IndexDriver
if ih, ok := harness.(IndexDriverHarness); ok {
idxDriver = ih.IndexDriver(dbs)
}
engine := NewEngineWithDbs(t, harness, dbs, idxDriver)

engine := NewEngineWithDbs(t, harness, dbs)
return engine
}

// NewEngineWithDbs returns a new engine with the databases provided. This is useful if you don't want to implement a
// full harness but want to run your own tests on DBs you create.
func NewEngineWithDbs(t *testing.T, harness Harness, databases []sql.Database, driver sql.IndexDriver) *sqle.Engine {
func NewEngineWithDbs(t *testing.T, harness Harness, databases []sql.Database) *sqle.Engine {
databases = append(databases, information_schema.NewInformationSchemaDatabase())
provider := harness.NewDatabaseProvider(databases...)

Expand All @@ -3620,12 +3587,12 @@ func NewEngineWithDbs(t *testing.T, harness Harness, databases []sql.Database, d
a = analyzer.NewDefault(provider)
}

idxReg := sql.NewIndexRegistry()
if driver != nil {
idxReg.RegisterIndexDriver(driver)
engine := sqle.New(a, new(sqle.Config))

if idh, ok := harness.(IndexDriverHarness); ok {
idh.InitializeIndexDriver(engine.Analyzer.Catalog.AllDatabases())
}

engine := sqle.New(a, new(sqle.Config))
return engine
}

Expand Down
2 changes: 1 addition & 1 deletion enginetest/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Example() {
db := createTestDatabase()
e := sqle.NewDefault(sql.NewDatabaseProvider(db))

ctx := sql.NewContext(context.Background(), sql.WithIndexRegistry(sql.NewIndexRegistry()), sql.WithViewRegistry(sql.NewViewRegistry())).WithCurrentDB("test")
ctx := sql.NewContext(context.Background()).WithCurrentDB("test")

_, r, err := e.Query(ctx, `SELECT name, count(*) FROM mytable
WHERE name = 'John Doe'
Expand Down
5 changes: 2 additions & 3 deletions enginetest/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ type SkippingHarness interface {
// driver they provide.
type IndexDriverHarness interface {
Harness
// IndexDriver returns an index driver for the databases given, which will have been created by calls to
// NewDatabase().
IndexDriver(dbs []sql.Database) sql.IndexDriver
// InitializeIndexDriver initializes the index driver for this test run with the databases given
InitializeIndexDriver(dbs []sql.Database)
}

// IndexHarness is an extension to Harness that lets an integrator test their implementation with native
Expand Down
3 changes: 3 additions & 0 deletions enginetest/memory_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,9 @@ func mergableIndexDriver(dbs []sql.Database) sql.IndexDriver {

func newUnmergableIndex(dbs []sql.Database, tableName string, exprs ...sql.Expression) *memory.UnmergeableIndex {
db, table := findTable(dbs, tableName)
if db == nil {
return nil
}
return &memory.UnmergeableIndex{
memory.MergeableIndex{
DB: db.Name(),
Expand Down
10 changes: 10 additions & 0 deletions enginetest/memoryharness.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,17 @@ type MemoryHarness struct {
parallelism int
numTablePartitions int
indexDriverInitializer IndexDriverInitalizer
driver sql.IndexDriver
nativeIndexSupport bool
session sql.Session
}

func (m *MemoryHarness) InitializeIndexDriver(dbs []sql.Database) {
if m.indexDriverInitializer != nil {
m.driver = m.indexDriverInitializer(dbs)
}
}

func (m *MemoryHarness) NewSession() *sql.Context {
return m.NewContext()
}
Expand Down Expand Up @@ -106,6 +113,9 @@ func (m *MemoryHarness) Parallelism() int {
func (m *MemoryHarness) NewContext() *sql.Context {
if m.session == nil {
m.session = NewBaseSession()
if m.driver != nil {
m.session.GetIndexRegistry().RegisterIndexDriver(m.driver)
}
}

return sql.NewContext(
Expand Down
2 changes: 1 addition & 1 deletion enginetest/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -6687,7 +6687,7 @@ var ViewTests = []QueryTest{
},
// info schema support
{
Query: "select * from information_schema.views where table_schema = 'mydb'",
Query: "select * from information_schema.views where table_schema = 'mydb' order by table_name",
Expected: []sql.Row{
sql.NewRow("def", "mydb", "myview", "SELECT * FROM mytable", "NONE", "YES", "", "DEFINER", "utf8mb4", "utf8mb4_0900_bin"),
sql.NewRow("def", "mydb", "myview2", "SELECT * FROM myview WHERE i = 1", "NONE", "YES", "", "DEFINER", "utf8mb4", "utf8mb4_0900_bin"),
Expand Down
Loading