@@ -644,74 +644,50 @@ 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- 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- // MySQL allows mixed string types in foreign key constraints:
674- // - CHAR can reference VARCHAR and vice versa
675- // - BINARY can reference VARBINARY and vice versa
676- if compatibleStringTypes (type1 , type2 ) {
677- type1String := type1 .(sql.StringType )
678- type2String := type2 .(sql.StringType )
679- if type1String .Collation ().CharacterSet () != type2String .Collation ().CharacterSet () {
680- return false
681- }
682- } else {
683- return false
684- }
685- }
647+ if type1 .Equals (type2 ) {
648+ return true
686649 }
687- return true
688- }
689650
690- // compatibleStringTypes checks if two different string types are compatible for foreign key constraints.
691- // MySQL allows mixed string types within the same category:
692- // - Character types: CHAR and VARCHAR
693- // - Binary types: BINARY and VARBINARY
694- func compatibleStringTypes (type1 sql.Type , type2 sql.Type ) bool {
695- if type1 == nil || type2 == nil {
696- return false
697- }
698-
699651 t1 := type1 .Type ()
700652 t2 := type2 .Type ()
701-
702- // Check if both are character string types (CHAR/VARCHAR)
703- if (t1 == sqltypes .Char || t1 == sqltypes .VarChar ) && (t2 == sqltypes .Char || t2 == sqltypes .VarChar ) {
704- 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+ case sqltypes .Set :
672+ // MySQL allows set foreign keys to match based on underlying numeric values.
673+ return true
674+ default :
675+ return false
676+ }
705677 }
706-
707- // Check if both are binary string types (BINARY/VARBINARY)
708- if (t1 == sqltypes .Binary || t1 == sqltypes .VarBinary ) && (t2 == sqltypes .Binary || t2 == sqltypes .VarBinary ) {
709- return true
678+
679+ // Mixed string types: CHAR/VARCHAR or BINARY/VARBINARY
680+ if ((t1 == sqltypes .Char || t1 == sqltypes .VarChar ) && (t2 == sqltypes .Char || t2 == sqltypes .VarChar )) ||
681+ ((t1 == sqltypes .Binary || t1 == sqltypes .VarBinary ) && (t2 == sqltypes .Binary || t2 == sqltypes .VarBinary )) {
682+ type1String := type1 .(sql.StringType )
683+ type2String := type2 .(sql.StringType )
684+ return type1String .Collation ().CharacterSet () == type2String .Collation ().CharacterSet ()
710685 }
711-
686+
712687 return false
713688}
714689
690+
715691// exprsAreIndexPrefix returns whether the given expressions are a prefix of the given index expressions
716692func exprsAreIndexPrefix (exprs , indexExprs []string ) bool {
717693 if len (exprs ) > len (indexExprs ) {
0 commit comments