Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions go/libraries/doltcore/sqle/dtablefunctions/dolt_diff_summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/dolthub/go-mysql-server/sql/types"

"github.com/dolthub/dolt/go/libraries/doltcore/diff"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
Expand Down Expand Up @@ -287,10 +288,19 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.
return deltas[i].ToName.Less(deltas[j].ToName)
})

ignorePatterns, err := getIgnorePatternsFromContext(ctx, ds.database)
if err != nil {
return nil, err
}

// If tableNameExpr defined, return a single table diff summary result
if ds.tableNameExpr != nil {
delta := findMatchingDelta(deltas, tableName)

if shouldIgnoreDelta(delta, ignorePatterns) {
return NewDiffSummaryTableFunctionRowIter([]*diff.TableDeltaSummary{}), nil
}

summ, err := getSummaryForDelta(ctx, delta, sqledb, fromDetails, toDetails, true)
if err != nil {
return nil, err
Expand All @@ -306,6 +316,10 @@ func (ds *DiffSummaryTableFunction) RowIter(ctx *sql.Context, row sql.Row) (sql.

var diffSummaries []*diff.TableDeltaSummary
for _, delta := range deltas {
if shouldIgnoreDelta(delta, ignorePatterns) {
continue
}

summ, err := getSummaryForDelta(ctx, delta, sqledb, fromDetails, toDetails, false)
if err != nil {
return nil, err
Expand Down Expand Up @@ -438,3 +452,45 @@ func getRowFromSummary(ds *diff.TableDeltaSummary) sql.Row {
ds.SchemaChange, // schema_change
}
}

// getIgnorePatternsFromContext retrieves ignore patterns from the dolt_ignore table.
func getIgnorePatternsFromContext(ctx *sql.Context, database sql.Database) (doltdb.IgnorePatterns, error) {
sess := dsess.DSessFromSess(ctx.Session)
dbName := database.Name()
roots, ok := sess.GetRoots(ctx, dbName)
if !ok {
return nil, fmt.Errorf("Could not load database %s", dbName)
}

ignorePatternMap, err := doltdb.GetIgnoredTablePatterns(ctx, roots, []string{""})
if err != nil {
return nil, err
}

// Return patterns for default schema
return ignorePatternMap[""], nil
}

// shouldIgnoreDelta determines if a table delta should be ignored based on dolt_ignore patterns.
// This follows the same logic as the dolt diff command: only "added" or "dropped" tables
// can be ignored, not modified/renamed tables.
func shouldIgnoreDelta(delta diff.TableDelta, ignorePatterns doltdb.IgnorePatterns) bool {
if delta.IsAdd() {
ignoreResult, err := ignorePatterns.IsTableNameIgnored(delta.ToName)
if err != nil {
return false // On error, don't ignore
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignoring the error isn't ideal. This would effectively mean that the regex was garbage to begin with, and the user should probably know that. Both places this method is used can bubble up errors, so I'll add a commit which does that.

}
return ignoreResult == doltdb.Ignore
}

if delta.IsDrop() {
ignoreResult, err := ignorePatterns.IsTableNameIgnored(delta.FromName)
if err != nil {
return false // On error, don't ignore
}
return ignoreResult == doltdb.Ignore
}

// For modified/renamed tables, don't ignore (consistent with dolt diff behavior)
return false
}
112 changes: 112 additions & 0 deletions go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -6806,4 +6806,116 @@ var QueryDiffTableScriptTests = []queries.ScriptTest{
},
},
},
{
Name: "dolt_diff_summary respects dolt_ignore: basic ignore functionality",
SetUpScript: []string{
"CREATE TABLE ignored_table (pk int primary key, c1 int);",
"CREATE TABLE not_ignored_table (pk int primary key, c1 int);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-m', 'add tables');",
"INSERT INTO dolt_ignore VALUES ('ignored_table2', true);",
"CREATE TABLE ignored_table2 (pk int primary key, c2 int);",
"CREATE TABLE not_ignored_table2 (pk int primary key, c2 int);",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING');",
Expected: []sql.Row{{2}}, // dolt_ignore and not_ignored_table2 should appear
},
{
Query: "SELECT to_table_name FROM dolt_diff_summary('HEAD', 'WORKING') ORDER BY to_table_name;",
Expected: []sql.Row{{"dolt_ignore"}, {"not_ignored_table2"}},
},
},
},
{
Name: "dolt_diff_summary respects dolt_ignore: wildcard patterns",
SetUpScript: []string{
"CREATE TABLE initial_table (pk int primary key);",
"CALL DOLT_ADD('.');",
"CALL DOLT_COMMIT('-m', 'initial');",
"INSERT INTO dolt_ignore VALUES ('temp_*', true);",
"CREATE TABLE temp_table1 (pk int primary key);",
"CREATE TABLE temp_table2 (pk int primary key);",
"CREATE TABLE regular_table (pk int primary key);",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING');",
Expected: []sql.Row{{2}}, // dolt_ignore and regular_table should appear
},
{
Query: "SELECT to_table_name FROM dolt_diff_summary('HEAD', 'WORKING') ORDER BY to_table_name;",
Expected: []sql.Row{{"dolt_ignore"}, {"regular_table"}},
},
},
},
{
Name: "dolt_diff_summary respects dolt_ignore: mixed ignore/don't ignore patterns",
SetUpScript: []string{
"CREATE TABLE initial_table (pk int primary key);",
"CALL DOLT_ADD('.');",
"CALL DOLT_COMMIT('-m', 'initial');",
"INSERT INTO dolt_ignore VALUES ('temp_*', true);",
"INSERT INTO dolt_ignore VALUES ('temp_important', false);", // don't ignore this one
"CREATE TABLE temp_table1 (pk int primary key);",
"CREATE TABLE temp_important (pk int primary key);",
"CREATE TABLE regular_table (pk int primary key);",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING');",
Expected: []sql.Row{{3}}, // dolt_ignore, temp_important and regular_table should appear
},
{
Query: "SELECT to_table_name FROM dolt_diff_summary('HEAD', 'WORKING') ORDER BY to_table_name;",
Expected: []sql.Row{{"dolt_ignore"}, {"regular_table"}, {"temp_important"}},
},
},
},
{
Name: "dolt_diff_summary respects dolt_ignore: specific table query",
SetUpScript: []string{
"CREATE TABLE initial_table (pk int primary key);",
"CALL DOLT_ADD('.');",
"CALL DOLT_COMMIT('-m', 'initial');",
"INSERT INTO dolt_ignore VALUES ('ignored_table', true);",
"CREATE TABLE ignored_table (pk int primary key);",
"CREATE TABLE not_ignored_table (pk int primary key);",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING', 'ignored_table');",
Expected: []sql.Row{{0}}, // specific query for ignored table returns empty
},
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING', 'not_ignored_table');",
Expected: []sql.Row{{1}}, // specific query for non-ignored table works
},
},
},
{
Name: "dolt_diff_summary respects dolt_ignore: dropped tables",
SetUpScript: []string{
"INSERT INTO dolt_ignore VALUES ('dummy', true);", // Create dolt_ignore in initial commit
"CREATE TABLE will_be_ignored (pk int primary key);",
"CREATE TABLE will_not_be_ignored (pk int primary key);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-m', 'add tables');",
"DELETE FROM dolt_ignore WHERE pattern = 'dummy';", // Remove dummy row
"INSERT INTO dolt_ignore VALUES ('will_be_ignored', true);", // Now this modifies dolt_ignore
"DROP TABLE will_be_ignored;",
"DROP TABLE will_not_be_ignored;",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING');",
Expected: []sql.Row{{2}}, // dolt_ignore (modified) and will_not_be_ignored (dropped)
},
{
Query: "SELECT from_table_name, diff_type FROM dolt_diff_summary('HEAD', 'WORKING') ORDER BY from_table_name;",
Expected: []sql.Row{{"dolt_ignore", "modified"}, {"will_not_be_ignored", "dropped"}},
},
},
},
}
91 changes: 91 additions & 0 deletions integration-tests/bats/ignore.bats
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,95 @@ SQL
[[ ! "$output" =~ "test2" ]] || false
[[ ! "$output" =~ "test3" ]] || false

}

