Skip to content

Commit

Permalink
Don't worry about matching MySQL's messages on the wire if it would r…
Browse files Browse the repository at this point in the history
…equire round-tripping the JSON Document.
  • Loading branch information
nicktobey committed Apr 26, 2024
1 parent 89332a9 commit 464869d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 15 deletions.
33 changes: 23 additions & 10 deletions sql/types/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,31 @@ func (t JsonType) SQL(ctx *sql.Context, dest []byte, v interface{}) (sqltypes.Va
return sqltypes.NULL, nil
}

// Convert to jsonType
jsVal, _, err := t.Convert(v)
if err != nil {
return sqltypes.NULL, err
}
js := jsVal.(sql.JSONWrapper)
var val []byte

str, err := StringifyJSON(js)
if err != nil {
return sqltypes.NULL, err
// If we read the JSON from a table, pass through the bytes to avoid a deserialization and reserialization round-trip.
// This is kind of a hack, and it means that reading JSON from tables no longer matches MySQL byte-for-byte.
// But its worth it to avoid the round-trip, which can be very slow.
if j, ok := v.(*LazyJSONDocument); ok {
str, err := MarshallJson(j)
if err != nil {
return sqltypes.NULL, err
}
val = AppendAndSliceBytes(dest, str)
} else {
// Convert to jsonType
jsVal, _, err := t.Convert(v)
if err != nil {
return sqltypes.NULL, err
}
js := jsVal.(sql.JSONWrapper)

str, err := StringifyJSON(js)
if err != nil {
return sqltypes.NULL, err
}
val = AppendAndSliceString(dest, str)
}
val := AppendAndSliceString(dest, str)

return sqltypes.MakeTrusted(sqltypes.TypeJSON, val), nil
}
Expand Down
7 changes: 2 additions & 5 deletions sql/types/json_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package types

import (
"bytes"
"database/sql/driver"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -43,13 +42,11 @@ func StringifyJSON(jsonWrapper sql.JSONWrapper) (string, error) {
if stringer, ok := jsonWrapper.(JSONStringer); ok {
return stringer.JSONString()
}
jsonBytes, err := MarshallJson(jsonWrapper)
val, err := jsonWrapper.ToInterface()
if err != nil {
return "", err
}
jsonBytes = bytes.ReplaceAll(jsonBytes, []byte(",\""), []byte(", \""))
jsonBytes = bytes.ReplaceAll(jsonBytes, []byte("\":"), []byte("\": "))
return string(jsonBytes), nil
return marshalToMySqlString(val)
}

// JSONBytes are values which can be represented as JSON.
Expand Down

0 comments on commit 464869d

Please sign in to comment.