Skip to content

Commit 13ad686

Browse files
authored
Merge pull request #460 from go-jet/json-unmrsh
Add support for configuring the JSON unmarshal function used when querying SELECT_JSON statements.
2 parents 7ab44bc + 1db6b12 commit 13ad686

File tree

6 files changed

+74
-3
lines changed

6 files changed

+74
-3
lines changed

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515

1616
// used in tests
1717
require (
18+
github.com/bytedance/sonic v1.13.1
1819
github.com/google/go-cmp v0.7.0
1920
github.com/pkg/profile v1.7.0
2021
github.com/shopspring/decimal v1.4.0
@@ -25,6 +26,8 @@ require (
2526

2627
require (
2728
filippo.io/edwards25519 v1.1.0 // indirect
29+
github.com/bytedance/sonic/loader v0.2.4 // indirect
30+
github.com/cloudwego/base64x v0.1.5 // indirect
2831
github.com/davecgh/go-spew v1.1.1 // indirect
2932
github.com/felixge/fgprof v0.9.3 // indirect
3033
github.com/friendsofgo/errors v0.9.2 // indirect
@@ -35,10 +38,13 @@ require (
3538
github.com/jackc/pgpassfile v1.0.0 // indirect
3639
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
3740
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
41+
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
3842
github.com/pmezard/go-difflib v1.0.0 // indirect
43+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
3944
github.com/volatiletech/inflect v0.0.1 // indirect
4045
github.com/volatiletech/randomize v0.0.1 // indirect
4146
github.com/volatiletech/strmangle v0.0.1 // indirect
47+
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
4248
golang.org/x/crypto v0.31.0 // indirect
4349
golang.org/x/text v0.21.0 // indirect
4450
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4
33
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
44
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
55
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
6+
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
7+
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
8+
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
9+
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
10+
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
611
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
712
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
813
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
14+
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
15+
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
16+
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
917
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
1018
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
1119
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -85,6 +93,9 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
8593
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
8694
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
8795
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
96+
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
97+
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
98+
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
8899
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
89100
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
90101
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -138,6 +149,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
138149
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
139150
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
140151
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
152+
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
153+
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
141154
github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU=
142155
github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA=
143156
github.com/volatiletech/null/v8 v8.1.2 h1:kiTiX1PpwvuugKwfvUNX/SU/5A2KGZMXfGD0DUHdKEI=
@@ -159,6 +172,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
159172
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
160173
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
161174
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
175+
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
176+
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
162177
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
163178
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
164179
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -254,3 +269,4 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
254269
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
255270
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
256271
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
272+
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

qrm/qrm.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ type Config struct {
1717
// to a field in the destination struct.
1818
// Does not apply to statements build with SELECT_JSON_OBJ or SELECT_JSON_ARR
1919
StrictScan bool
20+
21+
// JsonUnmarshalFunc is called by the Query method to unmarshal JSON query results created by
22+
// SELECT_JSON_OBJ and SELECT_JSON_ARR statements.
23+
// It can be replaced with any implementation that matches the standard "encoding/json" `Unmarshal` function signature.
24+
// By default, it uses the `Unmarshal` function from Go's standard `encoding/json` package.
25+
JsonUnmarshalFunc func(data []byte, v any) error
2026
}
2127

2228
// GlobalConfig is the package-wide configuration for SQL scanning.
23-
// This variable should be modified only once, for instance, during application initialization.
29+
// This variable is not thread safe, and it should be modified only once, for instance, during application initialization.
2430
var GlobalConfig = Config{
25-
StrictScan: false,
31+
StrictScan: false,
32+
JsonUnmarshalFunc: json.Unmarshal,
2633
}
2734

2835
// ErrNoRows is returned by Query when query result set is empty
@@ -116,7 +123,7 @@ func queryJson(ctx context.Context, db Queryable, query string, args []interface
116123
return 1, nil
117124
}
118125

119-
err = json.Unmarshal(jsonData, &destPtr)
126+
err = GlobalConfig.JsonUnmarshalFunc(jsonData, &destPtr)
120127

121128
if err != nil {
122129
return 1, fmt.Errorf("jet: invalid json, %w", err)

tests/postgres/chinook_db_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package postgres
22

33
import (
44
"context"
5+
"github.com/bytedance/sonic"
56
"github.com/go-jet/jet/v2/internal/testutils"
67
"github.com/go-jet/jet/v2/internal/utils/ptr"
78
. "github.com/go-jet/jet/v2/postgres"
@@ -225,10 +226,24 @@ func BenchmarkJoinEverythingJSON(b *testing.B) {
225226
}
226227
}
227228

229+
func BenchmarkJoinEverythingJsonSonic(b *testing.B) {
230+
useJsonUnmarshalFunc(sonic.Unmarshal, func() {
231+
for i := 0; i < b.N; i++ {
232+
testJoinEverythingJSON(b)
233+
}
234+
})
235+
}
236+
228237
func TestJoinEverythingJSON(t *testing.T) {
229238
testJoinEverythingJSON(t)
230239
}
231240

241+
func TestJoinEverythingJSONSonic(t *testing.T) {
242+
useJsonUnmarshalFunc(sonic.Unmarshal, func() {
243+
testJoinEverythingJSON(t)
244+
})
245+
}
246+
232247
func testJoinEverythingJSON(t require.TestingT) {
233248

234249
manager := Employee.AS("Manager")

tests/postgres/main_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package postgres
33
import (
44
"context"
55
"database/sql"
6+
"encoding/json"
67
"fmt"
78
"github.com/go-jet/jet/v2/qrm"
89
"github.com/go-jet/jet/v2/stmtcache"
@@ -108,6 +109,16 @@ func allowUnusedColumns(f func()) {
108109
f()
109110
}
110111

112+
func useJsonUnmarshalFunc(unmarshalJson func(data []byte, v any) error, f func()) {
113+
defer func() {
114+
qrm.GlobalConfig.JsonUnmarshalFunc = json.Unmarshal
115+
}()
116+
117+
qrm.GlobalConfig.JsonUnmarshalFunc = unmarshalJson
118+
119+
f()
120+
}
121+
111122
var loggedSQL string
112123
var loggedSQLArgs []interface{}
113124
var loggedDebugSQL string

tests/postgres/northwind_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package postgres
22

33
import (
4+
"github.com/bytedance/sonic"
45
"github.com/go-jet/jet/v2/internal/testutils"
56
. "github.com/go-jet/jet/v2/postgres"
67
"github.com/go-jet/jet/v2/tests/.gentestdata/jetdb/northwind/model"
@@ -110,6 +111,21 @@ func TestNorthwindJoinEverythingJson(t *testing.T) {
110111
testNorthwindJoinEverythingJson(t)
111112
}
112113

114+
func BenchmarkTestNorthwindJoinEverythingSonicJson(b *testing.B) {
115+
useJsonUnmarshalFunc(sonic.Unmarshal, func() {
116+
for i := 0; i < b.N; i++ {
117+
testNorthwindJoinEverythingJson(b)
118+
}
119+
})
120+
}
121+
122+
// uncomment when bug is fixed: https://github.com/bytedance/sonic/issues/774
123+
//func TestNorthwindJoinEverythingJsonSonic(t *testing.T) {
124+
// useJsonUnmarshalFunc(sonic.Unmarshal, func() {
125+
// testNorthwindJoinEverythingJson(t)
126+
// })
127+
//}
128+
113129
func testNorthwindJoinEverythingJson(t require.TestingT) {
114130

115131
stmt := SELECT_JSON_ARR(

0 commit comments

Comments
 (0)