Skip to content

Commit 0468109

Browse files
authored
Patch float with trailing zero for JSON and add useFloatWithTrailingZero flag (#1038)
* batch float with trailing zero and add a useFloatWithTrailingZero flag to enable * gofumpt * add test * fix linting and mysql errors on ci * update unit tests * remove and update tests, and fix linting errors
1 parent 1703405 commit 0468109

File tree

5 files changed

+432
-12
lines changed

5 files changed

+432
-12
lines changed

replication/binlogsyncer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ type BinlogSyncerConfig struct {
7676
// Use decimal.Decimal structure for decimals.
7777
UseDecimal bool
7878

79+
// FloatWithTrailingZero structure for floats.
80+
UseFloatWithTrailingZero bool
81+
7982
// RecvBufferSize sets the size in bytes of the operating system's receive buffer associated with the connection.
8083
RecvBufferSize int
8184

@@ -197,6 +200,7 @@ func NewBinlogSyncer(cfg BinlogSyncerConfig) *BinlogSyncer {
197200
b.parser.SetParseTime(b.cfg.ParseTime)
198201
b.parser.SetTimestampStringLocation(b.cfg.TimestampStringLocation)
199202
b.parser.SetUseDecimal(b.cfg.UseDecimal)
203+
b.parser.SetUseFloatWithTrailingZero(b.cfg.UseFloatWithTrailingZero)
200204
b.parser.SetVerifyChecksum(b.cfg.VerifyChecksum)
201205
b.parser.SetRowsEventDecodeFunc(b.cfg.RowsEventDecodeFunc)
202206
b.parser.SetTableMapOptionalMetaDecodeFunc(b.cfg.TableMapOptionalMetaDecodeFunc)

replication/json_binary.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package replication
33
import (
44
"fmt"
55
"math"
6+
"strconv"
67

78
"github.com/go-mysql-org/go-mysql/mysql"
89
"github.com/go-mysql-org/go-mysql/utils"
@@ -52,6 +53,8 @@ type (
5253
JsonDiffOperation byte
5354
)
5455

56+
type FloatWithTrailingZero float64
57+
5558
const (
5659
// The JSON value in the given path is replaced with a new value.
5760
//
@@ -96,6 +99,14 @@ func (jd *JsonDiff) String() string {
9699
return fmt.Sprintf("json_diff(op:%s path:%s value:%s)", jd.Op, jd.Path, jd.Value)
97100
}
98101

102+
func (f FloatWithTrailingZero) MarshalJSON() ([]byte, error) {
103+
if float64(f) == float64(int(f)) {
104+
return []byte(strconv.FormatFloat(float64(f), 'f', 1, 64)), nil
105+
}
106+
107+
return []byte(strconv.FormatFloat(float64(f), 'f', -1, 64)), nil
108+
}
109+
99110
func jsonbGetOffsetSize(isSmall bool) int {
100111
if isSmall {
101112
return jsonbSmallOffsetSize
@@ -124,8 +135,9 @@ func jsonbGetValueEntrySize(isSmall bool) int {
124135
// the common JSON encoding data.
125136
func (e *RowsEvent) decodeJsonBinary(data []byte) ([]byte, error) {
126137
d := jsonBinaryDecoder{
127-
useDecimal: e.useDecimal,
128-
ignoreDecodeErr: e.ignoreJSONDecodeErr,
138+
useDecimal: e.useDecimal,
139+
useFloatWithTrailingZero: e.useFloatWithTrailingZero,
140+
ignoreDecodeErr: e.ignoreJSONDecodeErr,
129141
}
130142

131143
if d.isDataShort(data, 1) {
@@ -141,9 +153,10 @@ func (e *RowsEvent) decodeJsonBinary(data []byte) ([]byte, error) {
141153
}
142154

143155
type jsonBinaryDecoder struct {
144-
useDecimal bool
145-
ignoreDecodeErr bool
146-
err error
156+
useDecimal bool
157+
useFloatWithTrailingZero bool
158+
ignoreDecodeErr bool
159+
err error
147160
}
148161

149162
func (d *jsonBinaryDecoder) decodeValue(tp byte, data []byte) interface{} {
@@ -175,6 +188,9 @@ func (d *jsonBinaryDecoder) decodeValue(tp byte, data []byte) interface{} {
175188
case JSONB_UINT64:
176189
return d.decodeUint64(data)
177190
case JSONB_DOUBLE:
191+
if d.useFloatWithTrailingZero {
192+
return d.decodeDoubleWithTrailingZero(data)
193+
}
178194
return d.decodeDouble(data)
179195
case JSONB_STRING:
180196
return d.decodeString(data)
@@ -395,6 +411,11 @@ func (d *jsonBinaryDecoder) decodeDouble(data []byte) float64 {
395411
return v
396412
}
397413

414+
func (d *jsonBinaryDecoder) decodeDoubleWithTrailingZero(data []byte) FloatWithTrailingZero {
415+
v := d.decodeDouble(data)
416+
return FloatWithTrailingZero(v)
417+
}
418+
398419
func (d *jsonBinaryDecoder) decodeString(data []byte) string {
399420
if d.err != nil {
400421
return ""

0 commit comments

Comments
 (0)