@test "ignore: dolt_diff_summary respects dolt_ignore patterns" {
# First commit some initial tables
dolt sql -q "CREATE TABLE initial_table (pk int primary key)"
dolt add .
dolt commit -m "Add initial table"

# Add ignore pattern and create new tables
dolt sql -q "INSERT INTO dolt_ignore VALUES ('should_ignore_new', true)"
dolt sql -q "CREATE TABLE should_ignore_new (pk int primary key)"
dolt sql -q "CREATE TABLE should_not_ignore_new (pk int primary key)"

# Test that dolt_diff_summary respects ignore patterns - should only show non-ignored tables
run dolt sql -q "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "1" ]] || false

# Verify which table is shown
run dolt sql -q "SELECT to_table_name FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "should_not_ignore_new" ]] || false
[[ ! "$output" =~ "should_ignore_new" ]] || false
}

@test "ignore: dolt_diff_summary respects wildcard ignore patterns" {
# First commit initial table
dolt sql -q "CREATE TABLE initial (pk int primary key)"
dolt add .
dolt commit -m "Add initial table"

# Add wildcard ignore pattern and create new tables
dolt sql -q "INSERT INTO dolt_ignore VALUES ('temp_*', true)"
dolt sql -q "CREATE TABLE temp_new_table (pk int primary key)"
dolt sql -q "CREATE TABLE regular_new_table (pk int primary key)"

# Should only show the regular table
run dolt sql -q "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "1" ]] || false

run dolt sql -q "SELECT to_table_name FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "regular_new_table" ]] || false
[[ ! "$output" =~ "temp_new_table" ]] || false
}

