nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: src-d/go-mysql-server
Pull request #603 (2019-01-23 12:23:10)

sql/analyzer: remove QueryProcess nodes from subqueries
Closes https://github.com/src-d/gitbase/issues/679

Because subqueries are analyzed as if they were a whole independent
query QueryProcess nodes were added to them. That caused that as
soon as a subquery finished, the process were marked as done. As a
result, some queries could error with "context canceled", as the
context of the query had already been canceled.

This fix removes the QueryProcess nodes from any subquery and makes
sure only the root node is wrapped in a QueryProcess.

Signed-off-by: Miguel Molina <miguel@erizocosmi.co>


Patch:
diff --git a/sql/analyzer/process.go b/sql/analyzer/process.go
index 84a87c4..5d486ac 100644
--- a/sql/analyzer/process.go
+++ b/sql/analyzer/process.go
@@ -71,5 +71,19 @@ func trackProcess(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
 		return n, nil
 	}
 
-	return plan.NewQueryProcess(n, func() { processList.Done(ctx.Pid()) }), nil
+	// Remove QueryProcess nodes from the subqueries. Otherwise, the process
+	// will be marked as done as soon as a subquery finishes.
+	node, err := n.TransformUp(func(n sql.Node) (sql.Node, error) {
+		if sq, ok := n.(*plan.SubqueryAlias); ok {
+			if qp, ok := sq.Child.(*plan.QueryProcess); ok {
+				return plan.NewSubqueryAlias(sq.Name(), qp.Child), nil
+			}
+		}
+		return n, nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return plan.NewQueryProcess(node, func() { processList.Done(ctx.Pid()) }), nil
 }


Test patch:
diff --git a/sql/analyzer/process_test.go b/sql/analyzer/process_test.go
index d95d86f..0c20074 100644
--- a/sql/analyzer/process_test.go
+++ b/sql/analyzer/process_test.go
@@ -70,6 +70,37 @@ func TestTrackProcess(t *testing.T) {
 	}
 }
 
