mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-22 19:43:51 -05:00
Rename dolt diff --summary to dolt diff --stat, remove some unused code
This commit is contained in:
@@ -46,7 +46,7 @@ type diffMode int
|
||||
const (
|
||||
SchemaOnlyDiff diffPart = 1 // 0b0001
|
||||
DataOnlyDiff diffPart = 2 // 0b0010
|
||||
Summary diffPart = 4 // 0b0100
|
||||
Stat diffPart = 4 // 0b0100
|
||||
|
||||
SchemaAndDataDiff = SchemaOnlyDiff | DataOnlyDiff
|
||||
|
||||
@@ -54,16 +54,16 @@ const (
|
||||
SQLDiffOutput diffOutput = 2
|
||||
JsonDiffOutput diffOutput = 3
|
||||
|
||||
DataFlag = "data"
|
||||
SchemaFlag = "schema"
|
||||
SummaryFlag = "summary"
|
||||
whereParam = "where"
|
||||
limitParam = "limit"
|
||||
SQLFlag = "sql"
|
||||
CachedFlag = "cached"
|
||||
SkinnyFlag = "skinny"
|
||||
MergeBase = "merge-base"
|
||||
DiffMode = "diff-mode"
|
||||
DataFlag = "data"
|
||||
SchemaFlag = "schema"
|
||||
StatFlag = "stat"
|
||||
whereParam = "where"
|
||||
limitParam = "limit"
|
||||
SQLFlag = "sql"
|
||||
CachedFlag = "cached"
|
||||
SkinnyFlag = "skinny"
|
||||
MergeBase = "merge-base"
|
||||
DiffMode = "diff-mode"
|
||||
)
|
||||
|
||||
var diffDocs = cli.CommandDocumentationContent{
|
||||
@@ -138,7 +138,7 @@ func (cmd DiffCmd) ArgParser() *argparser.ArgParser {
|
||||
ap := argparser.NewArgParser()
|
||||
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(StatFlag, "", "Show stats of data changes")
|
||||
ap.SupportsString(FormatFlag, "r", "result output format", "How to format diff output. Valid values are tabular, sql, json. Defaults to tabular.")
|
||||
ap.SupportsString(whereParam, "", "column", "filters columns based on values in the diff. See {{.EmphasisLeft}}dolt diff --help{{.EmphasisRight}} for details.")
|
||||
ap.SupportsInt(limitParam, "", "record_count", "limits to the first N diffs.")
|
||||
@@ -173,9 +173,9 @@ func (cmd DiffCmd) Exec(ctx context.Context, commandStr string, args []string, d
|
||||
}
|
||||
|
||||
func (cmd DiffCmd) validateArgs(apr *argparser.ArgParseResults) errhand.VerboseError {
|
||||
if apr.Contains(SummaryFlag) {
|
||||
if apr.Contains(StatFlag) {
|
||||
if apr.Contains(SchemaFlag) || apr.Contains(DataFlag) {
|
||||
return errhand.BuildDError("invalid Arguments: --summary cannot be combined with --schema or --data").Build()
|
||||
return errhand.BuildDError("invalid Arguments: --stat cannot be combined with --schema or --data").Build()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,8 +197,8 @@ func parseDiffArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
|
||||
dArgs.diffParts = DataOnlyDiff
|
||||
} else if apr.Contains(SchemaFlag) && !apr.Contains(DataFlag) {
|
||||
dArgs.diffParts = SchemaOnlyDiff
|
||||
} else if apr.Contains(SummaryFlag) {
|
||||
dArgs.diffParts = Summary
|
||||
} else if apr.Contains(StatFlag) {
|
||||
dArgs.diffParts = Stat
|
||||
}
|
||||
|
||||
dArgs.skinny = apr.Contains(SkinnyFlag)
|
||||
@@ -532,8 +532,8 @@ func diffUserTable(
|
||||
return errhand.BuildDError("cannot retrieve schema for table %s", td.ToName).AddCause(err).Build()
|
||||
}
|
||||
|
||||
if dArgs.diffParts&Summary != 0 {
|
||||
return printDiffSummary(ctx, td, fromSch.GetAllCols().Size(), toSch.GetAllCols().Size())
|
||||
if dArgs.diffParts&Stat != 0 {
|
||||
return printDiffStat(ctx, td, fromSch.GetAllCols().Size(), toSch.GetAllCols().Size())
|
||||
}
|
||||
|
||||
if dArgs.diffParts&SchemaOnlyDiff != 0 {
|
||||
|
||||
@@ -65,18 +65,18 @@ func newDiffWriter(diffOutput diffOutput) (diffWriter, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func printDiffSummary(ctx context.Context, td diff.TableDelta, oldColLen, newColLen int) errhand.VerboseError {
|
||||
func printDiffStat(ctx context.Context, td diff.TableDelta, oldColLen, newColLen int) errhand.VerboseError {
|
||||
// todo: use errgroup.Group
|
||||
ae := atomicerr.New()
|
||||
ch := make(chan diff.DiffSummaryProgress)
|
||||
ch := make(chan diff.DiffStatProgress)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
err := diff.SummaryForTableDelta(ctx, ch, td)
|
||||
err := diff.StatForTableDelta(ctx, ch, td)
|
||||
|
||||
ae.SetIfError(err)
|
||||
}()
|
||||
|
||||
acc := diff.DiffSummaryProgress{}
|
||||
acc := diff.DiffStatProgress{}
|
||||
var count int64
|
||||
var pos int
|
||||
eP := cli.NewEphemeralPrinter()
|
||||
@@ -119,15 +119,15 @@ func printDiffSummary(ctx context.Context, td diff.TableDelta, oldColLen, newCol
|
||||
}
|
||||
|
||||
if keyless {
|
||||
printKeylessSummary(acc)
|
||||
printKeylessStat(acc)
|
||||
} else {
|
||||
printSummary(acc, oldColLen, newColLen)
|
||||
printStat(acc, oldColLen, newColLen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func printSummary(acc diff.DiffSummaryProgress, oldColLen, newColLen int) {
|
||||
func printStat(acc diff.DiffStatProgress, oldColLen, newColLen int) {
|
||||
numCellInserts, numCellDeletes := sqle.GetCellsAddedAndDeleted(acc, newColLen)
|
||||
rowsUnmodified := uint64(acc.OldRowSize - acc.Changes - acc.Removes)
|
||||
unmodified := pluralize("Row Unmodified", "Rows Unmodified", rowsUnmodified)
|
||||
@@ -161,7 +161,7 @@ func printSummary(acc diff.DiffSummaryProgress, oldColLen, newColLen int) {
|
||||
cli.Printf("(%s vs %s)\n\n", oldValues, newValues)
|
||||
}
|
||||
|
||||
func printKeylessSummary(acc diff.DiffSummaryProgress) {
|
||||
func printKeylessStat(acc diff.DiffStatProgress) {
|
||||
insertions := pluralize("Row Added", "Rows Added", acc.Adds)
|
||||
deletions := pluralize("Row Deleted", "Rows Deleted", acc.Removes)
|
||||
|
||||
|
||||
+30
-30
@@ -34,16 +34,16 @@ import (
|
||||
|
||||
var ErrPrimaryKeySetChanged = errors.New("primary key set changed")
|
||||
|
||||
type DiffSummaryProgress struct {
|
||||
type DiffStatProgress struct {
|
||||
Adds, Removes, Changes, CellChanges, NewRowSize, OldRowSize, NewCellSize, OldCellSize uint64
|
||||
}
|
||||
|
||||
type prollyReporter func(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error
|
||||
type nomsReporter func(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error
|
||||
type prollyReporter func(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error
|
||||
type nomsReporter func(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error
|
||||
|
||||
// Summary reports a summary of diff changes between two values
|
||||
// Stat reports a stat of diff changes between two values
|
||||
// todo: make package private once dolthub is migrated
|
||||
func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.Index, fromSch, toSch schema.Schema) (err error) {
|
||||
func Stat(ctx context.Context, ch chan DiffStatProgress, from, to durable.Index, fromSch, toSch schema.Schema) (err error) {
|
||||
fc, err := from.Count()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -52,7 +52,7 @@ func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ch <- DiffSummaryProgress{OldRowSize: fc, NewRowSize: tc}
|
||||
ch <- DiffStatProgress{OldRowSize: fc, NewRowSize: tc}
|
||||
|
||||
fk, tk := schema.IsKeyless(fromSch), schema.IsKeyless(toSch)
|
||||
var keyless bool
|
||||
@@ -69,15 +69,15 @@ func Summary(ctx context.Context, ch chan DiffSummaryProgress, from, to durable.
|
||||
return diffNomsMaps(ctx, ch, keyless, from, to, fromSch, toSch)
|
||||
}
|
||||
|
||||
// SummaryForTableDelta pushes diff summary progress messages for the table delta given to the channel given
|
||||
func SummaryForTableDelta(ctx context.Context, ch chan DiffSummaryProgress, td TableDelta) error {
|
||||
// StatForTableDelta pushes diff stat progress messages for the table delta given to the channel given
|
||||
func StatForTableDelta(ctx context.Context, ch chan DiffStatProgress, td TableDelta) error {
|
||||
fromSch, toSch, err := td.GetSchemas(ctx)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("cannot retrieve schema for table %s", td.ToName).AddCause(err).Build()
|
||||
}
|
||||
|
||||
if !schema.ArePrimaryKeySetsDiffable(td.Format(), fromSch, toSch) {
|
||||
return fmt.Errorf("failed to compute diff summary for table %s: %w", td.CurName(), ErrPrimaryKeySetChanged)
|
||||
return fmt.Errorf("failed to compute diff stat for table %s: %w", td.CurName(), ErrPrimaryKeySetChanged)
|
||||
}
|
||||
|
||||
keyless, err := td.IsKeyless(ctx)
|
||||
@@ -97,7 +97,7 @@ func SummaryForTableDelta(ctx context.Context, ch chan DiffSummaryProgress, td T
|
||||
}
|
||||
}
|
||||
|
||||
func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless bool, from, to durable.Index, fromSch, toSch schema.Schema) error {
|
||||
func diffProllyTrees(ctx context.Context, ch chan DiffStatProgress, keyless bool, from, to durable.Index, fromSch, toSch schema.Schema) error {
|
||||
_, vMapping, err := schema.MapSchemaBasedOnTagAndName(fromSch, toSch)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -123,7 +123,7 @@ func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless b
|
||||
}
|
||||
ctc := uint64(len(toSch.GetAllCols().GetColumns())) * tc
|
||||
rpr = reportPkChanges
|
||||
ch <- DiffSummaryProgress{
|
||||
ch <- DiffStatProgress{
|
||||
OldRowSize: fc,
|
||||
NewRowSize: tc,
|
||||
OldCellSize: cfc,
|
||||
@@ -140,7 +140,7 @@ func diffProllyTrees(ctx context.Context, ch chan DiffSummaryProgress, keyless b
|
||||
return nil
|
||||
}
|
||||
|
||||
func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool, fromRows durable.Index, toRows durable.Index, fromSch, toSch schema.Schema) error {
|
||||
func diffNomsMaps(ctx context.Context, ch chan DiffStatProgress, keyless bool, fromRows durable.Index, toRows durable.Index, fromSch, toSch schema.Schema) error {
|
||||
var rpr nomsReporter
|
||||
if keyless {
|
||||
rpr = reportNomsKeylessChanges
|
||||
@@ -156,7 +156,7 @@ func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool
|
||||
}
|
||||
ctc := uint64(len(toSch.GetAllCols().GetColumns())) * tc
|
||||
rpr = reportNomsPkChanges
|
||||
ch <- DiffSummaryProgress{
|
||||
ch <- DiffStatProgress{
|
||||
OldRowSize: fc,
|
||||
NewRowSize: tc,
|
||||
OldCellSize: cfc,
|
||||
@@ -164,10 +164,10 @@ func diffNomsMaps(ctx context.Context, ch chan DiffSummaryProgress, keyless bool
|
||||
}
|
||||
}
|
||||
|
||||
return summaryWithReporter(ctx, ch, durable.NomsMapFromIndex(fromRows), durable.NomsMapFromIndex(toRows), rpr, fromSch, toSch)
|
||||
return statWithReporter(ctx, ch, durable.NomsMapFromIndex(fromRows), durable.NomsMapFromIndex(toRows), rpr, fromSch, toSch)
|
||||
}
|
||||
|
||||
func summaryWithReporter(ctx context.Context, ch chan DiffSummaryProgress, from, to types.Map, rpr nomsReporter, fromSch, toSch schema.Schema) (err error) {
|
||||
func statWithReporter(ctx context.Context, ch chan DiffStatProgress, from, to types.Map, rpr nomsReporter, fromSch, toSch schema.Schema) (err error) {
|
||||
ad := NewAsyncDiffer(1024)
|
||||
ad.Start(ctx, from, to)
|
||||
defer func() {
|
||||
@@ -199,8 +199,8 @@ func summaryWithReporter(ctx context.Context, ch chan DiffSummaryProgress, from,
|
||||
return nil
|
||||
}
|
||||
|
||||
func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error {
|
||||
var sum DiffSummaryProgress
|
||||
func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error {
|
||||
var sum DiffStatProgress
|
||||
switch change.Type {
|
||||
case tree.AddedDiff:
|
||||
sum.Adds++
|
||||
@@ -220,8 +220,8 @@ func reportPkChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, to
|
||||
}
|
||||
}
|
||||
|
||||
func reportKeylessChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffSummaryProgress) error {
|
||||
var sum DiffSummaryProgress
|
||||
func reportKeylessChanges(ctx context.Context, vMapping val.OrdinalMapping, fromD, toD val.TupleDesc, change tree.Diff, ch chan<- DiffStatProgress) error {
|
||||
var sum DiffStatProgress
|
||||
var n, n2 uint64
|
||||
switch change.Type {
|
||||
case tree.AddedDiff:
|
||||
@@ -280,13 +280,13 @@ func prollyCountCellDiff(mapping val.OrdinalMapping, fromD, toD val.TupleDesc, f
|
||||
return changed
|
||||
}
|
||||
|
||||
func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error {
|
||||
var summary DiffSummaryProgress
|
||||
func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error {
|
||||
var stat DiffStatProgress
|
||||
switch change.ChangeType {
|
||||
case types.DiffChangeAdded:
|
||||
summary = DiffSummaryProgress{Adds: 1}
|
||||
stat = DiffStatProgress{Adds: 1}
|
||||
case types.DiffChangeRemoved:
|
||||
summary = DiffSummaryProgress{Removes: 1}
|
||||
stat = DiffStatProgress{Removes: 1}
|
||||
case types.DiffChangeModified:
|
||||
oldTuple := change.OldValue.(types.Tuple)
|
||||
newTuple := change.NewValue.(types.Tuple)
|
||||
@@ -294,19 +294,19 @@ func reportNomsPkChanges(ctx context.Context, change *diff.Difference, fromSch,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
summary = DiffSummaryProgress{Changes: 1, CellChanges: cellChanges}
|
||||
stat = DiffStatProgress{Changes: 1, CellChanges: cellChanges}
|
||||
default:
|
||||
return errors.New("unknown change type")
|
||||
}
|
||||
select {
|
||||
case ch <- summary:
|
||||
case ch <- stat:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffSummaryProgress) error {
|
||||
func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, fromSch, toSch schema.Schema, ch chan<- DiffStatProgress) error {
|
||||
var oldCard uint64
|
||||
if change.OldValue != nil {
|
||||
v, err := change.OldValue.(types.Tuple).Get(row.KeylessCardinalityValIdx)
|
||||
@@ -325,18 +325,18 @@ func reportNomsKeylessChanges(ctx context.Context, change *diff.Difference, from
|
||||
newCard = uint64(v.(types.Uint))
|
||||
}
|
||||
|
||||
var summary DiffSummaryProgress
|
||||
var stat DiffStatProgress
|
||||
delta := int64(newCard) - int64(oldCard)
|
||||
if delta > 0 {
|
||||
summary = DiffSummaryProgress{Adds: uint64(delta)}
|
||||
stat = DiffStatProgress{Adds: uint64(delta)}
|
||||
} else if delta < 0 {
|
||||
summary = DiffSummaryProgress{Removes: uint64(-delta)}
|
||||
stat = DiffStatProgress{Removes: uint64(-delta)}
|
||||
} else {
|
||||
return fmt.Errorf("diff with delta = 0 for key: %s", change.KeyValue.HumanReadableString())
|
||||
}
|
||||
|
||||
select {
|
||||
case ch <- summary:
|
||||
case ch <- stat:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
@@ -486,10 +486,10 @@ func calcTableMergeStats(ctx context.Context, tbl *doltdb.Table, mergeTbl *doltd
|
||||
}
|
||||
|
||||
ae := atomicerr.New()
|
||||
ch := make(chan diff.DiffSummaryProgress)
|
||||
ch := make(chan diff.DiffStatProgress)
|
||||
go func() {
|
||||
defer close(ch)
|
||||
err := diff.Summary(ctx, ch, rows, mergeRows, sch, mergeSch)
|
||||
err := diff.Stat(ctx, ch, rows, mergeRows, sch, mergeSch)
|
||||
|
||||
ae.SetIfError(err)
|
||||
}()
|
||||
|
||||
@@ -275,7 +275,7 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If tableNameExpr defined, return a single table diff summary result
|
||||
// If tableNameExpr defined, return a single table diff stat result
|
||||
if ds.tableNameExpr != nil {
|
||||
delta := findMatchingDelta(deltas, tableName)
|
||||
diffSum, hasDiff, err := getDiffSummaryNodeFromDelta(ctx, delta, fromRoot, toRoot, tableName)
|
||||
@@ -352,7 +352,7 @@ func (ds *DiffSummaryTableFunction) evaluateArguments() (interface{}, interface{
|
||||
}
|
||||
|
||||
// getDiffSummaryNodeFromDelta returns diffSummaryNode object and whether there is data diff or not. It gets tables
|
||||
// from roots and diff summary if there is a valid table exists in both fromRoot and toRoot.
|
||||
// from roots and diff stat if there is a valid table exists in both fromRoot and toRoot.
|
||||
func getDiffSummaryNodeFromDelta(ctx *sql.Context, delta diff.TableDelta, fromRoot, toRoot *doltdb.RootValue, tableName string) (diffSummaryNode, bool, error) {
|
||||
var oldColLen int
|
||||
var newColLen int
|
||||
@@ -399,20 +399,20 @@ func getDiffSummaryNodeFromDelta(ctx *sql.Context, delta diff.TableDelta, fromRo
|
||||
return diffSummaryNode{tableName, diffSum, oldColLen, newColLen, keyless}, hasDiff, nil
|
||||
}
|
||||
|
||||
// getDiffSummary returns diff.DiffSummaryProgress object and whether there is a data diff or not.
|
||||
func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffSummaryProgress, bool, bool, error) {
|
||||
// getDiffSummary returns diff.DiffStatProgress object and whether there is a data diff or not.
|
||||
func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffStatProgress, bool, bool, error) {
|
||||
// got this method from diff_output.go
|
||||
|
||||
ch := make(chan diff.DiffSummaryProgress)
|
||||
ch := make(chan diff.DiffStatProgress)
|
||||
|
||||
grp, ctx2 := errgroup.WithContext(ctx)
|
||||
grp.Go(func() error {
|
||||
defer close(ch)
|
||||
err := diff.SummaryForTableDelta(ctx2, ch, td)
|
||||
err := diff.StatForTableDelta(ctx2, ch, td)
|
||||
return err
|
||||
})
|
||||
|
||||
acc := diff.DiffSummaryProgress{}
|
||||
acc := diff.DiffStatProgress{}
|
||||
var count int64
|
||||
grp.Go(func() error {
|
||||
for {
|
||||
@@ -437,16 +437,16 @@ func getDiffSummary(ctx *sql.Context, td diff.TableDelta) (diff.DiffSummaryProgr
|
||||
})
|
||||
|
||||
if err := grp.Wait(); err != nil {
|
||||
return diff.DiffSummaryProgress{}, false, false, err
|
||||
return diff.DiffStatProgress{}, false, false, err
|
||||
}
|
||||
|
||||
keyless, err := td.IsKeyless(ctx)
|
||||
if err != nil {
|
||||
return diff.DiffSummaryProgress{}, false, keyless, err
|
||||
return diff.DiffStatProgress{}, false, keyless, err
|
||||
}
|
||||
|
||||
if (acc.Adds+acc.Removes+acc.Changes) == 0 && (acc.OldCellSize-acc.NewCellSize) == 0 {
|
||||
return diff.DiffSummaryProgress{}, false, keyless, nil
|
||||
return diff.DiffStatProgress{}, false, keyless, nil
|
||||
}
|
||||
|
||||
return acc, true, keyless, nil
|
||||
@@ -473,7 +473,7 @@ func (d *diffSummaryTableFunctionRowIter) incrementIndexes() {
|
||||
|
||||
type diffSummaryNode struct {
|
||||
tblName string
|
||||
diffSummary diff.DiffSummaryProgress
|
||||
diffSummary diff.DiffStatProgress
|
||||
oldColLen int
|
||||
newColLen int
|
||||
keyless bool
|
||||
@@ -503,10 +503,10 @@ func (d *diffSummaryTableFunctionRowIter) Close(context *sql.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// getRowFromDiffSummary takes diff.DiffSummaryProgress and calculates the row_modified, cell_added, cell_deleted.
|
||||
// getRowFromDiffSummary takes diff.DiffStatProgress and calculates the row_modified, cell_added, cell_deleted.
|
||||
// If the number of cell change from old to new cell count does not equal to cell_added and/or cell_deleted, there
|
||||
// must be schema changes that affects cell_added and cell_deleted value addition to the row count * col length number.
|
||||
func getRowFromDiffSummary(tblName string, dsp diff.DiffSummaryProgress, newColLen, oldColLen int, keyless bool) sql.Row {
|
||||
func getRowFromDiffSummary(tblName string, dsp diff.DiffStatProgress, newColLen, oldColLen int, keyless bool) sql.Row {
|
||||
// if table is keyless table, match current CLI command result
|
||||
if keyless {
|
||||
return sql.Row{
|
||||
@@ -544,10 +544,10 @@ func getRowFromDiffSummary(tblName string, dsp diff.DiffSummaryProgress, newColL
|
||||
}
|
||||
}
|
||||
|
||||
// GetCellsAddedAndDeleted calculates cells added and deleted given diff.DiffSummaryProgress and toCommit table
|
||||
// GetCellsAddedAndDeleted calculates cells added and deleted given diff.DiffStatProgress and toCommit table
|
||||
// column length. We use rows added and deleted to calculate cells added and deleted, but it does not include
|
||||
// cells added and deleted from schema changes. Here we fill those in using total number of cells in each commit table.
|
||||
func GetCellsAddedAndDeleted(acc diff.DiffSummaryProgress, newColLen int) (uint64, uint64) {
|
||||
func GetCellsAddedAndDeleted(acc diff.DiffStatProgress, newColLen int) (uint64, uint64) {
|
||||
var numCellInserts, numCellDeletes float64
|
||||
rowToCellInserts := float64(acc.Adds) * float64(newColLen)
|
||||
rowToCellDeletes := float64(acc.Removes) * float64(newColLen)
|
||||
|
||||
@@ -2015,7 +2015,7 @@ inner join t as of @Commit3 on rows_unmodified = t.pk;`,
|
||||
Assertions: []queries.ScriptTestAssertion{
|
||||
{
|
||||
Query: "SELECT * from dolt_diff_summary('HEAD~', 'HEAD', 't');",
|
||||
ExpectedErrStr: "failed to compute diff summary for table t: primary key set changed",
|
||||
ExpectedErrStr: "failed to compute diff stat for table t: primary key set changed",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
// Copyright 2019 Dolthub, 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.
|
||||
//
|
||||
// This file incorporates work covered by the following copyright and
|
||||
// permission notice:
|
||||
//
|
||||
// Copyright 2016 Attic Labs, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, version 2.0:
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package diff
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
|
||||
humanize "github.com/dustin/go-humanize"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/d"
|
||||
"github.com/dolthub/dolt/go/store/datas"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
"github.com/dolthub/dolt/go/store/util/status"
|
||||
)
|
||||
|
||||
// Summary prints a summary of the diff between two values to stdout.
|
||||
func Summary(ctx context.Context, vr1 types.ValueReader, vr2 types.ValueReader, value1, value2 types.Value) {
|
||||
if is1, err := datas.IsCommit(value1); err != nil {
|
||||
panic(err)
|
||||
} else if is1 {
|
||||
if is2, err := datas.IsCommit(value2); err != nil {
|
||||
panic(err)
|
||||
} else if is2 {
|
||||
fmt.Println("Comparing commit values")
|
||||
|
||||
var err error
|
||||
value1, err = datas.GetCommittedValue(ctx, vr1, value1)
|
||||
d.PanicIfError(err)
|
||||
|
||||
value2, err = datas.GetCommittedValue(ctx, vr2, value2)
|
||||
d.PanicIfError(err)
|
||||
}
|
||||
}
|
||||
|
||||
var singular, plural string
|
||||
if value1.Kind() == value2.Kind() {
|
||||
switch value1.Kind() {
|
||||
case types.StructKind:
|
||||
singular = "field"
|
||||
plural = "fields"
|
||||
case types.MapKind:
|
||||
singular = "entry"
|
||||
plural = "entries"
|
||||
default:
|
||||
singular = "value"
|
||||
plural = "values"
|
||||
}
|
||||
}
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
var rp atomic.Value
|
||||
ch := make(chan diffSummaryProgress)
|
||||
|
||||
eg.Go(func() (err error) {
|
||||
defer close(ch)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
rp.Store(r)
|
||||
err = fmt.Errorf("panic")
|
||||
}
|
||||
}()
|
||||
err = diffSummary(ctx, ch, value1, value2)
|
||||
return
|
||||
})
|
||||
eg.Go(func() error {
|
||||
acc := diffSummaryProgress{}
|
||||
LOOP:
|
||||
for {
|
||||
select {
|
||||
case p, ok := <-ch:
|
||||
if !ok {
|
||||
break LOOP
|
||||
}
|
||||
acc.Adds += p.Adds
|
||||
acc.Removes += p.Removes
|
||||
acc.Changes += p.Changes
|
||||
acc.NewSize += p.NewSize
|
||||
acc.OldSize += p.OldSize
|
||||
if status.WillPrint() {
|
||||
formatStatus(acc, singular, plural)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
formatStatus(acc, singular, plural)
|
||||
status.Done()
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := eg.Wait(); err != nil {
|
||||
if r := rp.Load(); r != nil {
|
||||
panic(r)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type diffSummaryProgress struct {
|
||||
Adds, Removes, Changes, NewSize, OldSize uint64
|
||||
}
|
||||
|
||||
func diffSummary(ctx context.Context, ch chan diffSummaryProgress, v1, v2 types.Value) error {
|
||||
if !v1.Equals(v2) {
|
||||
if ShouldDescend(v1, v2) {
|
||||
var err error
|
||||
switch v1.Kind() {
|
||||
case types.ListKind:
|
||||
err = diffSummaryList(ctx, ch, v1.(types.List), v2.(types.List))
|
||||
case types.MapKind:
|
||||
err = diffSummaryMap(ctx, ch, v1.(types.Map), v2.(types.Map))
|
||||
case types.SetKind:
|
||||
err = diffSummarySet(ctx, ch, v1.(types.Set), v2.(types.Set))
|
||||
case types.StructKind:
|
||||
err = diffSummaryStructs(ctx, ch, v1.(types.Struct), v2.(types.Struct))
|
||||
default:
|
||||
panic("Unrecognized type in diff function")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ch <- diffSummaryProgress{Adds: 1, Removes: 1, NewSize: 1, OldSize: 1}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func diffSummaryList(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.List) error {
|
||||
select {
|
||||
case ch <- diffSummaryProgress{OldSize: v1.Len(), NewSize: v2.Len()}:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
spliceChan := make(chan types.Splice)
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var rp atomic.Value
|
||||
eg.Go(func() (err error) {
|
||||
defer close(spliceChan)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
rp.Store(r)
|
||||
err = fmt.Errorf("panic")
|
||||
}
|
||||
}()
|
||||
return v2.Diff(ctx, v1, spliceChan)
|
||||
})
|
||||
|
||||
eg.Go(func() (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
rp.Store(r)
|
||||
err = fmt.Errorf("panic")
|
||||
}
|
||||
}()
|
||||
LOOP:
|
||||
for {
|
||||
select {
|
||||
case splice, ok := <-spliceChan:
|
||||
if !ok {
|
||||
break LOOP
|
||||
}
|
||||
var summary diffSummaryProgress
|
||||
if splice.SpRemoved == splice.SpAdded {
|
||||
summary = diffSummaryProgress{Changes: splice.SpRemoved}
|
||||
} else {
|
||||
summary = diffSummaryProgress{Adds: splice.SpAdded, Removes: splice.SpRemoved}
|
||||
}
|
||||
select {
|
||||
case ch <- summary:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := eg.Wait(); err != nil {
|
||||
if r := rp.Load(); r != nil {
|
||||
panic(r)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func diffSummaryMap(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Map) error {
|
||||
return diffSummaryValueChanged(ctx, ch, v1.Len(), v2.Len(), func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
|
||||
return v2.Diff(ctx, v1, changeChan)
|
||||
})
|
||||
}
|
||||
|
||||
func diffSummarySet(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Set) error {
|
||||
return diffSummaryValueChanged(ctx, ch, v1.Len(), v2.Len(), func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
|
||||
return v2.Diff(ctx, v1, changeChan)
|
||||
})
|
||||
}
|
||||
|
||||
func diffSummaryStructs(ctx context.Context, ch chan<- diffSummaryProgress, v1, v2 types.Struct) error {
|
||||
// TODO: Operate on values directly
|
||||
t1, err := types.TypeOf(v1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t2, err := types.TypeOf(v2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
size1 := uint64(t1.Desc.(types.StructDesc).Len())
|
||||
size2 := uint64(t2.Desc.(types.StructDesc).Len())
|
||||
return diffSummaryValueChanged(ctx, ch, size1, size2, func(ctx context.Context, changeChan chan<- types.ValueChanged) error {
|
||||
return v2.Diff(ctx, v1, changeChan)
|
||||
})
|
||||
}
|
||||
|
||||
func diffSummaryValueChanged(ctx context.Context, ch chan<- diffSummaryProgress, oldSize, newSize uint64, f diffFunc) error {
|
||||
select {
|
||||
case ch <- diffSummaryProgress{OldSize: oldSize, NewSize: newSize}:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
changeChan := make(chan types.ValueChanged)
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var rp atomic.Value
|
||||
eg.Go(func() (err error) {
|
||||
defer close(changeChan)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
rp.Store(r)
|
||||
err = fmt.Errorf("panic")
|
||||
}
|
||||
}()
|
||||
return f(ctx, changeChan)
|
||||
})
|
||||
eg.Go(func() error {
|
||||
return reportChanges(ctx, ch, changeChan)
|
||||
})
|
||||
if err := eg.Wait(); err != nil {
|
||||
if r := rp.Load(); r != nil {
|
||||
panic(r)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reportChanges(ctx context.Context, ch chan<- diffSummaryProgress, changeChan chan types.ValueChanged) error {
|
||||
LOOP:
|
||||
for {
|
||||
select {
|
||||
case change, ok := <-changeChan:
|
||||
if !ok {
|
||||
break LOOP
|
||||
}
|
||||
var summary diffSummaryProgress
|
||||
switch change.ChangeType {
|
||||
case types.DiffChangeAdded:
|
||||
summary = diffSummaryProgress{Adds: 1}
|
||||
case types.DiffChangeRemoved:
|
||||
summary = diffSummaryProgress{Removes: 1}
|
||||
case types.DiffChangeModified:
|
||||
summary = diffSummaryProgress{Changes: 1}
|
||||
default:
|
||||
panic("unknown change type")
|
||||
}
|
||||
select {
|
||||
case ch <- summary:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatStatus(acc diffSummaryProgress, singular, plural string) {
|
||||
pluralize := func(singular, plural string, n uint64) string {
|
||||
var noun string
|
||||
if n != 1 {
|
||||
noun = plural
|
||||
} else {
|
||||
noun = singular
|
||||
}
|
||||
return fmt.Sprintf("%s %s", humanize.Comma(int64(n)), noun)
|
||||
}
|
||||
|
||||
insertions := pluralize("insertion", "insertions", acc.Adds)
|
||||
deletions := pluralize("deletion", "deletions", acc.Removes)
|
||||
changes := pluralize("change", "changes", acc.Changes)
|
||||
|
||||
oldValues := pluralize(singular, plural, acc.OldSize)
|
||||
newValues := pluralize(singular, plural, acc.NewSize)
|
||||
|
||||
status.Printf("%s (%.2f%%), %s (%.2f%%), %s (%.2f%%), (%s vs %s)", insertions, (float64(100*acc.Adds) / float64(acc.OldSize)), deletions, (float64(100*acc.Removes) / float64(acc.OldSize)), changes, (float64(100*acc.Changes) / float64(acc.OldSize)), oldValues, newValues)
|
||||
}
|
||||
@@ -35,12 +35,6 @@ type Map struct {
|
||||
valDesc val.TupleDesc
|
||||
}
|
||||
|
||||
type DiffSummary struct {
|
||||
Adds, Removes uint64
|
||||
Changes, CellChanges uint64
|
||||
NewSize, OldSize uint64
|
||||
}
|
||||
|
||||
// NewMap creates an empty prolly Tree Map
|
||||
func NewMap(node tree.Node, ns tree.NodeStore, keyDesc, valDesc val.TupleDesc) Map {
|
||||
tuples := tree.StaticMap[val.Tuple, val.Tuple, val.TupleDesc]{
|
||||
|
||||
@@ -137,7 +137,6 @@ var CopiedNomsFiles []CopiedNomsFile = []CopiedNomsFile{
|
||||
{Path: "store/diff/patch.go", NomsPath: "go/diff/patch.go", HadCopyrightNotice: true},
|
||||
{Path: "store/diff/patch_test.go", NomsPath: "go/diff/patch_test.go", HadCopyrightNotice: true},
|
||||
{Path: "store/diff/print_diff.go", NomsPath: "go/diff/print_diff.go", HadCopyrightNotice: true},
|
||||
{Path: "store/diff/summary.go", NomsPath: "go/diff/summary.go", HadCopyrightNotice: true},
|
||||
{Path: "store/hash/base32.go", NomsPath: "go/hash/base32.go", HadCopyrightNotice: true},
|
||||
{Path: "store/hash/base32_test.go", NomsPath: "go/hash/base32_test.go", HadCopyrightNotice: true},
|
||||
{Path: "store/hash/hash.go", NomsPath: "go/hash/hash.go", HadCopyrightNotice: true},
|
||||
|
||||
Reference in New Issue
Block a user