mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-23 05:13:00 -05:00
@@ -0,0 +1,4 @@
|
||||
pk, int, string, boolean, float, uint, uuid
|
||||
0, 0, "asdf", TRUE, 0.0, 0, "00000000-0000-0000-0000-000000000000"
|
||||
1, -1, "qwerty", FALSE, -1.0, 1, "00000000-0000-0000-0000-000000000001"
|
||||
2, 1, "", TRUE, 0.0, 0, "123e4567-e89b-12d3-a456-426655440000"
|
||||
|
@@ -0,0 +1,2 @@
|
||||
INSERT INTO test (pk, int, string, boolean, float, uint, uuid)
|
||||
VALUES (3, 3, "three", TRUE, 3.3, 3, "00000000-0000-0000-0000-000000000003");
|
||||
@@ -0,0 +1 @@
|
||||
DELETE FROM test WHERE pk=1;
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE test SET int=-1, boolean=FALSE, uint=2 WHERE pk=2;
|
||||
@@ -0,0 +1 @@
|
||||
INSERT INTO test (pk1, pk2, c1, c2, c3, c4, c5) VALUES (2, 2, 1, 2, 3, 4, 5);
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE test SET pk1=3, pk2=3 WHERE pk1=1 AND pk2=1;
|
||||
@@ -0,0 +1 @@
|
||||
DELETE FROM test WHERE pk1=1 AND pk2=0 ;
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE test SET pk1=3 WHERE pk1=0 AND pk2=1;
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE test SET c1=9, c3=9, c5=9 WHERE pk1=1 AND pk2=1;
|
||||
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env bats
|
||||
load $BATS_TEST_DIRNAME/helper/common.bash
|
||||
|
||||
setup() {
|
||||
setup_common
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test "diff sql output reconciles INSERT query" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 1pk5col-ints.schema` test
|
||||
dolt table import -u test `batshelper 1pk5col-ints.csv`
|
||||
dolt add test
|
||||
dolt commit -m "Added one initial row"
|
||||
|
||||
dolt checkout -b newbranch
|
||||
dolt sql -q 'INSERT INTO test (pk, c1, c2, c3, c4, c5) VALUES (2, 11, 0, 0, 0, 0)'
|
||||
dolt add test
|
||||
dolt commit -m "Added three rows"
|
||||
|
||||
# confirm a difference exists
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > query
|
||||
dolt checkout firstbranch
|
||||
dolt sql < query
|
||||
rm query
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
}
|
||||
|
||||
@test "diff sql output reconciles UPDATE query" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 1pk5col-ints.schema` test
|
||||
dolt table import -u test `batshelper 1pk5col-ints.csv`
|
||||
dolt add test
|
||||
dolt commit -m "Added one initial row"
|
||||
|
||||
dolt checkout -b newbranch
|
||||
dolt sql -q 'UPDATE test SET c1=11, c5=6 WHERE pk=0'
|
||||
dolt add test
|
||||
dolt commit -m "modified first row"
|
||||
|
||||
# confirm a difference exists
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > query
|
||||
dolt checkout firstbranch
|
||||
dolt sql < query
|
||||
rm query
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
}
|
||||
|
||||
@test "diff sql output reconciles DELETE query" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 1pk5col-ints.schema` test
|
||||
dolt table import -u test `batshelper 1pk5col-ints.csv`
|
||||
dolt add test
|
||||
dolt commit -m "Added one initial row"
|
||||
|
||||
dolt checkout -b newbranch
|
||||
dolt sql -q 'DELETE FROM test WHERE pk=0'
|
||||
dolt add test
|
||||
dolt commit -m "deleted first row"
|
||||
|
||||
# confirm a difference exists
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > query
|
||||
dolt checkout firstbranch
|
||||
dolt sql < query
|
||||
rm query
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
}
|
||||
|
||||
@test "diff sql output reconciles primary key change" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 1pk5col-ints.schema` test
|
||||
dolt table import -u test `batshelper 1pk5col-ints.csv`
|
||||
dolt add test
|
||||
dolt commit -m "Added one initial row"
|
||||
|
||||
dolt checkout -b newbranch
|
||||
dolt sql -q 'UPDATE test SET pk=2 WHERE pk=1'
|
||||
dolt add test
|
||||
dolt commit -m "modified first row"
|
||||
|
||||
# confirm a difference exists
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > query
|
||||
dolt checkout firstbranch
|
||||
dolt sql < query
|
||||
rm query
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
}
|
||||
|
||||
@test "sql diff supports all types" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 1pksupportedtypes.schema` test
|
||||
dolt table import -u test `batshelper 1pksupportedtypes.csv`
|
||||
dolt add .
|
||||
dolt commit -m "create/init table test"
|
||||
|
||||
# for each query file in helper/queries/1pksuppportedtypes/
|
||||
# run query on db, create sql diff patch, confirm they're equivalent
|
||||
dolt branch newbranch
|
||||
for query in delete add update
|
||||
do
|
||||
dolt checkout newbranch
|
||||
dolt sql < $BATS_TEST_DIRNAME/helper/queries/1pksupportedtypes/$query.sql
|
||||
dolt add test
|
||||
dolt commit -m "applied $query query"
|
||||
|
||||
# confirm a difference exists
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > patch.sql
|
||||
dolt checkout firstbranch
|
||||
dolt sql < patch.sql
|
||||
rm patch.sql
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
done
|
||||
}
|
||||
|
||||
@test "sql diff supports multiple primary keys" {
|
||||
dolt checkout -b firstbranch
|
||||
dolt table create -s=`batshelper 2pk5col-ints.schema` test
|
||||
dolt table import -u test `batshelper 2pk5col-ints.csv`
|
||||
dolt add .
|
||||
dolt commit -m "create/init table test"
|
||||
|
||||
# for each query file in helper/queries/2pk5col-ints/
|
||||
# run query on db, create sql diff patch, confirm they're equivalent
|
||||
dolt branch newbranch
|
||||
for query in delete add update single_pk_update all_pk_update
|
||||
do
|
||||
dolt checkout newbranch
|
||||
dolt sql < $BATS_TEST_DIRNAME/helper/queries/2pk5col-ints/$query.sql
|
||||
dolt add test
|
||||
dolt diff --sql
|
||||
dolt commit -m "applied $query query "
|
||||
|
||||
# confirm a difference exists
|
||||
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != "" ]] || false
|
||||
|
||||
dolt diff --sql newbranch firstbranch > patch.sql
|
||||
dolt checkout firstbranch
|
||||
dolt sql < patch.sql
|
||||
rm patch.sql
|
||||
dolt add test
|
||||
dolt commit -m "Reconciled with newbranch"
|
||||
|
||||
# confirm that both branches have the same content
|
||||
run dolt diff --sql newbranch firstbranch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "" ]] || false
|
||||
done
|
||||
}
|
||||
|
||||
@test "sql diff correctly exits on schema change" {
|
||||
dolt table import -c -s=`batshelper employees-sch.json` employees `batshelper employees-tbl.json`
|
||||
dolt add employees
|
||||
dolt commit -m "Added employees table with data"
|
||||
dolt schema add-column employees city string
|
||||
dolt table put-row employees id:3 "first name":taylor "last name":bantle title:"software engineer" "start date":"" "end date":"" city:"Santa Monica"
|
||||
run dolt diff --sql
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "SQL output of schema diffs is not yet supported" ]] || false
|
||||
}
|
||||
@@ -47,20 +47,33 @@ import (
|
||||
"github.com/liquidata-inc/dolt/go/store/types"
|
||||
)
|
||||
|
||||
type diffOutput int
|
||||
type diffPart int
|
||||
|
||||
const (
|
||||
SchemaOnlyDiff = 1 // 0b0001
|
||||
DataOnlyDiff = 2 // 0b0010
|
||||
Summary = 4 // 0b0100
|
||||
SchemaOnlyDiff diffPart = 1 // 0b0001
|
||||
DataOnlyDiff diffPart = 2 // 0b0010
|
||||
Summary diffPart = 4 // 0b0100
|
||||
|
||||
SchemaAndDataDiff = SchemaOnlyDiff | DataOnlyDiff
|
||||
|
||||
TabularDiffOutput diffOutput = 1
|
||||
SQLDiffOutput diffOutput = 2
|
||||
|
||||
DataFlag = "data"
|
||||
SchemaFlag = "schema"
|
||||
SummaryFlag = "summary"
|
||||
whereParam = "where"
|
||||
limitParam = "limit"
|
||||
SQLFlag = "sql"
|
||||
)
|
||||
|
||||
type DiffSink interface {
|
||||
GetSchema() schema.Schema
|
||||
ProcRowWithProps(r row.Row, props pipeline.ReadableMap) error
|
||||
Close() error
|
||||
}
|
||||
|
||||
var diffShortDesc = "Show changes between commits, commit and working tree, etc"
|
||||
var diffLongDesc = `Show changes between the working and staged tables, changes between the working tables and the tables within a commit, or changes between tables at two commits.
|
||||
|
||||
@@ -84,9 +97,10 @@ var diffSynopsis = []string{
|
||||
}
|
||||
|
||||
type diffArgs struct {
|
||||
diffParts int
|
||||
limit int
|
||||
where string
|
||||
diffParts diffPart
|
||||
diffOutput diffOutput
|
||||
limit int
|
||||
where string
|
||||
}
|
||||
|
||||
func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv) int {
|
||||
@@ -94,6 +108,7 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
|
||||
ap.SupportsFlag(DataFlag, "d", "Show only the data changes, do not show the schema changes (Both shown by default).")
|
||||
ap.SupportsFlag(SchemaFlag, "s", "Show only the schema changes, do not show the data changes (Both shown by default).")
|
||||
ap.SupportsFlag(SummaryFlag, "", "Show summary of data changes")
|
||||
ap.SupportsFlag(SQLFlag, "q", "Output diff as a SQL patch file of INSERT / UPDATE / DELETE statements")
|
||||
ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See dolt diff --help for details.")
|
||||
ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
|
||||
help, _ := cli.HelpAndUsagePrinters(commandStr, diffShortDesc, diffLongDesc, diffSynopsis, ap)
|
||||
@@ -106,6 +121,11 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
|
||||
diffParts = SchemaOnlyDiff
|
||||
}
|
||||
|
||||
diffOutput := TabularDiffOutput
|
||||
if apr.Contains(SQLFlag) {
|
||||
diffOutput = SQLDiffOutput
|
||||
}
|
||||
|
||||
summary := apr.Contains(SummaryFlag)
|
||||
|
||||
if summary {
|
||||
@@ -125,7 +145,7 @@ func Diff(ctx context.Context, commandStr string, args []string, dEnv *env.DoltE
|
||||
if verr == nil {
|
||||
whereClause := apr.GetValueOrDefault(whereParam, "")
|
||||
|
||||
verr = diffRoots(ctx, r1, r2, tables, dEnv, &diffArgs{diffParts, limit, whereClause})
|
||||
verr = diffRoots(ctx, r1, r2, tables, dEnv, &diffArgs{diffParts, diffOutput, limit, whereClause})
|
||||
}
|
||||
|
||||
if verr != nil {
|
||||
@@ -273,7 +293,9 @@ func diffRoots(ctx context.Context, r1, r2 *doltdb.RootValue, tblNames []string,
|
||||
}
|
||||
}
|
||||
|
||||
printTableDiffSummary(tblName, tbl1, tbl2)
|
||||
if dArgs.diffOutput == TabularDiffOutput {
|
||||
printTableDiffSummary(tblName, tbl1, tbl2)
|
||||
}
|
||||
|
||||
if tbl1 == nil || tbl2 == nil {
|
||||
continue
|
||||
@@ -344,12 +366,16 @@ func diffRoots(ctx context.Context, r1, r2 *doltdb.RootValue, tblNames []string,
|
||||
verr = diffSummary(ctx, rowData1, rowData2, colLen)
|
||||
}
|
||||
|
||||
if sch1Hash != sch2Hash && dArgs.diffOutput == SQLDiffOutput {
|
||||
return errhand.BuildDError("SQL output of schema diffs is not yet supported").Build()
|
||||
}
|
||||
|
||||
if dArgs.diffParts&SchemaOnlyDiff != 0 && sch1Hash != sch2Hash {
|
||||
verr = diffSchemas(tblName, sch2, sch1)
|
||||
}
|
||||
|
||||
if dArgs.diffParts&DataOnlyDiff != 0 {
|
||||
verr = diffRows(ctx, rowData1, rowData2, sch1, sch2, dArgs)
|
||||
verr = diffRows(ctx, rowData1, rowData2, sch1, sch2, dArgs, tblName)
|
||||
}
|
||||
|
||||
if verr != nil {
|
||||
@@ -458,7 +484,7 @@ func fromNamer(name string) string {
|
||||
return diff.From + "_" + name
|
||||
}
|
||||
|
||||
func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch schema.Schema, dArgs *diffArgs) errhand.VerboseError {
|
||||
func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch schema.Schema, dArgs *diffArgs, tblName string) errhand.VerboseError {
|
||||
joiner, err := rowconv.NewJoiner(
|
||||
[]rowconv.NamedSchema{
|
||||
{Name: diff.From, Sch: oldSch},
|
||||
@@ -467,7 +493,7 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
|
||||
map[string]rowconv.ColNamingFunc{diff.To: toNamer, diff.From: fromNamer},
|
||||
)
|
||||
|
||||
untypedUnionSch, ds, verr := createSplitter(newSch, oldSch, joiner)
|
||||
untypedUnionSch, ds, verr := createSplitter(newSch, oldSch, joiner, dArgs)
|
||||
if verr != nil {
|
||||
return verr
|
||||
}
|
||||
@@ -497,7 +523,12 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
|
||||
numHeaderRows = 2
|
||||
}
|
||||
|
||||
sink, err := diff.NewColorDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, numHeaderRows)
|
||||
var sink DiffSink
|
||||
if dArgs.diffOutput == TabularDiffOutput {
|
||||
sink, err = diff.NewColorDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, numHeaderRows)
|
||||
} else {
|
||||
sink, err = diff.NewSQLDiffSink(iohelp.NopWrCloser(cli.CliOut), untypedUnionSch, tblName)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("").AddCause(err).Build()
|
||||
@@ -516,29 +547,31 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
|
||||
return verr
|
||||
}
|
||||
|
||||
if schemasEqual {
|
||||
schRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
|
||||
if dArgs.diffOutput != SQLDiffOutput {
|
||||
if schemasEqual {
|
||||
schRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
}
|
||||
|
||||
p.InjectRow(fwtStageName, schRow)
|
||||
} else {
|
||||
newSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, oldColNames)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
}
|
||||
|
||||
p.InjectRowWithProps(fwtStageName, newSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedOld})
|
||||
oldSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
}
|
||||
|
||||
p.InjectRowWithProps(fwtStageName, oldSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedNew})
|
||||
}
|
||||
|
||||
p.InjectRow(fwtStageName, schRow)
|
||||
} else {
|
||||
newSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, oldColNames)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
}
|
||||
|
||||
p.InjectRowWithProps(fwtStageName, newSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedOld})
|
||||
oldSchRow, err := untyped.NewRowFromTaggedStrings(newRows.Format(), untypedUnionSch, newColNames)
|
||||
|
||||
if err != nil {
|
||||
return errhand.BuildDError("error: creating diff header").AddCause(err).Build()
|
||||
}
|
||||
|
||||
p.InjectRowWithProps(fwtStageName, oldSchRow, map[string]interface{}{diff.DiffTypeProp: diff.DiffModifiedNew})
|
||||
}
|
||||
|
||||
p.Start()
|
||||
@@ -553,7 +586,7 @@ func diffRows(ctx context.Context, newRows, oldRows types.Map, newSch, oldSch sc
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitter, untypedUnionSch schema.Schema, src *diff.RowDiffSource, sink *diff.ColorDiffSink, badRowCB pipeline.BadRowCallback) (*pipeline.Pipeline, errhand.VerboseError) {
|
||||
func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitter, untypedUnionSch schema.Schema, src *diff.RowDiffSource, sink DiffSink, badRowCB pipeline.BadRowCallback) (*pipeline.Pipeline, errhand.VerboseError) {
|
||||
var where FilterFn
|
||||
var selTrans *SelectTransform
|
||||
where, err := ParseWhere(joiner.GetSchema(), dArgs.where)
|
||||
@@ -575,14 +608,17 @@ func buildPipeline(dArgs *diffArgs, joiner *rowconv.Joiner, ds *diff.DiffSplitte
|
||||
transforms.AppendTransforms(pipeline.NewNamedTransform("select", selTrans.LimitAndFilter))
|
||||
}
|
||||
|
||||
fwtTr := fwt.NewAutoSizingFWTTransformer(untypedUnionSch, fwt.HashFillWhenTooLong, 1000)
|
||||
nullPrinter := nullprinter.NewNullPrinter(untypedUnionSch)
|
||||
|
||||
transforms.AppendTransforms(pipeline.NewNamedTransform("split_diffs", ds.SplitDiffIntoOldAndNew),
|
||||
transforms.AppendTransforms(
|
||||
pipeline.NewNamedTransform("split_diffs", ds.SplitDiffIntoOldAndNew),
|
||||
pipeline.NewNamedTransform(nullprinter.NULL_PRINTING_STAGE, nullPrinter.ProcessRow),
|
||||
pipeline.NamedTransform{Name: fwtStageName, Func: fwtTr.TransformToFWT},
|
||||
)
|
||||
|
||||
if dArgs.diffOutput == TabularDiffOutput {
|
||||
fwtTr := fwt.NewAutoSizingFWTTransformer(untypedUnionSch, fwt.HashFillWhenTooLong, 1000)
|
||||
transforms.AppendTransforms(pipeline.NamedTransform{Name: fwtStageName, Func: fwtTr.TransformToFWT})
|
||||
}
|
||||
|
||||
sinkProcFunc := pipeline.ProcFuncForSinkFunc(sink.ProcRowWithProps)
|
||||
p := pipeline.NewAsyncPipeline(pipeline.ProcFuncForSourceFunc(src.NextDiff), sinkProcFunc, transforms, badRowCB)
|
||||
if selTrans != nil {
|
||||
@@ -614,7 +650,7 @@ func mapTagToColName(sch, untypedUnionSch schema.Schema) (map[uint64]string, err
|
||||
return tagToCol, nil
|
||||
}
|
||||
|
||||
func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.Joiner) (schema.Schema, *diff.DiffSplitter, errhand.VerboseError) {
|
||||
func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.Joiner, dArgs *diffArgs) (schema.Schema, *diff.DiffSplitter, errhand.VerboseError) {
|
||||
dumbNewSch, err := dumbDownSchema(newSch)
|
||||
|
||||
if err != nil {
|
||||
@@ -633,6 +669,11 @@ func createSplitter(newSch schema.Schema, oldSch schema.Schema, joiner *rowconv.
|
||||
return nil, nil, errhand.BuildDError("Failed to merge schemas").Build()
|
||||
}
|
||||
|
||||
if dArgs.diffOutput == SQLDiffOutput {
|
||||
// sql diffs don't support schema changes yet => newSch == oldSch
|
||||
untypedUnionSch = newSch
|
||||
}
|
||||
|
||||
newToUnionConv := rowconv.IdentityConverter
|
||||
if newSch != nil {
|
||||
newToUnionMapping, err := rowconv.TagMapping(newSch, untypedUnionSch)
|
||||
|
||||
@@ -23,7 +23,6 @@ require (
|
||||
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/golang/snappy v0.0.1
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
|
||||
@@ -10,12 +10,17 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CAFxX/gcnotifier v0.0.0-20190112062741-224a280d589d h1:n0G4ckjMEj7bWuGYUX0i8YlBeBBJuZ+HEHvHfyBDZtI=
|
||||
github.com/CAFxX/gcnotifier v0.0.0-20190112062741-224a280d589d/go.mod h1:Rn2zM2MnHze07LwkneP48TWt6UiZhzQTwCvw6djVGfE=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895 h1:dmc/C8bpE5VkQn65PNbbyACDC8xw8Hpp/NEurdPmQDQ=
|
||||
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
|
||||
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8=
|
||||
@@ -29,6 +34,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
|
||||
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=
|
||||
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
@@ -40,15 +46,20 @@ github.com/aws/aws-sdk-go v1.21.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
|
||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2 h1:M+TYzBcNIRyzPRg66ndEqUMd7oWDmhvdQmaPC6EZNwM=
|
||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
|
||||
github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/codahale/blake2 v0.0.0-20150924215134-8d10d0420cbf h1:5ZeQB3mThuz5C2MSER6T5GdtXTF9CMMk42F9BOyRsEQ=
|
||||
github.com/codahale/blake2 v0.0.0-20150924215134-8d10d0420cbf/go.mod h1:BO2rLUAZMrpgh6GBVKi0Gjdqw2MgCtJrtmUdDeZRKjY=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/etcd v0.0.0-20170626015032-703663d1f6ed/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
@@ -85,6 +96,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
|
||||
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613 h1:ceTf7nwYVaHrjRyFNWH5q/B9tZYYyUYapvGrgaCPuYU=
|
||||
github.com/gocraft/dbr v0.0.0-20190708200302-a54124dfc613/go.mod h1:K/9g3pPouf13kP5K7pdriQEJAy272R9yXuWuDIEWJTM=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -103,10 +115,12 @@ github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8l
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@@ -118,26 +132,35 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/handlers v1.3.0 h1:tsg9qP3mjt1h4Roxp+M1paRjrVBfPSOpBuVclh6YluI=
|
||||
github.com/gorilla/handlers v1.3.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20160912153041-2d1e4548da23/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20180418170936-39de4380c2e0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v0.0.0-20161128002007-199c40a060d1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.0.0-20160407174126-ad28ea4487f0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.0.0-20161207011743-d3a67ab21bc8/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
@@ -147,6 +170,7 @@ github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4Fw
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7 h1:K//n/AqR5HjG3qxbrBCL4vJPW0MVFSs9CPK1OOJdRME=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||
@@ -167,6 +191,7 @@ github.com/klauspost/pgzip v1.2.0/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQ
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/liquidata-inc/go-mysql-server v0.4.1-0.20191113181502-9b6ae60379a4 h1:V7eKj0YpFA9qlflFvfB3Q6gq+VsL99K1XNlxkClYprQ=
|
||||
github.com/liquidata-inc/go-mysql-server v0.4.1-0.20191113181502-9b6ae60379a4/go.mod h1:DdWE0ku/mNfuLsRJIrHeHpDtB7am+6oopxEsQKmVkx8=
|
||||
@@ -189,10 +214,12 @@ github.com/mattn/go-runewidth v0.0.1/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -207,9 +234,12 @@ github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v0.0.0-20160824210600-b984ec7fa9ff/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pilosa/pilosa v1.3.0 h1:P27JB4tIqAN4Yc2Fw7wS5neD7JNkFKRUmwfyV87JMwQ=
|
||||
github.com/pilosa/pilosa v1.3.0/go.mod h1:97yLL9mpUqOj9naKu5XA/b/U6JLe3JGGUlc2HOTDw+A=
|
||||
github.com/pkg/errors v0.0.0-20190109061628-ffb6e22f0193/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
@@ -222,13 +252,17 @@ github.com/prometheus/client_golang v0.0.0-20180319131721-d49167c4b9f3/go.mod h1
|
||||
github.com/prometheus/client_model v0.0.0-20150212101744-fa8ad6fec335/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20160607094339-3a184ff7dfd4/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20160411190841-abf152e5f3e9/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 h1:YDeskXpkNDhPdWN3REluVa46HQOVuVkjkd2sWnrABNQ=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44 h1:XKCbzPvK4/BbMXoMJOkYP2ANxiAEO0HM1xn6psSbXxY=
|
||||
github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20160616024954-e64db453f351/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sanity-io/litter v1.1.0 h1:BllcKWa3VbZmOZbDCoszYLk7zCsKHz5Beossi8SUcTc=
|
||||
github.com/sanity-io/litter v1.1.0/go.mod h1:CJ0VCw2q4qKU7LaQr3n7UOSHzgEMgcGco7N/SkZQPjw=
|
||||
github.com/satori/go.uuid v0.0.0-20160713180306-0aa62d5ddceb/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v0.0.0-20170409071739-feef008d51ad/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM=
|
||||
@@ -242,6 +276,7 @@ github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw
|
||||
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
@@ -252,6 +287,7 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/src-d/go-oniguruma v1.0.0 h1:JDk5PUAjreGsGAKLsoDLNmrsaryjJ5RqT3h+Si6aw/E=
|
||||
github.com/src-d/go-oniguruma v1.0.0/go.mod h1:chVbff8kcVtmrhxtZ3yBVLLquXbzCS6DrxQaAK/CeqM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -264,15 +300,19 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
|
||||
github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/tealeg/xlsx v1.0.4-0.20190601071628-e2d23f3c43dc h1:WhjmAhd6qju7Jf7hseM3Gd26PMjJJbAcEYgfRnznnko=
|
||||
github.com/tealeg/xlsx v1.0.4-0.20190601071628-e2d23f3c43dc/go.mod h1:uxu5UY2ovkuRPWKQ8Q7JG0JbSivrISjdPzZQKeo74mA=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY=
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw=
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yudai/gojsondiff v0.0.0-20170626131258-081cda2ee950/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU=
|
||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
@@ -320,6 +360,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -365,6 +406,7 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
@@ -381,6 +423,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
||||
google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20150924051756-4e86f4367175/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ldap.v2 v2.5.0/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
|
||||
@@ -395,6 +438,8 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
modernc.org/mathutil v1.0.0 h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=
|
||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright 2019 Liquidata, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package diff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/row"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/pipeline"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/untyped/sqlexport"
|
||||
"github.com/liquidata-inc/dolt/go/store/types"
|
||||
)
|
||||
|
||||
type SQLDiffSink struct {
|
||||
sch schema.Schema
|
||||
sw *sqlexport.SqlExportWriter
|
||||
}
|
||||
|
||||
func NewSQLDiffSink(wr io.WriteCloser, sch schema.Schema, tableName string) (*SQLDiffSink, error) {
|
||||
sw, err := sqlexport.NewSQLDiffWriter(wr, tableName, sch)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &SQLDiffSink{sch, sw}, nil
|
||||
}
|
||||
|
||||
func (sds *SQLDiffSink) GetSchema() schema.Schema {
|
||||
return sds.sch
|
||||
}
|
||||
|
||||
func (sds *SQLDiffSink) ProcRowWithProps(r row.Row, props pipeline.ReadableMap) error {
|
||||
|
||||
taggedVals := make(row.TaggedValues)
|
||||
allCols := sds.sch.GetAllCols()
|
||||
colDiffs := make(map[string]DiffChType)
|
||||
|
||||
if prop, ok := props.Get(CollChangesProp); ok {
|
||||
if convertedVal, convertedOK := prop.(map[string]DiffChType); convertedOK {
|
||||
colDiffs = convertedVal
|
||||
}
|
||||
}
|
||||
|
||||
err := allCols.Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
if val, ok := r.GetColVal(tag); ok {
|
||||
taggedVals[tag] = val
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err = row.New(r.Format(), sds.sch, taggedVals)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
taggedVals[diffColTag] = types.String(" ")
|
||||
if prop, ok := props.Get(DiffTypeProp); ok {
|
||||
if dt, convertedOK := prop.(DiffChType); convertedOK {
|
||||
switch dt {
|
||||
case DiffAdded:
|
||||
return sds.sw.WriteInsertRow(context.TODO(), r)
|
||||
case DiffRemoved:
|
||||
return sds.sw.WriteDeleteRow(context.TODO(), r)
|
||||
case DiffModifiedOld:
|
||||
return nil
|
||||
case DiffModifiedNew:
|
||||
// TODO: minimize update statement to modified rows
|
||||
return sds.sw.WriteUpdateRow(context.TODO(), r)
|
||||
}
|
||||
// Treat the diff indicator string as a diff of the same type
|
||||
colDiffs[diffColName] = dt
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Close should release resources being held
|
||||
func (sds *SQLDiffSink) Close() error {
|
||||
if sds.sw != nil {
|
||||
if err := sds.sw.Close(context.TODO()); err != nil {
|
||||
return err
|
||||
}
|
||||
sds.sw = nil
|
||||
return nil
|
||||
} else {
|
||||
return errors.New("Already closed.")
|
||||
}
|
||||
}
|
||||
@@ -299,6 +299,7 @@ func (root *RootValue) HashOf() (hash.Hash, error) {
|
||||
// TableDiff returns the slices of tables added, modified, and removed when compared with another root value. Tables
|
||||
// In this instance that are not in the other instance are considered added, and tables in the other instance and not
|
||||
// this instance are considered removed.
|
||||
// TODO: is this logic redundant of doltcore/diff ?
|
||||
func (root *RootValue) TableDiff(ctx context.Context, other *RootValue) (added, modified, removed []string, err error) {
|
||||
added = []string{}
|
||||
modified = []string{}
|
||||
|
||||
@@ -55,6 +55,11 @@ func OpenSQLExportWriter(path string, tableName string, fs filesys.WritableFS, s
|
||||
return &SqlExportWriter{tableName: tableName, sch: sch, wr: wr}, nil
|
||||
}
|
||||
|
||||
func NewSQLDiffWriter(wr io.WriteCloser, tableName string, sch schema.Schema) (*SqlExportWriter, error) {
|
||||
// set writtenFirstRow = true to prevent table drop statement from being written
|
||||
return &SqlExportWriter{tableName: tableName, sch: sch, wr: wr, writtenFirstRow: true}, nil
|
||||
}
|
||||
|
||||
// Returns the schema of this TableWriter.
|
||||
func (w *SqlExportWriter) GetSchema() schema.Schema {
|
||||
return w.sch
|
||||
@@ -98,6 +103,16 @@ func (w *SqlExportWriter) Close(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *SqlExportWriter) WriteInsertRow(ctx context.Context, r row.Row) error {
|
||||
stmt, err := w.insertStatementForRow(r)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return iohelp.WriteLine(w.wr, stmt)
|
||||
}
|
||||
|
||||
func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
|
||||
var b strings.Builder
|
||||
b.WriteString("INSERT INTO ")
|
||||
@@ -105,7 +120,7 @@ func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
|
||||
b.WriteString(" ")
|
||||
|
||||
b.WriteString("(")
|
||||
var seenOne bool
|
||||
seenOne := false
|
||||
err := w.sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
if seenOne {
|
||||
b.WriteRune(',')
|
||||
@@ -145,6 +160,97 @@ func (w *SqlExportWriter) insertStatementForRow(r row.Row) (string, error) {
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
func (w *SqlExportWriter) WriteDeleteRow(ctx context.Context, r row.Row) error {
|
||||
var b strings.Builder
|
||||
b.WriteString("DELETE FROM ")
|
||||
b.WriteString(sql.QuoteIdentifier(w.tableName))
|
||||
|
||||
b.WriteString(" WHERE (")
|
||||
seenOne := false
|
||||
_, err := r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
|
||||
col := w.sch.GetAllCols().TagToCol[tag]
|
||||
if col.IsPartOfPK {
|
||||
if seenOne {
|
||||
b.WriteString(" AND ")
|
||||
}
|
||||
sqlString, err := w.sqlString(val)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
b.WriteString(sql.QuoteIdentifier(col.Name))
|
||||
b.WriteRune('=')
|
||||
b.WriteString(sqlString)
|
||||
seenOne = true
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.WriteString(");")
|
||||
return iohelp.WriteLine(w.wr, b.String())
|
||||
}
|
||||
|
||||
func (w *SqlExportWriter) WriteUpdateRow(ctx context.Context, r row.Row) error {
|
||||
var b strings.Builder
|
||||
b.WriteString("UPDATE ")
|
||||
b.WriteString(sql.QuoteIdentifier(w.tableName))
|
||||
b.WriteString(" ")
|
||||
|
||||
b.WriteString("SET ")
|
||||
seenOne := false
|
||||
_, err := r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
|
||||
col := w.sch.GetAllCols().TagToCol[tag]
|
||||
if !col.IsPartOfPK {
|
||||
if seenOne {
|
||||
b.WriteRune(',')
|
||||
}
|
||||
sqlString, err := w.sqlString(val)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
b.WriteString(sql.QuoteIdentifier(col.Name))
|
||||
b.WriteRune('=')
|
||||
b.WriteString(sqlString)
|
||||
seenOne = true
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.WriteString(" WHERE (")
|
||||
seenOne = false
|
||||
_, err = r.IterSchema(w.sch, func(tag uint64, val types.Value) (stop bool, err error) {
|
||||
col := w.sch.GetAllCols().TagToCol[tag]
|
||||
if col.IsPartOfPK {
|
||||
if seenOne {
|
||||
b.WriteString(" AND ")
|
||||
}
|
||||
sqlString, err := w.sqlString(val)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
b.WriteString(sql.QuoteIdentifier(col.Name))
|
||||
b.WriteRune('=')
|
||||
b.WriteString(sqlString)
|
||||
seenOne = true
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.WriteString(");")
|
||||
return iohelp.WriteLine(w.wr, b.String())
|
||||
}
|
||||
|
||||
func (w *SqlExportWriter) dropCreateStatement() string {
|
||||
var b strings.Builder
|
||||
b.WriteString("DROP TABLE IF EXISTS ")
|
||||
|
||||
@@ -37,19 +37,19 @@ func (*StringBuilderCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
rows []row.Row
|
||||
sch schema.Schema
|
||||
expectedOutput string
|
||||
}
|
||||
|
||||
func TestWriteRow(t *testing.T) {
|
||||
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
|
||||
tableName := "people"
|
||||
|
||||
dropCreateStatement := "DROP TABLE IF EXISTS `people`;\n" + sql.SchemaAsCreateStmt(tableName, dtestutils.TypedSchema)
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
rows []row.Row
|
||||
sch schema.Schema
|
||||
expectedOutput string
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "simple row",
|
||||
@@ -121,6 +121,102 @@ func TestWriteRow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteRow(t *testing.T) {
|
||||
tableName := "tricky"
|
||||
trickySch := dtestutils.CreateSchema(
|
||||
schema.NewColumn("anotherCol", 0, types.FloatKind, false),
|
||||
schema.NewColumn("a name with spaces", 1, types.IntKind, true),
|
||||
)
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "negative values and columns with spaces",
|
||||
rows: rs(dtestutils.NewRow(trickySch, types.Float(-3.14), types.Int(-42))),
|
||||
sch: trickySch,
|
||||
expectedOutput: "DELETE FROM `tricky` WHERE (`a name with spaces`=-42);" + "\n",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var stringWr StringBuilderCloser
|
||||
w := &SqlExportWriter{
|
||||
tableName: tableName,
|
||||
sch: tt.sch,
|
||||
wr: &stringWr,
|
||||
}
|
||||
|
||||
for _, r := range tt.rows {
|
||||
assert.NoError(t, w.WriteDeleteRow(context.Background(), r))
|
||||
}
|
||||
assert.Equal(t, tt.expectedOutput, stringWr.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateRow(t *testing.T) {
|
||||
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
|
||||
tableName := "people"
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "simple row",
|
||||
rows: rs(dtestutils.NewTypedRow(id, "some guy", 100, false, strPointer("normie"))),
|
||||
sch: dtestutils.TypedSchema,
|
||||
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
|
||||
},
|
||||
{
|
||||
name: "embedded quotes",
|
||||
rows: rs(dtestutils.NewTypedRow(id, `It's "Mister Perfect" to you`, 100, false, strPointer("normie"))),
|
||||
sch: dtestutils.TypedSchema,
|
||||
expectedOutput: "UPDATE `people` SET `name`=\"It's \\\"Mister Perfect\\\" to you\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
|
||||
},
|
||||
{
|
||||
name: "two rows",
|
||||
rows: rs(
|
||||
dtestutils.NewTypedRow(id, "some guy", 100, false, strPointer("normie")),
|
||||
dtestutils.NewTypedRow(id, "guy personson", 0, true, strPointer("officially a person"))),
|
||||
sch: dtestutils.TypedSchema,
|
||||
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=\"normie\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n" +
|
||||
"UPDATE `people` SET `name`=\"guy personson\",`age`=0,`is_married`=TRUE,`title`=\"officially a person\" WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
|
||||
},
|
||||
{
|
||||
name: "null values",
|
||||
rows: rs(dtestutils.NewTypedRow(id, "some guy", 100, false, nil)),
|
||||
sch: dtestutils.TypedSchema,
|
||||
expectedOutput: "UPDATE `people` SET `name`=\"some guy\",`age`=100,`is_married`=FALSE,`title`=NULL WHERE (`id`=\"00000000-0000-0000-0000-000000000000\");" + "\n",
|
||||
},
|
||||
}
|
||||
|
||||
trickySch := dtestutils.CreateSchema(
|
||||
schema.NewColumn("a name with spaces", 0, types.FloatKind, false),
|
||||
schema.NewColumn("anotherColumn", 1, types.IntKind, true),
|
||||
)
|
||||
|
||||
tests = append(tests, test{
|
||||
name: "negative values and columns with spaces",
|
||||
rows: rs(dtestutils.NewRow(trickySch, types.Float(-3.14), types.Int(-42))),
|
||||
sch: trickySch,
|
||||
expectedOutput: "UPDATE `people` SET `a name with spaces`=-3.14 WHERE (`anotherColumn`=-42);" + "\n",
|
||||
})
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var stringWr StringBuilderCloser
|
||||
w := &SqlExportWriter{
|
||||
tableName: tableName,
|
||||
sch: tt.sch,
|
||||
wr: &stringWr,
|
||||
}
|
||||
|
||||
for _, r := range tt.rows {
|
||||
assert.NoError(t, w.WriteUpdateRow(context.Background(), r))
|
||||
}
|
||||
assert.Equal(t, tt.expectedOutput, stringWr.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEndToEnd(t *testing.T) {
|
||||
id := uuid.MustParse("00000000-0000-0000-0000-000000000000")
|
||||
tableName := "people"
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
var AllowedAuthors = map[string]*struct{}{
|
||||
"Aaron Son <aaron@liquidata.co>": nil,
|
||||
"Andy Arthur <andy@liquidata.co>": nil,
|
||||
"Brian Hendriks <brian@liquidata.co>": nil,
|
||||
"Daylon Wilkins <daylon@liquidata.co>": nil,
|
||||
"Dustin Brown <dustin@liquidata.co>": nil,
|
||||
@@ -41,6 +42,7 @@ var AllowedAuthors = map[string]*struct{}{
|
||||
|
||||
var AllowedCommitters = map[string]*struct{}{
|
||||
"Aaron Son <aaron@liquidata.co>": nil,
|
||||
"Andy Arthur <andy@liquidata.co>": nil,
|
||||
"Brian Hendriks <brian@liquidata.co>": nil,
|
||||
"Daylon Wilkins <daylon@liquidata.co>": nil,
|
||||
"Dustin Brown <dustin@liquidata.co>": nil,
|
||||
|
||||
Reference in New Issue
Block a user