diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index d9230bb389..cb0c68f114 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -357,11 +357,16 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds } } - ws, err := ds.WorkingSet(ctx, db.RevisionQualifiedName()) - if err != nil { + // Grab the staged root, if we have a valid working set, so we can show the staged changes + // in the system table, too. If we're in a detached head mode, just reuse the working root. + stagedRoot, err := workingSetStagedRoot(ctx, db.RevisionQualifiedName()) + if err == doltdb.ErrOperationNotSupportedInDetachedHead { + stagedRoot = root + } else if err != nil { return nil, false, err } - dt, err := dtables.NewCommitDiffTable(ctx, db.Name(), tname, db.ddb, root, ws.StagedRoot()) + + dt, err := dtables.NewCommitDiffTable(ctx, db.Name(), tname, db.ddb, root, stagedRoot) if err != nil { return nil, false, err } @@ -702,6 +707,18 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds return resolveOverriddenNonexistentTable(ctx, tblName, db) } +// workingSetStagedRoot returns the staged root for the current session in the database +// named |dbName|. If a working set is not available (e.g. if a commit or tag is checked +// out), this function returns an ErrOperationNotSupportedInDetachedHead error. +func workingSetStagedRoot(ctx *sql.Context, dbName string) (doltdb.RootValue, error) { + ds := dsess.DSessFromSess(ctx.Session) + ws, err := ds.WorkingSet(ctx, dbName) + if err != nil { + return nil, err + } + return ws.StagedRoot(), nil +} + // resolveAsOf resolves given expression to a commit, if one exists. func resolveAsOf(ctx *sql.Context, db Database, asOf interface{}) (*doltdb.Commit, doltdb.RootValue, error) { head, err := db.rsr.CWBHeadRef() diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go index 892ad8f886..699f0364e3 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_diff.go @@ -4984,6 +4984,35 @@ var CommitDiffSystemTableScriptTests = []queries.ScriptTest{ }, }, }, + { + // When in a detached head mode, dolt_commit_diff should still work, even though it doesn't have a staged root + Name: "detached head", + SetUpScript: []string{ + "CREATE TABLE t (pk int primary key, c1 varchar(100));", + "CALL dolt_commit('-Am', 'create table t');", + "SET @commit1 = hashof('HEAD');", + "INSERT INTO t VALUES (1, 'one');", + "CALL dolt_commit('-Am', 'insert 1');", + "SET @commit2 = hashof('HEAD');", + "CALL dolt_tag('v1', @commit2);", + }, + Assertions: []queries.ScriptTestAssertion{ + { + Query: "use mydb/v1;", + Expected: []sql.Row{}, + }, + { + // With no working set, this query should still compute the diff between two commits + Query: "SELECT COUNT(*) AS table_diff_num FROM dolt_commit_diff_t WHERE from_commit=@commit1 AND to_commit=@commit2;", + Expected: []sql.Row{{1}}, + }, + { + // With no working set, STAGED should reference the current root of the checked out tag + Query: "SELECT COUNT(*) AS table_diff_num FROM dolt_commit_diff_t WHERE from_commit=@commit1 AND to_commit='STAGED';", + Expected: []sql.Row{{1}}, + }, + }, + }, { // When a column is dropped and recreated with a different type, we expect only the new column