From ce3c09097f7948efd95b2582fe9922406481e428 Mon Sep 17 00:00:00 2001 From: elianddb Date: Fri, 13 Feb 2026 15:52:09 -0800 Subject: [PATCH] fix suggestions --- .../dtables/constraint_violations_prolly.go | 2 +- .../sqle/enginetest/dolt_queries_merge.go | 200 +++++++++++++++++- .../enginetest/dolt_transaction_queries.go | 131 ------------ 3 files changed, 200 insertions(+), 133 deletions(-) diff --git a/go/libraries/doltcore/sqle/dtables/constraint_violations_prolly.go b/go/libraries/doltcore/sqle/dtables/constraint_violations_prolly.go index a1c5a74324..2e2583c481 100644 --- a/go/libraries/doltcore/sqle/dtables/constraint_violations_prolly.go +++ b/go/libraries/doltcore/sqle/dtables/constraint_violations_prolly.go @@ -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 } diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go index ebd34c8bd3..91d71bcc49 100644 --- a/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_queries_merge.go @@ -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{ diff --git a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go index 35f8c779ca..6456861340 100755 --- a/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go +++ b/go/libraries/doltcore/sqle/enginetest/dolt_transaction_queries.go @@ -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(),