@@ -228,7 +228,7 @@ func (fkEditor *ForeignKeyEditor) OnUpdateSetNull(ctx *sql.Context, refActionDat
228
228
229
229
// Delete handles both the standard DELETE statement and propagated referential actions from a parent table's ON DELETE.
230
230
func (fkEditor * ForeignKeyEditor ) Delete (ctx * sql.Context , row sql.Row , depth int ) error {
231
- //TODO: may need to process some cascades after the update to avoid recursive violations, write some tests on this
231
+ // TODO: may need to process some cascades after the update to avoid recursive violations, write some tests on this
232
232
for _ , refActionData := range fkEditor .RefActions {
233
233
switch refActionData .ForeignKey .OnDelete {
234
234
default : // RESTRICT and friends
@@ -426,7 +426,7 @@ func (reference *ForeignKeyReferenceHandler) CheckReference(ctx *sql.Context, ro
426
426
return nil
427
427
}
428
428
}
429
-
429
+
430
430
return sql .ErrForeignKeyChildViolation .New (reference .ForeignKey .Name , reference .ForeignKey .Table ,
431
431
reference .ForeignKey .ParentTable , reference .RowMapper .GetKeyString (row ))
432
432
}
@@ -458,7 +458,7 @@ type ForeignKeyRowMapper struct {
458
458
Updater sql.ForeignKeyEditor
459
459
SourceSch sql.Schema
460
460
// TargetTypeConversions are a set of functions to transform the value in the table to the corresponding value in the
461
- // other table. This is required when the types of the two tables are compatible but different (e.g. INT and BIGINT).
461
+ // other table. This is required when the types of the two tables are compatible but different (e.g. INT and BIGINT).
462
462
TargetTypeConversions []ForeignKeyTypeConversionFn
463
463
// IndexPositions hold the mapping between an index's column position and the source row's column position. Given
464
464
// an index (x1, x2) and a source row (y1, y2, y3) and the relation (x1->y3, x2->y1), this slice would contain
@@ -486,18 +486,20 @@ func (mapper *ForeignKeyRowMapper) GetIter(ctx *sql.Context, row sql.Row, refChe
486
486
if rowVal == nil {
487
487
return sql .RowsToRowIter (), nil
488
488
}
489
-
489
+
490
490
targetType := mapper .SourceSch [rowPos ].Type
491
491
// Transform the type of the value in this row to the one in the other table for the index lookup, if necessary
492
492
if mapper .TargetTypeConversions != nil && mapper .TargetTypeConversions [rowPos ] != nil {
493
493
var err error
494
494
targetType , rowVal , err = mapper .TargetTypeConversions [rowPos ](ctx , rowVal )
495
- // TODO: possible for this to fail without error, which means the value cannot be found in the other table
495
+ // An error means the type conversion failed, which typically means there's no way to convert the value given to
496
+ // the target value because of e.g. range constraints (trying to assign an INT to a TINYINT column). We treat
497
+ // this as an empty result for this iterator, since this value cannot possibly be present in the other table.
496
498
if err != nil {
497
- return nil , err
499
+ return sql . RowsToRowIter (), nil
498
500
}
499
501
}
500
-
502
+
501
503
rang [rangPosition ] = sql .ClosedRangeColumnExpr (rowVal , rowVal , targetType )
502
504
}
503
505
for i , appendType := range mapper .AppendTypes {
@@ -507,7 +509,7 @@ func (mapper *ForeignKeyRowMapper) GetIter(ctx *sql.Context, row sql.Row, refChe
507
509
if ! mapper .Index .CanSupport (rang ) {
508
510
return nil , ErrInvalidLookupForIndexedTable .New (rang .DebugString ())
509
511
}
510
- //TODO: profile this, may need to redesign this or add a fast path
512
+ // TODO: profile this, may need to redesign this or add a fast path
511
513
lookup := sql.IndexLookup {Ranges : sql.MySQLRangeCollection {rang }, Index : mapper .Index }
512
514
513
515
editorData := mapper .Updater .IndexedAccess (lookup )
@@ -557,9 +559,10 @@ func GetChildParentMapping(parentSch sql.Schema, childSch sql.Schema, fkDef sql.
557
559
return mapping , nil
558
560
}
559
561
560
- // ForeignKeyTypeConversionDirection specifies whether a child column type is being converted to its parent type for
562
+ // ForeignKeyTypeConversionDirection specifies whether a child column type is being converted to its parent type for
561
563
// constraint enforcement, or vice versa.
562
564
type ForeignKeyTypeConversionDirection byte
565
+
563
566
const (
564
567
ChildToParent ForeignKeyTypeConversionDirection = iota
565
568
ParentToChild
@@ -569,17 +572,17 @@ const (
569
572
// enforcement. The target type is returned along with the transformed value, or an error if the transformation fails.
570
573
type ForeignKeyTypeConversionFn func (ctx * sql.Context , val any ) (sql.Type , any , error )
571
574
572
- // GetForeignKeyTypeConversions returns a set of functions to convert a type in a one foreign key column table to the
575
+ // GetForeignKeyTypeConversions returns a set of functions to convert a type in a one foreign key column table to the
573
576
// type in the corresponding table. Specify the schema of both child and parent tables, as well as whether the
574
577
// transformation is from child to parent or vice versa.
575
578
func GetForeignKeyTypeConversions (
576
- parentSch sql.Schema ,
577
- childSch sql.Schema ,
578
- fkDef sql.ForeignKeyConstraint ,
579
- direction ForeignKeyTypeConversionDirection ,
579
+ parentSch sql.Schema ,
580
+ childSch sql.Schema ,
581
+ fkDef sql.ForeignKeyConstraint ,
582
+ direction ForeignKeyTypeConversionDirection ,
580
583
) ([]ForeignKeyTypeConversionFn , error ) {
581
- var mapping []ForeignKeyTypeConversionFn
582
-
584
+ var convFns []ForeignKeyTypeConversionFn
585
+
583
586
for i := range fkDef .Columns {
584
587
childIndex := childSch .IndexOfColName (fkDef .Columns [i ])
585
588
if childIndex < 0 {
@@ -594,13 +597,13 @@ func GetForeignKeyTypeConversions(
594
597
595
598
childType := childSch [childIndex ].Type
596
599
parentType := parentSch [parentIndex ].Type
597
-
600
+
598
601
childExtendedType , _ := childType .(types.ExtendedType )
599
602
// if even one of the types is not an extended type, then we can't transform any values
600
603
if childExtendedType == nil {
601
604
return nil , nil
602
605
}
603
-
606
+
604
607
if ! childType .Equals (parentType ) {
605
608
parentExtendedType , _ := parentType .(types.ExtendedType )
606
609
if parentExtendedType == nil {
@@ -615,15 +618,15 @@ func GetForeignKeyTypeConversions(
615
618
toType = childExtendedType
616
619
}
617
620
618
- if mapping == nil {
619
- mapping = make ([]ForeignKeyTypeConversionFn , len (childSch ))
621
+ if convFns == nil {
622
+ convFns = make ([]ForeignKeyTypeConversionFn , len (childSch ))
620
623
}
621
- mapping [childIndex ] = func (ctx * sql.Context , val any ) (sql.Type , any , error ) {
624
+ convFns [childIndex ] = func (ctx * sql.Context , val any ) (sql.Type , any , error ) {
622
625
convertedVal , err := toType .ConvertToType (ctx , fromType , val )
623
626
return toType , convertedVal , err
624
627
}
625
628
}
626
629
}
627
-
628
- return mapping , nil
630
+
631
+ return convFns , nil
629
632
}
0 commit comments