@@ -644,71 +644,47 @@ func FindFKIndexWithPrefix(ctx *sql.Context, tbl sql.IndexAddressableTable, pref
644644// foreignKeyComparableTypes returns whether the two given types are able to be used as parent/child columns in a
645645// foreign key.
646646func 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- default :
667- return false
668- }
669- } else {
670- // MySQL allows mixed string types in foreign key constraints:
671- // - CHAR can reference VARCHAR and vice versa
672- // - BINARY can reference VARBINARY and vice versa
673- if compatibleStringTypes (type1 , type2 ) {
674- type1String := type1 .(sql.StringType )
675- type2String := type2 .(sql.StringType )
676- if type1String .Collation ().CharacterSet () != type2String .Collation ().CharacterSet () {
677- return false
678- }
679- } else {
680- return false
681- }
682- }
647+ if type1 .Equals (type2 ) {
648+ return true
683649 }
684- return true
685- }
686650
687- // compatibleStringTypes checks if two different string types are compatible for foreign key constraints.
688- // MySQL allows mixed string types within the same category:
689- // - Character types: CHAR and VARCHAR
690- // - Binary types: BINARY and VARBINARY
691- func compatibleStringTypes (type1 sql.Type , type2 sql.Type ) bool {
692- if type1 == nil || type2 == nil {
693- return false
694- }
695-
696651 t1 := type1 .Type ()
697652 t2 := type2 .Type ()
698-
699- // Check if both are character string types (CHAR/VARCHAR)
700- if (t1 == sqltypes .Char || t1 == sqltypes .VarChar ) && (t2 == sqltypes .Char || t2 == sqltypes .VarChar ) {
701- return true
653+
654+ // Same type with different parameters
655+ if t1 == t2 {
656+ switch t1 {
657+ case sqltypes .Char , sqltypes .VarChar , sqltypes .Binary , sqltypes .VarBinary :
658+ // There seems to be a special case where CHAR/VARCHAR/BINARY/VARBINARY can have unequal lengths.
659+ // Have not tested every type nor combination, but this seems specific to those 4 types.
660+ type1String := type1 .(sql.StringType )
661+ type2String := type2 .(sql.StringType )
662+ return type1String .Collation ().CharacterSet () == type2String .Collation ().CharacterSet ()
663+ case sqltypes .Enum :
664+ // Enum types can reference each other in foreign keys regardless of their string values.
665+ // MySQL allows enum foreign keys to match based on underlying numeric values.
666+ return true
667+ case sqltypes .Decimal :
668+ // MySQL allows decimal foreign keys with different precision/scale
669+ // The foreign key constraint validation will handle the actual value comparison
670+ return true
671+ default :
672+ return false
673+ }
702674 }
703-
704- // Check if both are binary string types (BINARY/VARBINARY)
705- if (t1 == sqltypes .Binary || t1 == sqltypes .VarBinary ) && (t2 == sqltypes .Binary || t2 == sqltypes .VarBinary ) {
706- return true
675+
676+ // Mixed string types: CHAR/VARCHAR or BINARY/VARBINARY
677+ if ((t1 == sqltypes .Char || t1 == sqltypes .VarChar ) && (t2 == sqltypes .Char || t2 == sqltypes .VarChar )) ||
678+ ((t1 == sqltypes .Binary || t1 == sqltypes .VarBinary ) && (t2 == sqltypes .Binary || t2 == sqltypes .VarBinary )) {
679+ type1String := type1 .(sql.StringType )
680+ type2String := type2 .(sql.StringType )
681+ return type1String .Collation ().CharacterSet () == type2String .Collation ().CharacterSet ()
707682 }
708-
683+
709684 return false
710685}
711686
687+
712688// exprsAreIndexPrefix returns whether the given expressions are a prefix of the given index expressions
713689func exprsAreIndexPrefix (exprs , indexExprs []string ) bool {
714690 if len (exprs ) > len (indexExprs ) {
0 commit comments