Skip to content

Support the dolt_conflicts_resolve workflow when a table is dropped on one side of a merge. #9203

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

nicktobey
Copy link
Contributor

@nicktobey nicktobey commented May 10, 2025

The original behavior (reporting dropped tables as schema conflicts) was moved to its own PR: #9208

This PR contains the follow-up work to allow dolt conflicts resolve to function in the presence of table drops. See below for examples where this doesn't currently work as expected.

Currently, attempting to merge when a table has been drop on one branch and had its data modified on the other produces an immediate error that aborts the merge. This error does not necessarily have enough context to determine the affected table, which makes resolving the merge difficult.

Given that we already handle a simultaneous drop + schema modification (by treating it as a schema conflict), we should be able to handle the simpler case of data modifications as well.

Since dropping a table is technically a schema change, this should now get reported as a schema conflict, and pause the merge, allowing the user to query dolt_schema_conflicts for more information.

I'm not thrilled about the behavioral change observed in the BATS test "merge: ourRoot renames, theirRoot modifies the schema".

What's happening there is that a renamed table is seen as a drop + a create. So the merge code sees a create with no conflicts, and attempts to add it to the same root as the original table (which is now in a conflict state.) Since both tables contain duplicate tags, this causes an error. This probably isn't what we want to happen, and we should figure out the intended behavior before merging this PR.

@coffeegoddd
Copy link
Contributor

@nicktobey DOLT

comparing_percentages
100.000000 to 100.000000
version result total
260a7ff ok 5937457
version total_tests
260a7ff 5937457
correctness_percentage
100.0

Copy link
Contributor

@macneale4 macneale4 left a comment

Choose a reason for hiding this comment

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

I think you should focus on making dolt_conflicts_resolve work before worrying about the dolt conflicts CLI command. Honestly we should migrate or deprecate the cli command.

At present This is the merge error I get:

db/dev*> CALL DOLT_CONFLICTS_RESOLVE("--ours", "TABLEFOO");
Unable to automatically resolve schema conflicts since data changes may not have been fully merged yet. To continue, abort this merge (dolt merge --abort) then apply ALTER TABLE statements to one side of this merge to get the two schemas in sync with the desired schema, then rerun the merge. To track resolution of this limitation, follow https://github.com/dolthub/dolt/issues/6616

@@ -751,7 +751,19 @@ SQL
run dolt merge feature-branch

log_status_eq 1
[[ "$output" =~ "conflict: table with same name deleted and modified" ]] || false
[[ "$output" =~ "CONFLICT (schema): Merge conflict in test" ]] || false
Copy link
Contributor

Choose a reason for hiding this comment

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

Matching all the lines like this seems pretty frail. Would it make more sense to build these into the go engine tests?

@nicktobey
Copy link
Contributor Author

Alright, I modified dolt_conflicts_resolve to allow resolving conflicts when the table was deleted on one side of the branch.

Unfortunately, the conflict resolution workflow seems to be broken for this case:

Assuming that the branch containing the data edit is named editBranch and the branch dropping the table is named dropBranch:

When checking out editBranch and merging dropBranch:

Output of dolt status:

On branch editBranch
You have unmerged tables.
  (fix conflicts and run "dolt commit")
  (use "dolt merge --abort" to abort the merge)

Unmerged paths:
  (use "dolt add <table>..." to mark resolution)
	schema conflict:  testTable
	both modified:    testTable
  • dolt conflicts resolve --ours tableName appears to do nothing: the branch is not marked resolved and the merge cannot be committed.
  • dolt conflicts resolve --theirs tableNamecauses a panic:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x10 pc=0x101ce5d8c]

goroutine 1 [running]:
github.com/dolthub/dolt/go/libraries/doltcore/doltdb.ValidateTagUniqueness({0x1036ba600, 0x14001f74a00}, {0x1037692c8, 0x14002089980}, {0x14001673344, 0x4}, 0x0)
	/Users/nick/Documents/dolt/go/libraries/doltcore/doltdb/root_val.go:1339 +0x3c
github.com/dolthub/dolt/go/libraries/doltcore/doltdb.(*rootValue).PutTable(0x14002089980, {0x1036ba600, 0x14001f74a00}, {{0x14001673344?, 0x14002089a40?}, {0x0?, 0x1?}}, 0x0)
	/Users/nick/Documents/dolt/go/libraries/doltcore/doltdb/root_val.go:911 +0x6c