+func TestTrackProcessSubquery(t *testing.T) {
+	require := require.New(t)
+	rule := getRuleFrom(OnceAfterAll, "track_process")
+	catalog := sql.NewCatalog()
+	a := NewDefault(catalog)
+
+	node := plan.NewProject(
+		nil,
+		plan.NewSubqueryAlias("f",
+			plan.NewQueryProcess(
+				plan.NewResolvedTable(mem.NewTable("foo", nil)),
+				nil,
+			),
+		),
+	)
+
+	result, err := rule.Apply(sql.NewEmptyContext(), a, node)
+	require.NoError(err)
+
+	expectedChild := plan.NewProject(
+		nil,
+		plan.NewSubqueryAlias("f",
+			plan.NewResolvedTable(mem.NewTable("foo", nil)),
+		),
+	)
+
+	proc, ok := result.(*plan.QueryProcess)
+	require.True(ok)
+	require.Equal(expectedChild, proc.Child)
+}
+
 func withoutProcessTracking(a *Analyzer) *Analyzer {
 	afterAll := a.Batches[len(a.Batches)-1]
 	afterAll.Rules = afterAll.Rules[1:]
Repository: src-d/go-mysql-server
Pull request #660 (2019-04-05 14:53:29)

Add build, tag for oniguruma, remove for mysql_go_regex, update README
- Adds a build tag for oniguruma.
- Removes the existing one for Go's regex.
- Updates the README removing references to oniguruma.

Signed-off-by: Juanjo Alvarez <juanjo@sourced.tech>

ajnavarro: @juanjux it is `oniguruma` not `onigurama`
juanjux: @ajnavarro renamed...

Patch:
diff --git a/README.md b/README.md
index 8277412..84c8f90 100644
--- a/README.md
+++ b/README.md
@@ -41,16 +41,6 @@ To install it, run:
 go get gopkg.in/src-d/go-mysql-server.v0
 ```
 
-## Regular expression engine
-
-The **go-mysql-server** uses [oniguruma](github.com/kkos/oniguruma) as a default regular expression engine, so it's required to install the oniguruma first.
-For Linux (if you have the `apt-get` tool) or OSX (if you have `homebrew` tool) the easiest way is by command:
-```sh
-make oniguruma # on linux you may need `sudo`
-```
-
-If you want to use regex engine from go's standard library, you have to compile **go-mysql-server** with `--tags mysql_go_regex` argument.
-
 ## Documentation
 
 * [go-mysql-server godoc](https://godoc.org/github.com/src-d/go-mysql-server)
diff --git a/internal/regex/regex_go.go b/internal/regex/regex_go.go
index c7c4453..a55fa42 100644
--- a/internal/regex/regex_go.go
+++ b/internal/regex/regex_go.go
@@ -1,5 +1,3 @@
-// +build mysql_go_regex
-
 package regex
 
 import (
diff --git a/internal/regex/regex_oniguruma.go b/internal/regex/regex_oniguruma.go
index 39444ac..52f8948 100644
--- a/internal/regex/regex_oniguruma.go
+++ b/internal/regex/regex_oniguruma.go
@@ -1,3 +1,5 @@
+// +build oniguruma
+
 package regex
 
 import (


Test patch:
diff --git a/internal/regex/regex_test.go b/internal/regex/regex_test.go
index 1720ed7..118a19c 100644
--- a/internal/regex/regex_test.go
+++ b/internal/regex/regex_test.go
@@ -10,12 +10,12 @@ func dummy(s string) (Matcher, Disposer, error) { return nil, nil, nil }
 
 func getDefault() string {
 	for _, n := range Engines() {
-		if n == "go" {
+		if n == "oniguruma" {
 			return n
 		}
 	}
 
-	return "oniguruma"
+	return "go"
 }
 
 func TestRegistration(t *testing.T) {
@@ -33,9 +33,6 @@ func TestRegistration(t *testing.T) {
 	engines = Engines()
 	require.Len(engines, number)
 
-	err = Register("oniguruma", dummy)
-	require.Equal(true, ErrRegexAlreadyRegistered.Is(err))
-
 	err = Register("nil", dummy)
 	require.NoError(err)
 	require.Len(Engines(), number+1)
Repository: src-d/go-mysql-server
Pull request #690 (2019-04-23 14:51:35)

sql/analyzer: only check aliases to qualify in the topmost project
Because aliases on the topmost project or groupby were checked using
plan.InspectExpressions, it did so recursively. That was not the
intended behaviour, since it could find other aliases in a subquery
or other nodes down the tree.
Instead, now only the expressions of the project or groupby are
checked.


Patch:
diff --git a/sql/analyzer/resolve_columns.go b/sql/analyzer/resolve_columns.go
index 980f31e..0979f71 100644
--- a/sql/analyzer/resolve_columns.go
+++ b/sql/analyzer/resolve_columns.go
@@ -6,11 +6,11 @@ import (
 	"strings"
 
 	"gopkg.in/src-d/go-errors.v1"
+	"gopkg.in/src-d/go-mysql-server.v0/internal/similartext"
 	"gopkg.in/src-d/go-mysql-server.v0/sql"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/plan"
 	"gopkg.in/src-d/go-vitess.v1/vt/sqlparser"
-	"gopkg.in/src-d/go-mysql-server.v0/internal/similartext"
 )
 
 func checkAliases(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error) {
@@ -313,15 +313,13 @@ func isDefinedInChildProject(n sql.Node, col *expression.UnresolvedColumn) bool
 	}
 
 	var found bool
-	plan.InspectExpressions(x, func(e sql.Expression) bool {
-		alias, ok := e.(*expression.Alias)
+	for _, expr := range x.(sql.Expressioner).Expressions() {
+		alias, ok := expr.(*expression.Alias)
 		if ok && strings.ToLower(alias.Name()) == strings.ToLower(col.Name()) {
 			found = true
-			return false
+			break
 		}
-
-		return true
-	})
+	}
 
 	return found
 }


Test patch:
diff --git a/engine_test.go b/engine_test.go
index dfd90bc..7d4a7fa 100644
--- a/engine_test.go
+++ b/engine_test.go
@@ -929,6 +929,26 @@ var queries = []struct {
 		`SELECT i AS i FROM mytable ORDER BY i`,
 		[]sql.Row{{int64(1)}, {int64(2)}, {int64(3)}},
 	},
+	{
+		`
+		SELECT
+			i,
+			foo
+		FROM (
+			SELECT
+				i,
+				COUNT(DISTINCT s) AS foo
+			FROM mytable
+			GROUP BY i
+		) AS q
+		ORDER BY foo DESC
+		`,
+		[]sql.Row{
+			{int64(1), int64(1)},
+			{int64(2), int64(1)},
+			{int64(3), int64(1)},
+		},
+	},
 }
 
 func TestQueries(t *testing.T) {
Repository: src-d/go-mysql-server
Pull request #696 (2019-04-24 10:09:23)

Support SHOW SCHEMAS (upgrade vitess to v1.6.0)
Signed-off-by: kuba-- <kuba@sourced.tech>
Closes https://github.com/src-d/go-mysql-server/issues/652


Patch:
diff --git a/go.mod b/go.mod
index e160f37..fe953a7 100644
--- a/go.mod
+++ b/go.mod
@@ -22,6 +22,6 @@ require (
 	golang.org/x/net v0.0.0-20190227022144-312bce6e941f // indirect
 	google.golang.org/grpc v1.19.0 // indirect
 	gopkg.in/src-d/go-errors.v1 v1.0.0
-	gopkg.in/src-d/go-vitess.v1 v1.5.0
+	gopkg.in/src-d/go-vitess.v1 v1.6.0
 	gopkg.in/yaml.v2 v2.2.2
 )
diff --git a/go.sum b/go.sum
index 8ae8582..16ee097 100644
--- a/go.sum
+++ b/go.sum
@@ -160,8 +160,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc=
 gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg=
-gopkg.in/src-d/go-vitess.v1 v1.5.0 h1:oOjzjcSli51TD44fXlJx4S/TZmE8kiNgZUgCuw5B4DU=
-gopkg.in/src-d/go-vitess.v1 v1.5.0/go.mod h1:+g/wDtovsUgE2ioi32fo5Vavrtvfd/N1AvnknTmTvZE=
+gopkg.in/src-d/go-vitess.v1 v1.6.0 h1:jIe2MXLIewejW6sebf7IPnSzwt4fPQIj53nPuzg/xD8=
+gopkg.in/src-d/go-vitess.v1 v1.6.0/go.mod h1:+g/wDtovsUgE2ioi32fo5Vavrtvfd/N1AvnknTmTvZE=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/sql/parse/parse.go b/sql/parse/parse.go
index a222be3..6fe8242 100644
--- a/sql/parse/parse.go
+++ b/sql/parse/parse.go
@@ -244,7 +244,7 @@ func convertShow(s *sqlparser.Show, query string) (sql.Node, error) {
 		}
 
 		return node, nil
-	case sqlparser.KeywordString(sqlparser.DATABASES):
+	case sqlparser.KeywordString(sqlparser.DATABASES), sqlparser.KeywordString(sqlparser.SCHEMAS):
 		return plan.NewShowDatabases(), nil
 	case sqlparser.KeywordString(sqlparser.FIELDS), sqlparser.KeywordString(sqlparser.COLUMNS):
 		// TODO(erizocosmico): vitess parser does not support EXTENDED.


Test patch:
diff --git a/engine_test.go b/engine_test.go
index 7d4a7fa..51090a3 100644
--- a/engine_test.go
+++ b/engine_test.go
@@ -450,6 +450,10 @@ var queries = []struct {
 		`SHOW DATABASES`,
 		[]sql.Row{{"mydb"}, {"foo"}},
 	},
+	{
+		`SHOW SCHEMAS`,
+		[]sql.Row{{"mydb"}, {"foo"}},
+	},
 	{
 		`SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA`,
 		[]sql.Row{
Repository: src-d/go-mysql-server
Pull request #711 (2019-05-14 13:43:44)

Make ARRAY_LENGTH working with JSON arrays
Signed-off-by: kuba-- <kuba@sourced.tech>
This PR add support to `ARRAY_LENGTH` for other type of array (e.g. `JSON`).
If we want to count something what will be extracted from diffs by `EXPLODE/JSON_EXTRACT` we need `ARRAY_LENGTH` with support for other arrays, e.g.:

`SELECT ARRAY_LENGTH(JSON_EXTRACT('[{"i":0}, {"i":1, "y":"yyy"}, {"i":2, "x":"xxx"}]', '$.i'))`


Patch:
diff --git a/sql/expression/function/arraylength.go b/sql/expression/function/arraylength.go
index cfbc1ca..98b0197 100644
--- a/sql/expression/function/arraylength.go
+++ b/sql/expression/function/arraylength.go
@@ -38,7 +38,7 @@ func (f *ArrayLength) TransformUp(fn sql.TransformExprFunc) (sql.Expression, err
 
 // Eval implements the Expression interface.
 func (f *ArrayLength) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
-	if !sql.IsArray(f.Child.Type()) {
+	if t := f.Child.Type(); !sql.IsArray(t) && t != sql.JSON {
 		return nil, sql.ErrInvalidType.New(f.Child.Type().Type().String())
 	}
 


Test patch:
diff --git a/engine_test.go b/engine_test.go
index 6a87c88..d172c9a 100644
--- a/engine_test.go
+++ b/engine_test.go
@@ -1069,6 +1069,15 @@ var queries = []struct {
 		[]sql.Row{{float64(1)}},
 	},
 	{
+
+		`SELECT ARRAY_LENGTH(JSON_EXTRACT('[1, 2, 3]', '$'))`,
+		[]sql.Row{{int32(3)}},
+	},
+	{
+		`SELECT ARRAY_LENGTH(JSON_EXTRACT('[{"i":0}, {"i":1, "y":"yyy"}, {"i":2, "x":"xxx"}]', '$.i'))`,
+		[]sql.Row{{int32(3)}},
+  },
+  {
 		`SELECT GREATEST(1, 2, 3, 4)`,
 		[]sql.Row{{int64(4)}},
 	},
Repository: src-d/go-mysql-server
Pull request #721 (2019-05-23 08:12:05)

sql/analyzer: convert_dates should not change column name


Patch:
diff --git a/sql/analyzer/convert_dates.go b/sql/analyzer/convert_dates.go
index 326c1cb..6fd8492 100644
--- a/sql/analyzer/convert_dates.go
+++ b/sql/analyzer/convert_dates.go
@@ -1,8 +1,6 @@
 package analyzer
 
 import (
-	"fmt"
-
 	"gopkg.in/src-d/go-mysql-server.v0/sql"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function"
@@ -140,9 +138,8 @@ func addDateConvert(
 		// and propagate the changes up the chain.
 		if gf, ok := e.(*expression.GetField); ok && expressions[e.String()] && aliasRootProjections {
 			if _, ok := result.(*expression.GetField); !ok {
-				name := fmt.Sprintf("%s__%s", gf.Table(), gf.Name())
-				result = expression.NewAlias(result, name)
-				nodeReplacements[tableCol{gf.Table(), gf.Name()}] = name
+				result = expression.NewAlias(result, gf.Name())
+				nodeReplacements[tableCol{gf.Table(), gf.Name()}] = gf.Name()
 			}
 		}
 	}


Test patch:
diff --git a/sql/analyzer/convert_dates_test.go b/sql/analyzer/convert_dates_test.go
index bc83c0f..a3d8281 100644
--- a/sql/analyzer/convert_dates_test.go
+++ b/sql/analyzer/convert_dates_test.go
@@ -159,7 +159,7 @@ func TestConvertDatesProject(t *testing.T) {
 	)
 	expected := plan.NewFilter(
 		expression.NewEquals(
-			expression.NewGetField(0, sql.Int64, "__foo", false),
+			expression.NewGetField(0, sql.Int64, "foo", false),
 			expression.NewLiteral("2019-06-06 00:00:00", sql.Text),
 		),
 		plan.NewProject([]sql.Expression{
@@ -168,7 +168,7 @@ func TestConvertDatesProject(t *testing.T) {
 					expression.NewGetField(0, sql.Timestamp, "foo", false),
 					expression.ConvertToDatetime,
 				),
-				"__foo",
+				"foo",
 			),
 		}, table),
 	)
@@ -196,7 +196,7 @@ func TestConvertDatesGroupBy(t *testing.T) {
 	)
 	expected := plan.NewFilter(
 		expression.NewEquals(
-			expression.NewGetField(0, sql.Int64, "__foo", false),
+			expression.NewGetField(0, sql.Int64, "foo", false),
 			expression.NewLiteral("2019-06-06 00:00:00", sql.Text),
 		),
 		plan.NewGroupBy(
@@ -206,7 +206,7 @@ func TestConvertDatesGroupBy(t *testing.T) {
 						expression.NewGetField(0, sql.Timestamp, "foo", false),
 						expression.ConvertToDatetime,
 					),
-					"__foo",
+					"foo",
 				),
 			},
 			[]sql.Expression{
Repository: src-d/go-mysql-server
Pull request #728 (2019-05-28 08:51:03)

sql/analyzer: case insensitive checks for group by rules


Patch:
diff --git a/sql/analyzer/resolve_orderby.go b/sql/analyzer/resolve_orderby.go
index bdea67b..ef973fa 100644
--- a/sql/analyzer/resolve_orderby.go
+++ b/sql/analyzer/resolve_orderby.go
@@ -29,7 +29,7 @@ func resolveOrderBy(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error)
 		childNewCols := columnsDefinedInNode(sort.Child)
 		var schemaCols []string
 		for _, col := range sort.Child.Schema() {
-			schemaCols = append(schemaCols, col.Name)
+			schemaCols = append(schemaCols, strings.ToLower(col.Name))
 		}
 
 		var colsFromChild []string
@@ -38,9 +38,10 @@ func resolveOrderBy(ctx *sql.Context, a *Analyzer, n sql.Node) (sql.Node, error)
 			ns := findExprNameables(f.Column)
 
 			for _, n := range ns {
-				if stringContains(childNewCols, n.Name()) {
+				name := strings.ToLower(n.Name())
+				if stringContains(childNewCols, name) {
 					colsFromChild = append(colsFromChild, n.Name())
-				} else if !stringContains(schemaCols, n.Name()) {
+				} else if !stringContains(schemaCols, name) {
 					missingCols = append(missingCols, n.Name())
 				}
 			}
@@ -140,7 +141,7 @@ func columnsDefinedInNode(n sql.Node) []string {
 	for _, e := range exprs {
 		alias, ok := e.(*expression.Alias)
 		if ok {
-			cols = append(cols, alias.Name())
+			cols = append(cols, strings.ToLower(alias.Name()))
 		}
 	}
 


Test patch:
diff --git a/engine_test.go b/engine_test.go
index 02c8373..cc6c34f 100644
--- a/engine_test.go
+++ b/engine_test.go
@@ -1198,6 +1198,10 @@ var queries = []struct {
 		`SELECT CHAR_LENGTH('áé'), LENGTH('àè')`,
 		[]sql.Row{{int32(2), int32(4)}},
 	},
+	{
+		"SELECT i, COUNT(i) AS `COUNT(i)` FROM (SELECT i FROM mytable) t GROUP BY i ORDER BY i, `COUNT(i)` DESC",
+		[]sql.Row{{int64(1), int64(1)}, {int64(2), int64(1)}, {int64(3), int64(1)}},
+	},
 }
 
 func TestQueries(t *testing.T) {
Repository: src-d/go-mysql-server
Pull request #730 (2019-05-28 13:15:30)

sql/analyzer: do not wrap aggregations with convert, just their arguments


Patch:
diff --git a/sql/analyzer/convert_dates.go b/sql/analyzer/convert_dates.go
index 6fd8492..60c5b31 100644
--- a/sql/analyzer/convert_dates.go
+++ b/sql/analyzer/convert_dates.go
@@ -4,6 +4,7 @@ import (
 	"gopkg.in/src-d/go-mysql-server.v0/sql"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function"
+	"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function/aggregation"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/plan"
 )
 
@@ -101,7 +102,21 @@ func addDateConvert(
 	// No need to wrap expressions that already validate times, such as
 	// convert, date_add, etc and those expressions whose Type method
 	// cannot be called because they are placeholders.
-	switch e.(type) {
+	switch e := e.(type) {
+	case *aggregation.Max:
+		child, err := addDateConvert(e.Child, node, replacements, nodeReplacements, expressions, false)
+		if err != nil {
+			return nil, err
+		}
+
+		return aggregation.NewMax(child), nil
+	case *aggregation.Min:
+		child, err := addDateConvert(e.Child, node, replacements, nodeReplacements, expressions, false)
+		if err != nil {
+			return nil, err
+		}
+
+		return aggregation.NewMin(child), nil
 	case *expression.Convert,
 		*expression.Arithmetic,
 		*function.DateAdd,


Test patch:
diff --git a/sql/analyzer/convert_dates_test.go b/sql/analyzer/convert_dates_test.go
index a3d8281..defcbde 100644
--- a/sql/analyzer/convert_dates_test.go
+++ b/sql/analyzer/convert_dates_test.go
@@ -8,6 +8,7 @@ import (
 	"gopkg.in/src-d/go-mysql-server.v0/sql"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function"
+	"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function/aggregation"
 	"gopkg.in/src-d/go-mysql-server.v0/sql/plan"
 )
 
@@ -64,6 +65,30 @@ func TestConvertDates(t *testing.T) {
 				expression.ConvertToDatetime,
 			),
 		},
+		{
+			"min aggregation",
+			aggregation.NewMin(
+				expression.NewGetField(0, sql.Timestamp, "foo", false),
+			),
+			aggregation.NewMin(
+				expression.NewConvert(
+					expression.NewGetField(0, sql.Timestamp, "foo", false),
+					expression.ConvertToDatetime,
+				),
+			),
+		},
+		{
+			"max aggregation",
+			aggregation.NewMax(
+				expression.NewGetField(0, sql.Timestamp, "foo", false),
+			),
+			aggregation.NewMax(
+				expression.NewConvert(
+					expression.NewGetField(0, sql.Timestamp, "foo", false),
+					expression.ConvertToDatetime,
+				),
+			),
+		},
 		{
 			"convert to other type",
 			expression.NewConvert(
Repository: src-d/go-mysql-server
Pull request #732 (2019-05-29 08:59:29)

Upgrade vitess to v1.7.0
Signed-off-by: kuba-- <kuba@sourced.tech>


Patch:
diff --git a/go.mod b/go.mod
index fe953a7..4ba4986 100644
--- a/go.mod
+++ b/go.mod
@@ -22,6 +22,6 @@ require (
 	golang.org/x/net v0.0.0-20190227022144-312bce6e941f // indirect
 	google.golang.org/grpc v1.19.0 // indirect
 	gopkg.in/src-d/go-errors.v1 v1.0.0
-	gopkg.in/src-d/go-vitess.v1 v1.6.0
+	gopkg.in/src-d/go-vitess.v1 v1.7.0
 	gopkg.in/yaml.v2 v2.2.2
 )
diff --git a/go.sum b/go.sum
index 16ee097..b1ac166 100644
--- a/go.sum
+++ b/go.sum
@@ -162,6 +162,8 @@ gopkg.in/src-d/go-errors.v1 v1.0.0 h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIf
 gopkg.in/src-d/go-errors.v1 v1.0.0/go.mod h1:q1cBlomlw2FnDBDNGlnh6X0jPihy+QxZfMMNxPCbdYg=
 gopkg.in/src-d/go-vitess.v1 v1.6.0 h1:jIe2MXLIewejW6sebf7IPnSzwt4fPQIj53nPuzg/xD8=
 gopkg.in/src-d/go-vitess.v1 v1.6.0/go.mod h1:+g/wDtovsUgE2ioi32fo5Vavrtvfd/N1AvnknTmTvZE=
+gopkg.in/src-d/go-vitess.v1 v1.7.0 h1:7hYhf5sesJDLxl8//V/q6IyQJ4mOktLmkkfosMM9d00=
+gopkg.in/src-d/go-vitess.v1 v1.7.0/go.mod h1:+g/wDtovsUgE2ioi32fo5Vavrtvfd/N1AvnknTmTvZE=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=


Test patch:
diff --git a/engine_test.go b/engine_test.go
index fc770b3..541425e 100644
--- a/engine_test.go
+++ b/engine_test.go
@@ -1226,6 +1226,10 @@ var queries = []struct {
 		`SELECT NOW() - (NOW() - INTERVAL 1 SECOND)`,
 		[]sql.Row{{int64(1)}},
 	},
+	{
+		`SELECT SUBSTR(SUBSTRING('0123456789ABCDEF', 1, 10), -4)`,
+		[]sql.Row{{"6789"}},
+	},
 }
 
 func TestQueries(t *testing.T) {