Skip to content

Commit d02e79a

Browse files
authored
*: don't use zero value of mysql.Result (#969)
* *: don't use zero value of mysql.Result Signed-off-by: lance6716 <[email protected]> * try to fix CI Signed-off-by: lance6716 <[email protected]> * fix CI Signed-off-by: lance6716 <[email protected]> --------- Signed-off-by: lance6716 <[email protected]>
1 parent 7108b1d commit d02e79a

11 files changed

+38
-45
lines changed

client/client_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ func (s *clientTestSuite) TestConn_Insert() {
185185
pkg, err := s.c.Execute(str)
186186
require.NoError(s.T(), err)
187187
require.Equal(s.T(), uint64(1), pkg.AffectedRows)
188+
require.EqualValues(s.T(), 0, pkg.ColumnNumber())
188189
}
189190

190191
func (s *clientTestSuite) TestConn_Insert2() {

client/conn.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,10 @@ func (c *Conn) ExecuteMultiple(query string, perResultCallback ExecPerResultCall
343343
// streaming session
344344
// if this would end up in WriteValue, it would just be ignored as all
345345
// responses should have been handled in perResultCallback
346-
return &Result{Resultset: &Resultset{
347-
Streaming: StreamingMultiple,
348-
StreamingDone: true,
349-
}}, nil
346+
rs := NewResultset(0)
347+
rs.Streaming = StreamingMultiple
348+
rs.StreamingDone = true
349+
return NewResult(rs), nil
350350
}
351351

352352
// ExecuteSelectStreaming will call perRowCallback for every row in resultset

client/conn_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,20 @@ func (s *connTestSuite) TestExecuteMultiple() {
113113
count := 0
114114
result, err := s.c.ExecuteMultiple(strings.Join(queries, "; "), func(result *mysql.Result, err error) {
115115
switch count {
116-
// the INSERT/DELETE query have no resultset, but should have set affectedrows
117-
// the err should be nil
118-
// also, since this is not the last query, the SERVER_MORE_RESULTS_EXISTS
119-
// flag should be set
120116
case 0, 2:
117+
// the INSERT/DELETE query have empty resultset, but should have set affectedrows
118+
// the err should be nil
119+
// also, since this is not the last query, the SERVER_MORE_RESULTS_EXISTS
120+
// flag should be set
121121
require.True(s.T(), result.Status&mysql.SERVER_MORE_RESULTS_EXISTS > 0)
122-
require.Nil(s.T(), result.Resultset)
122+
require.Equal(s.T(), 0, result.Resultset.RowNumber())
123123
require.Equal(s.T(), uint64(1), result.AffectedRows)
124124
require.NoError(s.T(), err)
125125
case 1:
126126
// the SELECT query should have an resultset
127127
// still not the last query, flag should be set
128128
require.True(s.T(), result.Status&mysql.SERVER_MORE_RESULTS_EXISTS > 0)
129-
require.NotNil(s.T(), result.Resultset)
129+
require.Greater(s.T(), result.Resultset.RowNumber(), 0)
130130
require.NoError(s.T(), err)
131131
case 3:
132132
// this query is obviously bogus so the error should be non-nil

client/resp.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (c *Conn) handleOKPacket(data []byte) (*Result, error) {
3939
var n int
4040
var pos = 1
4141

42-
r := new(Result)
42+
r := NewResultReserveResultset(0)
4343

4444
r.AffectedRows, _, n = LengthEncodedInt(data[pos:])
4545
pos += n
@@ -283,9 +283,7 @@ func (c *Conn) readResultset(data []byte, binary bool) (*Result, error) {
283283
return nil, ErrMalformPacket
284284
}
285285

286-
result := &Result{
287-
Resultset: NewResultset(int(count)),
288-
}
286+
result := NewResultReserveResultset(int(count))
289287

290288
if err := c.readResultColumns(result); err != nil {
291289
return nil, errors.Trace(err)

mysql/result.go

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package mysql
22

3+
// Result should be created by NewResultWithoutRows or NewResult. The zero value
4+
// of Result is invalid.
35
type Result struct {
46
Status uint16
57
Warnings uint16
@@ -10,6 +12,18 @@ type Result struct {
1012
*Resultset
1113
}
1214

15+
func NewResult(resultset *Resultset) *Result {
16+
return &Result{
17+
Resultset: resultset,
18+
}
19+
}
20+
21+
func NewResultReserveResultset(fieldCount int) *Result {
22+
return &Result{
23+
Resultset: NewResultset(fieldCount),
24+
}
25+
}
26+
1327
type Executer interface {
1428
Execute(query string, args ...interface{}) (*Result, error)
1529
}

mysql/resultset.go

+3-13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const (
2222
StreamingMultiple
2323
)
2424

25+
// Resultset should be created with NewResultset to avoid nil pointer and reduce
26+
// GC pressure.
2527
type Resultset struct {
2628
Fields []*Field
2729
FieldNames map[string]int
@@ -61,9 +63,7 @@ func (r *Resultset) Reset(fieldsCount int) {
6163
r.RowDatas = r.RowDatas[:0]
6264

6365
if r.FieldNames != nil {
64-
for k := range r.FieldNames {
65-
delete(r.FieldNames, k)
66-
}
66+
clear(r.FieldNames)
6767
} else {
6868
r.FieldNames = make(map[string]int)
6969
}
@@ -80,22 +80,12 @@ func (r *Resultset) Reset(fieldsCount int) {
8080
}
8181

8282
// RowNumber is returning the number of rows in the [Resultset].
83-
//
84-
// For a nil [Resultset] 0 is returned.
8583
func (r *Resultset) RowNumber() int {
86-
if r == nil {
87-
return 0
88-
}
8984
return len(r.Values)
9085
}
9186

9287
// ColumnNumber is returning the number of fields in the [Resultset].
93-
//
94-
// For a nil [Resultset] 0 is returned.
9588
func (r *Resultset) ColumnNumber() int {
96-
if r == nil {
97-
return 0
98-
}
9989
return len(r.Fields)
10090
}
10191

mysql/resultset_helper.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,7 @@ func formatField(field *Field, value interface{}) error {
168168
}
169169

170170
func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultset, error) {
171-
r := new(Resultset)
172-
173-
r.Fields = make([]*Field, len(names))
171+
r := NewResultset(len(names))
174172

175173
var b []byte
176174

@@ -234,9 +232,7 @@ func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultse
234232
}
235233

236234
func BuildSimpleBinaryResultset(names []string, values [][]interface{}) (*Resultset, error) {
237-
r := new(Resultset)
238-
239-
r.Fields = make([]*Field, len(names))
235+
r := NewResultset(len(names))
240236

241237
var b []byte
242238

mysql/resultset_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package mysql
33
import "testing"
44

55
func TestColumnNumber(t *testing.T) {
6-
r := Result{}
7-
// Make sure ColumnNumber doesn't panic if ResultSet is nil
8-
// https://github.com/go-mysql-org/go-mysql/issues/964
6+
r := NewResultReserveResultset(0)
7+
// Make sure ColumnNumber doesn't panic when constructing a Result with 0
8+
// columns. https://github.com/go-mysql-org/go-mysql/issues/964
99
r.ColumnNumber()
1010
}

server/command.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,7 @@ func (h EmptyHandler) HandleQuery(query string) (*Result, error) {
214214
if err != nil {
215215
return nil, err
216216
}
217-
return &mysql.Result{
218-
Status: 0,
219-
Warnings: 0,
220-
InsertId: 0,
221-
AffectedRows: 0,
222-
Resultset: r,
223-
}, nil
217+
return mysql.NewResult(r), nil
224218
}
225219

226220
return nil, fmt.Errorf("not supported now")

server/resp.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
func (c *Conn) writeOK(r *Result) error {
1212
if r == nil {
13-
r = &Result{}
13+
r = NewResultReserveResultset(0)
1414
}
1515

1616
r.Status |= c.status

server/stmt.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ func (c *Conn) handleStmtReset(data []byte) (*Result, error) {
336336

337337
s.ResetParams()
338338

339-
return &Result{}, nil
339+
return NewResultReserveResultset(0), nil
340340
}
341341

342342
// stmt close command has no response

0 commit comments

Comments
 (0)