MCPcopy Create free account
hub / github.com/apecloud/myduckserver / encodeJsonValue

Function encodeJsonValue

binlogreplication/binlog_json_serialization.go:233–288  ·  view source on GitHub ↗

encodeJsonObject encodes the specified |jsonValue| into MySQL's internal JSON encoding and returns the type ID indicating what type of value this is, the encoded value, and any error encountered.

(jsonValue any)

Source from the content-addressed store, hash-verified

231
232// encodeJsonObject encodes the specified |jsonValue| into MySQL's internal JSON encoding and returns
233// the type ID indicating what type of value this is, the encoded value, and any error encountered.
234func encodeJsonValue(jsonValue any) (typeId byte, buffer []byte, err error) {
235 if jsonValue == nil {
236 buffer = append(buffer, jsonLiteralValueNull)
237 return jsonTypeLiteral, buffer, nil
238 }
239
240 switch v := jsonValue.(type) {
241 case bool:
242 if v {
243 buffer = append(buffer, jsonLiteralValueTrue)
244 } else {
245 buffer = append(buffer, jsonLiteralValueFalse)
246 }
247 return jsonTypeLiteral, buffer, nil
248
249 case string:
250 // String lengths use a special encoding that can span multiple bytes
251 buffer, err = appendStringLength(buffer, len(v))
252 if err != nil {
253 return 0, nil, err
254 }
255
256 buffer = append(buffer, []byte(v)...)
257 return jsonTypeString, buffer, nil
258
259 case float64:
260 // NOTE: all our numbers end up being represented as float64s currently when we parse stored JSON
261 bits := math.Float64bits(v)
262 buffer = append(buffer, make([]byte, 8)...)
263 binary.LittleEndian.PutUint64(buffer, bits)
264 return jsonTypeDouble, buffer, nil
265
266 case []any:
267 // MySQL attempts to use the small encoding first, and if offset sizes overflow, then it switches to the
268 // large encoding. This is a little messy/inefficient to try the small encoding first, but because of the
269 // way the binary format is designed, we can't know if/when we'll need the large format without serializing
270 // the data first.
271 id, encodedArray, err := encodeJsonArray(v, false)
272 if err == nil {
273 return id, encodedArray, nil
274 }
275 return encodeJsonArray(v, true)
276
277 case map[string]any:
278 // See the comment above about MySQL's JSON serialization format, and why we try the small encoding first,
279 // before we know if we need the large encoding or not.
280 id, encodedObject, err := encodeJsonObject(v, false)
281 if err == nil {
282 return id, encodedObject, nil
283 }
284 return encodeJsonObject(v, true)
285
286 default:
287 return 0x00, nil, fmt.Errorf("unexpected type in JSON document: %T", v)
288 }
289}
290

Callers 3

encodeJsonDocFunction · 0.85
encodeJsonArrayFunction · 0.85
encodeJsonObjectFunction · 0.85

Calls 3

appendStringLengthFunction · 0.85
encodeJsonArrayFunction · 0.85
encodeJsonObjectFunction · 0.85

Tested by

no test coverage detected