Giter Site home page Giter Site logo

dolthub / go-mysql-server Goto Github PK

View Code? Open in Web Editor NEW
2.2K 23.0 189.0 56.77 MB

A MySQL-compatible relational database with a storage agnostic query engine. Implemented in pure Go.

License: Apache License 2.0

Makefile 0.01% Go 99.98% C 0.01% C# 0.01% Java 0.01% PHP 0.01% Python 0.01% Ruby 0.01% Shell 0.01%
sql-engine mysql-server query-engine database mysql relational-database sql sql-server

go-mysql-server's Introduction

A MySQL compatible database engine written in pure Go

go-mysql-server is a data-source agnostic SQL engine and server which runs queries on data sources you provide, using the MySQL dialect and wire protocol. A simple in-memory database implementation is included, and you can query any data source you want by implementing your own backend.

Dolt, a SQL database with Git-style versioning, is the main production database implementation of this package. Check out that project for a reference implementation. Or, hop into the Dolt Discord server here if you want to talk to the core developers behind go-mysql-server and Dolt.

Compatibility

With the exception of specific limitations (see below), go-mysql-server is a drop-in replacement for MySQL. Any client library, tool, query, SQL syntax, SQL function, etc. that works with MySQL should also work with go-mysql-server. If you find a gap in functionality, please file an issue.

For full MySQL compatibility documentation, see the Dolt docs on this topic.

Scope of this project

  • SQL server and engine to query your data sources.
  • In-memory database backend implementation suitable for use in tests.
  • Interfaces you can use to implement new backends to query your own data sources.
  • With a few caveats and using a full database implementation, a drop-in MySQL database replacement.

go-mysql-server has two primary uses case:

  1. Stand-in for MySQL in a golang test environment, using the built-in memory database implementation.

  2. Providing access to arbitrary data sources with SQL queries by implementing a handful of interfaces. The most complete real-world implementation is Dolt.

Installation

Add go-mysql-server as a dependency to your project. In the directory with the go.mod file, run:

go get github.com/dolthub/go-mysql-server@latest

Using the in-memory test server

The in-memory test server can replace a real MySQL server in tests. Start the server using the code in the _example directory, also reproduced below.

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/dolthub/vitess/go/vt/proto/query"

	sqle "github.com/dolthub/go-mysql-server"
	"github.com/dolthub/go-mysql-server/memory"
	"github.com/dolthub/go-mysql-server/server"
	"github.com/dolthub/go-mysql-server/sql"
	"github.com/dolthub/go-mysql-server/sql/types"
)

// This is an example of how to implement a MySQL server.
// After running the example, you may connect to it using the following:
//
// > mysql --host=localhost --port=3306 --user=root mydb --execute="SELECT * FROM mytable;"
// +----------+-------------------+-------------------------------+----------------------------+
// | name     | email             | phone_numbers                 | created_at                 |
// +----------+-------------------+-------------------------------+----------------------------+
// | Jane Deo | [email protected] | ["556-565-566","777-777-777"] | 2022-11-01 12:00:00.000001 |
// | Jane Doe | [email protected]      | []                            | 2022-11-01 12:00:00.000001 |
// | John Doe | [email protected]      | ["555-555-555"]               | 2022-11-01 12:00:00.000001 |
// | John Doe | [email protected]   | []                            | 2022-11-01 12:00:00.000001 |
// +----------+-------------------+-------------------------------+----------------------------+
//
// The included MySQL client is used in this example, however any MySQL-compatible client will work.

var (
	dbName    = "mydb"
	tableName = "mytable"
	address   = "localhost"
	port      = 3306
)

func main() {
	pro := createTestDatabase()
	engine := sqle.NewDefault(pro)

	session := memory.NewSession(sql.NewBaseSession(), pro)
	ctx := sql.NewContext(context.Background(), sql.WithSession(session))
	ctx.SetCurrentDatabase("test")

	// This variable may be found in the "users_example.go" file. Please refer to that file for a walkthrough on how to
	// set up the "mysql" database to allow user creation and user checking when establishing connections. This is set
	// to false for this example, but feel free to play around with it and see how it works.
	if enableUsers {
		if err := enableUserAccounts(ctx, engine); err != nil {
			panic(err)
		}
	}

	config := server.Config{
		Protocol: "tcp",
		Address:  fmt.Sprintf("%s:%d", address, port),
	}
	s, err := server.NewServer(config, engine, memory.NewSessionBuilder(pro), nil)
	if err != nil {
		panic(err)
	}
	if err = s.Start(); err != nil {
		panic(err)
	}
}

func createTestDatabase() *memory.DbProvider {
	db := memory.NewDatabase(dbName)
	db.BaseDatabase.EnablePrimaryKeyIndexes()

	pro := memory.NewDBProvider(db)
	session := memory.NewSession(sql.NewBaseSession(), pro)
	ctx := sql.NewContext(context.Background(), sql.WithSession(session))

	table := memory.NewTable(db, tableName, sql.NewPrimaryKeySchema(sql.Schema{
		{Name: "name", Type: types.Text, Nullable: false, Source: tableName, PrimaryKey: true},
		{Name: "email", Type: types.Text, Nullable: false, Source: tableName, PrimaryKey: true},
		{Name: "phone_numbers", Type: types.JSON, Nullable: false, Source: tableName},
		{Name: "created_at", Type: types.MustCreateDatetimeType(query.Type_DATETIME, 6), Nullable: false, Source: tableName},
	}), db.GetForeignKeyCollection())
	db.AddTable(tableName, table)

	creationTime := time.Unix(0, 1667304000000001000).UTC()
	_ = table.Insert(ctx, sql.NewRow("Jane Deo", "[email protected]", types.MustJSON(`["556-565-566", "777-777-777"]`), creationTime))
	_ = table.Insert(ctx, sql.NewRow("Jane Doe", "[email protected]", types.MustJSON(`[]`), creationTime))
	_ = table.Insert(ctx, sql.NewRow("John Doe", "[email protected]", types.MustJSON(`["555-555-555"]`), creationTime))
	_ = table.Insert(ctx, sql.NewRow("John Doe", "[email protected]", types.MustJSON(`[]`), creationTime))

	return pro
}

