diff --git a/go/libraries/doltcore/sqle/dtablefunctions/dolt_diff_summary.go b/go/libraries/doltcore/sqle/dtablefunctions/dolt_diff_summary.go index 1991082545f..060e1e9153e 100644 --- a/go/libraries/doltcore/sqle/dtablefunctions/dolt_diff_summary.go +++ b/go/libraries/doltcore/sqle/dtablefunctions/dolt_diff_summary.go @@ -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" @@ -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 @@ -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 @@ -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 + } + 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 +} diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go index fb0ae3c155b..cb1b29b690f 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go @@ -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"}}, + }, + }, + }, } diff --git a/integration-tests/bats/ignore.bats b/integration-tests/bats/ignore.bats index 3c0f9d7e5b4..b16958f3217 100644 --- a/integration-tests/bats/ignore.bats +++ b/integration-tests/bats/ignore.bats @@ -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 } \ No newline at end of file