Skip to content

Commit 9b97430

Browse files
elianddbclaude
andcommitted
Fix charset validation context handling and enum regression
- Use WithContext pattern to preserve *sql.Context type for enum validation - Add ellipses truncation test case for long invalid byte sequences - Clean up overbloated comments to focus on why vs what - Ensure both charset and enum validation work with MySQL compatibility 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 6be4633 commit 9b97430

File tree

4 files changed

+15
-8
lines changed

4 files changed

+15
-8
lines changed

enginetest/queries/script_queries.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7162,6 +7162,10 @@ where
71627162
{types.OkResult{RowsAffected: 1}},
71637163
},
71647164
},
7165+
{
7166+
Query: "insert into t(c) values (X'999897969594939291');",
7167+
ExpectedErrStr: "Incorrect string value: '\\x99\\x98\\x97\\x96\\x95\\x94...' for column 'c' at row 1",
7168+
},
71657169
},
71667170
},
71677171
{

sql/rowexec/insert.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ func (i *insertIter) Next(ctx *sql.Context) (returnRow sql.Row, returnErr error)
113113
// Do any necessary type conversions to the target schema
114114
for idx, col := range i.schema {
115115
if row[idx] != nil {
116-
// Add column name and row number to context for proper error messages
117-
ctxWithColumnInfo := context.WithValue(ctx, types.ColumnNameKey, col.Name)
118-
ctxWithColumnInfo = context.WithValue(ctxWithColumnInfo, types.RowNumberKey, i.rowNumber)
119-
116+
// Add column/row context for charset error messages
117+
ctxWithValues := context.WithValue(ctx.Context, types.ColumnNameKey, col.Name)
118+
ctxWithValues = context.WithValue(ctxWithValues, types.RowNumberKey, i.rowNumber)
119+
ctxWithColumnInfo := ctx.WithContext(ctxWithValues)
120120
converted, inRange, cErr := col.Type.Convert(ctxWithColumnInfo, row[idx])
121121
if cErr == nil && !inRange {
122122
cErr = sql.ErrValueOutOfRange.New(row[idx], col.Type)

sql/types/enum.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ func (t EnumType) Convert(ctx context.Context, v interface{}) (interface{}, sql.
172172
if _, ok := t.At(value); ok {
173173
return uint16(value), sql.InRange, nil
174174
}
175+
// If value is not a valid enum index, return error
176+
return nil, sql.OutOfRange, ErrConvertingToEnum.New(value)
175177
case uint:
176178
return t.Convert(ctx, int(value))
177179
case int8:
@@ -185,6 +187,8 @@ func (t EnumType) Convert(ctx context.Context, v interface{}) (interface{}, sql.
185187
if _, ok := t.At(int(value)); ok {
186188
return value, sql.InRange, nil
187189
}
190+
// If value is not a valid enum index, return error
191+
return nil, sql.OutOfRange, ErrConvertingToEnum.New(value)
188192
case int32:
189193
return t.Convert(ctx, int(value))
190194
case uint32:

sql/types/strings.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ func ConvertToBytes(ctx context.Context, v interface{}, t sql.StringType, dest [
514514
}
515515

516516
// getColumnContext extracts column name and row number from context.
517-
// Returns defaults if context values are not available.
518517
func getColumnContext(ctx context.Context) (string, int64) {
519518
colName := "<unknown>"
520519
rowNum := int64(0)
@@ -526,12 +525,12 @@ func getColumnContext(ctx context.Context) (string, int64) {
526525
rowNum = num
527526
}
528527

528+
529529
return colName, rowNum
530530
}
531531

532-
// formatInvalidByteForError formats invalid bytes for error messages to match MySQL behavior exactly.
533-
// MySQL shows all consecutive invalid bytes starting from the first invalid byte position.
534-
// When there are many invalid bytes, MySQL truncates with "..." after showing several bytes.
532+
// formatInvalidByteForError formats invalid bytes for MySQL-compatible error messages.
533+
// Shows consecutive invalid bytes, truncating with "..." after 6 bytes.
535534
func formatInvalidByteForError(bytesVal []byte) string {
536535
if len(bytesVal) == 0 {
537536
return fallbackInvalidByte

0 commit comments

Comments
 (0)