Skip to content

Commit 382e13d

Browse files
nussjustinjulienschmidt
authored andcommitted
Avoid allocating on each call to rows.Columns (go-sql-driver#444)
* Cache column names for result sets * Test that Columns() avoids allocating on second call * Add Justin Nuß to the AUTHORS file
1 parent aeb7d3c commit 382e13d

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Jian Zhen <zhenjl at gmail.com>
3232
Joshua Prunier <joshua.prunier at gmail.com>
3333
Julien Lefevre <julien.lefevr at gmail.com>
3434
Julien Schmidt <go-sql-driver at julienschmidt.com>
35+
Justin Nuß <nuss.justin at gmail.com>
3536
Kamil Dziedzic <kamil at klecza.pl>
3637
Kevin Malachowski <kevin at chowski.com>
3738
Lennart Rudolph <lrudolph at hmc.edu>

driver_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -1916,3 +1916,36 @@ func TestInterruptBySignal(t *testing.T) {
19161916
}
19171917
})
19181918
}
1919+
1920+
func TestColumnsReusesSlice(t *testing.T) {
1921+
rows := mysqlRows{
1922+
rs: resultSet{
1923+
columns: []mysqlField{
1924+
{
1925+
tableName: "test",
1926+
name: "A",
1927+
},
1928+
{
1929+
tableName: "test",
1930+
name: "B",
1931+
},
1932+
},
1933+
},
1934+
}
1935+
1936+
allocs := testing.AllocsPerRun(1, func() {
1937+
cols := rows.Columns()
1938+
1939+
if len(cols) != 2 {
1940+
t.Fatalf("expected 2 columns, got %d", len(cols))
1941+
}
1942+
})
1943+
1944+
if allocs != 0 {
1945+
t.Fatalf("expected 0 allocations, got %d", int(allocs))
1946+
}
1947+
1948+
if rows.rs.columnNames == nil {
1949+
t.Fatalf("expected columnNames to be set, got nil")
1950+
}
1951+
}

rows.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ type mysqlField struct {
2222
}
2323

2424
type resultSet struct {
25-
columns []mysqlField
26-
done bool
25+
columns []mysqlField
26+
columnNames []string
27+
done bool
2728
}
2829

2930
type mysqlRows struct {
@@ -40,6 +41,10 @@ type textRows struct {
4041
}
4142

4243
func (rows *mysqlRows) Columns() []string {
44+
if rows.rs.columnNames != nil {
45+
return rows.rs.columnNames
46+
}
47+
4348
columns := make([]string, len(rows.rs.columns))
4449
if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
4550
for i := range columns {
@@ -54,6 +59,8 @@ func (rows *mysqlRows) Columns() []string {
5459
columns[i] = rows.rs.columns[i].name
5560
}
5661
}
62+
63+
rows.rs.columnNames = columns
5764
return columns
5865
}
5966

0 commit comments

Comments
 (0)