This example populates the database by creating memory.Database and memory.Table objects via golang code, but you can also populate it by issuing CREATE DATABASE, CREATE TABLE, etc. statements to the server once it's running.

Once the server is running, connect with any MySQL client, including the golang MySQL connector and the mysql shell.

> mysql --host=localhost --port=3306 --user=root mydb --execute="SELECT * FROM mytable;"
+----------+-------------------+-------------------------------+----------------------------+
| name     | email             | phone_numbers                 | created_at                 |
+----------+-------------------+-------------------------------+----------------------------+
| Jane Deo | [email protected] | ["556-565-566","777-777-777"] | 2022-11-01 12:00:00.000001 |
| Jane Doe | [email protected]      | []                            | 2022-11-01 12:00:00.000001 |
| John Doe | [email protected]      | ["555-555-555"]               | 2022-11-01 12:00:00.000001 |
| John Doe | [email protected]   | []                            | 2022-11-01 12:00:00.000001 |
+----------+-------------------+-------------------------------+----------------------------+

Limitations of the in-memory database implementation

The in-memory database implementation included with this package is intended for use in tests. It has specific limitations that we know of:

Custom backend implementations

You can create your own backend to query your own data sources by implementing some interfaces. For detailed instructions, see the backend guide.

Technical documentation for contributors and backend developers

  • Architecture is an overview of the various packages of the project and how they fit together.
  • Contribution guide for new contributors, including instructions for how to get your PR merged.

Powered by go-mysql-server

Are you building a database backend using go-mysql-server? We would like to hear from you and include you in this list.

Security Policy

go-mysql-server's security policy is maintained in this repository. Please follow the disclosure instructions there. Please do not initially report security issues in this repository's public GitHub issues.

Acknowledgements

go-mysql-server was originally developed by the {source-d} organzation, and this repository was originally forked from src-d. We want to thank the entire {source-d} development team for their work on this project, especially Miguel Molina (@erizocosmico) and Juanjo Álvarez Martinez (@juanjux).

License

Apache License 2.0, see LICENSE

go-mysql-server's People

Contributors

agarciamontoro avatar ajnavarro avatar andy-wm-arthur avatar bake avatar bheni avatar cmoog avatar coffeegoddd avatar druvv avatar erizocosmico avatar firelizzard18 avatar fulghum avatar hydrocharged avatar jennifersp avatar jfontan avatar jycor avatar macneale4 avatar max-hoffman avatar mcarmonaa avatar mcuadros avatar nicktobey avatar ntakouris avatar pavelsafronov avatar reltuk avatar sananguliyev avatar smola avatar stephkyou avatar tbantle22 avatar theodesp avatar vinairachakonda avatar zachmu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-mysql-server's Issues

regex-metrics can't be initialized

According to the README, we should set some global variables to collect metrics. Unfortunately, the regex package is internal, so it's not possible for users to set those variables.

In general, I really feel that the ergonomics of using metrics should be improved. Copy-pasting from the README is hardly a good workflow, not least because we have to manually poll the README to see if new metrics where added or old ones changed. The global variables containing the counters are not documented in regards to what labels they expect. And of course, counter-variables should not be global anyway, but fields of the corresponding struct.

IMO a preferable API would be a RegisterMetrics method on sqle.Engine and the like, which takes a provider.Provider, or - even better - taking a Provider in the constructors. That way, the user does not have to set up the specific metrics used with the correct fields and we can use our own provider that registers the metrics to a custom prometheus.Registry.

Support for prepared statements

This is more important than we have been treating it, because there are many drivers that do this under the hood without clients explicitly asking for it. From #169

Support for VALUES in INSERT ... ON DUPLICATE KEY UPDATE

In mysql there is a specific version of the VALUES function that goes after the ON DUPLICATE KEY UPDATE statement that references a named column in the INSERT portion of the statement: https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

Currently running a command that uses this feature will result in: unknown error: unsupported syntax: values(column_name)

My guess is this is happening somewhere in vitess which may not support this feature. I may look into it myself but modifying vitess sounds like quite the deep dive.

Example test case:

INSERT INTO mytable (i,s) VALUES (1, "foo"), (2, "bar"), (3, "qux")
ON DUPLICATE KEY UPDATE s= CONCAT(VALUES(i), VALUES(s));

Support UTC_TIMESTAMP()

Looking at using this project for unit-testing purposes; very nice to have an in-memory Mysql database!

It's good to have NOW() support but I do need UTC_TIMESTAMP() as well. Is this something on the agenda soon, or should I dive in and figure out a PR?

Thanks 👍

Support Insert opeartion for sqlx.

I use github.com/dolthub/go-mysql-server v0.9.0

When I use sqlx to insert data, into the dolthub/go-mysql-server database.
I can't get result.LastInsertID(), it always return id, err = 0, nil

memory database with JSON column cannot be updated

func TestJsonUpdate(t *testing.T) {
	table := memory.NewTable(t.Name(), sql.Schema{
		{Name: "json", Type: sql.JSON, Nullable: false, Source: t.Name()},
	})

	old := sql.NewRow(sql.JSONDocument{Val: []string{"foo", "bar"}})
	new := sql.NewRow(sql.JSONDocument{Val: []string{"foo"}})

	ctx := sql.NewEmptyContext()
	table.Insert(ctx, old)

	up := table.Updater(ctx)
	up.Update(ctx, old, new)
}

results in

--- FAIL: TestJsonUpdate (0.00s)
panic: runtime error: comparing uncomparable type []string [recovered]
        panic: runtime error: comparing uncomparable type []string

goroutine 22 [running]:
testing.tRunner.func1.2(0x16996e0, 0xc000289e70)
        GOPATH/src/testing/testing.go:1144 +0x332
testing.tRunner.func1(0xc000102a80)
        GOPATH/src/testing/testing.go:1147 +0x4b6
