Skip to content

Commit 28212d4

Browse files
authored
Merge pull request jmoiron#767 from liftoffio/gpark.sqlx.reset-slice
Make Select reset slice length
2 parents a62bc60 + 421d1cd commit 28212d4

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

sqlx.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,9 +878,10 @@ func structOnlyError(t reflect.Type) error {
878878
}
879879

880880
// scanAll scans all rows into a destination, which must be a slice of any
881-
// type. If the destination slice type is a Struct, then StructScan will be
882-
// used on each row. If the destination is some other kind of base type, then
883-
// each row must only have one column which can scan into that type. This
881+
// type. It resets the slice length to zero before appending each element to
882+
// the slice. If the destination slice type is a Struct, then StructScan will
883+
// be used on each row. If the destination is some other kind of base type,
884+
// then each row must only have one column which can scan into that type. This
884885
// allows you to do something like:
885886
//
886887
// rows, _ := db.Query("select id from people;")
@@ -910,6 +911,7 @@ func scanAll(rows rowsi, dest interface{}, structOnly bool) error {
910911
if err != nil {
911912
return err
912913
}
914+
direct.SetLen(0)
913915

914916
isPtr := slice.Elem().Kind() == reflect.Ptr
915917
base := reflectx.Deref(slice.Elem())

sqlx_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,3 +1892,35 @@ func TestIn130Regression(t *testing.T) {
18921892
}
18931893
})
18941894
}
1895+
1896+
func TestSelectReset(t *testing.T) {
1897+
RunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {
1898+
loadDefaultFixture(db, t)
1899+
1900+
filledDest := []string{"a", "b", "c"}
1901+
err := db.Select(&filledDest, "SELECT first_name FROM person ORDER BY first_name ASC;")
1902+
if err != nil {
1903+
t.Fatal(err)
1904+
}
1905+
if len(filledDest) != 2 {
1906+
t.Errorf("Expected 2 first names, got %d.", len(filledDest))
1907+
}
1908+
expected := []string{"Jason", "John"}
1909+
for i, got := range filledDest {
1910+
if got != expected[i] {
1911+
t.Errorf("Expected %d result to be %s, but got %s.", i, expected[i], got)
1912+
}
1913+
}
1914+
1915+
var emptyDest []string
1916+
err = db.Select(&emptyDest, "SELECT first_name FROM person WHERE first_name = 'Jack';")
1917+
if err != nil {
1918+
t.Fatal(err)
1919+
}
1920+
// Verify that selecting 0 rows into a nil target didn't create a
1921+
// non-nil slice.
1922+
if emptyDest != nil {
1923+
t.Error("Expected emptyDest to be nil")
1924+
}
1925+
})
1926+
}

0 commit comments

Comments
 (0)