@@ -644,36 +644,40 @@ func FindFKIndexWithPrefix(ctx *sql.Context, tbl sql.IndexAddressableTable, pref
644
644
// foreignKeyComparableTypes returns whether the two given types are able to be used as parent/child columns in a
645
645
// foreign key.
646
646
func foreignKeyComparableTypes (ctx * sql.Context , type1 sql.Type , type2 sql.Type ) bool {
647
- if ! type1 .Equals (type2 ) {
648
- // There seems to be a special case where CHAR/VARCHAR/BINARY/VARBINARY can have unequal lengths.
649
- // Have not tested every type nor combination, but this seems specific to those 4 types.
650
- if type1 .Type () == type2 .Type () {
651
- switch type1 .Type () {
652
- case sqltypes .Char , sqltypes .VarChar , sqltypes .Binary , sqltypes .VarBinary :
653
- type1String := type1 .(sql.StringType )
654
- type2String := type2 .(sql.StringType )
655
- if type1String .Collation ().CharacterSet () != type2String .Collation ().CharacterSet () {
656
- return false
657
- }
658
- case sqltypes .Enum :
659
- // Enum types can reference each other in foreign keys regardless of their string values.
660
- // MySQL allows enum foreign keys to match based on underlying numeric values.
661
- return true
662
- case sqltypes .Decimal :
663
- // MySQL allows decimal foreign keys with different precision/scale
664
- // The foreign key constraint validation will handle the actual value comparison
665
- return true
666
- case sqltypes .Set :
667
- // MySQL allows set foreign keys to match based on underlying numeric values.
668
- return true
669
- default :
670
- return false
671
- }
672
- } else {
673
- return false
647
+ if type1 .Equals (type2 ) {
648
+ return true
649
+ }
650
+
651
+ t1 := type1 .Type ()
652
+ t2 := type2 .Type ()
653
+
654
+ // Handle same-type cases for special types
655
+ if t1 == t2 {
656
+ switch t1 {
657
+ case sqltypes .Enum :
658
+ // Enum types can reference each other in foreign keys regardless of their string values.
659
+ // MySQL allows enum foreign keys to match based on underlying numeric values.
660
+ return true
661
+ case sqltypes .Decimal :
662
+ // MySQL allows decimal foreign keys with different precision/scale
663
+ // The foreign key constraint validation will handle the actual value comparison
664
+ return true
665
+ case sqltypes .Set :
666
+ // MySQL allows set foreign keys to match based on underlying numeric values.
667
+ return true
674
668
}
675
669
}
676
- return true
670
+
671
+ // Handle string types (both same-type with different lengths and mixed types)
672
+ if (types .IsTextOnly (type1 ) && types .IsTextOnly (type2 )) ||
673
+ (types .IsBinaryType (type1 ) && types .IsBinaryType (type2 )) {
674
+ // String types must have matching character sets
675
+ type1String := type1 .(sql.StringType )
676
+ type2String := type2 .(sql.StringType )
677
+ return type1String .Collation ().CharacterSet () == type2String .Collation ().CharacterSet ()
678
+ }
679
+
680
+ return false
677
681
}
678
682
679
683
// exprsAreIndexPrefix returns whether the given expressions are a prefix of the given index expressions
0 commit comments