panic(0x16996e0, 0xc000289e70)
        GOPATH/src/runtime/panic.go:965 +0x1b9
github.com/dolthub/go-mysql-server/memory.(*tableEditor).Update(0xc000133f18, 0xc000204ab0, 0xc000289d90, 0x1, 0x1, 0xc000289dc0, 0x1, 0x1, 0x105a2a5, 0x10740c0)
        CODE/go-mysql-server/memory/table.go:621 +0x275
github.com/dolthub/go-mysql-server/memory_test.TestJsonUpdate(0xc000102a80)
        CODE/go-mysql-server/memory/regression_test.go:36 +0x405
testing.tRunner(0xc000102a80, 0x178a6a0)
        GOPATH/src/testing/testing.go:1194 +0xef
created by testing.(*T).Run
        GOPATH/src/testing/testing.go:1239 +0x2b3
FAIL    github.com/dolthub/go-mysql-server/memory       0.019s
FAIL

Better error message for unquoted string in AS OF queries

Current error message is not helpful. Customer feedback:

"panic: unresolved column is a placeholder node, but Eval was called". So if I type "SELECT * FROM my_cool_table AS OF my_cool_branch", I get this. Quoting the AS OF parameter is nonintuitive, because other strings (e.g. table names) don't need them, so a friendlier error would be useful."

Remove Consul Dependency

The first primary use case of go-mysql-server is:

Stand-in for MySQL in a golang test environment, using the built-in memory database implementation.

When I imported it into my project, it errored due to an ambiguous import, as go-mysql-server imported a different version of Consul (???) than my project. Here's the essential bits of the log:

go: downloading github.com/liquidata-inc/go-mysql-server v0.6.0
go: found github.com/liquidata-inc/go-mysql-server in github.com/liquidata-inc/go-mysql-server v0.6.0
go: downloading github.com/liquidata-inc/vitess v0.0.0-20200807222445-2db8e9fb6365
go: downloading github.com/hashicorp/golang-lru v0.5.3
go: downloading github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
go: downloading github.com/mitchellh/hashstructure v1.0.0
go: downloading github.com/hashicorp/consul v1.4.0
# my/project
package my/project
	imports github.com/abronan/valkeyrie/store/consul
	imports github.com/hashicorp/consul/api: ambiguous import: found package github.com/hashicorp/consul/api in multiple modules:
	github.com/hashicorp/consul v1.4.0 (/Users/tooolbox/go/pkg/mod/github.com/hashicorp/[email protected]/api)
	github.com/hashicorp/consul/api v1.1.0 (/Users/tooolbox/go/pkg/mod/github.com/hashicorp/consul/[email protected])

I imagine that go-mysql-server isn't actually using the Consul API anywhere, it's just an accident of the dependency tree, but I think it's a tad overboard. If anything can be done to remove this dependency it would be appreciated.

Question/Feature Request: How can I increase the parallelism of expression evaluation?

I have a situation where I have a custom SQL function that is a bit slow (like a single network request slow). Because rows are demanded one at a time from a RowIter, these expressions are evaluated one at a time, meaning we run these network requests one at a time. I would like some way to evaluate these rows in parallel as this would greatly improve the speed of my queries. I can't prefetch everything because I do not have all the data needed for all the network requests until query execution. A while back I tried making a custom SQL plan node which wraps another node and prefetches rows from its child node in parallel, but I ran into some issues where the RowIter implementation I was calling misbehaved as it was not threadsafe. Do you have any suggestions for me? Was the parallel prefetch node a good/bad idea? I really appreciate your help with this, thanks.

Cut new release

I assume the last release (v0.5.1) was before the hard-fork. It would be great if you could cut a new release, as currently, this project isn't easily usable with modules - go get github.com/liquidata-inc/go-mysql-server downloads v0.5.1, which still declares the module name as gopkg.in/src-d/go-mysql-server.v0. So go build refuses to build.

sql.FilteredTable usage and implementation

I've just started looking at go-mysql-server and it seems very powerful - for a particular use case I have in mind I'm looking at using a data source where I would like to implement the sql.FilteredTable when querying data (since the underlying API for this data source can filter the data more efficiently).

However from the documentation/code, its not clear what action the HandledFilters & WithFilters should perform.

// FilteredTable is a table that can produce a specific RowIter
// that's more optimized given the filters.
type FilteredTable interface {
	Table
	HandledFilters(filters []Expression) []Expression
	WithFilters(filters []Expression) Table
}

Further the memory ref implementation seems to indicate that filter pushdowns are "broken" - is this in reference to the query engine being able to support them or just the memory implementation.

	// pushdown info
	filters    []sql.Expression // currently unused, filter pushdown is significantly broken right now
	projection []string
	columns    []int

and

// sql.FilteredTable functionality in the Table type was disabled for a long period of time, and has developed major
// issues with the current analyzer logic. It's only used in the pushdown unit tests, and sql.FilteredTable should be
// considered unstable until this situation is fixed.
type FilteredTable struct {
	*Table
}

unsupported syntax: create database mapping

Love this project!

While trying it out i got this error

Error 1105: unknown error: unsupported syntax: create database mapping

when issuing

CREATE SCHEMA IF NOT EXISTS mapping;

against a in memory instance.

	driver := sqlserver.NewDefault()
	driver.AddDatabase(memory.NewDatabase("default"))

	config := server.Config{
		Protocol: "tcp",
		Address:  "localhost:3306",
		Auth:     auth.NewNativeSingle("root", "pass", auth.AllPermissions),
	}

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

	go func() {
		err := s.Start()
		if err != nil {
			panic(err)
		}
	}()

I am using:
github.com/dolthub/go-mysql-server v0.6.1-0.20201228192939-415fc40f3a71
github.com/go-sql-driver/mysql v1.5.0

For now i can work around it by creating the schemas via driver.AddDatabase().

LastInsertId always returns 0

When running several insert commands like

result, err := db.Exec("INSERT INTO mytable SET number = 18;")
id, err := result.LastInsertId()

Against a simple table like

