Skip to content

Commit d8f6566

Browse files
author
James Cor
committed
implement rounding behavior
1 parent f5ea93f commit d8f6566

File tree

5 files changed

+198
-53
lines changed

5 files changed

+198
-53
lines changed

sql/columndefault.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,15 @@ func (e *ColumnDefaultValue) Eval(ctx *Context, r Row) (interface{}, error) {
8282

8383
if e.OutType != nil {
8484
var inRange ConvertInRange
85-
if val, inRange, err = e.OutType.Convert(ctx, val); err != nil {
85+
if roundType, isRoundType := e.OutType.(RoundingNumberType); isRoundType {
86+
val, inRange, err = roundType.ConvertRound(ctx, val)
87+
} else {
88+
val, inRange, err = e.OutType.Convert(ctx, val)
89+
}
90+
if err != nil {
8691
return nil, ErrIncompatibleDefaultType.New()
87-
} else if !inRange {
92+
}
93+
if !inRange {
8894
return nil, ErrValueOutOfRange.New(val, e.OutType)
8995
}
9096
}
@@ -227,13 +233,19 @@ func (e *ColumnDefaultValue) CheckType(ctx *Context) error {
227233
if val == nil && !e.ReturnNil {
228234
return ErrIncompatibleDefaultType.New()
229235
}
230-
_, inRange, err := e.OutType.Convert(ctx, val)
236+
// TODO: ColumnDefaultValue.Eval() has the same chunk of code; use helper method?
237+
var inRange ConvertInRange
238+
if roundType, isRoundType := e.OutType.(RoundingNumberType); isRoundType {
239+
val, inRange, err = roundType.ConvertRound(ctx, val)
240+
} else {
241+
val, inRange, err = e.OutType.Convert(ctx, val)
242+
}
231243
if err != nil {
232244
return ErrIncompatibleDefaultType.Wrap(err)
233-
} else if !inRange {
245+
}
246+
if !inRange {
234247
return ErrIncompatibleDefaultType.Wrap(ErrValueOutOfRange.New(val, e.Expr))
235248
}
236-
237249
}
238250
return nil
239251
}

sql/rowexec/insert.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,14 @@ func (i *insertIter) Next(ctx *sql.Context) (returnRow sql.Row, returnErr error)
122122
ctxWithColumnInfo := ctx.WithContext(ctxWithValues)
123123
val := row[idx]
124124
// TODO: check mysql strict sql_mode
125-
converted, inRange, cErr := col.Type.Convert(ctxWithColumnInfo, val)
125+
var converted any
126+
var inRange sql.ConvertInRange
127+
var cErr error
128+
if typ, ok := col.Type.(sql.RoundingNumberType); ok {
129+
converted, inRange, cErr = typ.ConvertRound(ctx, val)
130+
} else {
131+
converted, inRange, cErr = col.Type.Convert(ctxWithColumnInfo, val)
132+
}
126133
if cErr == nil && !inRange {
127134
cErr = sql.ErrValueOutOfRange.New(val, col.Type)
128135
}

sql/type.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ type NumberType interface {
128128
DisplayWidth() int
129129
}
130130

131+
// RoundingNumberType represents Number Types that implement an additional interface
132+
// that supports rounding when converting rather than the default truncation.
133+
type RoundingNumberType interface {
134+
NumberType
135+
ConvertRound(context.Context, any) (any, ConvertInRange, error)
136+
}
137+
131138
// StringType represents all string types, including VARCHAR and BLOB.
132139
// https://dev.mysql.com/doc/refman/8.0/en/char.html
133140
// https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html

0 commit comments

Comments
 (0)