diff --git a/go/libraries/doltcore/diff/table_deltas.go b/go/libraries/doltcore/diff/table_deltas.go index 93de7eff0e7..e91b7d3023a 100644 --- a/go/libraries/doltcore/diff/table_deltas.go +++ b/go/libraries/doltcore/diff/table_deltas.go @@ -404,6 +404,81 @@ func (td TableDelta) HasSchemaChanged(ctx context.Context) (bool, error) { return !fromSchemaHash.Equal(toSchemaHash), nil } +func (td TableDelta) HasChangesIgnoringColumnTags(ctx context.Context) (bool, error) { + + if td.FromTable == nil && td.ToTable == nil { + return true, nil + } + + if td.IsAdd() || td.IsDrop() { + return true, nil + } + + if td.IsRename() { + return true, nil + } + + if td.HasFKChanges() { + return true, nil + } + + fromRowDataHash, err := td.FromTable.GetRowDataHash(ctx) + if err != nil { + return false, err + } + + toRowDataHash, err := td.ToTable.GetRowDataHash(ctx) + if err != nil { + return false, err + } + + // Any change to the table data counts as a change + if !fromRowDataHash.Equal(toRowDataHash) { + return true, nil + } + + fromTableHash, err := td.FromTable.HashOf() + if err != nil { + return false, err + } + + toTableHash, err := td.FromTable.HashOf() + if err != nil { + return false, err + } + + // If the data hashes have changed, the table has obviously changed. + if !fromTableHash.Equal(toTableHash) { + return true, nil + } + + fromSchemaHash, err := td.FromTable.GetSchemaHash(ctx) + if err != nil { + return false, err + } + + toSchemaHash, err := td.ToTable.GetSchemaHash(ctx) + if err != nil { + return false, err + } + + // If neither data nor schema hashes have changed, the table is obviously the same. + if fromSchemaHash.Equal(toSchemaHash) { + return false, nil + } + + // The schema hash has changed but the data has remained the same. We must inspect the schema to determine + // whether the change is observable or if only column tags have changed. + + fromSchema, toSchema, err := td.GetSchemas(ctx) + if err != nil { + return false, err + } + + // SchemasAreEqual correctly accounts for tags + return !schema.SchemasAreEqual(fromSchema, toSchema), nil +} + func (td TableDelta) HasDataChanged(ctx context.Context) (bool, error) { // Database collation change is not a data change if td.FromTable == nil && td.ToTable == nil { @@ -445,6 +520,9 @@ func (td TableDelta) HasPrimaryKeySetChanged() bool { } func (td TableDelta) HasChanges() (bool, error) { + fromString := td.FromTable.DebugString(context.Background(), td.FromTable.NodeStore()) + toString := td.ToTable.DebugString(context.Background(), td.ToTable.NodeStore()) + _, _ = fromString, toString hashChanged, err := td.HasHashChanged() if err != nil { return false, err diff --git a/go/libraries/doltcore/sqle/dtables/status_table.go b/go/libraries/doltcore/sqle/dtables/status_table.go index b383c1ec195..8550bdfb2b3 100644 --- a/go/libraries/doltcore/sqle/dtables/status_table.go +++ b/go/libraries/doltcore/sqle/dtables/status_table.go @@ -124,6 +124,20 @@ func newStatusItr(ctx *sql.Context, st *StatusTable) (*StatusItr, error) { return nil, err } + // Some tables may differ only in column tags and/or recorded conflicts. + // We try to make such changes invisible to users and shouldn't display them for unstaged tables. + changedUnstagedTables := make([]diff.TableDelta, 0, len(unstagedTables)) + for _, unstagedTableDiff := range unstagedTables { + changed, err := unstagedTableDiff.HasChangesIgnoringColumnTags(ctx) + if err != nil { + return nil, err + } + if changed { + changedUnstagedTables = append(changedUnstagedTables, unstagedTableDiff) + } + } + unstagedTables = changedUnstagedTables + stagedSchemas, unstagedSchemas, err := diff.GetStagedUnstagedDatabaseSchemaDeltas(ctx, roots) if err != nil { return nil, err diff --git a/integration-tests/bats/sql-status.bats b/integration-tests/bats/sql-status.bats index fdbf58f418f..9a8823c208d 100644 --- a/integration-tests/bats/sql-status.bats +++ b/integration-tests/bats/sql-status.bats @@ -150,5 +150,32 @@ teardown() { run dolt sql -r csv -q "select * from dolt_status ORDER BY status" [ "$status" -eq 0 ] [[ "$output" =~ 'dolt_docs,false,conflict' ]] || false - [[ "$output" =~ 'dolt_docs,false,modified' ]] || false -} \ No newline at end of file +} + +@test "sql-status: tables with no observable changes don't show in status but can be staged" { +dolt sql <