CREATE TABLE IF NOT EXISTS mytable (
id int unsigned NOT NULL AUTO_INCREMENT,
number int unsigned DEFAULT NULL,
PRIMARY KEY (id),
) DEFAULT CHARSET=utf8;

the returned id is always 0. While the go-mysql-driver returns the correct pkey.

Used libraries:
github.com/dolthub/go-mysql-server v0.6.1-0.20201228192939-415fc40f3a71
github.com/go-sql-driver/mysql v1.5.0

test suggestions?

I'd like to use this for tests (like I did with the src-d version before it was abandoned.) One of the things I could never figure out how to do with go-mysql-server was various kinds of error injection. For example, I'd like to be able to do weird stuff like if someone searches by a specific id I insert a sleep to test my timeout code. For another id I'd like to be able to surface some weird error, so I can make sure my mysql error handling works. Any ideas on how to do this? I couldn't figure it out from the docs, but maybe I missed something.

JSON string comparison seems broken (change in behavior from v0.6.0 and v0.10.0)

In a MySQL server

mysql> select json_extract('{"xid":"hello"}', '$.xid') = "hello";
+----------------------------------------------------+
| json_extract('{"xid":"hello"}', '$.xid') = "hello" |
+----------------------------------------------------+
|                                                  1 |
+----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_unquote(json_extract('{"xid":"hello"}', '$.xid')) = "hello";
+------------------------------------------------------------------+
| json_unquote(json_extract('{"xid":"hello"}', '$.xid')) = "hello" |
+------------------------------------------------------------------+
|                                                                1 |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

With go-mysql-server v0.6.0

MySQL [(none)]> select json_extract('{"xid":"hello"}', '$.xid') = "hello";
+--------------------------------------------------------+
| JSON_EXTRACT("{\"xid\":\"hello\"}", "$.xid") = "hello" |
+--------------------------------------------------------+
|                                                      1 |
+--------------------------------------------------------+
1 row in set (0.001 sec)

MySQL [(none)]> select json_unquote(json_extract('{"xid":"hello"}', '$.xid')) = "hello";
+----------------------------------------------------------------------+
| JSON_UNQUOTE(JSON_EXTRACT("{\"xid\":\"hello\"}", "$.xid")) = "hello" |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+
1 row in set (0.001 sec)

With go-mysql-server v0.10.0

MySQL [(none)]> select json_extract('{"xid":"hello"}', '$.xid') = "hello";
+----------------------------------------------------+
| json_extract('{"xid":"hello"}', '$.xid') = "hello" |
+----------------------------------------------------+
|                                                  0 |
+----------------------------------------------------+
1 row in set (0.001 sec)

MySQL [(none)]> select json_unquote(json_extract('{"xid":"hello"}', '$.xid')) = "hello";
ERROR 1105 (HY000): incompatible conversion to SQL type: LONGTEXT

The comparison is now false and unquoting fails completely. I believe the root cause is sql.LongText.Convert failing to handle JSONDocument values, so Equals.Compare ends up converting the json value to nil.

DB Startup Config File - values not utilized

Hi,

I am trying to override the default values when starting the mysql server using the --config parameter and yaml config definition as described in
the docs. (Example below) The file is apparently loaded (I performed a test using a non-existent file name which did generate a file not found error), yet all of the default values are still being utilized. I changed the user name, timeouts, etc., yet the original defaults are still be used on startup. What am I missing here?

behavior:
read_only: false
autocommit: true

user:
name: root
password: ""

listener:
host: localhost
port: 3306
max_connections: 1
read_timeout_millis: 30000
write_timeout_millis: 30000

databases: []

unresolved function is a placeholder node, but Eval was called

I'm not sure what to do with this panic:

panic: unresolved function is a placeholder node, but Eval was called [recovered]
        panic: unresolved function is a placeholder node, but Eval was called

Here's the stacktrace not including our code:

