Skip to content

Commit 83decf7

Browse files
committed
properly convert enum/set columns to string columns with alter table
1 parent b7bba45 commit 83decf7

File tree

5 files changed

+16
-21
lines changed

5 files changed

+16
-21
lines changed

memory/table.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,8 @@ func (t *Table) ModifyColumn(ctx *sql.Context, columnName string, column *sql.Co
14131413
var oldRowWithoutVal sql.Row
14141414
oldRowWithoutVal = append(oldRowWithoutVal, row[:oldIdx]...)
14151415
oldRowWithoutVal = append(oldRowWithoutVal, row[oldIdx+1:]...)
1416-
newVal, inRange, err := column.Type.Convert(ctx, row[oldIdx])
1416+
oldType := data.schema.Schema[oldIdx].Type
1417+
newVal, inRange, err := types.TypeAwareConversion(ctx, row[oldIdx], oldType, column.Type)
14171418
if err != nil {
14181419
if sql.ErrNotMatchingSRID.Is(err) {
14191420
err = sql.ErrNotMatchingSRIDWithColName.New(columnName, err)

sql/expression/case.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (c *Case) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
136136
}
137137
// When unable to convert to the type of the case, return the original value
138138
// A common error here is "Out of bounds value for decimal type"
139-
if ret, err := types.TypeAwareConversion(ctx, bval, b.Value.Type(), t); err == nil {
139+
if ret, inRange, err := types.TypeAwareConversion(ctx, bval, b.Value.Type(), t); inRange && err == nil {
140140
return ret, nil
141141
}
142142
return bval, nil
@@ -150,7 +150,7 @@ func (c *Case) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
150150
}
151151
// When unable to convert to the type of the case, return the original value
152152
// A common error here is "Out of bounds value for decimal type"
153-
if ret, err := types.TypeAwareConversion(ctx, val, c.Else.Type(), t); err == nil {
153+
if ret, inRange, err := types.TypeAwareConversion(ctx, val, c.Else.Type(), t); inRange && err == nil {
154154
return ret, nil
155155
}
156156
return val, nil

sql/expression/comparison.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func (c *comparison) castLeftAndRight(ctx *sql.Context, left, right interface{})
188188
if r, inRange, err := leftType.Convert(ctx, right); inRange && err == nil {
189189
return left, r, leftType, nil
190190
} else {
191-
l, err := types.TypeAwareConversion(ctx, left, leftType, rightType)
191+
l, _, err := types.TypeAwareConversion(ctx, left, leftType, rightType)
192192
if err != nil {
193193
return nil, nil, nil, err
194194
}
@@ -200,7 +200,7 @@ func (c *comparison) castLeftAndRight(ctx *sql.Context, left, right interface{})
200200
if l, inRange, err := rightType.Convert(ctx, left); inRange && err == nil {
201201
return l, right, rightType, nil
202202
} else {
203-
r, err := types.TypeAwareConversion(ctx, right, rightType, leftType)
203+
r, _, err := types.TypeAwareConversion(ctx, right, rightType, leftType)
204204
if err != nil {
205205
return nil, nil, nil, err
206206
}

sql/expression/convert.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,7 @@ func convertValue(ctx *sql.Context, val interface{}, castTo string, originType s
291291
}
292292
switch strings.ToLower(castTo) {
293293
case ConvertToBinary:
294-
if types.IsSet(originType) || types.IsEnum(originType) {
295-
val, _ = types.TypeAwareConversion(ctx, val, originType, types.LongText)
296-
}
297-
b, _, err := types.LongBlob.Convert(ctx, val)
294+
b, _, err := types.TypeAwareConversion(ctx, val, originType, types.LongBlob)
298295
if err != nil {
299296
return nil, nil
300297
}
@@ -312,7 +309,7 @@ func convertValue(ctx *sql.Context, val interface{}, castTo string, originType s
312309
}
313310
return truncateConvertedValue(b, typeLength)
314311
case ConvertToChar, ConvertToNChar:
315-
s, err := types.TypeAwareConversion(ctx, val, originType, types.LongText)
312+
s, _, err := types.TypeAwareConversion(ctx, val, originType, types.LongText)
316313
if err != nil {
317314
return nil, nil
318315
}

sql/types/conversion.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -738,19 +738,16 @@ func GeneralizeTypes(a, b sql.Type) sql.Type {
738738
// TypeAwareConversion converts a value to a specified type, with awareness of the value's original type. This is
739739
// necessary because some types, such as EnumType and SetType, are stored as ints and require information from the
740740
// original type to properly convert to strings.
741-
func TypeAwareConversion(ctx *sql.Context, val interface{}, originalType sql.Type, convertedType sql.Type) (interface{}, error) {
741+
func TypeAwareConversion(ctx *sql.Context, val interface{}, originalType sql.Type, convertedType sql.Type) (interface{}, sql.ConvertInRange, error) {
742742
if val == nil {
743-
return nil, nil
743+
return nil, sql.InRange, nil
744744
}
745-
var converted interface{}
746745
var err error
747-
if IsTextOnly(convertedType) {
748-
converted, _, err = ConvertToCollatedString(ctx, val, originalType)
749-
} else {
750-
converted, _, err = convertedType.Convert(ctx, val)
751-
}
752-
if err != nil {
753-
return nil, err
746+
if (IsEnum(originalType) || IsSet(originalType)) && IsText(convertedType) {
747+
val, _, err = ConvertToCollatedString(ctx, val, originalType)
748+
if err != nil {
749+
return nil, sql.OutOfRange, err
750+
}
754751
}
755-
return converted, nil
752+
return convertedType.Convert(ctx, val)
756753
}

0 commit comments

Comments
 (0)