@@ -997,23 +997,16 @@ func convertToInt64(ctx context.Context, t NumberTypeImpl_, v interface{}) (int6
997
997
// StringType{}.Zero() returns empty string, but should represent "0" for number value
998
998
return 0 , sql .InRange , nil
999
999
}
1000
-
1001
- // Check if strict conversion mode is enabled (e.g., for JSON_TABLE ERROR ON ERROR )
1000
+
1001
+ // Check if strict mode is enabled via sql_mode (STRICT_TRANS_TABLES/STRICT_ALL_TABLES )
1002
1002
strictMode := false
1003
- if strictValue := ctx .Value (StrictConvertKey ); strictValue != nil {
1004
- if strict , ok := strictValue .(bool ); ok {
1005
- strictMode = strict
1006
- }
1007
- }
1008
- // Also check for string-based key (for schema validation)
1009
- if ! strictMode {
1010
- if strictValue := ctx .Value ("strict_convert" ); strictValue != nil {
1011
- if strict , ok := strictValue .(bool ); ok {
1012
- strictMode = strict
1013
- }
1014
- }
1003
+ if sqlCtx , ok := ctx .(* sql.Context ); ok && sqlCtx != nil {
1004
+ strictMode = sql .ValidateStrictMode (sqlCtx )
1015
1005
}
1016
-
1006
+
1007
+ // Note: IGNORE mode handling is done at the iterator level
1008
+ // rather than in individual type conversions for better separation of concerns
1009
+
1017
1010
// Parse first an integer, which allows for more values than float64
1018
1011
i , err := strconv .ParseInt (v , 10 , 64 )
1019
1012
if err == nil {
@@ -1022,26 +1015,24 @@ func convertToInt64(ctx context.Context, t NumberTypeImpl_, v interface{}) (int6
1022
1015
// If that fails, try as a float and truncate it to integral
1023
1016
f , err := strconv .ParseFloat (v , 64 )
1024
1017
if err != nil {
1025
- // In strict mode, return error instead of truncating
1026
- if strictMode {
1027
- return 0 , sql .OutOfRange , sql .ErrInvalidValue .New (originalV , "int" )
1028
- }
1029
-
1030
- // Use same truncation logic as float conversion for MySQL compatibility
1031
- s := numre .FindString (v )
1018
+ // Always try MySQL-compatible truncation first for arithmetic expressions
1019
+ s := numre .FindString (originalV )
1032
1020
if s != "" {
1033
- f , _ = strconv .ParseFloat (s , 64 )
1034
- f = math .Round (f )
1035
- // Generate warning for truncated string
1036
- if sqlCtx , ok := ctx .(* sql.Context ); ok && sqlCtx != nil {
1037
- sqlCtx .Warn (1366 , "Incorrect integer value: '%s' for column" , originalV )
1021
+ f , parseErr := strconv .ParseFloat (s , 64 )
1022
+ if parseErr == nil {
1023
+ f = math .Round (f )
1024
+ return int64 (f ), sql .InRange , nil
1038
1025
}
1039
- return int64 (f ), sql .InRange , nil
1040
1026
}
1041
- // If no valid number found, return 0 (MySQL behavior for pure non-numeric strings)
1042
- if sqlCtx , ok := ctx .(* sql.Context ); ok && sqlCtx != nil {
1043
- sqlCtx .Warn (1366 , "Incorrect integer value: '%s' for column" , originalV )
1027
+
1028
+ // For purely non-numeric strings like 'two', 'four', etc., return error
1029
+ // This allows Dolt's diff system to handle incompatible type conversions correctly
1030
+ // In strict mode, also return error for better schema validation
1031
+ if strictMode || s == "" {
1032
+ return 0 , sql .OutOfRange , sql .ErrInvalidValue .New (originalV , "int" )
1044
1033
}
1034
+
1035
+ // If no valid number found, return 0 (MySQL behavior for pure non-numeric strings)
1045
1036
return 0 , sql .InRange , nil
1046
1037
}
1047
1038
f = math .Round (f )
@@ -1547,23 +1538,16 @@ func convertToUint8(ctx context.Context, t NumberTypeImpl_, v interface{}) (uint
1547
1538
case string :
1548
1539
originalV := v
1549
1540
v = strings .Trim (v , intCutSet )
1550
-
1551
- // Check if strict conversion mode is enabled (e.g., for procedure parameter validation )
1541
+
1542
+ // Check if strict mode is enabled via sql_mode (STRICT_TRANS_TABLES/STRICT_ALL_TABLES )
1552
1543
strictMode := false
1553
- if strictValue := ctx .Value (StrictConvertKey ); strictValue != nil {
1554
- if strict , ok := strictValue .(bool ); ok {
1555
- strictMode = strict
1556
- }
1557
- }
1558
- // Also check for string-based key (for schema validation)
1559
- if ! strictMode {
1560
- if strictValue := ctx .Value ("strict_convert" ); strictValue != nil {
1561
- if strict , ok := strictValue .(bool ); ok {
1562
- strictMode = strict
1563
- }
1564
- }
1544
+ if sqlCtx , ok := ctx .(* sql.Context ); ok && sqlCtx != nil {
1545
+ strictMode = sql .ValidateStrictMode (sqlCtx )
1565
1546
}
1566
-
1547
+
1548
+ // Note: IGNORE mode handling is done at the iterator level
1549
+ // rather than in individual type conversions for better separation of concerns
1550
+
1567
1551
if i , err := strconv .ParseUint (v , 10 , 8 ); err == nil {
1568
1552
return uint8 (i ), sql .InRange , nil
1569
1553
}
@@ -1572,21 +1556,22 @@ func convertToUint8(ctx context.Context, t NumberTypeImpl_, v interface{}) (uint
1572
1556
return val , inRange , err
1573
1557
}
1574
1558
}
1575
-
1576
- // In strict mode, return error instead of truncating
1577
- if strictMode {
1578
- return 0 , sql .OutOfRange , sql .ErrInvalidValue .New (originalV , t .String ())
1579
- }
1580
-
1559
+
1581
1560
// Use same truncation logic as float conversion for MySQL compatibility
1582
- s := numre .FindString (v )
1561
+ s := numre .FindString (originalV )
1583
1562
if s != "" {
1584
1563
if f , err := strconv .ParseFloat (s , 64 ); err == nil {
1585
1564
if val , inRange , err := convertToUint8 (ctx , t , f ); err == nil {
1586
1565
return val , inRange , err
1587
1566
}
1588
1567
}
1589
1568
}
1569
+
1570
+ // In strict mode, return error instead of truncating for schema validation
1571
+ if strictMode {
1572
+ return 0 , sql .OutOfRange , sql .ErrInvalidValue .New (originalV , t .String ())
1573
+ }
1574
+
1590
1575
// If no valid number found, return 0 (MySQL behavior for pure non-numeric strings)
1591
1576
return 0 , sql .InRange , nil
1592
1577
case bool :
@@ -1639,38 +1624,34 @@ func convertToFloat64(ctx context.Context, t NumberTypeImpl_, v interface{}) (fl
1639
1624
}
1640
1625
return float64 (i ), nil
1641
1626
case string :
1642
- v = strings .Trim (v , numericCutSet )
1643
1627
originalV := v
1644
-
1645
- // Check if strict conversion mode is enabled (e.g., for schema validation)
1628
+ v = strings .Trim (v , numericCutSet )
1629
+
1630
+ // Check if strict mode is enabled via sql_mode (STRICT_TRANS_TABLES/STRICT_ALL_TABLES)
1646
1631
strictMode := false
1647
- if strictValue := ctx .Value (StrictConvertKey ); strictValue != nil {
1648
- if strict , ok := strictValue .(bool ); ok {
1649
- strictMode = strict
1650
- }
1632
+ if sqlCtx , ok := ctx .(* sql.Context ); ok && sqlCtx != nil {
1633
+ strictMode = sql .ValidateStrictMode (sqlCtx )
1651
1634
}
1652
- // Also check for string-based key (for schema validation)
1653
- if ! strictMode {
1654
- if strictValue := ctx .Value ("strict_convert" ); strictValue != nil {
1655
- if strict , ok := strictValue .(bool ); ok {
1656
- strictMode = strict
1657
- }
1658
- }
1659
- }
1660
-
1635
+
1636
+ // Note: IGNORE mode handling is done at the iterator level
1637
+ // rather than in individual type conversions for better separation of concerns
1638
+
1661
1639
i , err := strconv .ParseFloat (v , 64 )
1662
1640
if err != nil {
1663
- // In strict mode, return error instead of truncating
1641
+ // Always try MySQL-compatible truncation first for arithmetic expressions
1642
+ s := numre .FindString (originalV )
1643
+ if s != "" {
1644
+ f , parseErr := strconv .ParseFloat (s , 64 )
1645
+ if parseErr == nil {
1646
+ return f , nil
1647
+ }
1648
+ }
1649
+
1650
+ // In strict mode, return error instead of truncating for schema validation
1664
1651
if strictMode {
1665
1652
return 0 , sql .ErrInvalidValue .New (originalV , t .String ())
1666
1653
}
1667
-
1668
- // parse the first longest valid numbers
1669
- s := numre .FindString (v )
1670
- if s != "" {
1671
- i , _ = strconv .ParseFloat (s , 64 )
1672
- return i , nil
1673
- }
1654
+
1674
1655
// If no valid number found, return 0 (MySQL behavior for pure non-numeric strings)
1675
1656
return 0 , nil
1676
1657
}
0 commit comments