mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-02 19:39:56 -05:00
Use processTableDelta logic in td.GetSummary
This commit is contained in:
@@ -479,7 +479,7 @@ func maybeResolve(ctx context.Context, dEnv *env.DoltEnv, spec string) (*doltdb.
|
||||
return root, true
|
||||
}
|
||||
|
||||
func printDiffSummary(ctx context.Context, tds []diff.TableDelta, engine *engine.SqlEngine, dArgs *diffArgs) errhand.VerboseError {
|
||||
func printDiffSummary(ctx context.Context, tds []diff.TableDelta, ddb *doltdb.DoltDB, dArgs *diffArgs) errhand.VerboseError {
|
||||
sqlSch := sql.Schema{
|
||||
&sql.Column{Name: "Table name", Type: types.Text, Nullable: false},
|
||||
&sql.Column{Name: "Diff Type", Type: types.Text, Nullable: false},
|
||||
@@ -500,17 +500,12 @@ func printDiffSummary(ctx context.Context, tds []diff.TableDelta, engine *engine
|
||||
return errhand.BuildDError("error: both tables in tableDelta are nil").Build()
|
||||
}
|
||||
|
||||
dataChanged, verr := getDataHasChanged(ctx, engine, td, dArgs)
|
||||
if verr != nil {
|
||||
return verr
|
||||
}
|
||||
|
||||
summ, err := td.GetSummary(ctx, dataChanged)
|
||||
summ, err := td.GetSummary(ctx)
|
||||
if err != nil {
|
||||
return errhand.BuildDError("could not get table delta summary").AddCause(err).Build()
|
||||
}
|
||||
|
||||
err = wr.WriteSqlRow(ctx, sql.Row{td.CurName(), summ.DiffType, dataChanged, summ.HasSchemaChanges})
|
||||
err = wr.WriteSqlRow(ctx, sql.Row{td.CurName(), summ.DiffType, summ.DataChange, summ.SchemaChange})
|
||||
if err != nil {
|
||||
return errhand.BuildDError("could not write table delta summary").AddCause(err).Build()
|
||||
}
|
||||
@@ -537,7 +532,7 @@ func diffUserTables(ctx context.Context, dEnv *env.DoltEnv, dArgs *diffArgs) err
|
||||
})
|
||||
|
||||
if dArgs.diffParts&Summary != 0 {
|
||||
return printDiffSummary(ctx, tableDeltas, engine, dArgs)
|
||||
return printDiffSummary(ctx, tableDeltas, dEnv.DoltDB, dArgs)
|
||||
}
|
||||
|
||||
dw, err := newDiffWriter(dArgs.diffOutput)
|
||||
@@ -719,54 +714,6 @@ func sqlSchemaDiff(ctx context.Context, td diff.TableDelta, toSchemas map[string
|
||||
return ddlStatements, nil
|
||||
}
|
||||
|
||||
func getDataHasChanged(ctx context.Context,
|
||||
se *engine.SqlEngine,
|
||||
td diff.TableDelta,
|
||||
dArgs *diffArgs,
|
||||
) (bool, errhand.VerboseError) {
|
||||
diffable := schema.ArePrimaryKeySetsDiffable(td.Format(), td.FromSch, td.ToSch)
|
||||
canSqlDiff := !(td.ToSch == nil || (td.FromSch != nil && !schema.SchemasAreEqual(td.FromSch, td.ToSch)))
|
||||
|
||||
// can't diff
|
||||
if !diffable {
|
||||
// TODO: this messes up some structured output if the user didn't redirect it
|
||||
cli.PrintErrf("Primary key sets differ between revisions for table %s, skipping data diff\n", td.ToName)
|
||||
return false, nil
|
||||
} else if dArgs.diffOutput == SQLDiffOutput && !canSqlDiff {
|
||||
// TODO: this is overly broad, we can absolutely do better
|
||||
_, _ = fmt.Fprintf(cli.CliErr, "Incompatible schema change, skipping data diff\n")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
tableName := td.CurName()
|
||||
|
||||
columns := getColumnNamesString(td.FromSch, td.ToSch)
|
||||
query := fmt.Sprintf("select %s, %s from dolt_diff('%s', '%s', '%s') limit 1", columns, "diff_type", dArgs.fromRef, dArgs.toRef, tableName)
|
||||
|
||||
sqlCtx, err := engine.NewLocalSqlContext(ctx, se)
|
||||
if err != nil {
|
||||
return false, errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
|
||||
_, rowIter, err := se.Query(sqlCtx, query)
|
||||
if sql.ErrSyntaxError.Is(err) {
|
||||
return false, errhand.BuildDError("Failed to parse diff query. Invalid where clause?\nDiff query: %s", query).AddCause(err).Build()
|
||||
} else if err != nil {
|
||||
return false, errhand.BuildDError("Error running diff query:\n%s", query).AddCause(err).Build()
|
||||
}
|
||||
|
||||
defer rowIter.Close(sqlCtx)
|
||||
|
||||
_, err = rowIter.Next(sqlCtx)
|
||||
if err == io.EOF {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func diffRows(
|
||||
ctx context.Context,
|
||||
se *engine.SqlEngine,
|
||||
|
||||
@@ -58,10 +58,10 @@ type TableDelta struct {
|
||||
}
|
||||
|
||||
type TableDeltaSummary struct {
|
||||
DiffType string
|
||||
HasDataChanges bool
|
||||
HasSchemaChanges bool
|
||||
TableName string
|
||||
DiffType string
|
||||
DataChange bool
|
||||
SchemaChange bool
|
||||
TableName string
|
||||
}
|
||||
|
||||
// GetStagedUnstagedTableDeltas represents staged and unstaged changes as TableDelta slices.
|
||||
@@ -287,13 +287,16 @@ func (td TableDelta) IsRename() bool {
|
||||
return td.FromName != td.ToName
|
||||
}
|
||||
|
||||
func (td TableDelta) Type() string {
|
||||
func (td TableDelta) TypeString() string {
|
||||
if td.IsAdd() {
|
||||
return "added"
|
||||
}
|
||||
if td.IsDrop() {
|
||||
return "dropped"
|
||||
}
|
||||
if td.IsRename() {
|
||||
return "renamed"
|
||||
}
|
||||
return "modified"
|
||||
}
|
||||
|
||||
@@ -404,17 +407,78 @@ func (td TableDelta) IsKeyless(ctx context.Context) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// isTableDataEmpty return true if the table does not contain any data
|
||||
func isTableDataEmpty(ctx context.Context, table *doltdb.Table) (bool, error) {
|
||||
rowData, err := table.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return rowData.Empty()
|
||||
}
|
||||
|
||||
// GetSummary returns a summary of the table delta.
|
||||
func (td TableDelta) GetSummary(ctx context.Context, dataChanged bool) (*TableDeltaSummary, error) {
|
||||
func (td TableDelta) GetSummary(ctx context.Context) (*TableDeltaSummary, error) {
|
||||
// Dropping a table is always a schema change, and also a data change if the table contained data
|
||||
if td.IsDrop() {
|
||||
isEmpty, err := isTableDataEmpty(ctx, td.FromTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TableDeltaSummary{
|
||||
TableName: td.FromName,
|
||||
DataChange: !isEmpty,
|
||||
SchemaChange: true,
|
||||
DiffType: "dropped",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Renaming a table is always a schema change, and also a data change if the table data differs
|
||||
if td.IsRename() {
|
||||
dataChanged, err := td.HasHashChanged()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TableDeltaSummary{
|
||||
TableName: td.ToName,
|
||||
DataChange: dataChanged,
|
||||
SchemaChange: true,
|
||||
DiffType: "renamed",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Creating a table is always a schema change, and also a data change if data was inserted
|
||||
if td.IsAdd() {
|
||||
isEmpty, err := isTableDataEmpty(ctx, td.ToTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TableDeltaSummary{
|
||||
TableName: td.ToName,
|
||||
DataChange: !isEmpty,
|
||||
SchemaChange: true,
|
||||
DiffType: "added",
|
||||
}, nil
|
||||
}
|
||||
|
||||
dataChanged, err := td.HasHashChanged()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
schemaChanged, err := td.HasSchemaChanged(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &TableDeltaSummary{
|
||||
HasSchemaChanges: schemaChanged,
|
||||
HasDataChanges: dataChanged,
|
||||
DiffType: td.Type(),
|
||||
TableName: td.CurName(),
|
||||
TableName: td.ToName,
|
||||
DataChange: dataChanged,
|
||||
SchemaChange: schemaChanged,
|
||||
DiffType: "modified",
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -241,20 +241,20 @@ func (d *doltDiffWorkingSetRowItr) Next(ctx *sql.Context) (sql.Row, error) {
|
||||
return nil, io.EOF
|
||||
}
|
||||
|
||||
change, err := processTableDelta(ctx, tableDelta)
|
||||
change, err := tableDelta.GetSummary(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sqlRow := sql.NewRow(
|
||||
changeSet,
|
||||
change.tableName,
|
||||
change.TableName,
|
||||
nil, // committer
|
||||
nil, // email
|
||||
nil, // date
|
||||
nil, // message
|
||||
change.dataChange,
|
||||
change.schemaChange,
|
||||
change.DataChange,
|
||||
change.SchemaChange,
|
||||
)
|
||||
|
||||
return sqlRow, nil
|
||||
@@ -288,7 +288,7 @@ type doltDiffCommitHistoryRowItr struct {
|
||||
commits []*doltdb.Commit
|
||||
meta *datas.CommitMeta
|
||||
hash hash.Hash
|
||||
tableChanges []tableChange
|
||||
tableChanges []diff.TableDeltaSummary
|
||||
tableChangesIdx int
|
||||
}
|
||||
|
||||
@@ -358,13 +358,13 @@ func (itr *doltDiffCommitHistoryRowItr) Next(ctx *sql.Context) (sql.Row, error)
|
||||
|
||||
return sql.NewRow(
|
||||
h.String(),
|
||||
tableChange.tableName,
|
||||
tableChange.TableName,
|
||||
meta.Name,
|
||||
meta.Email,
|
||||
meta.Time(),
|
||||
meta.Description,
|
||||
tableChange.dataChange,
|
||||
tableChange.schemaChange,
|
||||
tableChange.DataChange,
|
||||
tableChange.SchemaChange,
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ func (itr *doltDiffCommitHistoryRowItr) loadTableChanges(ctx context.Context, co
|
||||
|
||||
// calculateTableChanges calculates the tables that changed in the specified commit, by comparing that
|
||||
// commit with its immediate ancestor commit.
|
||||
func (itr *doltDiffCommitHistoryRowItr) calculateTableChanges(ctx context.Context, commit *doltdb.Commit) ([]tableChange, error) {
|
||||
func (itr *doltDiffCommitHistoryRowItr) calculateTableChanges(ctx context.Context, commit *doltdb.Commit) ([]diff.TableDeltaSummary, error) {
|
||||
if len(commit.DatasParents()) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -424,9 +424,9 @@ func (itr *doltDiffCommitHistoryRowItr) calculateTableChanges(ctx context.Contex
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tableChanges := make([]tableChange, len(deltas))
|
||||
tableChanges := make([]diff.TableDeltaSummary, len(deltas))
|
||||
for i := 0; i < len(deltas); i++ {
|
||||
change, err := processTableDelta(itr.ctx, deltas[i])
|
||||
change, err := deltas[i].GetSummary(itr.ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -442,68 +442,6 @@ func (itr *doltDiffCommitHistoryRowItr) calculateTableChanges(ctx context.Contex
|
||||
return tableChanges, nil
|
||||
}
|
||||
|
||||
// processTableDelta processes the specified TableDelta to determine what kind of change it was (i.e. table drop,
|
||||
// table rename, table create, or data update) and returns a tableChange struct representing the change.
|
||||
func processTableDelta(ctx *sql.Context, delta diff.TableDelta) (*tableChange, error) {
|
||||
// Dropping a table is always a schema change, and also a data change if the table contained data
|
||||
if delta.IsDrop() {
|
||||
isEmpty, err := isTableDataEmpty(ctx, delta.FromTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tableChange{
|
||||
tableName: delta.FromName,
|
||||
dataChange: !isEmpty,
|
||||
schemaChange: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Renaming a table is always a schema change, and also a data change if the table data differs
|
||||
if delta.IsRename() {
|
||||
dataChanged, err := delta.HasHashChanged()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tableChange{
|
||||
tableName: delta.ToName,
|
||||
dataChange: dataChanged,
|
||||
schemaChange: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Creating a table is always a schema change, and also a data change if data was inserted
|
||||
if delta.IsAdd() {
|
||||
isEmpty, err := isTableDataEmpty(ctx, delta.ToTable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tableChange{
|
||||
tableName: delta.ToName,
|
||||
dataChange: !isEmpty,
|
||||
schemaChange: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
dataChanged, err := delta.HasHashChanged()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
schemaChanged, err := delta.HasSchemaChanged(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tableChange{
|
||||
tableName: delta.ToName,
|
||||
dataChange: dataChanged,
|
||||
schemaChange: schemaChanged,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close closes the iterator.
|
||||
func (itr *doltDiffCommitHistoryRowItr) Close(*sql.Context) error {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user