@test "ignore: dolt_diff_summary respects ignore patterns for dropped tables" {
# Create and commit tables that will be dropped
dolt sql -q "CREATE TABLE will_be_ignored (pk int primary key)"
dolt sql -q "CREATE TABLE will_not_be_ignored (pk int primary key)"
dolt add .
dolt commit -m "Add tables to be dropped"

# Add ignore pattern and drop tables
dolt sql -q "INSERT INTO dolt_ignore VALUES ('will_be_ignored', true)"
dolt sql -q "DROP TABLE will_be_ignored"
dolt sql -q "DROP TABLE will_not_be_ignored"

# Should only show the non-ignored dropped table
run dolt sql -q "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "1" ]] || false

run dolt sql -q "SELECT from_table_name, diff_type FROM dolt_diff_summary('HEAD', 'WORKING')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "will_not_be_ignored" ]] || false
[[ "$output" =~ "dropped" ]] || false
[[ ! "$output" =~ "will_be_ignored" ]] || false
}

@test "ignore: dolt_diff_summary specific table query respects ignore patterns" {
# Create and commit initial table
dolt sql -q "CREATE TABLE initial_table (pk int primary key)"
dolt add .
dolt commit -m "Add initial table"

# Add ignore pattern and create new tables
dolt sql -q "INSERT INTO dolt_ignore VALUES ('ignored_table_new', true)"
dolt sql -q "CREATE TABLE ignored_table_new (pk int primary key)"
dolt sql -q "CREATE TABLE not_ignored_table (pk int primary key)"

# Specific query for ignored table should return empty
run dolt sql -q "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING', 'ignored_table_new')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "0" ]] || false

# Specific query for non-ignored table should work
run dolt sql -q "SELECT COUNT(*) FROM dolt_diff_summary('HEAD', 'WORKING', 'not_ignored_table')" -r csv
[ "$status" -eq 0 ]
[[ "$output" =~ "1" ]] || false
}
Loading