Skip to content

Adding skipped tests for UPDATE ... JOIN bugs #3024

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 1 commit into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions enginetest/enginetests.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ func TestReadOnlyDatabases(t *testing.T, harness ReadOnlyDatabaseHarness) {

for _, querySet := range [][]queries.WriteQueryTest{
queries.InsertQueries,
queries.UpdateTests,
queries.UpdateWriteQueryTests,
queries.DeleteTests,
queries.ReplaceQueries,
} {
Expand Down Expand Up @@ -1352,9 +1352,12 @@ func TestReplaceIntoErrors(t *testing.T, harness Harness) {

func TestUpdate(t *testing.T, harness Harness) {
harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.FloattableData, setup.NiltableData, setup.TypestableData, setup.Pk_tablesData, setup.OthertableData, setup.TabletestData)
for _, tt := range queries.UpdateTests {
for _, tt := range queries.UpdateWriteQueryTests {
RunWriteQueryTest(t, harness, tt)
}
for _, tt := range queries.UpdateScriptTests {
TestScript(t, harness, tt)
}
}

func TestUpdateIgnore(t *testing.T, harness Harness) {
Expand Down Expand Up @@ -1421,9 +1424,12 @@ func TestDelete(t *testing.T, harness Harness) {

func TestUpdateQueriesPrepared(t *testing.T, harness Harness) {
harness.Setup(setup.MydbData, setup.MytableData, setup.Mytable_del_idxData, setup.OthertableData, setup.TypestableData, setup.Pk_tablesData, setup.FloattableData, setup.NiltableData, setup.TabletestData)
for _, tt := range queries.UpdateTests {
for _, tt := range queries.UpdateWriteQueryTests {
runWriteQueryTestPrepared(t, harness, tt)
}
for _, tt := range queries.UpdateScriptTests {
TestScriptPrepared(t, harness, tt)
}
}

func TestDeleteQueriesPrepared(t *testing.T, harness Harness) {
Expand Down
41 changes: 40 additions & 1 deletion enginetest/queries/check_scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ var ChecksOnUpdateScriptTests = []ScriptTest{
},
},
{
Name: "Update join updates",
Name: "Update join - single table",
SetUpScript: []string{
"CREATE TABLE sales (year_built int primary key, CONSTRAINT `valid_year_built` CHECK (year_built <= 2022));",
"INSERT INTO sales VALUES (1981);",
Expand Down Expand Up @@ -535,6 +535,45 @@ var ChecksOnUpdateScriptTests = []ScriptTest{
},
},
},
{
Name: "Update join - multiple tables",
SetUpScript: []string{
"CREATE TABLE sales (year_built int primary key, CONSTRAINT `valid_year_built` CHECK (year_built <= 2022));",
"INSERT INTO sales VALUES (1981);",
"CREATE TABLE locations (state char(2) primary key, CONSTRAINT `state` CHECK (state != 'GA'));",
"INSERT INTO locations VALUES ('WA');",
},
Assertions: []ScriptTestAssertion{
{
Query: "UPDATE sales JOIN locations SET sales.year_built = 2000, locations.state = 'GA';",
ExpectedErr: sql.ErrCheckConstraintViolated,
},
{
Query: "UPDATE sales JOIN locations SET sales.year_built = 2025, locations.state = 'CA';",
ExpectedErr: sql.ErrCheckConstraintViolated,
},
{
Query: "select * from sales;",
Expected: []sql.Row{{1981}},
},
{
Query: "select * from locations;",
Expected: []sql.Row{{"WA"}},
},
{
Query: "UPDATE sales JOIN locations SET sales.year_built = 2000, locations.state = 'CA';",
Expected: []sql.Row{{types.OkResult{2, 0, plan.UpdateInfo{2, 2, 0}}}},
},
{
Query: "select * from sales;",
Expected: []sql.Row{{2000}},
},
{
Query: "select * from locations;",
Expected: []sql.Row{{"CA"}},
},
},
},
}

var DisallowedCheckConstraintsScripts = []ScriptTest{
Expand Down
105 changes: 104 additions & 1 deletion enginetest/queries/update_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/dolthub/vitess/go/mysql"
)

var UpdateTests = []WriteQueryTest{
var UpdateWriteQueryTests = []WriteQueryTest{
{
WriteQuery: "UPDATE mytable SET s = 'updated';",
ExpectedWriteResult: []sql.Row{{NewUpdateResult(3, 3)}},
Expand Down Expand Up @@ -470,6 +470,109 @@ var UpdateTests = []WriteQueryTest{
},
}

var UpdateScriptTests = []ScriptTest{
{
Dialect: "mysql",
Name: "UPDATE join – single table, with FK constraint",
SetUpScript: []string{
"CREATE TABLE customers (id INT PRIMARY KEY, name TEXT);",
"CREATE TABLE orders (id INT PRIMARY KEY, customer_id INT, amount INT, FOREIGN KEY (customer_id) REFERENCES customers(id));",
"INSERT INTO customers VALUES (1, 'Alice'), (2, 'Bob');",
"INSERT INTO orders VALUES (101, 1, 50), (102, 2, 75);",
},
Assertions: []ScriptTestAssertion{
{
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
Skip: true,
Query: "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.customer_id = 123 where o.customer_id != 1;",
ExpectedErr: sql.ErrCheckConstraintViolated,
},
{
Query: "SELECT * FROM orders;",
Expected: []sql.Row{
{101, 1, 50}, {102, 2, 75},
},
},
},
},
{
Dialect: "mysql",
Name: "UPDATE join – multiple tables, with FK constraint",
SetUpScript: []string{
"CREATE TABLE parent1 (id INT PRIMARY KEY);",
"CREATE TABLE parent2 (id INT PRIMARY KEY);",
"CREATE TABLE child1 (id INT PRIMARY KEY, p1_id INT, FOREIGN KEY (p1_id) REFERENCES parent1(id));",
"CREATE TABLE child2 (id INT PRIMARY KEY, p2_id INT, FOREIGN KEY (p2_id) REFERENCES parent2(id));",
"INSERT INTO parent1 VALUES (1), (3);",
"INSERT INTO parent2 VALUES (1), (3);",
"INSERT INTO child1 VALUES (10, 1);",
"INSERT INTO child2 VALUES (20, 1);",
},
Assertions: []ScriptTestAssertion{
{
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
Skip: true,
Query: `UPDATE child1 c1
JOIN child2 c2 ON c1.id = 10 AND c2.id = 20
SET c1.p1_id = 999, c2.p2_id = 3;`,
ExpectedErr: sql.ErrForeignKeyChildViolation,
},
{
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
Skip: true,
Query: `UPDATE child1 c1
JOIN child2 c2 ON c1.id = 10 AND c2.id = 20
SET c1.p1_id = 3, c2.p2_id = 999;`,
ExpectedErr: sql.ErrForeignKeyChildViolation,
},
{
Query: "SELECT * FROM child1;",
Expected: []sql.Row{{10, 1}},
},
{
Query: "SELECT * FROM child2;",
Expected: []sql.Row{{20, 1}},
},
},
},
{
Dialect: "mysql",
Name: "UPDATE join – multiple tables, with trigger",
SetUpScript: []string{
"CREATE TABLE a (id INT PRIMARY KEY, x INT);",
"CREATE TABLE b (id INT PRIMARY KEY, y INT);",
"CREATE TABLE logbook (entry TEXT);",
`CREATE TRIGGER trig_a AFTER UPDATE ON a FOR EACH ROW
BEGIN
INSERT INTO logbook VALUES ('a updated');
END;`,
`CREATE TRIGGER trig_b AFTER UPDATE ON b FOR EACH ROW
BEGIN
INSERT INTO logbook VALUES ('b updated');
END;`,
"INSERT INTO a VALUES (5, 100);",
"INSERT INTO b VALUES (6, 200);",
},
Assertions: []ScriptTestAssertion{
{
Query: `UPDATE a
JOIN b ON a.id = 5 AND b.id = 6
SET a.x = 101, b.y = 201;`,
},
{
// TODO: UPDATE ... JOIN does not properly apply triggers when multiple tables are being updated,
// and will currently only apply triggers from one of the tables.
Skip: true,
Query: "SELECT * FROM logbook ORDER BY entry;",
Expected: []sql.Row{
{"a updated"},
{"b updated"},
},
},
},
},
}

var SpatialUpdateTests = []WriteQueryTest{
{
WriteQuery: "UPDATE point_table SET p = point(123.456,789);",
Expand Down