Skip to content

Commit

Permalink
fix hangup when error in multi resultsets (#1462)
Browse files Browse the repository at this point in the history
Fix #1361

Co-authored-by: Inada Naoki <songofacandy@gmail.com>
  • Loading branch information
keeplearning20221 and methane authored Nov 15, 2023
1 parent b2e2ccb commit a4c260b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

Aaron Hopkins <go-sql-driver at die.net>
Achille Roussel <achille.roussel at gmail.com>
Aidan <aidan.liu at pingcap.com>
Alex Snast <alexsn at fb.com>
Alexey Palazhchenko <alexey.palazhchenko at gmail.com>
Andrew Reid <andrew.reid at tixtrack.com>
Expand Down
41 changes: 41 additions & 0 deletions driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3430,3 +3430,44 @@ func TestConnectionAttributes(t *testing.T) {
}
rows.Close()
}

func TestErrorInMultiResult(t *testing.T) {
// https://github.com/go-sql-driver/mysql/issues/1361
var db *sql.DB
if _, err := ParseDSN(dsn); err != errInvalidDSNUnsafeCollation {
db, err = sql.Open("mysql", dsn)
if err != nil {
t.Fatalf("error connecting: %s", err.Error())
}
defer db.Close()
}

dbt := &DBTest{t, db}
query := `
CREATE PROCEDURE test_proc1()
BEGIN
SELECT 1,2;
SELECT 3,4;
SIGNAL SQLSTATE '10000' SET MESSAGE_TEXT = "some error", MYSQL_ERRNO = 10000;
END;
`
runCallCommand(dbt, query, "test_proc1")
}

func runCallCommand(dbt *DBTest, query, name string) {
dbt.mustExec(fmt.Sprintf("DROP PROCEDURE IF EXISTS %s", name))
dbt.mustExec(query)
defer dbt.mustExec("DROP PROCEDURE " + name)
rows, err := dbt.db.Query(fmt.Sprintf("CALL %s", name))
if err != nil {
return
}
defer rows.Close()

for rows.Next() {
}
for rows.NextResultSet() {
for rows.Next() {
}
}
}
8 changes: 7 additions & 1 deletion rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,13 @@ func (rows *mysqlRows) nextResultSet() (int, error) {
rows.rs = resultSet{}
// rows.mc.affectedRows and rows.mc.insertIds accumulate on each call to
// nextResultSet.
return rows.mc.resultUnchanged().readResultSetHeaderPacket()
resLen, err := rows.mc.resultUnchanged().readResultSetHeaderPacket()
if err != nil {
// Clean up about multi-results flag
rows.rs.done = true
rows.mc.status = rows.mc.status & (^statusMoreResultsExists)
}
return resLen, err
}

func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
Expand Down

0 comments on commit a4c260b

Please sign in to comment.