Skip to content

Commit 86b2f29

Browse files
kardianosbradfitz
authored andcommitted
database/sql: add support for multiple result sets
Many database systems allow returning multiple result sets in a single query. This can be useful when dealing with many intermediate results on the server and there is a need to return more then one arity of data to the client. Fixes #12382 Change-Id: I480a9ac6dadfc8743e0ba8b6d868ccf8442a9ca1 Reviewed-on: https://go-review.googlesource.com/30592 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent be48aa3 commit 86b2f29

File tree

5 files changed

+334
-87
lines changed

5 files changed

+334
-87
lines changed

src/database/sql/driver/driver.go

+16
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,22 @@ type Rows interface {
213213
Next(dest []Value) error
214214
}
215215

216+
// RowsNextResultSet extends the Rows interface by providing a way to signal
217+
// the driver to advance to the next result set.
218+
type RowsNextResultSet interface {
219+
Rows
220+
221+
// HasNextResultSet is called at the end of the current result set and
222+
// reports whether there is another result set after the current one.
223+
HasNextResultSet() bool
224+
225+
// NextResultSet advances the driver to the next result set even
226+
// if there are remaining rows in the current result set.
227+
//
228+
// NextResultSet should return io.EOF when there are no more result sets.
229+
NextResultSet() error
230+
}
231+
216232
// Tx is a transaction.
217233
type Tx interface {
218234
Commit() error

src/database/sql/example_test.go

+62
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,65 @@ func ExampleDB_QueryRow() {
4444
fmt.Printf("Username is %s\n", username)
4545
}
4646
}
47+
48+
func ExampleDB_QueryMultipleResultSets() {
49+
age := 27
50+
q := `
51+
create temp table uid (id bigint); -- Create temp table for queries.
52+
insert into uid
53+
select id from users where age < ?; -- Populate temp table.
54+
55+
-- First result set.
56+
select
57+
users.id, name
58+
from
59+
users
60+
join uid on users.id = uid.id
61+
;
62+
63+
-- Second result set.
64+
select
65+
ur.user, ur.role
66+
from
67+
user_roles as ur
68+
join uid on uid.id = ur.user
69+
;
70+
`
71+
rows, err := db.Query(q, age)
72+
if err != nil {
73+
log.Fatal(err)
74+
}
75+
defer rows.Close()
76+
77+
for rows.Next() {
78+
var (
79+
id int64
80+
name string
81+
)
82+
if err := rows.Scan(&id, &name); err != nil {
83+
log.Fatal(err)
84+
}
85+
fmt.Printf("id %d name is %s\n", id, name)
86+
}
87+
if !rows.NextResultSet() {
88+
log.Fatal("expected more result sets", rows.Err())
89+
}
90+
var roleMap = map[int64]string{
91+
1: "user",
92+
2: "admin",
93+
3: "gopher",
94+
}
95+
for rows.Next() {
96+
var (
97+
id int64
98+
role int64
99+
)
100+
if err := rows.Scan(&id, &role); err != nil {
101+
log.Fatal(err)
102+
}
103+
fmt.Printf("id %d has role %s\n", id, roleMap[role])
104+
}
105+
if err := rows.Err(); err != nil {
106+
log.Fatal(err)
107+
}
108+
}

0 commit comments

Comments
 (0)