Added validation that FKs referencing system tables don't specify referential actions

This commit is contained in:
Jason Fulghum
2025-09-15 13:11:21 -07:00
parent b0f06a49e0
commit 472e8ff7a9
2 changed files with 45 additions and 0 deletions
@@ -2791,6 +2791,35 @@ var BranchesSystemTableTests = []queries.ScriptTest{
},
},
},
{
Name: "foreign keys referencing dolt_branches cannot use referential actions",
SetUpScript: []string{
"CREATE TABLE ext_branch_metadata(branch_name varchar(300) primary key, owner varchar(255));",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "ALTER TABLE ext_branch_metadata ADD CONSTRAINT fk123 FOREIGN KEY (branch_name) REFERENCES dolt_branches(name) ON DELETE CASCADE;",
ExpectedErrStr: "foreign keys referencing Dolt system tables do not support referential actions",
},
{
Query: "ALTER TABLE ext_branch_metadata ADD CONSTRAINT fk123 FOREIGN KEY (branch_name) REFERENCES dolt_branches(name) ON UPDATE CASCADE;",
ExpectedErrStr: "foreign keys referencing Dolt system tables do not support referential actions",
},
{
Query: "ALTER TABLE ext_branch_metadata ADD CONSTRAINT fk123 FOREIGN KEY (branch_name) REFERENCES dolt_branches(name) ON DELETE RESTRICT;",
ExpectedErrStr: "foreign keys referencing Dolt system tables do not support referential actions",
},
{
Query: "ALTER TABLE ext_branch_metadata ADD CONSTRAINT fk123 FOREIGN KEY (branch_name) REFERENCES dolt_branches(name) ON UPDATE RESTRICT;",
ExpectedErrStr: "foreign keys referencing Dolt system tables do not support referential actions",
},
{
// Explicitly using "NO ACTION" is allowed
Query: "ALTER TABLE ext_branch_metadata ADD CONSTRAINT fk123 FOREIGN KEY (branch_name) REFERENCES dolt_branches(name) ON DELETE NO ACTION ON UPDATE NO ACTION;",
Expected: []sql.Row{{types.NewOkResult(0)}},
},
},
},
{
Name: "dolt_branches.name index",
SetUpScript: []string{
+16
View File
@@ -2658,6 +2658,22 @@ func (t *WritableDoltTable) createForeignKey(
return doltdb.ForeignKey{}, err
}
} else {
// FKs referencing system tables, like dolt_branches, that are not backed by a real
// Dolt table, do not currently allow non-default referential actions. Other system
// tables, like the dolt_ci_ system tables, are backed by dolt tables and rely on
// referential actions to work properly.
if !strings.HasPrefix(strings.ToLower(sqlFk.ParentTable), "dolt_ci_") {
if sqlFk.OnDelete != sql.ForeignKeyReferentialAction_NoAction &&
sqlFk.OnDelete != sql.ForeignKeyReferentialAction_DefaultAction {
return doltdb.ForeignKey{}, fmt.Errorf(
"foreign keys referencing Dolt system tables do not support referential actions")
} else if sqlFk.OnUpdate != sql.ForeignKeyReferentialAction_NoAction &&
sqlFk.OnUpdate != sql.ForeignKeyReferentialAction_DefaultAction {
return doltdb.ForeignKey{}, fmt.Errorf(
"foreign keys referencing Dolt system tables do not support referential actions")
}
}
sqlRefTbl, ok, err := t.db.GetTableInsensitive(ctx, sqlFk.ParentTable)
if err != nil {
return doltdb.ForeignKey{}, err