Skip to content

Commit 68264f3

Browse files
committed
amend to existing patterns
1 parent f4895ed commit 68264f3

File tree

3 files changed

+24
-17
lines changed

3 files changed

+24
-17
lines changed

enginetest/queries/script_queries.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10538,7 +10538,7 @@ where
1053810538
},
1053910539
{
1054010540
Query: "insert into child_dec_4_1 values (78.9);",
10541-
ExpectedErr: sql.ErrForeignKeyChildViolationMySQL845,
10541+
ExpectedErr: sql.ErrForeignKeyChildViolation,
1054210542
},
1054310543

1054410544
{
@@ -10561,7 +10561,7 @@ where
1056110561
},
1056210562
{
1056310563
Query: "insert into child_dec_65_30 values (1.23);",
10564-
ExpectedErr: sql.ErrForeignKeyChildViolationMySQL845,
10564+
ExpectedErr: sql.ErrForeignKeyChildViolation,
1056510565
},
1056610566
{
1056710567
Query: "insert into child_dec_4_2 values (99.99);",

sql/errors.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,7 @@ var (
419419
ErrInsertIntoNonNullableProvidedNull = errors.NewKind("column name '%v' is non-nullable but attempted to set a value of null")
420420

421421
// ErrForeignKeyChildViolation is called when a rows is added but there is no parent row, and a foreign key constraint fails. Add the parent row first.
422-
ErrForeignKeyChildViolation = errors.NewKind("cannot add or update a child row - Foreign key violation on fk: `%s`, table: `%s`, referenced table: `%s`, key: `%s`")
423-
ErrForeignKeyChildViolationMySQL845 = errors.NewKind("cannot add or update a child row: a foreign key constraint fails (`%s`.`%s`, CONSTRAINT `%s` FOREIGN KEY (`%s`) REFERENCES `%s` (`%s`))")
422+
ErrForeignKeyChildViolation = errors.NewKind("cannot add or update a child row - Foreign key violation on fk: `%s`, table: `%s`, referenced table: `%s`, key: `%s`")
424423

425424
// ErrForeignKeyParentViolation is called when a parent row that is deleted has children, and a foreign key constraint fails. Delete the children first.
426425
ErrForeignKeyParentViolation = errors.NewKind("cannot delete or update a parent row - Foreign key violation on fk: `%s`, table: `%s`, referenced table: `%s`, key: `%s`")
@@ -982,7 +981,6 @@ func CastSQLError(err error) *mysql.SQLError {
982981
code = mysql.ERDupEntry
983982
case ErrPartitionNotFound.Is(err):
984983
code = 1526 // TODO: Needs to be added to vitess
985-
case ErrForeignKeyChildViolationMySQL845.Is(err):
986984
case ErrForeignKeyChildViolation.Is(err):
987985
code = mysql.ErNoReferencedRow2 // test with mysql returns 1452 vs 1216
988986
case ErrForeignKeyParentViolation.Is(err):

sql/plan/foreign_key_editor.go

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -512,11 +512,9 @@ func (reference *ForeignKeyReferenceHandler) CheckReference(ctx *sql.Context, ro
512512
return err
513513
}
514514
if err == nil {
515-
// We have a parent row, but for DECIMAL types we need to be strict about precision/scale
516-
if shouldReject := reference.validateDecimalMatch(); shouldReject {
517-
return sql.ErrForeignKeyChildViolationMySQL845.New(reference.ForeignKey.Database, reference.ForeignKey.Table,
518-
reference.ForeignKey.Name, strings.Join(reference.ForeignKey.Columns, ", "),
519-
reference.ForeignKey.ParentTable, strings.Join(reference.ForeignKey.ParentColumns, ", "))
515+
// We have a parent row, but check for type-specific validation
516+
if validationErr := reference.validateDecimalConstraints(row); validationErr != nil {
517+
return validationErr
520518
}
521519
// We have a parent row so throw no error
522520
return nil
@@ -545,23 +543,34 @@ func (reference *ForeignKeyReferenceHandler) CheckReference(ctx *sql.Context, ro
545543
reference.ForeignKey.ParentTable, reference.RowMapper.GetKeyString(row))
546544
}
547545

548-
func (reference *ForeignKeyReferenceHandler) validateDecimalMatch() bool {
546+
// validateDecimalConstraints checks that decimal foreign key columns have compatible scales.
547+
func (reference *ForeignKeyReferenceHandler) validateDecimalConstraints(row sql.Row) error {
549548
if reference.RowMapper.Index == nil {
550-
return false
549+
return nil
551550
}
551+
552552
indexColumnTypes := reference.RowMapper.Index.ColumnExpressionTypes()
553553
for i := range reference.ForeignKey.Columns {
554554
if i >= len(indexColumnTypes) {
555555
continue
556556
}
557+
557558
childColIdx := reference.RowMapper.IndexPositions[i]
558-
childDecimal, childOk := reference.RowMapper.SourceSch[childColIdx].Type.(sql.DecimalType)
559-
parentDecimal, parentOk := indexColumnTypes[i].Type.(sql.DecimalType)
560-
if childOk && parentOk && childDecimal.Scale() != parentDecimal.Scale() {
561-
return true
559+
childType := reference.RowMapper.SourceSch[childColIdx].Type
560+
parentType := indexColumnTypes[i].Type
561+
562+
// For decimal types, check scale compatibility (following existing pattern for type-specific validation)
563+
if childDecimal, ok := childType.(sql.DecimalType); ok {
564+
if parentDecimal, ok := parentType.(sql.DecimalType); ok {
565+
if childDecimal.Scale() != parentDecimal.Scale() {
566+
return sql.ErrForeignKeyChildViolation.New(reference.ForeignKey.Name, reference.ForeignKey.Table,
567+
reference.ForeignKey.ParentTable, reference.RowMapper.GetKeyString(row))
568+
}
569+
}
562570
}
563571
}
564-
return false
572+
573+
return nil
565574
}
566575

567576
// CheckTable checks that every row in the table has an index entry in the referenced table.

0 commit comments

Comments
 (0)