Skip to content

Commit

Permalink
types: fix the behavior of casting json string to integers (#48010)
Browse files Browse the repository at this point in the history
close #47864
  • Loading branch information
YangKeao authored Oct 26, 2023
1 parent a565692 commit e13113a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
15 changes: 10 additions & 5 deletions pkg/types/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,12 +630,17 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j BinaryJSON, unsigned bool,
return int64(u), sc.HandleOverflow(err, err)
case JSONTypeCodeString:
str := string(hack.String(j.GetString()))
if !unsigned {
r, e := StrToInt(sc.TypeCtxOrDefault(), str, false)
return r, sc.HandleOverflow(e, e)
// The behavior of casting json string as an integer is consistent with casting a string as an integer.
// See the `builtinCastStringAsIntSig` in `expression` pkg. The only difference is that this function
// doesn't append any warning. This behavior is compatible with MySQL.
isNegative := len(str) > 1 && str[0] == '-'
if !isNegative {
r, err := StrToUint(sc.TypeCtxOrDefault(), str, false)
return int64(r), sc.HandleOverflow(err, err)
}
u, err := StrToUint(sc.TypeCtxOrDefault(), str, false)
return int64(u), sc.HandleOverflow(err, err)

r, err := StrToInt(sc.TypeCtxOrDefault(), str, false)
return r, sc.HandleOverflow(err, err)
}
return 0, errors.New("Unknown type code in JSON")
}
Expand Down
15 changes: 15 additions & 0 deletions tests/integrationtest/r/expression/json.result
Original file line number Diff line number Diff line change
Expand Up @@ -602,3 +602,18 @@ json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to last]')
select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to 2]');
json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to 2]')
[1, 2, 3]
drop table if exists t;
create table t (a json);
insert into t values ('"-1"');
insert into t values ('"18446744073709551615"');
insert into t values ('"18446744073709552000"');
select a, cast(a as unsigned) from t;
a cast(a as unsigned)
"-1" 18446744073709551615
"18446744073709551615" 18446744073709551615
"18446744073709552000" 18446744073709551615
select a, cast(a as signed) from t;
a cast(a as signed)
"-1" -1
"18446744073709551615" -1
"18446744073709552000" -1
10 changes: 10 additions & 0 deletions tests/integrationtest/t/expression/json.test
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,13 @@ select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[1 to 100]');
select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to last]');
select json_extract('[{"a": [1,2,3,4]}]', '$[0].a[0 to 2]');

# TestCastJSONStringToInteger
drop table if exists t;
create table t (a json);
insert into t values ('"-1"');
insert into t values ('"18446744073709551615"');
insert into t values ('"18446744073709552000"');
-- sorted_result
select a, cast(a as unsigned) from t;
-- sorted_result
select a, cast(a as signed) from t;

0 comments on commit e13113a

Please sign in to comment.