fix suggestions

This commit is contained in:
elianddb
2026-02-13 15:52:09 -08:00
parent 62c9addfd2
commit ce3c09097f
3 changed files with 200 additions and 133 deletions

View File

@@ -71,7 +71,7 @@ func getConstraintViolationsSchema(ctx context.Context, t *doltdb.Table, tn dolt
cols := make([]schema.Column, 0, baseColColl.Size()+schSize)
cols = append(cols, baseCols[0:2]...)
infoCol, err := schema.NewColumnWithTypeInfo("violation_info", schema.DoltConstraintViolationsInfoTag, typeinfo.JSONType, false, "", false, "")
infoCol, err := schema.NewColumnWithTypeInfo("violation_info", schema.DoltConstraintViolationsInfoTag, typeinfo.JSONType, true, "", false, "")
if err != nil {
return nil, err
}

View File

@@ -4556,7 +4556,6 @@ var MergeArtifactsScripts = []queries.ScriptTest{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t;",
Expected: []sql.Row{{4}},
},
// Omit violation_info from select so test passes under Doltgres (in-process returns Columns as []string, wire/protocol returns []interface{}).
{
Query: "SELECT from_root_ish, violation_type, pk, a, b FROM dolt_constraint_violations_t ORDER BY pk, CAST(violation_info AS CHAR);",
Expected: []sql.Row{
@@ -4576,6 +4575,205 @@ var MergeArtifactsScripts = []queries.ScriptTest{
},
},
},
{
// Uses JSON_EXTRACT for single-violation delete; MySQL-only (Doltgres uses different JSON syntax).
Dialect: "mysql",
Name: "clearing constraint violations (MySQL): single delete, bulk delete, and commit",
SetUpScript: []string{
"SET dolt_force_transaction_commit = on;",
"CREATE TABLE t (pk int primary key, a int not null, b int not null, unique key ua (a), unique key ub (b));",
"INSERT INTO t VALUES (1, 10, 20);",
"CALL DOLT_COMMIT('-Am', 'init');",
"CALL DOLT_BRANCH('other');",
"UPDATE t SET a = 0, b = 0;",
"CALL DOLT_COMMIT('-am', 'main: row 1 -> (0,0)');",
"CALL DOLT_CHECKOUT('other');",
"INSERT INTO t VALUES (2, 0, 0);",
"CALL DOLT_COMMIT('-am', 'other: add row (2,0,0)');",
"CALL DOLT_CHECKOUT('main');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('other');",
Expected: []sql.Row{{"", 0, 1, "conflicts found"}},
},
{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t;",
Expected: []sql.Row{{4}},
},
{
Query: "DELETE FROM dolt_constraint_violations_t WHERE pk = 1 AND violation_type = 'unique index' AND JSON_EXTRACT(violation_info, '$.Name') = 'ua';",
Expected: []sql.Row{{types.NewOkResult(1)}},
},
{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t;",
Expected: []sql.Row{{3}},
},
{
Query: "DELETE FROM dolt_constraint_violations_t WHERE pk = 1;",
Expected: []sql.Row{{types.NewOkResult(1)}},
},
{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t WHERE pk = 1;",
Expected: []sql.Row{{0}},
},
{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t WHERE pk = 2;",
Expected: []sql.Row{{2}},
},
{
Query: "UPDATE t SET a = 1, b = 2 WHERE pk = 2;",
Expected: []sql.Row{{types.OkResult{RowsAffected: uint64(1), Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}},
},
{
Query: "DELETE FROM dolt_constraint_violations_t WHERE pk = 2;",
Expected: []sql.Row{{types.NewOkResult(2)}},
},
{
Query: "SELECT COUNT(*) FROM dolt_constraint_violations_t;",
Expected: []sql.Row{{0}},
},
{
Query: "CALL DOLT_COMMIT('-am', 'merge and resolve violations');",
Expected: []sql.Row{{doltCommit}},
},
{
Query: "SELECT * FROM t ORDER BY pk;",
Expected: []sql.Row{{1, 0, 0}, {2, 1, 2}},
},
},
},
{
// Merge error when a table has multiple constraint violations (e.g. same row violates two unique keys)
Name: "merge error lists all constraint violations when table has multiple violations",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, col1 int UNIQUE, col2 int UNIQUE);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO t values (2, 1, 1);",
"CALL DOLT_COMMIT('-am', 'right edit');",
"CALL DOLT_CHECKOUT('main');",
"INSERT INTO t VALUES (1, 1, 1);",
"CALL DOLT_COMMIT('-am', 'left edit');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Unique Key Constraint Violation,\n" +
"\tName: col1,\n" +
"\tColumns: [col1] (2 row(s))" +
"\nType: Unique Key Constraint Violation,\n" +
"\tName: col2,\n" +
"\tColumns: [col2] (2 row(s))",
},
{
Query: "SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "merge error includes row count for foreign key violations",
Dialect: "mysql",
SetUpScript: []string{
"CREATE TABLE parent (pk int PRIMARY KEY);",
"CREATE TABLE child (pk int PRIMARY KEY, fk int, FOREIGN KEY (fk) REFERENCES parent(pk));",
"INSERT INTO parent VALUES (1);",
"INSERT INTO child VALUES (1, 1);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create tables');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO child VALUES (2, 1), (3, 1);",
"CALL DOLT_COMMIT('-am', 'add two children referencing parent');",
"CALL DOLT_CHECKOUT('main');",
"SET FOREIGN_KEY_CHECKS = 0;",
"DELETE FROM parent WHERE pk = 1;",
"SET FOREIGN_KEY_CHECKS = 1;",
"CALL DOLT_COMMIT('-am', 'delete parent');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Foreign Key Constraint Violation\n" +
"\tForeignKey: child_ibfk_1,\n" +
"\tTable: child,\n" +
"\tReferencedTable: parent,\n" +
"\tIndex: fk,\n" +
"\tReferencedIndex: (3 row(s))",
},
{
Query: "SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "merge error includes row count for null constraint violations",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, c int);",
"INSERT INTO t VALUES (1, 1), (2, 2);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"UPDATE t SET c = NULL WHERE pk IN (1, 2);",
"CALL DOLT_COMMIT('-am', 'set both to null');",
"CALL DOLT_CHECKOUT('main');",
"ALTER TABLE t MODIFY c int NOT NULL;",
"CALL DOLT_COMMIT('-am', 'add not null');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Null Constraint Violation,\n" +
"\tColumns: [c] (2 row(s))",
},
{
Query: "SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "merge error includes row count for check constraint violations",
Dialect: "mysql",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, col int);",
"INSERT INTO t VALUES (1, 1), (2, 2);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO t VALUES (3, -1), (4, -1);",
"CALL DOLT_COMMIT('-am', 'add rows that will violate check');",
"CALL DOLT_CHECKOUT('main');",
"ALTER TABLE t ADD CONSTRAINT chk_positive CHECK (col > 0);",
"CALL DOLT_COMMIT('-am', 'add check constraint');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Check Constraint Violation,\n" +
"\tName: chk_positive,\n" +
"\tExpression: (`col` > 0) (2 row(s))",
},
{
Query: "SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
}
var SchemaConflictScripts = []queries.ScriptTest{

View File

@@ -2231,137 +2231,6 @@ var DoltConstraintViolationTransactionTests = []queries.TransactionTest{
},
},
},
{
// Commit error when a table has multiple constraint violations (e.g. same row violates two unique keys)
// must list all violations in the error (transactions.go builds the message from artifact map).
Name: "commit error lists all constraint violations when table has multiple violations",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, col1 int UNIQUE, col2 int UNIQUE);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO t values (2, 1, 1);",
"CALL DOLT_COMMIT('-am', 'right edit');",
"CALL DOLT_CHECKOUT('main');",
"INSERT INTO t VALUES (1, 1, 1);",
"CALL DOLT_COMMIT('-am', 'left edit');",
},
Assertions: []queries.ScriptTestAssertion{
{
// Deduplicated by constraint: each unique key appears once with row count so the message explains what happened.
Query: "/* client a */ CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Unique Key Constraint Violation,\n" +
"\tName: col1,\n" +
"\tColumns: [col1] (2 row(s))" +
"\nType: Unique Key Constraint Violation,\n" +
"\tName: col2,\n" +
"\tColumns: [col2] (2 row(s))",
},
{
Query: "/* client a */ SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "commit error includes row count for foreign key violations",
SetUpScript: []string{
"CREATE TABLE parent (pk int PRIMARY KEY);",
"CREATE TABLE child (pk int PRIMARY KEY, fk int, FOREIGN KEY (fk) REFERENCES parent(pk));",
"INSERT INTO parent VALUES (1);",
"INSERT INTO child VALUES (1, 1);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create tables');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO child VALUES (2, 1), (3, 1);",
"CALL DOLT_COMMIT('-am', 'add two children referencing parent');",
"CALL DOLT_CHECKOUT('main');",
"SET FOREIGN_KEY_CHECKS = 0;",
"DELETE FROM parent WHERE pk = 1;",
"SET FOREIGN_KEY_CHECKS = 1;",
"CALL DOLT_COMMIT('-am', 'delete parent');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "/* client a */ CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Foreign Key Constraint Violation\n" +
"\tForeignKey: child_ibfk_1,\n" +
"\tTable: child,\n" +
"\tReferencedTable: parent,\n" +
"\tIndex: fk,\n" +
"\tReferencedIndex: (3 row(s))",
},
{
Query: "/* client a */ SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "commit error includes row count for null constraint violations",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, c int);",
"INSERT INTO t VALUES (1, 1), (2, 2);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"UPDATE t SET c = NULL WHERE pk IN (1, 2);",
"CALL DOLT_COMMIT('-am', 'set both to null');",
"CALL DOLT_CHECKOUT('main');",
"ALTER TABLE t MODIFY c int NOT NULL;",
"CALL DOLT_COMMIT('-am', 'add not null');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "/* client a */ CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Null Constraint Violation,\n" +
"\tColumns: [c] (2 row(s))",
},
{
Query: "/* client a */ SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
{
Name: "commit error includes row count for check constraint violations",
SetUpScript: []string{
"CREATE TABLE t (pk int PRIMARY KEY, col int);",
"INSERT INTO t VALUES (1, 1), (2, 2);",
"CALL DOLT_ADD('.')",
"CALL DOLT_COMMIT('-am', 'create table');",
"CALL DOLT_CHECKOUT('-b', 'right');",
"INSERT INTO t VALUES (3, -1), (4, -1);",
"CALL DOLT_COMMIT('-am', 'add rows that will violate check');",
"CALL DOLT_CHECKOUT('main');",
"ALTER TABLE t ADD CONSTRAINT chk_positive CHECK (col > 0);",
"CALL DOLT_COMMIT('-am', 'add check constraint');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "/* client a */ CALL DOLT_MERGE('right');",
ExpectedErrStr: dsess.ErrUnresolvedConstraintViolationsCommit.Error() + dsess.ConstraintViolationsListPrefix +
"\nType: Check Constraint Violation,\n" +
"\tName: chk_positive,\n" +
"\tExpression: (`col` > 0) (2 row(s))",
},
{
Query: "/* client a */ SELECT * from DOLT_CONSTRAINT_VIOLATIONS;",
Expected: []sql.Row{},
},
},
},
// {
// Name: "Run GC concurrently with other transactions",
// SetUpScript: gcSetup(),