CheckModifyTypeCompatible checks whether changes column type to another is compatible and can be changed. If types are compatible and can be directly changed, nil err will be returned; otherwise the types are incompatible. There are two cases when types incompatible: 1. returned canReorg == true: ty
(origin *FieldType, to *FieldType)
| 1471 | // 1. returned canReorg == true: types can be changed by reorg |
| 1472 | // 2. returned canReorg == false: type change not supported yet |
| 1473 | func CheckModifyTypeCompatible(origin *FieldType, to *FieldType) (canReorg bool, err error) { |
| 1474 | // Deal with the same type. |
| 1475 | if origin.GetType() == to.GetType() { |
| 1476 | if origin.GetType() == mysql.TypeEnum || origin.GetType() == mysql.TypeSet { |
| 1477 | typeVar := "set" |
| 1478 | if origin.GetType() == mysql.TypeEnum { |
| 1479 | typeVar = "enum" |
| 1480 | } |
| 1481 | if len(to.GetElems()) < len(origin.GetElems()) { |
| 1482 | msg := fmt.Sprintf("the number of %s column's elements is less than the original: %d", typeVar, len(origin.GetElems())) |
| 1483 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(msg) |
| 1484 | } |
| 1485 | for index, originElem := range origin.GetElems() { |
| 1486 | toElem := to.GetElems()[index] |
| 1487 | if originElem != toElem { |
| 1488 | msg := fmt.Sprintf("cannot modify %s column value %s to %s", typeVar, originElem, toElem) |
| 1489 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(msg) |
| 1490 | } |
| 1491 | } |
| 1492 | } |
| 1493 | |
| 1494 | if origin.GetType() == mysql.TypeNewDecimal { |
| 1495 | // Floating-point and fixed-point types also can be UNSIGNED. As with integer types, this attribute prevents |
| 1496 | // negative values from being stored in the column. Unlike the integer types, the upper range of column values |
| 1497 | // remains the same. |
| 1498 | if to.GetFlen() != origin.GetFlen() || to.GetDecimal() != origin.GetDecimal() || mysql.HasUnsignedFlag(to.GetFlag()) != mysql.HasUnsignedFlag(origin.GetFlag()) { |
| 1499 | msg := fmt.Sprintf("decimal change from decimal(%d, %d) to decimal(%d, %d)", origin.GetFlen(), origin.GetDecimal(), to.GetFlen(), to.GetDecimal()) |
| 1500 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(msg) |
| 1501 | } |
| 1502 | } |
| 1503 | |
| 1504 | needReorg, reason := needReorgToChange(origin, to) |
| 1505 | if !needReorg { |
| 1506 | return false, nil |
| 1507 | } |
| 1508 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(reason) |
| 1509 | } |
| 1510 | |
| 1511 | // Deal with the different type. |
| 1512 | if !checkTypeChangeSupported(origin, to) { |
| 1513 | unsupportedMsg := fmt.Sprintf("change from original type %v to %v is currently unsupported yet", origin.CompactStr(), to.CompactStr()) |
| 1514 | return false, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(unsupportedMsg) |
| 1515 | } |
| 1516 | |
| 1517 | // Check if different type can directly convert and no need to reorg. |
| 1518 | stringToString := IsString(origin.GetType()) && IsString(to.GetType()) |
| 1519 | integerToInteger := mysql.IsIntegerType(origin.GetType()) && mysql.IsIntegerType(to.GetType()) |
| 1520 | if stringToString || integerToInteger { |
| 1521 | needReorg, reason := needReorgToChange(origin, to) |
| 1522 | if !needReorg { |
| 1523 | return false, nil |
| 1524 | } |
| 1525 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(reason) |
| 1526 | } |
| 1527 | |
| 1528 | notCompatibleMsg := fmt.Sprintf("type %v not match origin %v", to.CompactStr(), origin.CompactStr()) |
| 1529 | return true, dbterror.ErrUnsupportedModifyColumn.GenWithStackByArgs(notCompatibleMsg) |
| 1530 | } |
no test coverage detected
searching dependent graphs…