Skip to content

Commit 96605b1

Browse files
authored
Merge pull request #1280 from ydb-platform/int32-to-uint32
fix cast int* to uint*
2 parents a4e2eab + dca66d2 commit 96605b1

File tree

3 files changed

+280
-8
lines changed

3 files changed

+280
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
* Allowed the use of DSN without specifying the protocol/scheme
2+
* Allowed casts from signed YDB types to unsigned destination types if source value is not negative
23
* Removed public `query.Identifier` interface for exclude any external implementations for use with YDB
34

45
## v3.74.0

internal/value/value.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,18 +801,66 @@ func (v int8Value) castTo(dst interface{}) error {
801801
case *int64:
802802
*vv = int64(v)
803803

804+
return nil
805+
806+
case *uint64:
807+
if v < 0 {
808+
return xerrors.WithStackTrace(fmt.Errorf(
809+
"%w '%+v' (type '%s') to '%T' destination",
810+
ErrCannotCast, v, v.Type().Yql(), vv,
811+
))
812+
}
813+
814+
*vv = uint64(v)
815+
804816
return nil
805817
case *int32:
806818
*vv = int32(v)
807819

820+
return nil
821+
822+
case *uint32:
823+
if v < 0 {
824+
return xerrors.WithStackTrace(fmt.Errorf(
825+
"%w '%+v' (type '%s') to '%T' destination",
826+
ErrCannotCast, v, v.Type().Yql(), vv,
827+
))
828+
}
829+
830+
*vv = uint32(v)
831+
808832
return nil
809833
case *int16:
810834
*vv = int16(v)
811835

836+
return nil
837+
838+
case *uint16:
839+
if v < 0 {
840+
return xerrors.WithStackTrace(fmt.Errorf(
841+
"%w '%+v' (type '%s') to '%T' destination",
842+
ErrCannotCast, v, v.Type().Yql(), vv,
843+
))
844+
}
845+
846+
*vv = uint16(v)
847+
812848
return nil
813849
case *int8:
814850
*vv = int8(v)
815851

852+
return nil
853+
854+
case *uint8:
855+
if v < 0 {
856+
return xerrors.WithStackTrace(fmt.Errorf(
857+
"%w '%+v' (type '%s') to '%T' destination",
858+
ErrCannotCast, v, v.Type().Yql(), vv,
859+
))
860+
}
861+
862+
*vv = uint8(v)
863+
816864
return nil
817865
case *float64:
818866
*vv = float64(v)
@@ -929,14 +977,50 @@ func (v int32Value) castTo(dst interface{}) error {
929977
case *int64:
930978
*vv = int64(v)
931979

980+
return nil
981+
982+
case *uint64:
983+
if v < 0 {
984+
return xerrors.WithStackTrace(fmt.Errorf(
985+
"%w '%+v' (type '%s') to '%T' destination",
986+
ErrCannotCast, v, v.Type().Yql(), vv,
987+
))
988+
}
989+
990+
*vv = uint64(v)
991+
932992
return nil
933993
case *int:
934994
*vv = int(v)
935995

996+
return nil
997+
998+
case *uint:
999+
if v < 0 {
1000+
return xerrors.WithStackTrace(fmt.Errorf(
1001+
"%w '%+v' (type '%s') to '%T' destination",
1002+
ErrCannotCast, v, v.Type().Yql(), vv,
1003+
))
1004+
}
1005+
1006+
*vv = uint(v)
1007+
9361008
return nil
9371009
case *int32:
9381010
*vv = int32(v)
9391011

1012+
return nil
1013+
1014+
case *uint32:
1015+
if v < 0 {
1016+
return xerrors.WithStackTrace(fmt.Errorf(
1017+
"%w '%+v' (type '%s') to '%T' destination",
1018+
ErrCannotCast, v, v.Type().Yql(), vv,
1019+
))
1020+
}
1021+
1022+
*vv = uint32(v)
1023+
9401024
return nil
9411025
case *float64:
9421026
*vv = float64(v)
@@ -991,6 +1075,18 @@ func (v int64Value) castTo(dst interface{}) error {
9911075
case *int64:
9921076
*vv = int64(v)
9931077

1078+
return nil
1079+
1080+
case *uint64:
1081+
if v < 0 {
1082+
return xerrors.WithStackTrace(fmt.Errorf(
1083+
"%w '%+v' (type '%s') to '%T' destination",
1084+
ErrCannotCast, v, v.Type().Yql(), vv,
1085+
))
1086+
}
1087+
1088+
*vv = uint64(v)
1089+
9941090
return nil
9951091
case *float64:
9961092
*vv = float64(v)

internal/value/value_test.go

Lines changed: 183 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ func TestCastNumbers(t *testing.T) {
951951
len: 8,
952952
},
953953
{
954-
value: Int64Value(2),
954+
value: Int64Value(-2),
955955
signed: true,
956956
len: 8,
957957
},
@@ -961,7 +961,7 @@ func TestCastNumbers(t *testing.T) {
961961
len: 4,
962962
},
963963
{
964-
value: Int32Value(4),
964+
value: Int32Value(-4),
965965
signed: true,
966966
len: 4,
967967
},
@@ -971,7 +971,7 @@ func TestCastNumbers(t *testing.T) {
971971
len: 2,
972972
},
973973
{
974-
value: Int16Value(6),
974+
value: Int16Value(-6),
975975
signed: true,
976976
len: 2,
977977
},
@@ -981,7 +981,7 @@ func TestCastNumbers(t *testing.T) {
981981
len: 1,
982982
},
983983
{
984-
value: Int8Value(8),
984+
value: Int8Value(-8),
985985
signed: true,
986986
len: 1,
987987
},
@@ -1044,8 +1044,8 @@ func TestCastNumbers(t *testing.T) {
10441044
}
10451045
for _, dst := range numberDestinations {
10461046
for _, src := range numberValues {
1047-
t.Run(fmt.Sprintf("%s→%s",
1048-
src.value.Yql(), reflect.ValueOf(dst.destination).Type().Elem().String(),
1047+
t.Run(fmt.Sprintf("%s(%s)→%s",
1048+
src.value.Type().Yql(), src.value.Yql(), reflect.ValueOf(dst.destination).Type().Elem().String(),
10491049
), func(t *testing.T) {
10501050
mustErr := false
10511051
switch {
@@ -1061,8 +1061,8 @@ func TestCastNumbers(t *testing.T) {
10611061
require.NoError(t, err)
10621062
}
10631063
})
1064-
t.Run(fmt.Sprintf("Optional(%s)→%s",
1065-
src.value.Yql(), reflect.ValueOf(dst.destination).Type().Elem().String(),
1064+
t.Run(fmt.Sprintf("Optional(%s(%s))→%s",
1065+
src.value.Type().Yql(), src.value.Yql(), reflect.ValueOf(dst.destination).Type().Elem().String(),
10661066
), func(t *testing.T) {
10671067
mustErr := false
10681068
switch {
@@ -1082,6 +1082,181 @@ func TestCastNumbers(t *testing.T) {
10821082
}
10831083
}
10841084

1085+
func TestCastNegativeNumbers(t *testing.T) {
1086+
for _, tt := range []struct {
1087+
value Value
1088+
dst interface{}
1089+
err error
1090+
}{
1091+
{
1092+
value: Int64Value(1),
1093+
dst: ptr[uint64](),
1094+
},
1095+
{
1096+
value: Int64Value(-2),
1097+
dst: ptr[uint64](),
1098+
err: ErrCannotCast,
1099+
},
1100+
{
1101+
value: Int64Value(1),
1102+
dst: ptr[uint32](),
1103+
err: ErrCannotCast,
1104+
},
1105+
{
1106+
value: Int64Value(-2),
1107+
dst: ptr[uint32](),
1108+
err: ErrCannotCast,
1109+
},
1110+
{
1111+
value: Int64Value(1),
1112+
dst: ptr[uint16](),
1113+
err: ErrCannotCast,
1114+
},
1115+
{
1116+
value: Int64Value(-2),
1117+
dst: ptr[uint16](),
1118+
err: ErrCannotCast,
1119+
},
1120+
{
1121+
value: Int64Value(1),
1122+
dst: ptr[uint8](),
1123+
err: ErrCannotCast,
1124+
},
1125+
{
1126+
value: Int64Value(-2),
1127+
dst: ptr[uint8](),
1128+
err: ErrCannotCast,
1129+
},
1130+
{
1131+
value: Int32Value(1),
1132+
dst: ptr[uint64](),
1133+
},
1134+
{
1135+
value: Int32Value(-2),
1136+
dst: ptr[uint64](),
1137+
err: ErrCannotCast,
1138+
},
1139+
{
1140+
value: Int32Value(1),
1141+
dst: ptr[uint32](),
1142+
},
1143+
{
1144+
value: Int32Value(-2),
1145+
dst: ptr[uint32](),
1146+
err: ErrCannotCast,
1147+
},
1148+
{
1149+
value: Int32Value(1),
1150+
dst: ptr[uint16](),
1151+
err: ErrCannotCast,
1152+
},
1153+
{
1154+
value: Int32Value(-2),
1155+
dst: ptr[uint16](),
1156+
err: ErrCannotCast,
1157+
},
1158+
{
1159+
value: Int32Value(1),
1160+
dst: ptr[uint8](),
1161+
err: ErrCannotCast,
1162+
},
1163+
{
1164+
value: Int32Value(-2),
1165+
dst: ptr[uint8](),
1166+
err: ErrCannotCast,
1167+
},
1168+
1169+
{
1170+
value: Int16Value(1),
1171+
dst: ptr[uint64](),
1172+
err: ErrCannotCast,
1173+
},
1174+
{
1175+
value: Int16Value(-2),
1176+
dst: ptr[uint64](),
1177+
err: ErrCannotCast,
1178+
},
1179+
{
1180+
value: Int16Value(1),
1181+
dst: ptr[uint32](),
1182+
err: ErrCannotCast,
1183+
},
1184+
{
1185+
value: Int16Value(-2),
1186+
dst: ptr[uint32](),
1187+
err: ErrCannotCast,
1188+
},
1189+
{
1190+
value: Int16Value(1),
1191+
dst: ptr[uint16](),
1192+
err: ErrCannotCast,
1193+
},
1194+
{
1195+
value: Int16Value(-2),
1196+
dst: ptr[uint16](),
1197+
err: ErrCannotCast,
1198+
},
1199+
{
1200+
value: Int16Value(1),
1201+
dst: ptr[uint8](),
1202+
err: ErrCannotCast,
1203+
},
1204+
{
1205+
value: Int32Value(-2),
1206+
dst: ptr[uint8](),
1207+
err: ErrCannotCast,
1208+
},
1209+
1210+
{
1211+
value: Int8Value(1),
1212+
dst: ptr[uint64](),
1213+
},
1214+
{
1215+
value: Int8Value(-2),
1216+
dst: ptr[uint64](),
1217+
err: ErrCannotCast,
1218+
},
1219+
{
1220+
value: Int8Value(1),
1221+
dst: ptr[uint32](),
1222+
},
1223+
{
1224+
value: Int8Value(-2),
1225+
dst: ptr[uint32](),
1226+
err: ErrCannotCast,
1227+
},
1228+
{
1229+
value: Int8Value(1),
1230+
dst: ptr[uint16](),
1231+
},
1232+
{
1233+
value: Int8Value(-2),
1234+
dst: ptr[uint16](),
1235+
err: ErrCannotCast,
1236+
},
1237+
{
1238+
value: Int8Value(1),
1239+
dst: ptr[uint8](),
1240+
},
1241+
{
1242+
value: Int8Value(-2),
1243+
dst: ptr[uint8](),
1244+
err: ErrCannotCast,
1245+
},
1246+
} {
1247+
t.Run(fmt.Sprintf("%s(%s)→%s",
1248+
tt.value.Type().Yql(), tt.value.Yql(), reflect.ValueOf(tt.dst).Type().Elem().String(),
1249+
), func(t *testing.T) {
1250+
err := CastTo(tt.value, tt.dst)
1251+
if tt.err != nil {
1252+
require.ErrorIs(t, err, tt.err)
1253+
} else {
1254+
require.NoError(t, err)
1255+
}
1256+
})
1257+
}
1258+
}
1259+
10851260
func TestCastOtherTypes(t *testing.T) {
10861261
for _, tt := range []struct {
10871262
v Value

0 commit comments

Comments
 (0)