Skip to content
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 {
"bigbillieb@fake.horse",
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: "mysql-test-runner@liquidata.co",
date: "",
message: "Initialize data repository",
commit_order: 1,
parents: [],
},
],
Expand All @@ -26,13 +27,15 @@ export const logTests = [
email: "dolt@dolthub.com",
date: "",
message: "Create table test",
commit_order: 2,
},
{
commit_hash: "",
committer: "mysql-test-runner",
email: "mysql-test-runner@liquidata.co",
date: "",
message: "Initialize data repository",
commit_order: 1,
},
],
matcher: logsMatcher,
Expand All @@ -47,6 +50,7 @@ export const logTests = [
email: "dolt@dolthub.com",
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: "dolt@dolthub.com",
date: "",
commit_order: 2,
parents: [""],
},
{
Expand All @@ -43,6 +45,7 @@ export const mergeTests = [
committer: "mysql-test-runner",
email: "mysql-test-runner@liquidata.co",
date: "",
commit_order: 1,
parents: [],
},
],
Expand Down
Loading