Skip to content

Implement commit_order in dolt_log system table and table function #9250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 28, 2025
Merged
24 changes: 20 additions & 4 deletions go/cmd/dolt/commands/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,30 @@ func getCommitInfoWithOptions(queryist cli.Queryist, sqlCtx *sql.Context, ref st
return nil, fmt.Errorf("error parsing timestamp '%s': %v", row[3], err)
}
message := row[4].(string)
parent := row[5].(string)
height := uint64(len(rows))

var commitOrder uint64
switch v := row[5].(type) {
case uint64:
commitOrder = v
case string:
var err error
commitOrder, err = strconv.ParseUint(v, 10, 64)
if err != nil {
return nil, fmt.Errorf("error parsing commit_order '%s': %v", v, err)
}
default:
return nil, fmt.Errorf("unexpected type for commit_order: %T", v)
}

parent := row[6].(string)
height := commitOrder

isHead := commitHash == hashOfHead

var signature string
if len(row) > 7 {
signature = row[7].(string)
if opts.showSignature {
// Signature is always the last column when present
signature = row[len(row)-1].(string)
}

localBranchesForHash, err := getBranchesForHash(queryist, sqlCtx, commitHash, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ var logTableSchema = sql.Schema{
&sql.Column{Name: "email", Type: types.Text},
&sql.Column{Name: "date", Type: types.Datetime},
&sql.Column{Name: "message", Type: types.Text},
&sql.Column{Name: "commit_order", Type: types.Uint64},
}

// NewInstance creates a new instance of TableFunction interface
Expand Down Expand Up @@ -764,7 +765,12 @@ func (itr *logTableFunctionRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, err
}

row := sql.NewRow(commitHash.String(), meta.Name, meta.Email, meta.Time(), meta.Description)
height, err := commit.Height()
if err != nil {
return nil, err
}

row := sql.NewRow(commitHash.String(), meta.Name, meta.Email, meta.Time(), meta.Description, height)

if itr.showParents {
prStr, err := getParentsString(ctx, commit)
Expand Down
14 changes: 12 additions & 2 deletions go/libraries/doltcore/sqle/dtables/log_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (dt *LogTable) Schema() sql.Schema {
{Name: "email", Type: types.Text, Source: dt.tableName, PrimaryKey: false, DatabaseSource: dt.dbName},
{Name: "date", Type: types.Datetime, Source: dt.tableName, PrimaryKey: false, DatabaseSource: dt.dbName},
{Name: "message", Type: types.Text, Source: dt.tableName, PrimaryKey: false, DatabaseSource: dt.dbName},
{Name: "commit_order", Type: types.Uint64, Source: dt.tableName, PrimaryKey: false, DatabaseSource: dt.dbName},
}
}

Expand All @@ -109,7 +110,11 @@ func (dt *LogTable) Partitions(*sql.Context) (sql.PartitionIter, error) {
func (dt *LogTable) PartitionRows(ctx *sql.Context, p sql.Partition) (sql.RowIter, error) {
switch p := p.(type) {
case *doltdb.CommitPart:
return sql.RowsToRowIter(sql.NewRow(p.Hash().String(), p.Meta().Name, p.Meta().Email, p.Meta().Time(), p.Meta().Description)), nil
height, err := p.Commit().Height()
if err != nil {
return nil, err
}
return sql.RowsToRowIter(sql.NewRow(p.Hash().String(), p.Meta().Name, p.Meta().Email, p.Meta().Time(), p.Meta().Description, height)), nil
default:
return NewLogItr(ctx, dt.ddb, dt.head)
}
Expand Down Expand Up @@ -246,7 +251,12 @@ func (itr *LogItr) Next(ctx *sql.Context) (sql.Row, error) {
return nil, err
}

return sql.NewRow(h.String(), meta.Name, meta.Email, meta.Time(), meta.Description), nil
height, err := cm.Height()
if err != nil {
return nil, err
}

return sql.NewRow(h.String(), meta.Name, meta.Email, meta.Time(), meta.Description, height), nil
}

// Close closes the iterator.
Expand Down
59 changes: 59 additions & 0 deletions go/libraries/doltcore/sqle/enginetest/dolt_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -4786,6 +4786,65 @@ var LogTableFunctionScriptTests = []queries.ScriptTest{
},
},
},
{
Name: "commit_order column in dolt_log system table and function",
SetUpScript: []string{
"create table t (pk int primary key);",
"call dolt_add('.')",
"set @Commit1 = '';",
"call dolt_commit_hash_out(@Commit1, '-am', 'commit 1');",
"call dolt_commit('--allow-empty', '-m', 'commit 2');",
"call dolt_checkout('-b', 'feature');",
"call dolt_commit('--allow-empty', '-m', 'feature commit');",
"call dolt_checkout('main');",
"call dolt_commit('--allow-empty', '-m', 'main commit');",
"call dolt_merge('feature', '-m', 'merge feature');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "describe dolt_log;",
Expected: []sql.Row{
{"commit_hash", "text", "NO", "PRI", nil, ""},
{"committer", "text", "NO", "", nil, ""},
{"email", "text", "NO", "", nil, ""},
{"date", "datetime", "NO", "", nil, ""},
{"message", "text", "NO", "", nil, ""},
{"commit_order", "bigint unsigned", "NO", "", nil, ""},
},
},
{
Query: "select commit_order from dolt_log where message = 'commit 1';",
Expected: []sql.Row{
{uint64(2)},
},
},
{
Query: "select commit_order from dolt_log() where message = 'commit 1';",
Expected: []sql.Row{
{uint64(2)},
},
},
{
Query: "select (select commit_order from dolt_log where message = 'commit 1') = (select commit_order from dolt_log() where message = 'commit 1') as same_order;",
Expected: []sql.Row{
{true},
},
},
{
Query: "select count(distinct commit_order) = 5 as has_five_orders from dolt_log;",
Expected: []sql.Row{
{true},
},
},
// Test that commits on parallel branches can have the same commit_order (height)
{
Query: "select count(*) from (select commit_order, count(*) as cnt from dolt_log group by commit_order having cnt > 1) as duplicate_orders;",
Expected: []sql.Row{
{1}, // feature and main commits should have same order
},
},
},
},
}

