mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-04 18:49:00 -06:00
added bats and error handling
This commit is contained in:
@@ -45,8 +45,7 @@ teardown() {
|
||||
dolt add .
|
||||
dolt commit -m rows
|
||||
dolt sql -q 'update quiz set c2 = "1" where pk = 0'
|
||||
dolt query_diff 'select test.pk, test.c1, test.c2, quiz.pk, quiz.c1 from test join quiz on test.c2 = quiz.c2 order by test.c2'
|
||||
run dolt query_diff 'select test.pk, test.c1, test.c2, quiz.pk, quiz.c1 from test join quiz on test.c2 = quiz.c2 order by test.c2'
|
||||
run dolt query_diff 'select test.pk, test.c1, test.c2, quiz.pk, quiz.c1 from test join quiz on test.c2 = quiz.c2 order by test.pk, quiz.pk'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "| | pk | c1 | c2 | pk | c1 |" ]]
|
||||
[[ "$output" =~ "| - | 0 | 0 | 0 | 0 | 0 |" ]]
|
||||
@@ -66,3 +65,22 @@ teardown() {
|
||||
[[ "$output" =~ "| - | 1 | 1 | 1 |" ]]
|
||||
[[ "$output" =~ "| + | 2 | 2 | 2 |" ]]
|
||||
}
|
||||
|
||||
@test "dolt query_diff query error" {
|
||||
dolt add .
|
||||
dolt commit -m 'added tables'
|
||||
run dolt query_diff head^ head 'select * from test order by pk'
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "error executing query on from root" ]]
|
||||
run dolt query_diff head head^ 'select * from test order by pk'
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "error executing query on to root" ]]
|
||||
}
|
||||
|
||||
@test "dolt query diff prints query plan if query is undiffable" {
|
||||
dolt add .
|
||||
dolt commit -m rows
|
||||
run dolt query_diff 'select * from test'
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "query plan:" ]]
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ func (cmd QueryDiffCmd) Exec(ctx context.Context, commandStr string, args []stri
|
||||
help, usage := cli.HelpAndUsagePrinters(cli.GetCommandDocumentation(commandStr, queryDiffDocs, ap))
|
||||
apr := cli.ParseArgs(ap, args, help)
|
||||
|
||||
from, to, leftover, err := GetDiffRoots(ctx, dEnv, apr.Args())
|
||||
from, to, leftover, err := getDiffRoots(ctx, dEnv, apr.Args())
|
||||
|
||||
var verr errhand.VerboseError
|
||||
if err != nil {
|
||||
@@ -109,7 +109,7 @@ func (cmd QueryDiffCmd) Exec(ctx context.Context, commandStr string, args []stri
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
|
||||
func GetDiffRoots(ctx context.Context, dEnv *env.DoltEnv, args []string) (from, to *doltdb.RootValue, leftover []string, err error) {
|
||||
func getDiffRoots(ctx context.Context, dEnv *env.DoltEnv, args []string) (from, to *doltdb.RootValue, leftover []string, err error) {
|
||||
headRoot, err := dEnv.StagedRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
@@ -177,30 +177,7 @@ func maybeResolve(ctx context.Context, dEnv *env.DoltEnv, spec string) (*doltdb.
|
||||
}
|
||||
|
||||
func validateQueryDiff(ctx context.Context, dEnv *env.DoltEnv, from *doltdb.RootValue, to *doltdb.RootValue, query string) errhand.VerboseError {
|
||||
//sqlCtx, eng, err := makeSqlEngine(ctx, dEnv, to)
|
||||
//if err != nil {
|
||||
// return errhand.BuildDError("Cannot diff query, query is not ordered. Error describing query plan").AddCause(err).Build()
|
||||
//}
|
||||
//
|
||||
//query = fmt.Sprintf("describe %s", query)
|
||||
//_, iter, err := processQuery(sqlCtx, query, eng)
|
||||
//if err != nil {
|
||||
// return errhand.BuildDError("Cannot diff query, query is not ordered. Error describing query plan").AddCause(err).Build()
|
||||
//}
|
||||
//
|
||||
//var qp strings.Builder
|
||||
//for {
|
||||
// r, err := iter.Next()
|
||||
// if err == io.EOF {
|
||||
// break
|
||||
// } else if err != nil {
|
||||
// return errhand.BuildDError("Cannot diff query, query is not ordered. Error describing query plan").AddCause(err).Build()
|
||||
// }
|
||||
// sv, _ := typeinfo.StringDefaultType.ConvertValueToNomsValue(r[0])
|
||||
// qp.WriteString(fmt.Sprintf("%s\n", string(sv.(types.String))))
|
||||
//}
|
||||
//
|
||||
//return errhand.BuildDError("Cannot diff query, query is not ordered. Add ORDER BY statement.\nquery plan:\n%s", qp.String()).Build()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
sqle "github.com/liquidata-inc/go-mysql-server"
|
||||
"github.com/liquidata-inc/go-mysql-server/sql"
|
||||
@@ -49,7 +50,7 @@ func MakeQueryDiffer(ctx context.Context, dEnv *env.DoltEnv, fromRoot, toRoot *d
|
||||
return nil, err
|
||||
}
|
||||
|
||||
from, to, err := hackThatPlan(fromCtx, toCtx, fromEng, toEng, query)
|
||||
from, to, err := modifyQueryPlans(fromCtx, toCtx, fromEng, toEng, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -125,8 +126,7 @@ type NodeDiffer interface {
|
||||
ToNode() sql.Node
|
||||
}
|
||||
|
||||
// todo: consult Engine.Query() for logic re: perms, catalog
|
||||
func hackThatPlan(fromCtx *sql.Context, toCtx *sql.Context, fromEng *sqle.Engine, toEng *sqle.Engine, query string) (fromPlan, toPlan sql.Node, err error) {
|
||||
func modifyQueryPlans(fromCtx *sql.Context, toCtx *sql.Context, fromEng *sqle.Engine, toEng *sqle.Engine, query string) (fromPlan, toPlan sql.Node, err error) {
|
||||
parsed, err := parse.Parse(fromCtx, query)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -134,14 +134,23 @@ func hackThatPlan(fromCtx *sql.Context, toCtx *sql.Context, fromEng *sqle.Engine
|
||||
|
||||
fromPlan, err = fromEng.Analyzer.Analyze(fromCtx, parsed)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, fmt.Errorf("error executing query on from root: %s", err.Error())
|
||||
}
|
||||
toPlan, err = toEng.Analyzer.Analyze(toCtx, parsed)
|
||||
err = recursiveValidateQueryPlan(fromPlan)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errWithQueryPlan(fromCtx, fromEng, query, err)
|
||||
}
|
||||
|
||||
fromPlan, toPlan, err = recurseModifyPlans(fromCtx, toCtx, fromPlan, toPlan)
|
||||
toPlan, err = toEng.Analyzer.Analyze(toCtx, parsed)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error executing query on to root: %s", err.Error())
|
||||
}
|
||||
err = recursiveValidateQueryPlan(toPlan)
|
||||
if err != nil {
|
||||
return nil, nil, errWithQueryPlan(toCtx, toEng, query, err)
|
||||
}
|
||||
|
||||
fromPlan, toPlan, err = recursiveModifyQueryPlans(fromCtx, toCtx, fromPlan, toPlan)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -149,7 +158,20 @@ func hackThatPlan(fromCtx *sql.Context, toCtx *sql.Context, fromEng *sqle.Engine
|
||||
return fromPlan, toPlan, nil
|
||||
}
|
||||
|
||||
func recurseModifyPlans(fromCtx, toCtx *sql.Context, from, to sql.Node) (modFrom, modTo sql.Node, err error) {
|
||||
func recursiveValidateQueryPlan(p sql.Node) error {
|
||||
switch p.(type) {
|
||||
case *plan.Sort:
|
||||
return nil
|
||||
default:
|
||||
cc := p.Children()
|
||||
if cc == nil {
|
||||
return fmt.Errorf("query plan does not contain a sort node")
|
||||
}
|
||||
return recursiveValidateQueryPlan(cc[0])
|
||||
}
|
||||
}
|
||||
|
||||
func recursiveModifyQueryPlans(fromCtx, toCtx *sql.Context, from, to sql.Node) (modFrom, modTo sql.Node, err error) {
|
||||
switch from.(type) {
|
||||
case *plan.Sort:
|
||||
nd, err := newSortNodeDiffer(fromCtx, toCtx, from.(*plan.Sort), to.(*plan.Sort))
|
||||
@@ -161,9 +183,9 @@ func recurseModifyPlans(fromCtx, toCtx *sql.Context, from, to sql.Node) (modFrom
|
||||
fc := from.Children()
|
||||
tc := to.Children()
|
||||
if fc == nil || tc == nil {
|
||||
return nil, nil, fmt.Errorf("reached bottom of query plan")
|
||||
panic("query plan does not contain a sort node")
|
||||
}
|
||||
fc[0], tc[0], err = recurseModifyPlans(fromCtx, toCtx, fc[0], tc[0])
|
||||
fc[0], tc[0], err = recursiveModifyQueryPlans(fromCtx, toCtx, fc[0], tc[0])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -212,3 +234,24 @@ func makeSqlEngine(ctx context.Context, dEnv *env.DoltEnv, root *doltdb.RootValu
|
||||
|
||||
return sqlCtx, engine, nil
|
||||
}
|
||||
|
||||
func errWithQueryPlan(ctx *sql.Context, eng *sqle.Engine, query string, cause error) error {
|
||||
_, iter, err := eng.Query(ctx, fmt.Sprintf("describe %s", query))
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot diff query. Error describing query plan: %s\n", err.Error())
|
||||
}
|
||||
|
||||
var qp strings.Builder
|
||||
qp.WriteString("query plan:\n")
|
||||
for {
|
||||
r, err := iter.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("cannot diff query. Error describing query plan: %s\n", err.Error())
|
||||
}
|
||||
qp.WriteString(fmt.Sprintf("\t%s\n", r[0].(string)))
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot diff query: %s\n%s", cause.Error(), qp.String())
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ var setupCommon = []testCommand{
|
||||
{commands.SqlCmd{}, []string{"-q", "create table quiz (pk int not null primary key, c0 int)"}},
|
||||
{commands.SqlCmd{}, []string{"-q", "insert into quiz values (0,10), (1,11), (2,22), (3,33)"}},
|
||||
{commands.AddCmd{}, []string{"."}},
|
||||
{commands.CommitCmd{}, []string{"-m", "setup common"}},
|
||||
}
|
||||
|
||||
var queryDifferTests = []queryDifferTest{
|
||||
@@ -133,7 +134,7 @@ func testQueryDiffer(t *testing.T, test queryDifferTest) {
|
||||
assert.Equal(t, 0, exitCode)
|
||||
}
|
||||
|
||||
fromRoot, err := dEnv.StagedRoot(ctx)
|
||||
fromRoot, err := dEnv.HeadRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
toRoot, err := dEnv.WorkingRoot(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user