github.com/dolthub/dolt/go/libraries/doltcore/sqle/dprocedures.ResolveSchemaConflicts(0x14001f74a00, 0x14002094690, 0x140020681e0, 0x0, {0x14001b6d2c0, 0x1, 0x4?})
	/Users/nick/Documents/dolt/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go:395 +0x320
github.com/dolthub/dolt/go/libraries/doltcore/sqle/dprocedures.DoDoltConflictsResolve(0x14001f74a00, {0x14001b6d100, 0x2, 0x2})
	/Users/nick/Documents/dolt/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go:535 +0x3ec
github.com/dolthub/dolt/go/libraries/doltcore/sqle/dprocedures.doltConflictsResolve(0x14001f21b98?, {0x14001b6d100?, 0x0?, 0x0?})
	/Users/nick/Documents/dolt/go/libraries/doltcore/sqle/dprocedures/dolt_conflicts_resolve.go:48 +0x20
reflect.Value.call({0x1031df680?, 0x10367fff8?, 0x14001f20135?}, {0x10259967c, 0x4}, {0x14002068230, 0x3, 0x1030d8d00?})
	/Users/nick/go/pkg/mod/golang.org/[email protected]/src/reflect/value.go:581 +0x978
reflect.Value.Call({0x1031df680?, 0x10367fff8?, 0x10376caa8?}, {0x14002068230?, 0x1030d8d00?, 0x14000b84800?})
	/Users/nick/go/pkg/mod/golang.org/[email protected]/src/reflect/value.go:365 +0x94
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildExternalProcedure(0x14001f223c8?, 0x14001f74a00, 0x14001f68cb0, {0x1019313e0?, 0x14001f22398?, 0x101a064e4?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/rel.go:725 +0x370
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x14001f66760, 0x10036ce3c?, {0x1036cacb0?, 0x14001f68cb0}, {0x0, 0x0, 0x0})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:154 +0x2910
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x14001f66760?, 0x14001f74a00?, {0x1036cacb0, 0x14001f68cb0}, {0x0?, 0x0?, 0x0?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:36 +0x98
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildProcedure(0x14001f22658?, 0x1003ce8d8?, 0x14001f22638?, {0x0?, 0x14001f22630?, 0x1030070b6?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/rel.go:336 +0x40
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x14001f66760, 0x100370edc?, {0x1036c83e8?, 0x14000a60700}, {0x0, 0x0, 0x0})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:244 +0x25f8
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x14001f66760?, 0x14001f74a00?, {0x1036c83e8, 0x14000a60700}, {0x0?, 0x0?, 0x0?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:36 +0x98
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildCall(0x14001f66760, 0x14001f74a00, 0x140020fe790, {0x0, 0x0, 0x0})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/proc.go:202 +0x868
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x14001f66760, 0x1019f666c?, {0x1036c8238?, 0x140020fe790}, {0x0, 0x0, 0x0})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:106 +0xe64
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x14001f66760?, 0x14001f74a00?, {0x1036c8238, 0x140020fe790}, {0x0?, 0x0?, 0x0?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/node_builder.gen.go:36 +0x98
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).Build(0x14001f66760, 0x14001f74a00, {0x1036c8238, 0x140020fe790}, {0x0, 0x0, 0x0})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/sql/rowexec/builder.go:40 +0xa0
github.com/dolthub/go-mysql-server.(*Engine).QueryWithBindings(0x140007240e0, 0x14001f74a00, {0x14001f28880, 0x2f}, {0x0, 0x0}, 0x0, 0x0)
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/engine.go:443 +0x3a0
github.com/dolthub/go-mysql-server.(*Engine).Query(0x2?, 0x1030d93c0?, {0x14001f28880?, 0x10?})
	/Users/nick/go/pkg/mod/github.com/dolthub/[email protected]/engine.go:256 +0x30
github.com/dolthub/dolt/go/cmd/dolt/commands/engine.(*SqlEngine).Query(0x1036c6468?, 0x106687d00?, {0x14001f28880?, 0x0?})
	/Users/nick/Documents/dolt/go/cmd/dolt/commands/engine/sqlengine.go:410 +0x24
github.com/dolthub/dolt/go/cmd/dolt/commands.GetRowsForSql({0x10369ff50?, 0x140005cc1c0?}, 0x14001f74a00, {0x14001f28880?, 0x2?})
	/Users/nick/Documents/dolt/go/cmd/dolt/commands/utils.go:328 +0x40
github.com/dolthub/dolt/go/cmd/dolt/commands/cnfcmds.AutoResolveTables({0x10369ff50, 0x140005cc1c0}, 0x14001f74a00, 0x1, {0x14001fb0000?, 0x9cb8ed0c4b61f547?, 0x8080808080808047?})
	/Users/nick/Documents/dolt/go/cmd/dolt/commands/cnfcmds/auto_resolve.go:56 +0x14c
github.com/dolthub/dolt/go/cmd/dolt/commands/cnfcmds.autoResolve({0x10369ff50, 0x140005cc1c0}, 0x14001f74a00, 0x14001fd1020)
	/Users/nick/Documents/dolt/go/cmd/dolt/commands/cnfcmds/resolve.go:132 +0x368
github.com/dolthub/dolt/go/cmd/dolt/commands/cnfcmds.ResolveCmd.Exec({}, {0x1036bae50, 0x14001fd2180}, {0x14001ac4198, 0x16}, {0x140001c8030, 0x2, 0x2}, 0x14000b84030?, {0x1036ba718, ...})
	/Users/nick/Documents/dolt/go/cmd/dolt/commands/cnfcmds/resolve.go:108 +0x25c
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.handleCommand({{0x1025a430a, 0x9}, {0x10264e7da, 0x33}, {0x0, 0x0}, {0x104ea6ce0, 0x2, 0x2}, 0x0}, ...)
	/Users/nick/Documents/dolt/go/cmd/dolt/cli/command.go:246 +0x57c
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.Exec({{0x1025a430a, 0x9}, {0x10264e7da, 0x33}, {0x0, 0x0}, {0x104ea6ce0, 0x2, 0x2}, 0x0}, ...)
	/Users/nick/Documents/dolt/go/cmd/dolt/cli/command.go:195 +0x234
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.handleCommand({{0x1025993b0, 0x4}, {0x1025bc185, 0x11}, {0x0, 0x0}, {0x104eec620, 0x39, 0x39}, 0x0}, ...)
	/Users/nick/Documents/dolt/go/cmd/dolt/cli/command.go:246 +0x57c
github.com/dolthub/dolt/go/cmd/dolt/cli.SubCommandHandler.Exec({{0x1025993b0, 0x4}, {0x1025bc185, 0x11}, {0x0, 0x0}, {0x104eec620, 0x39, 0x39}, 0x0}, ...)
	/Users/nick/Documents/dolt/go/cmd/dolt/cli/command.go:195 +0x234
main.runMain()
	/Users/nick/Documents/dolt/go/cmd/dolt/dolt.go:531 +0x276c
main.main()
	/Users/nick/Documents/dolt/go/cmd/dolt/dolt.go:194 +0x1c

When checking out dropBranch and merging editBranch:

Output of dolt status:

On branch drop
You have unmerged tables.
  (fix conflicts and run "dolt commit")
  (use "dolt merge --abort" to abort the merge)

Unmerged paths:
  (use "dolt add <table>..." to mark resolution)
	schema conflict:  test
  • The table does not exist in the working set (since we dropped it)
  • dolt conflicts resolve --ours tableName returns error: the table(s) tableName do not exist
  • dolt conflicts resolve --theirs tableName returns error: the table(s) tableName do not exist
  • dolt conflicts resolve --ours . appears to do nothing.
  • dolt conflicts resolve --theirs . appears to do nothing.
  • Conflicts cannot be marked resolved with dolt add <table>... returns error: the table(s) tableName do not exist

It seems like the workflow was never designed to handle the case of resolving a conflict where one side of the merge drops the table.

…nflicts because one side of the merge was deleted.
@nicktobey nicktobey force-pushed the nicktobey/schemaconflict branch from f271d38 to 21094c5 Compare May 12, 2025 20:34
@nicktobey nicktobey changed the title When a table is deleted on one branch and has its data modified on the other, record this as a schema conflict. Support the dolt_conflicts_resolve workflow when a table is dropped on one side of a merge. May 12, 2025
@coffeegoddd
Copy link
Contributor

@nicktobey DOLT

comparing_percentages
100.000000 to 100.000000
version result total
21094c5 ok 5937457
version total_tests
21094c5 5937457
correctness_percentage
100.0

@nicktobey nicktobey marked this pull request as draft May 13, 2025 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants