@@ -402,14 +402,14 @@ func TestStringSQL_InvalidUTF8Handling(t *testing.T) {
402402 name : "Issue #8893 exact scenario - DoltLab with latin1 ® (0xAE)" ,
403403 typ : Text ,
404404 input : []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }, // "DoltLab" + 0xAE
405- expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
405+ expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
406406 expectError : false ,
407407 },
408408 {
409409 name : "Multiple invalid UTF-8 bytes" ,
410410 typ : Text ,
411411 input : []byte {0x48 , 0x65 , 0x6C , 0x6C , 0x6F , 0x98 , 0x76 , 0x54 }, // "Hello" + invalid bytes
412- expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
412+ expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
413413 expectError : false ,
414414 },
415415 {
@@ -430,29 +430,29 @@ func TestStringSQL_InvalidUTF8Handling(t *testing.T) {
430430 name : "VARCHAR with invalid UTF-8" ,
431431 typ : MustCreateStringWithDefaults (sqltypes .VarChar , 100 ),
432432 input : []byte {0x54 , 0x65 , 0x73 , 0x74 , 0xAE , 0x98 }, // "Test" + invalid bytes
433- expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
433+ expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
434434 expectError : false ,
435435 },
436436 {
437437 name : "CHAR with invalid UTF-8" ,
438438 typ : MustCreateStringWithDefaults (sqltypes .Char , 100 ),
439439 input : []byte {0x41 , 0x42 , 0x43 , 0xAE }, // "ABC" + invalid byte
440- expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
440+ expected : "" , // Should return NULL for invalid UTF-8 (matches MySQL behavior)
441441 expectError : false ,
442442 },
443443 }
444444
445445 for _ , test := range tests {
446446 t .Run (test .name , func (t * testing.T ) {
447447 result , err := test .typ .SQL (ctx , nil , test .input )
448-
448+
449449 if test .expectError {
450450 assert .Error (t , err )
451451 } else {
452452 require .NoError (t , err )
453- if test .expected == "" && (test .name == "Issue #8893 exact scenario - DoltLab with latin1 ® (0xAE)" ||
454- test .name == "Multiple invalid UTF-8 bytes" ||
455- test .name == "VARCHAR with invalid UTF-8" ||
453+ if test .expected == "" && (test .name == "Issue #8893 exact scenario - DoltLab with latin1 ® (0xAE)" ||
454+ test .name == "Multiple invalid UTF-8 bytes" ||
455+ test .name == "VARCHAR with invalid UTF-8" ||
456456 test .name == "CHAR with invalid UTF-8" ) {
457457 // For invalid UTF-8 cases, we expect NULL (which returns empty string but is actually NULL)
458458 assert .True (t , result .IsNull (), "Expected NULL for invalid UTF-8" )
@@ -469,35 +469,35 @@ func TestStringSQL_InvalidUTF8Handling(t *testing.T) {
469469// This verifies the MySQL-compatible behavior required for issue dolthub/dolt#8893.
470470func TestStringSQL_StrictConvertValidation (t * testing.T ) {
471471 ctx := sql .NewEmptyContext ()
472-
472+
473473 // The exact invalid UTF-8 data from issue #8893
474474 invalidUTF8 := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE } // "DoltLab" + 0xAE
475-
475+
476476 stringType := Text
477-
477+
478478 // Test 1: Convert should now accept invalid UTF-8 and return NULL (matches MySQL INSERT behavior)
479479 t .Run ("Convert should accept invalid UTF-8 and return NULL for INSERT operations" , func (t * testing.T ) {
480480 result , _ , err := stringType .Convert (ctx , string (invalidUTF8 ))
481481 require .NoError (t , err )
482482 assert .Nil (t , result , "Expected NULL for invalid UTF-8 in Convert (matches MySQL)" )
483483 })
484-
484+
485485 // Test 2: SQL should accept invalid UTF-8 and return NULL (permissive for SELECT, matches MySQL)
486486 t .Run ("SQL should accept invalid UTF-8 for SELECT operations" , func (t * testing.T ) {
487487 result , err := stringType .SQL (ctx , nil , invalidUTF8 )
488488 require .NoError (t , err )
489489 assert .True (t , result .IsNull (), "Expected NULL for invalid UTF-8 (matches MySQL behavior)" )
490490 })
491-
491+
492492 // Test 3: Valid UTF-8 should work in both cases
493493 t .Run ("Valid UTF-8 should work in both Convert and SQL" , func (t * testing.T ) {
494494 validUTF8 := []byte ("DoltLab®" ) // Proper UTF-8
495-
495+
496496 // Convert should work
497497 converted , _ , err := stringType .Convert (ctx , string (validUTF8 ))
498498 require .NoError (t , err )
499499 assert .Equal (t , "DoltLab®" , converted )
500-
500+
501501 // SQL should work
502502 result , err := stringType .SQL (ctx , nil , validUTF8 )
503503 require .NoError (t , err )
@@ -509,61 +509,61 @@ func TestStringSQL_StrictConvertValidation(t *testing.T) {
509509// described in issue dolthub/dolt#8893 to ensure MySQL-compatible behavior.
510510func TestStringSQL_CustomerWorkflow_Issue8893 (t * testing.T ) {
511511 ctx := sql .NewEmptyContext ()
512-
512+
513513 // Customer's exact problematic data: "DoltLab®" with latin1 ® (0xAE)
514514 customerData := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }
515515 textType := Text
516-
516+
517517 t .Run ("Customer Scenario 1: Basic SELECT that was failing" , func (t * testing.T ) {
518518 // Customer reported: SELECT name FROM Products; threw "invalid string for charset utf8mb4"
519519 // After fix: Should return NULL instead of error
520520 result , err := textType .SQL (ctx , nil , customerData )
521521 require .NoError (t , err , "Customer's basic SELECT should not throw errors" )
522522 assert .True (t , result .IsNull (), "Should return NULL for invalid UTF-8 (matches MySQL)" )
523523 })
524-
524+
525525 t .Run ("Customer Scenario 2: INSERT with problematic data" , func (t * testing.T ) {
526526 // Customer had existing data that was problematic
527527 // Our fix should allow INSERT operations to complete with NULL values
528528 convertResult , _ , err := textType .Convert (ctx , string (customerData ))
529529 require .NoError (t , err , "INSERT operations should not fail" )
530530 assert .Nil (t , convertResult , "Should insert NULL for invalid UTF-8 (matches MySQL)" )
531531 })
532-
532+
533533 t .Run ("Customer Scenario 3: Data identification queries" , func (t * testing.T ) {
534534 // Customer needs to identify problematic records with WHERE clauses
535535 // Test that NULL values work properly in comparisons
536536 result , err := textType .SQL (ctx , nil , customerData )
537537 require .NoError (t , err )
538-
538+
539539 // Simulate: SELECT * FROM Products WHERE name IS NULL;
540540 assert .True (t , result .IsNull (), "NULL values should be identifiable with IS NULL" )
541-
542- // Simulate: SELECT * FROM Products WHERE name IS NOT NULL;
541+
542+ // Simulate: SELECT * FROM Products WHERE name IS NOT NULL;
543543 validData := []byte ("ValidProduct" )
544544 validResult , err := textType .SQL (ctx , nil , validData )
545545 require .NoError (t , err )
546546 assert .False (t , validResult .IsNull (), "Valid data should not be NULL" )
547547 })
548-
548+
549549 t .Run ("Customer Scenario 4: Mixed valid and invalid data" , func (t * testing.T ) {
550550 // Customer's table had mix of valid and invalid data
551551 testCases := []struct {
552- name string
553- data []byte
554- isValid bool
552+ name string
553+ data []byte
554+ isValid bool
555555 }{
556556 {"Valid product name" , []byte ("ValidProduct" ), true },
557557 {"Customer's problematic data" , customerData , false },
558558 {"Another valid name" , []byte ("AnotherProduct®" ), true }, // Proper UTF-8 ®
559559 {"Different invalid UTF-8" , []byte {0x48 , 0x65 , 0x6C , 0x6C , 0x6F , 0x98 }, false },
560560 }
561-
561+
562562 for _ , tc := range testCases {
563563 t .Run (tc .name , func (t * testing.T ) {
564564 result , err := textType .SQL (ctx , nil , tc .data )
565565 require .NoError (t , err , "No queries should fail regardless of data validity" )
566-
566+
567567 if tc .isValid {
568568 assert .False (t , result .IsNull (), "Valid UTF-8 should not return NULL" )
569569 assert .Equal (t , string (tc .data ), result .ToString ())
@@ -573,23 +573,23 @@ func TestStringSQL_CustomerWorkflow_Issue8893(t *testing.T) {
573573 })
574574 }
575575 })
576-
576+
577577 t .Run ("Customer Scenario 5: Export/cleanup operations" , func (t * testing.T ) {
578578 // Customer wanted to export data and re-import with proper encoding
579579 // All SELECT operations should work without throwing errors
580-
580+
581581 // Simulate customer's export query that was failing
582582 problemData := [][]byte {
583- customerData , // Original issue
584- {0x48 , 0x65 , 0x6C , 0x6C , 0x6F , 0x98 , 0x76 , 0x54 }, // Other invalid UTF-8
585- {0x54 , 0x65 , 0x73 , 0x74 , 0xAE , 0x98 }, // Multiple invalid bytes
583+ customerData , // Original issue
584+ {0x48 , 0x65 , 0x6C , 0x6C , 0x6F , 0x98 , 0x76 , 0x54 }, // Other invalid UTF-8
585+ {0x54 , 0x65 , 0x73 , 0x74 , 0xAE , 0x98 }, // Multiple invalid bytes
586586 }
587-
587+
588588 for i , data := range problemData {
589589 t .Run (fmt .Sprintf ("Export query %d" , i + 1 ), func (t * testing.T ) {
590590 result , err := textType .SQL (ctx , nil , data )
591591 require .NoError (t , err , "Export queries must not fail" )
592-
592+
593593 // Customer can now identify records that need fixing
594594 if result .IsNull () {
595595 // This record needs attention in the re-import
@@ -604,76 +604,76 @@ func TestStringSQL_CustomerWorkflow_Issue8893(t *testing.T) {
604604// for the specific scenarios in issue dolthub/dolt#8893.
605605func TestStringSQL_MySQLCompatibility_Issue8893 (t * testing.T ) {
606606 ctx := sql .NewEmptyContext ()
607-
607+
608608 t .Run ("MySQL VARBINARY behavior comparison" , func (t * testing.T ) {
609609 // Test data: 0x446F6C744C6162AE (DoltLab + latin1 ®)
610610 varbinaryData := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }
611-
611+
612612 // MySQL behavior for VARBINARY with invalid UTF-8:
613613 // - Basic SELECT: Shows "DoltLab�" (replacement character in display)
614614 // - This is handled at the display level, our SQL function should return the data
615615 binaryType := LongBlob // Binary type should pass through unchanged
616616 result , err := binaryType .SQL (ctx , nil , varbinaryData )
617617 require .NoError (t , err )
618618 assert .False (t , result .IsNull (), "Binary data should pass through unchanged" )
619-
619+
620620 // The display shows replacement character, but the data itself is preserved
621621 resultBytes := []byte (result .ToString ())
622622 assert .Equal (t , varbinaryData , resultBytes , "Binary data should be preserved exactly" )
623623 })
624-
624+
625625 t .Run ("MySQL TEXT behavior comparison" , func (t * testing.T ) {
626626 // Test data: 0x446F6C744C6162AE (DoltLab + latin1 ®)
627627 invalidUTF8Data := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }
628628 textType := Text
629-
629+
630630 // MySQL behavior for TEXT with invalid UTF-8:
631631 // - SELECT: Returns NULL
632632 // - INSERT: Accepts and stores NULL
633633 // - CAST to utf8mb4: Returns NULL
634-
634+
635635 // Test SELECT behavior
636636 result , err := textType .SQL (ctx , nil , invalidUTF8Data )
637637 require .NoError (t , err , "SELECT should not error (MySQL compatibility)" )
638638 assert .True (t , result .IsNull (), "Should return NULL for invalid UTF-8 (matches MySQL)" )
639-
639+
640640 // Test INSERT behavior (Convert function)
641641 convertResult , _ , err := textType .Convert (ctx , string (invalidUTF8Data ))
642642 require .NoError (t , err , "INSERT should not error (MySQL compatibility)" )
643643 assert .Nil (t , convertResult , "Should insert NULL for invalid UTF-8 (matches MySQL)" )
644644 })
645-
645+
646646 t .Run ("MySQL CAST behavior comparison" , func (t * testing.T ) {
647647 // Test MySQL: SELECT CAST(0x446F6C744C6162AE AS CHAR CHARACTER SET utf8mb4);
648648 // Result: NULL
649649 invalidUTF8Data := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }
650-
650+
651651 // Test both SQL and Convert functions
652652 textType := Text
653-
653+
654654 // SQL function (used in SELECT CAST(...))
655655 sqlResult , err := textType .SQL (ctx , nil , invalidUTF8Data )
656656 require .NoError (t , err )
657657 assert .True (t , sqlResult .IsNull (), "CAST in SELECT should return NULL (matches MySQL)" )
658-
658+
659659 // Convert function (used in INSERT with CAST(...))
660660 convertResult , _ , err := textType .Convert (ctx , string (invalidUTF8Data ))
661661 require .NoError (t , err )
662662 assert .Nil (t , convertResult , "CAST in INSERT should return NULL (matches MySQL)" )
663663 })
664-
664+
665665 t .Run ("Customer's exact error message scenario" , func (t * testing.T ) {
666666 // Customer reported: "invalid string for charset utf8mb4"
667667 // This should no longer occur with our fix
668668 customerData := []byte {0x44 , 0x6F , 0x6C , 0x74 , 0x4C , 0x61 , 0x62 , 0xAE }
669669 textType := Text
670-
670+
671671 // Before fix: This would throw "invalid string for charset utf8mb4"
672672 // After fix: Should return NULL without any error
673673 result , err := textType .SQL (ctx , nil , customerData )
674674 require .NoError (t , err , "Should not throw 'invalid string for charset utf8mb4' error" )
675675 assert .True (t , result .IsNull (), "Should handle invalid UTF-8 gracefully with NULL" )
676-
676+
677677 // Verify the error message pattern is not present
678678 if err != nil {
679679 assert .NotContains (t , err .Error (), "invalid string for charset utf8mb4" ,
0 commit comments