Skip to content

Commit 4ea43cb

Browse files
committed
Use mc.buf while interpolating
benchmark old ns/op new ns/op delta BenchmarkInterpolation 1900 1399 -26.37% benchmark old allocs new allocs delta BenchmarkInterpolation 2 1 -50.00% benchmark old bytes new bytes delta BenchmarkInterpolation 448 160 -64.29%
1 parent 96b3f4c commit 4ea43cb

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

benchmark_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ func BenchmarkInterpolation(b *testing.B) {
222222
},
223223
maxPacketAllowed: maxPacketSize,
224224
maxWriteSize: maxPacketSize - 1,
225+
buf: newBuffer(nil),
225226
}
226227

227228
args := []driver.Value{

connection.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,37 +165,45 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
165165
return stmt, err
166166
}
167167

168-
// estimateParamLength calculates upper bound of string length from types.
169-
func estimateParamLength(args []driver.Value) (int, bool) {
170-
l := 0
168+
// estimateInterpolatedLength calculates lower bound of interpolated query length.
169+
func estimateInterpolatedLength(query string, args []driver.Value) int {
170+
min := len(query)
171171
for _, a := range args {
172+
if a == nil {
173+
min += 4 // NULL
174+
continue
175+
}
172176
switch v := a.(type) {
173177
case int64, float64:
174-
// 24 (-1.7976931348623157e+308) may be upper bound. But I'm not sure.
175-
l += 25
178+
min += 1 // 0
176179
case bool:
177-
l += 1 // 0 or 1
180+
min += 1 // 0 or 1
178181
case time.Time:
179-
l += 30 // '1234-12-23 12:34:56.777777'
182+
min += 23 // '1234-12-23 12:34:56'
180183
case string:
181-
l += len(v)*2 + 2
184+
min += len(v) + 2 // ''
182185
case []byte:
183-
l += len(v)*2 + 2
186+
min += len(v) + 2
184187
default:
185-
return 0, false
188+
panic("driver.Value has invalid type")
186189
}
187190
}
188-
return l, true
191+
return min
189192
}
190193

191194
func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
192-
estimated, ok := estimateParamLength(args)
193-
if !ok {
195+
min := estimateInterpolatedLength(query, args)
196+
if min+4 > maxPacketSize { // 4 bytes for packet header
194197
return "", driver.ErrSkip
195198
}
196-
estimated += len(query)
197199

198-
buf := make([]byte, 0, estimated)
200+
buf := mc.buf.takeCompleteBuffer()
201+
if buf == nil {
202+
// can not take the buffer. Something must be wrong with the connection
203+
errLog.Print(ErrBusyBuffer)
204+
return "", driver.ErrBadConn
205+
}
206+
buf = buf[:0]
199207
argPos := 0
200208

201209
for i := 0; i < len(query); i++ {

0 commit comments

Comments
 (0)