var LargeJsonObjectScriptTests = []queries.ScriptTest{
Expand Down
2 changes: 2 additions & 0 deletions go/libraries/doltcore/sqle/sqlselect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ func BasicSelectTests() []SelectTest {
"[email protected]",
time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC).In(LoadedLocalLocation()),
"Initialize data repository",
uint64(1), // commit_order for the initial commit
},
},
ExpectedSqlSchema: sql.Schema{
Expand All @@ -761,6 +762,7 @@ func BasicSelectTests() []SelectTest {
&sql.Column{Name: "email", Type: gmstypes.Text},
&sql.Column{Name: "date", Type: gmstypes.Datetime},
&sql.Column{Name: "message", Type: gmstypes.Text},
&sql.Column{Name: "commit_order", Type: gmstypes.Uint64},
},
},
{
Expand Down
80 changes: 80 additions & 0 deletions integration-tests/bats/system-tables.bats
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,86 @@ teardown() {
[[ ! "$output" =~ "Added test table" ]] || false
}

@test "system-tables: dolt_log system table includes commit_order column" {
dolt sql -q "create table test (pk int, c1 int, primary key(pk))"
dolt add test
dolt commit -m "Added test table"
dolt commit --allow-empty -m "Empty commit"

# Test that dolt_log system table has commit_order column
run dolt sql -q "describe dolt_log"
[ $status -eq 0 ]
[[ "$output" =~ "commit_order" ]] || false

# Test that commit_order values are present and numeric
run dolt sql -q "select commit_order from dolt_log where message = 'Added test table'"
[ $status -eq 0 ]
[[ "$output" =~ [0-9]+ ]] || false

# Test that we have 3 distinct commit orders (init commit + 2 new commits)
run dolt sql -q "select count(distinct commit_order) from dolt_log"
[ $status -eq 0 ]
[[ "$output" =~ "3" ]] || false
}

@test "system-tables: dolt_log() table function includes commit_order column" {
dolt sql -q "create table test2 (pk int, c1 int, primary key(pk))"
dolt add test2
dolt commit -m "Added test2 table"

# Test that dolt_log() function has commit_order column
run dolt sql -q "select commit_order from dolt_log() where message = 'Added test2 table'"
[ $status -eq 0 ]
[[ "$output" =~ [0-9]+ ]] || false

# Test that the function and system table return the same commit_order for the same commit
run dolt sql -q "select (select commit_order from dolt_log where message = 'Added test2 table') = (select commit_order from dolt_log() where message = 'Added test2 table') as orders_match"
[ $status -eq 0 ]
[[ "$output" =~ "true" ]] || false
}

@test "system-tables: commit_order reflects topological order for branches" {
if [ "$SQL_ENGINE" = "remote-engine" ]; then
skip "needs checkout which is unsupported for remote-engine"
fi

# Create initial commit
dolt sql -q "create table test (pk int, c1 int, primary key(pk))"
dolt add test
dolt commit -m "initial commit"

# Create a branch
dolt checkout -b feature
dolt commit --allow-empty -m "feature commit"

# Go back to main and make another commit
dolt checkout main
dolt commit --allow-empty -m "main commit"

# Both feature and main commits should have the same commit_order (height)
# since they branched from the same parent
# Get the commit hashes and compare their heights using dolt_log() function
run dolt sql -q "select commit_hash from dolt_commits where message = 'feature commit'"
[ $status -eq 0 ]
feature_hash=$(echo "$output" | tail -n 1 | tr -d ' |')

run dolt sql -q "select commit_hash from dolt_commits where message = 'main commit'"
[ $status -eq 0 ]
main_hash=$(echo "$output" | tail -n 1 | tr -d ' |')

run dolt sql -q "select (select commit_order from dolt_log('$feature_hash') limit 1) = (select commit_order from dolt_log('$main_hash') limit 1) as same_height"
[ $status -eq 0 ]
[[ "$output" =~ "true" ]] || false

# Merge feature into main
dolt merge feature -m "merge feature"

# The merge commit should have a higher commit_order than both branch commits
run dolt sql -q "select (select commit_order from dolt_log where message = 'merge feature') > (select commit_order from dolt_log where message = 'main commit') as merge_higher"
[ $status -eq 0 ]
[[ "$output" =~ "true" ]] || false
}

@test "system-tables: query dolt_branches system table" {
dolt checkout -b create-table-branch
dolt sql -q "create table test (pk int, c1 int, primary key(pk))"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const logTests = [
email: "[email protected]",
date: "",
message: "Initialize data repository",
commit_order: 1,
parents: [],
},
],
Expand All @@ -26,13 +27,15 @@ export const logTests = [
email: "[email protected]",
date: "",
message: "Create table test",
commit_order: 2,
},
{
commit_hash: "",
committer: "mysql-test-runner",
email: "[email protected]",
date: "",
message: "Initialize data repository",
commit_order: 1,
},
],
matcher: logsMatcher,
Expand All @@ -47,6 +50,7 @@ export const logTests = [
email: "[email protected]",
date: "",
message: "Create table test",
commit_order: 2,
parents: [""],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function branchesMatcher(rows, exp) {
}

export function logsMatcher(rows, exp) {
const exceptionKeys = ["commit_hash", "date", "parents"];
const exceptionKeys = ["commit_hash", "date", "parents", "commit_order"];

function getExceptionIsValid(row, key, expRow) {
const val = row[key];
Expand All @@ -75,6 +75,8 @@ export function logsMatcher(rows, exp) {
val.split(", ").filter((v) => !!v.length).length ===
expRow.parents.length
);
case "commit_order":
return typeof val === "number" && val > 0;
default:
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const mergeTests = [
committer: "dolt",
email: "dolt@%",
date: "",
commit_order: 3,
parents: ["", ""],
},
{
Expand All @@ -35,6 +36,7 @@ export const mergeTests = [
committer: "Dolt",
email: "[email protected]",
date: "",
commit_order: 2,
parents: [""],
},
{
Expand All @@ -43,6 +45,7 @@ export const mergeTests = [
committer: "mysql-test-runner",
email: "[email protected]",
date: "",
commit_order: 1,
parents: [],
},
],
Expand Down
Loading