Skip to content

Commit 7bc2294

Browse files
authored
Merge pull request #3114 from dolthub/elianddb/9511-fix-set-type-cast
dolthub/dolt#9511 - Fix SET type casting to CHAR and BINARY
2 parents ea7a469 + 656d0b8 commit 7bc2294

File tree

2 files changed

+80
-8
lines changed

2 files changed

+80
-8
lines changed

enginetest/queries/script_queries.go

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9355,7 +9355,7 @@ where
93559355
},
93569356
},
93579357
{
9358-
Name: "enum conversion to strings",
9358+
Name: "enum conversions",
93599359
Dialect: "mysql",
93609360
SetUpScript: []string{
93619361
"create table t (e enum('abc', 'defg', 'hijkl'));",
@@ -9491,6 +9491,38 @@ where
94919491
{"abc"},
94929492
},
94939493
},
9494+
{
9495+
Query: "select e, cast(e as unsigned) from t order by e;",
9496+
Expected: []sql.Row{
9497+
{"abc", uint64(1)},
9498+
{"defg", uint64(2)},
9499+
{"hijkl", uint64(3)},
9500+
},
9501+
},
9502+
{
9503+
Query: "select e, cast(e as decimal) from t order by e;",
9504+
Expected: []sql.Row{
9505+
{"abc", "1"},
9506+
{"defg", "2"},
9507+
{"hijkl", "3"},
9508+
},
9509+
},
9510+
{
9511+
Query: "select e, cast(e as float) from t order by e;",
9512+
Expected: []sql.Row{
9513+
{"abc", float32(1)},
9514+
{"defg", float32(2)},
9515+
{"hijkl", float32(3)},
9516+
},
9517+
},
9518+
{
9519+
Query: "select e, cast(e as double) from t order by e;",
9520+
Expected: []sql.Row{
9521+
{"abc", float64(1)},
9522+
{"defg", float64(2)},
9523+
{"hijkl", float64(3)},
9524+
},
9525+
},
94949526
},
94959527
},
94969528
{
@@ -9953,7 +9985,7 @@ where
99539985
},
99549986
},
99559987
{
9956-
Name: "set conversion to strings",
9988+
Name: "set conversions",
99579989
Dialect: "mysql",
99589990
SetUpScript: []string{
99599991
"create table t (s set('abc', 'defg', 'hijkl'));",
@@ -10077,25 +10109,59 @@ where
1007710109
},
1007810110
},
1007910111
{
10080-
// https://github.com/dolthub/dolt/issues/9511
10081-
Skip: true,
1008210112
Query: "select s, cast(s as char) from t order by s;",
1008310113
Expected: []sql.Row{
1008410114
{"abc", "abc"},
10115+
{"defg", "defg"},
1008510116
{"abc,defg", "abc,defg"},
1008610117
{"abc,defg,hijkl", "abc,defg,hijkl"},
1008710118
},
1008810119
},
1008910120
{
10090-
// https://github.com/dolthub/dolt/issues/9511
10091-
Skip: true,
1009210121
Query: "select s, cast(s as binary) from t order by s;",
1009310122
Expected: []sql.Row{
1009410123
{"abc", []uint8("abc")},
10124+
{"defg", []uint8("defg")},
1009510125
{"abc,defg", []uint8("abc,defg")},
1009610126
{"abc,defg,hijkl", []uint8("abc,defg,hijkl")},
1009710127
},
1009810128
},
10129+
{
10130+
Query: "select s, cast(s as unsigned) from t order by s;",
10131+
Expected: []sql.Row{
10132+
{"abc", uint64(1)},
10133+
{"defg", uint64(2)},
10134+
{"abc,defg", uint64(3)},
10135+
{"abc,defg,hijkl", uint64(7)},
10136+
},
10137+
},
10138+
{
10139+
Query: "select s, cast(s as decimal) from t order by s;",
10140+
Expected: []sql.Row{
10141+
{"abc", "1"},
10142+
{"defg", "2"},
10143+
{"abc,defg", "3"},
10144+
{"abc,defg,hijkl", "7"},
10145+
},
10146+
},
10147+
{
10148+
Query: "select s, cast(s as float) from t order by s;",
10149+
Expected: []sql.Row{
10150+
{"abc", float32(1)},
10151+
{"defg", float32(2)},
10152+
{"abc,defg", float32(3)},
10153+
{"abc,defg,hijkl", float32(7)},
10154+
},
10155+
},
10156+
{
10157+
Query: "select s, cast(s as double) from t order by s;",
10158+
Expected: []sql.Row{
10159+
{"abc", float64(1)},
10160+
{"defg", float64(2)},
10161+
{"abc,defg", float64(3)},
10162+
{"abc,defg,hijkl", float64(7)},
10163+
},
10164+
},
1009910165
},
1010010166
},
1010110167
{

sql/expression/convert.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,17 +278,22 @@ func (c *Convert) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
278278
return casted, nil
279279
}
280280

281-
// convertValue only returns an error if converting to JSON, Date, and Datetime;
282-
// the zero value is returned for float types. Nil is returned in all other cases.
281+
// convertValue converts a value from its current type to the specified target type for CAST/CONVERT operations.
282+
// It handles type-specific conversion logic and applies length/scale constraints where applicable.
283283
// If |typeLength| and |typeScale| are 0, they are ignored, otherwise they are used as constraints on the
284284
// converted type where applicable (e.g. Char conversion supports only |typeLength|, Decimal conversion supports
285285
// |typeLength| and |typeScale|).
286+
// Only returns an error if converting to JSON, Date, and Datetime; the zero value is returned for float types.
287+
// Nil is returned in all other cases.
286288
func convertValue(ctx *sql.Context, val interface{}, castTo string, originType sql.Type, typeLength, typeScale int) (interface{}, error) {
287289
if val == nil {
288290
return nil, nil
289291
}
290292
switch strings.ToLower(castTo) {
291293
case ConvertToBinary:
294+
if types.IsSet(originType) || types.IsEnum(originType) {
295+
val, _ = types.TypeAwareConversion(ctx, val, originType, types.LongText)
296+
}
292297
b, _, err := types.LongBlob.Convert(ctx, val)
293298
if err != nil {
294299
return nil, nil
@@ -307,6 +312,7 @@ func convertValue(ctx *sql.Context, val interface{}, castTo string, originType s
307312
}
308313
return truncateConvertedValue(b, typeLength)
309314
case ConvertToChar, ConvertToNChar:
315+
val, _ = types.TypeAwareConversion(ctx, val, originType, types.LongText)
310316
s, _, err := types.LongText.Convert(ctx, val)
311317
if err != nil {
312318
return nil, nil

0 commit comments

Comments
 (0)