Skip to content

Commit

Permalink
expression: PropagateType should never let orignal data overflow (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
windtalker authored May 9, 2024
1 parent f304f04 commit c33b6cd
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 1 deletion.
16 changes: 16 additions & 0 deletions pkg/expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util/chunk"
"github.com/pingcap/tidb/pkg/util/generatedexpr"
"github.com/pingcap/tidb/pkg/util/mathutil"
"github.com/pingcap/tidb/pkg/util/size"
"github.com/pingcap/tidb/pkg/util/zeropool"
)
Expand Down Expand Up @@ -1214,6 +1215,21 @@ func PropagateType(evalType types.EvalType, args ...Expression) {
if newDecimal > mysql.MaxDecimalScale {
newDecimal = mysql.MaxDecimalScale
}
if oldFlen-oldDecimal > newFlen-newDecimal {
// the input data should never be overflow under the new type
if newDecimal > oldDecimal {
// if the target decimal part is larger than the original decimal part, we try to extend
// the decimal part as much as possible while keeping the integer part big enough to hold
// the original data. For example, original type is Decimal(50, 0), new type is Decimal(48,30), then
// incDecimal = min(30-0, mysql.MaxDecimalWidth-50) = 15
// the new target Decimal will be Decimal(50+15, 0+15) = Decimal(65, 15)
incDecimal := mathutil.Min(newDecimal-oldDecimal, mysql.MaxDecimalWidth-oldFlen)
newFlen = oldFlen + incDecimal
newDecimal = oldDecimal + incDecimal
} else {
newFlen, newDecimal = oldFlen, oldDecimal
}
}
}
args[0].GetType().SetFlenUnderLimit(newFlen)
args[0].GetType().SetDecimalUnderLimit(newDecimal)
Expand Down
3 changes: 3 additions & 0 deletions tests/integrationtest/r/executor/issues.result
Original file line number Diff line number Diff line change
Expand Up @@ -865,3 +865,6 @@ SELECT count(`t`.`c`) FROM (`s`) JOIN `t` GROUP BY `t`.`c`;
count(`t`.`c`)
170
set @@tidb_max_chunk_size = default;
select tan(9021874879467600608071521900001091070693729763119983979);
tan(9021874879467600608071521900001091070693729763119983979)
8.068627196084492
5 changes: 4 additions & 1 deletion tests/integrationtest/t/executor/issues.test
Original file line number Diff line number Diff line change
Expand Up @@ -659,4 +659,7 @@ insert into s values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),
insert into s values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1);
SELECT /*+ stream_agg()*/ count(`t`.`c`) FROM (`s`) JOIN `t` GROUP BY `t`.`c`;
SELECT count(`t`.`c`) FROM (`s`) JOIN `t` GROUP BY `t`.`c`;
set @@tidb_max_chunk_size = default;
set @@tidb_max_chunk_size = default;

# TestIssue52672
select tan(9021874879467600608071521900001091070693729763119983979);

0 comments on commit c33b6cd

Please sign in to comment.