github.com/liquidata-inc/go-mysql-server/sql/expression.(*UnresolvedFunction).Eval(0xc00020ad80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/expression/unresolved.go:128 +0x39
github.com/liquidata-inc/go-mysql-server/sql/parse.columnDefinitionToColumn(0x0, 0xc00030cc00, 0xc000098780, 0x4, 0x4, 0xc0000ccbc0, 0x4, 0x8)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:820 +0x374
github.com/liquidata-inc/go-mysql-server/sql/parse.TableSpecToSchema(0x0, 0xc0002009c0, 0xc0002f6000, 0x11f2280, 0xc0000be790, 0x0, 0xfd3660)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:769 +0xba
github.com/liquidata-inc/go-mysql-server/sql/parse.convertCreateTable(0xc0001ea1c0, 0xc0002769a0, 0xff90bd, 0x6, 0x351, 0x380)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:624 +0x3f
github.com/liquidata-inc/go-mysql-server/sql/parse.convertDDL(0xc0001ea1c0, 0xc000558700, 0x351, 0xc0002769a0, 0x0, 0x0, 0xc000558a80, 0xc00043cbd8)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:463 +0x26f
github.com/liquidata-inc/go-mysql-server/sql/parse.convert(0xc0001ea1c0, 0x11fe620, 0xc000276840, 0xc000558700, 0x351, 0x0, 0xc000558a80, 0x351, 0x0)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:153 +0x251
github.com/liquidata-inc/go-mysql-server/sql/parse.Parse(0xc0001ea1c0, 0xc000558380, 0x353, 0x0, 0x0, 0x0, 0x0)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/sql/parse/parse.go:125 +0x54a
github.com/liquidata-inc/go-mysql-server.(*Engine).Query(0xc0000982e0, 0xc0001ea000, 0xc000558380, 0x353, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/frew/go/pkg/mod/github.com/liquidata-inc/[email protected]/engine.go:116 +0x108

This was trying to run the following DDL:

CREATE TABLE `job_dismissal` (
  `job_dismissal_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `contact_id` int(10) unsigned NOT NULL,
  `quiz_id` int(10) unsigned DEFAULT NULL,
  `external_job_id` varchar(100) DEFAULT NULL,
  `job_fingerprint` varchar(32) NOT NULL,
  `create_time` timestamp(6) NOT NULL DEFAULT NOW(),
  PRIMARY KEY (`job_dismissal_id`),
  KEY `idx_qzdsmsl_contact_id_dismissal_id` (`contact_id`,`job_dismissal_id`,`job_fingerprint`),
  KEY `idx_qzdsmsl_quiz_id_contact_id` (`quiz_id`,`contact_id`),
  KEY `idx_qzdsmsl_create_time` (`create_time`),
  CONSTRAINT `FK_QZDSMSL_contact_id` FOREIGN KEY (`contact_id`) REFERENCES `contact` (`contact_id`),
  CONSTRAINT `FK_QZDSMSL_quiz_id` FOREIGN KEY (`quiz_id`) REFERENCES `quiz` (`quiz_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='This table will have INSERTs and DELETEs only';

Note that I replaced CURRENT_TIMESTAMP(6) with NOW() because CURRENT_TIMESTAMP(6) errors with unsupported syntax: current_timestamp(6). I suspect that's much easier to resolve than this.

undefined ViewSelectPositionStart & ViewSelectPositionEnd

I'm getting this on both macOS and Linux running go1.14 (I get it during installation of the package and then when I try to compile a program that uses the package)

# github.com/liquidata-inc/go-mysql-server/sql/parse
../go/src/github.com/liquidata-inc/go-mysql-server/sql/parse/parse.go:792:22: c.ViewSelectPositionStart undefined (type *sqlparser.DDL has no field or method ViewSelectPositionStart)
../go/src/github.com/liquidata-inc/go-mysql-server/sql/parse/parse.go:792:48: c.ViewSelectPositionEnd undefined (type *sqlparser.DDL has no field or method ViewSelectPositionEnd)

Combine index lookups on different columns of multi-column indexes with different operators

Right now expressions on the columns of a key with different operators, such as:

select * from sales_estimate where act_symbol = 'AAPL' and retrieval_date < '2017-11-01';

Assuming that act_symbol and retrieval_date are two columns in the key, we can't form an index lookup on these terms because the two comparisons use different operators (= and <). Fixing this will take a little thought -- none of the current index interfaces address this possibility for multi-key indexes.

In-memory join hangs forever when primary table has rows and secondary table has no rows

Title explains the entire issue. I think the root cause is

if len(i.secondaryRows.Get()) == 0 {
return io.EOF
}
. When EOF is returned by that line loadSecondary immediately returns that EOF without resetting primaryRow or pos. This causes the joinIter to get stuck on this row forever and fetch the secondary table RowIter infinite times. I'm not sure why that EOF behavior is necessary. Additionally, even if that were fixed, the secondary table RowIter would be fetch once per primary row, which it shouldn't have to do. This is happening because the number of rows in the row cache is being used to determine if the row cache has been filled yet, but if the cache was filled with an empty table it behaves as if it was uninitialized, so it keeps trying to fill it over and over. This can be expensive for tables that fetch rows via slow operations, like network requests, even if the number of rows is 0.

`go get github.com/dolthub/go-mysql-server` got the wrong path?

I tried to import the dependency using go get github.com/dolthub/go-mysql-server, but i got err msg:

$ go get github.com/dolthub/go-mysql-server
go: github.com/dolthub/go-mysql-server upgrade => v0.6.0
go get: github.com/dolthub/[email protected]: parsing go.mod:
        module declares its path as: github.com/liquidata-inc/go-mysql-server
                but was required as: github.com/dolthub/go-mysql-server

If you use go mod tidy to import the dependencies in the example, you can also encounter this problem!

So, i'm wondering if you can solve this problem?

Analyzer becomes very slow for many joins

Hey there,

Been playing around with this library for a pet project of mine. Really enjoying it so far, so thanks for your work!

I ran into an issue with the analyzer. I haven't quite figured out exactly what's causing it, but for a certain number of joins the analyzer seems to run into an expensive loop somewhere. I created a small program to demonstrate the issue:

https://gist.github.com/ligustah/2f058e3dc6635bd113048301d1c227e7

Tried profiling/tracing to see where it gets stuck, but it didn't really come out conclusive for me. Maybe you can have a look or point me in the right direction?

(edit: worth noting, it doesn't seem to be an endless loop. in another test on my machine the query would complete after like 6 minutes. on a mysql server running in docker it completes within milliseconds)

Create Table Statement to NewTable format?

Looking through the examples I found the memory database helpful and am able to get an instance of go-mysql-server up and running. I am able to populate databases and table names from my custom source but am running into an issue with the table schema.

In the examples I see the follow which works:
table := NewTable(tableName, sql.Schema{
{Name: "name", Type: sql.Text, Nullable: false, Source: tableName},
{Name: "email", Type: sql.Text, Nullable: false, Source: tableName},
{Name: "phone_numbers", Type: sql.JSON, Nullable: false, Source: tableName},
{Name: "created_at", Type: sql.Timestamp, Nullable: false, Source: tableName},
})

But for my custom backend I actually have the table definitions already in SQL create table format:
CREATE TABLE fancy_table1 (
param_num smallint(6) NOT NULL DEFAULT '0',
name varchar(255) NOT NULL DEFAULT '',
units varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (param_num)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

I can create the tables from the cli via:
mysql --host 127.0.0.1 -u root mydb < createtables.sql

However I am wondering if there is a way using the parser already build into go-mysql-server to convert the SQL query into something I can easily feed into NewTable?

Error: Unsupported feature: LIMIT with non-integer literal

Getting the following error:

Error 1105: unknown error: unsupported feature: LIMIT with non-integer literal

Even though the query I'm running actually does use an integer, it's just interpolated.

Minimal repo:

_, err := db.Query(`SELECT * FROM foo LIMIT ?`, 10)
// err is "Error 1105: unknown error: unsupported feature: LIMIT with non-integer literal"

(maybe the error means non-literal integers are not supported? using LIMIT 10 instead of interpolating works.)

Better error message on syntax errors

We only report the text offset near an error, which is hard to work with. We already implemented something similar in Dolt, but should push it down to the parser itself.

From #169

Please cut a new release with the new group name

the 0.6.0 release points to liquidata-inc causing an issue with new projects attempting to use this project:

        github.com/dolthub/go-mysql-server: github.com/dolthub/[email protected]: parsing go.mod:
        module declares its path as: github.com/liquidata-inc/go-mysql-server
                but was required as: github.com/dolthub/go-mysql-server

Better support for parallel tests

First off, huge thank you for this project. Integration tests run dramatically faster with this in-memory DB than in MySQL.

We have a large number of integration tests and would like to adopt go-mysql-server for this. We use t.Parallel() throughout to reduce the running time. We also have a 540kb SQL file that we use to seed the database for our tests.

To prevent tests running in parallel from affecting one another, each test gets its own copy of the database with a slightly different name, e.g. test_1, test_2. Each database needs to be seeded using this SQL file, and currently we do this with the following:

func seedDB(
	user, pass, host, dbName string,
	port int,
	seedData []byte,
) error {
	cmd := exec.Command("mysql", "-h"+host, fmt.Sprintf("-P%d", port),
		"-p"+pass, "-u"+user, "-D"+dbName)
	cmd.Stdin = bytes.NewReader(seedData)

	var out, stderr bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &stderr

	if err := cmd.Run(); err != nil {
		fmt.Printf("run: %+v\n: %+v, %v\n", out.String(),
			stderr.String(), err)
		return err
	}
	return nil
}

This approach is very slow, and takes roughly 4s per test on Ubuntu 20.10. Across a large number of tests, this adds up to a large amount of time.

If we could seed the database with SQL directly in Go or otherwise copy and rename the database on each test, that would dramatically speed up our test runs. Any chance a solution like this would be accepted?

Parallel queries

Hello,
Has there been any implementations leveraging Go's concurrency capabilities?
I'm quite sure it wouldn't be hard to implement read-only parallel queries with sync.mutexes if it hasn't been done yet

. and ./auth fail tests when not on windows

I suspect this is why:

auth/audit_test.go:// +build !windows
auth/common_test.go:// +build !windows
auth/native_test.go:// +build !windows
auth/none_test.go:// +build !windows
engine_pilosa_test.go:// +build !windows

The failure mode is some kind of deadlock or something? It just sits forever

Project name is clunky & misleading

go-mysql-server is a bit of a clunky name and import path, when I first saw the project appear in Go news feeds I thought it was another mysql driver.

However this is a really cool project! A Go SQL engine for testing, data interfaces etc

Perhaps a name-change could reflect this?

ie

  • mysqlingo
  • sqlingo
  • sqle
  • liquidsql

Vitess Dep

Per the readme:

go-mysql-server relies on a fork of vitess, which implements the SQL parsing and SQL server for the engine. To use this fork of vitess, you must include the same replace directive in your project's go.mod file as this package does (see the go.mod file for the exact line to copy and paste):

replace vitess.io/vitess => github.com/liquidata-inc/vitess v0.0.0-20200430040751-192bb76ecd8b

However, when I look at the go.mod file on master, there's no replace directive. Is this documentation outdated?

Unbound variables in subqueries

When using the "driver" package, I kept running into the following errors:

DEBU[0115] [6.873ms] [rows:-] SELECT count(*) FROM information_schema.tables WHERE table_schema = 'test-db' AND table_name = 'entries' AND table_type = 'BASE TABLE' 
DEBU[0115] [0.853ms] [rows:0] CREATE TABLE `entries` (`id` bigint AUTO_INCREMENT,`value` bigint,PRIMARY KEY (`id`)) 
ERRO[0115] unbound variable "v1" in query: [0.778ms] [rows:0] INSERT INTO `entries` (`value`,`id`) VALUES (4,1) 
ERRO[0115] unbound variable "v1" in query: [0.614ms] [rows:0] INSERT INTO `entries` (`value`,`id`) VALUES (10,2) 
ERRO[0115] unbound variable "v1" in query: [0.622ms] [rows:0] INSERT INTO `entries` (`value`,`id`) VALUES (30,3) 

The fix appears to be changing driver/value.go to add a "v" prefix to ordinal placeholder values:

                        name = "v"+strconv.FormatInt(int64(v.Ordinal), 10)

... because the SQL plan code appears to expect "v1" "v2" and so on.

Feedback from attempted usage in Integration tests

Very cool project, thank you!

I was hopeful this would work as a drop-in replacement for MySQL for purpose of integration tests, since the MySQL docker container takes a full 10s to start up and can be a bit flaky. Just sharing my experience doing that in case it's helpful.

My test used DDL like this:

CREATE TABLE stream_rules (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(64) CHARACTER SET utf8mb4 NOT NULL,
  global BOOL NOT NULL DEFAULT FALSE,
  srcRegion VARCHAR(16) CHARACTER SET latin1 NOT NULL,
  dstRegion VARCHAR(16) CHARACTER SET latin1 NOT NULL,
  fields JSON NOT NULL,
  FOREIGN KEY (srcRegion) REFERENCES regions(id),
  FOREIGN KEY (dstRegion) REFERENCES regions(id)
) ENGINE=InnoDB;

It was rejected on two grounds:

  • It required global and fields in backticks, although MySQL accepts them without
  • It reported an error: ERROR 1105 (HY000): unknown error: Constraint already exists, due to not supplying an explicit constraint name for the foreign keys.

While modifying the DDL, I had a typo and got this error

Error 1105: unknown error: syntax error at position 601

The position alone is difficult to trace back to the mistake in the query. It would be very helpful if it contained the portion of the query in question.

The previous items were easy enough to fix (although with just a couple tables used by my test, it made me think our migrations would not apply cleanly). The blocker was that this standard code:

	rows, err := db.QueryContext(ctx, `
SELECT id, name, global, srcRegion, dstRegion, fields
  FROM stream_rules
 WHERE `+where+`
`, args...)

turns into a prepared statement:

ERROR: mysql_server caught panic:
prepared statements are not implemented
/Users/robfig/alpha/gocode/src/github.com/liquidata-inc/go-mysql-server/server/handler.go:97 (0x1671cb8)
        com/liquidata-inc/go-mysql-server/server.(*Handler).ComPrepare: panic("prepared statements are not implemented")
/Users/robfig/alpha/gocode/src/github.com/liquidata-inc/vitess/go/mysql/conn.go:914 (0x141a94a)
        com/liquidata-inc/vitess/go/mysql.(*Conn).handleNextCommand: fld, err := handler.ComPrepare(c, queries[0])
/Users/robfig/alpha/gocode/src/github.com/liquidata-inc/vitess/go/mysql/server.go:472 (0x143680c)
        com/liquidata-inc/vitess/go/mysql.(*Listener).handle: err := c.handleNextCommand(l.handler)
/usr/local/Cellar/go/1.14/libexec/src/runtime/asm_amd64.s:1373 (0x1064450)
        goexit: BYTE    $0x90   // NOP

I suppose the driver prepares statements automatically, which was a surprise to me.

Anyway, best of luck!

go get github.com/dolthub/go-mysql-server error

➜  tt go mod init tt
go: creating new go.mod: module tt
➜  tt ls
go.mod
➜  tt cat go.mod
module tt

go 1.15
➜  tt go get github.com/dolthub/go-mysql-server

go: github.com/dolthub/go-mysql-server upgrade => v0.6.0
go get: github.com/dolthub/[email protected]: parsing go.mod:
	module declares its path as: github.com/liquidata-inc/go-mysql-server
	        but was required as: github.com/dolthub/go-mysql-server

err:`go get github.com/dolthub/go-mysql-server`

github.com/dolthub/go-mysql-server/sql/expression/function/aggregation
# github.com/dolthub/go-mysql-server/sql/expression/function/aggregation
../go/src/github.com/dolthub/go-mysql-server/sql/expression/function/aggregation/count.go:165:33: not enough arguments in call to hashstructure.Hash
	have (interface {}, nil)
	want (interface {}, hashstructure.Format, *hashstructure.HashOptions)
$ go version
go version go1.15.7 darwin/amd64

full trace:

$ go get -u -v github.com/dolthub/go-mysql-server
github.com/dolthub/go-mysql-server (download)
github.com/cespare/xxhash (download)
github.com/dolthub/vitess (download)
github.com/golang/protobuf (download)
get "google.golang.org/protobuf/encoding/prototext": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/encoding/prototext?go-get=1
get "google.golang.org/protobuf/encoding/prototext": verifying non-authoritative meta tag
google.golang.org/protobuf (download)
get "google.golang.org/protobuf/encoding/protowire": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/encoding/protowire?go-get=1
get "google.golang.org/protobuf/encoding/protowire": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/errors": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/errors?go-get=1
get "google.golang.org/protobuf/internal/errors": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/detrand": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/detrand?go-get=1
get "google.golang.org/protobuf/internal/detrand": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/encoding/messageset": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/encoding/messageset?go-get=1
get "google.golang.org/protobuf/internal/encoding/messageset": verifying non-authoritative meta tag
get "google.golang.org/protobuf/reflect/protoreflect": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/reflect/protoreflect?go-get=1
get "google.golang.org/protobuf/reflect/protoreflect": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/pragma": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/pragma?go-get=1
get "google.golang.org/protobuf/internal/pragma": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/encoding/text": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/encoding/text?go-get=1
get "google.golang.org/protobuf/internal/encoding/text": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/flags": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/flags?go-get=1
get "google.golang.org/protobuf/internal/flags": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/strs": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/strs?go-get=1
get "google.golang.org/protobuf/internal/strs": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/genid": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/genid?go-get=1
get "google.golang.org/protobuf/internal/genid": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/order": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/order?go-get=1
get "google.golang.org/protobuf/internal/order": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/set": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/set?go-get=1
get "google.golang.org/protobuf/internal/set": verifying non-authoritative meta tag
get "google.golang.org/protobuf/proto": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/proto?go-get=1
get "google.golang.org/protobuf/proto": verifying non-authoritative meta tag
get "google.golang.org/protobuf/reflect/protoregistry": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/reflect/protoregistry?go-get=1
get "google.golang.org/protobuf/reflect/protoregistry": verifying non-authoritative meta tag
get "google.golang.org/protobuf/runtime/protoiface": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/runtime/protoiface?go-get=1
get "google.golang.org/protobuf/runtime/protoiface": verifying non-authoritative meta tag
get "google.golang.org/protobuf/runtime/protoimpl": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/runtime/protoimpl?go-get=1
get "google.golang.org/protobuf/runtime/protoimpl": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/filedesc": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/filedesc?go-get=1
get "google.golang.org/protobuf/internal/filedesc": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/descfmt": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/descfmt?go-get=1
get "google.golang.org/protobuf/internal/descfmt": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/descopts": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/descopts?go-get=1
get "google.golang.org/protobuf/internal/descopts": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/encoding/defval": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/encoding/defval?go-get=1
get "google.golang.org/protobuf/internal/encoding/defval": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/filetype": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/filetype?go-get=1
get "google.golang.org/protobuf/internal/filetype": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/impl": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/impl?go-get=1
get "google.golang.org/protobuf/internal/impl": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/encoding/tag": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/encoding/tag?go-get=1
get "google.golang.org/protobuf/internal/encoding/tag": verifying non-authoritative meta tag
get "google.golang.org/protobuf/internal/version": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/internal/version?go-get=1
get "google.golang.org/protobuf/internal/version": verifying non-authoritative meta tag
get "golang.org/x/net/context": found meta tag get.metaImport{Prefix:"golang.org/x/net", VCS:"git", RepoRoot:"https://go.googlesource.com/net"} at //golang.org/x/net/context?go-get=1
get "golang.org/x/net/context": verifying non-authoritative meta tag
golang.org/x/net (download)
get "google.golang.org/grpc/codes": found meta tag get.metaImport{Prefix:"google.golang.org/grpc", VCS:"git", RepoRoot:"https://github.com/grpc/grpc-go"} at //google.golang.org/grpc/codes?go-get=1
get "google.golang.org/grpc/codes": verifying non-authoritative meta tag
google.golang.org/grpc (download)
get "google.golang.org/grpc/status": found meta tag get.metaImport{Prefix:"google.golang.org/grpc", VCS:"git", RepoRoot:"https://github.com/grpc/grpc-go"} at //google.golang.org/grpc/status?go-get=1
get "google.golang.org/grpc/status": verifying non-authoritative meta tag
get "google.golang.org/genproto/googleapis/rpc/status": found meta tag get.metaImport{Prefix:"google.golang.org/genproto", VCS:"git", RepoRoot:"https://github.com/googleapis/go-genproto"} at //google.golang.org/genproto/googleapis/rpc/status?go-get=1
get "google.golang.org/genproto/googleapis/rpc/status": verifying non-authoritative meta tag
google.golang.org/genproto (download)
get "google.golang.org/protobuf/types/known/anypb": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/types/known/anypb?go-get=1
get "google.golang.org/protobuf/types/known/anypb": verifying non-authoritative meta tag
get "google.golang.org/grpc/internal/status": found meta tag get.metaImport{Prefix:"google.golang.org/grpc", VCS:"git", RepoRoot:"https://github.com/grpc/grpc-go"} at //google.golang.org/grpc/internal/status?go-get=1
get "google.golang.org/grpc/internal/status": verifying non-authoritative meta tag
get "google.golang.org/protobuf/types/known/durationpb": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/types/known/durationpb?go-get=1
get "google.golang.org/protobuf/types/known/durationpb": verifying non-authoritative meta tag
get "google.golang.org/protobuf/types/known/timestamppb": found meta tag get.metaImport{Prefix:"google.golang.org/protobuf", VCS:"git", RepoRoot:"https://go.googlesource.com/protobuf"} at //google.golang.org/protobuf/types/known/timestamppb?go-get=1
get "google.golang.org/protobuf/types/known/timestamppb": verifying non-authoritative meta tag
github.com/golang/glog (download)
github.com/hashicorp/golang-lru (download)
github.com/opentracing/opentracing-go (download)
github.com/shopspring/decimal (download)
github.com/sirupsen/logrus (download)
get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/unix?go-get=1
get "golang.org/x/sys/unix": verifying non-authoritative meta tag
golang.org/x/sys (download)
get "golang.org/x/sys/internal/unsafeheader": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/internal/unsafeheader?go-get=1
get "golang.org/x/sys/internal/unsafeheader": verifying non-authoritative meta tag
github.com/spf13/cast (download)
get "gopkg.in/src-d/go-errors.v1": found meta tag get.metaImport{Prefix:"gopkg.in/src-d/go-errors.v1", VCS:"git", RepoRoot:"https://gopkg.in/src-d/go-errors.v1"} at //gopkg.in/src-d/go-errors.v1?go-get=1
gopkg.in/src-d/go-errors.v1 (download)
github.com/pkg/errors (download)
github.com/go-kit/kit (download)
github.com/mitchellh/hashstructure (download)
github.com/lestrrat-go/strftime (download)
github.com/oliveagle/jsonpath (download)
github.com/pmezard/go-difflib (download)
github.com/dolthub/go-mysql-server/sql/expression/function/aggregation
# github.com/dolthub/go-mysql-server/sql/expression/function/aggregation
../go/src/github.com/dolthub/go-mysql-server/sql/expression/function/aggregation/count.go:165:33: not enough arguments in call to hashstructure.Hash
	have (interface {}, nil)
	want (interface {}, hashstructure.Format, *hashstructure.HashOptions)

expression.Tuple is uncomparable

expession.Tuple.Type() returns a slice of types, which cannot be compared in Golang.

tmp> create table test (pk int primary key, c0 int);
tmp> insert into test values (0,0);
Query OK, 1 row affected
tmp> delete from test where (pk,c0) = (0,0);
panic: runtime error: comparing uncomparable type sql.tupleType

goroutine 178 [running]:
github.com/dolthub/go-mysql-server/sql/expression.(*comparison).Compare(0xc00020efa0, 0xc00058db00, 0xc0002e0220, 0x2, 0x2, 0x1, 0xc0004add50, 0x1d1be9b)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/expression/comparison.go:47 +0x27c
github.com/dolthub/go-mysql-server/sql/expression.(*Equals).Eval(0xc00020efa0, 0xc00058db00, 0xc0002e0220, 0x2, 0x2, 0x0, 0x2, 0x2, 0xc0002e0220)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/expression/comparison.go:163 +0x5c
github.com/dolthub/go-mysql-server/sql.EvaluateCondition(0xc00058db00, 0x2851e80, 0xc00020efa0, 0xc0002e0220, 0x2, 0x2, 0xc00058a300, 0x33429a0, 0x0)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/core.go:606 +0x62
github.com/dolthub/go-mysql-server/sql/plan.(*FilterIter).Next(0xc000369bc0, 0xc0004ade8c, 0x3, 0x2, 0x0, 0x2828780)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/plan/filter.go:103 +0x9b
github.com/dolthub/go-mysql-server/sql/plan.(*exchangeRowIter).iterPartition(0xc00058a280, 0x28180c0, 0xc000418c70)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/plan/exchange.go:253 +0x31d
github.com/dolthub/go-mysql-server/sql/plan.(*exchangeRowIter).start.func1(0xc00058a280, 0xc000418c60, 0x28180c0, 0xc000418c70)
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/plan/exchange.go:178 +0x3f
created by github.com/dolthub/go-mysql-server/sql/plan.(*exchangeRowIter).start
	/Users/andyarthur/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.6.1-0.20201206203230-59fe20b2e36d/sql/plan/exchange.go:177 +0x115

Too slow With mysql client

compare with src-d/go-mysql-server i run same code and liquidata-inc/go-mysql-server is too slow ,will connect timeout

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.