From a66ae0d4c47323b7deef13cc8aac5324a3edca00 Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Wed, 10 Apr 2024 12:17:39 +0800 Subject: [PATCH] fix: timeout on query should return context.DeadlineExceeded (#4060) --- core/stores/sqlx/sqlconn.go | 2 +- core/stores/sqlx/stmt_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/core/stores/sqlx/sqlconn.go b/core/stores/sqlx/sqlconn.go index d6ca746da..dfdb3f4ba 100644 --- a/core/stores/sqlx/sqlconn.go +++ b/core/stores/sqlx/sqlconn.go @@ -296,7 +296,7 @@ func (db *commonSqlConn) queryRows(ctx context.Context, scanner func(*sql.Rows) return query(ctx, conn, func(rows *sql.Rows) error { e := scanner(rows) - if e != nil { + if e != nil && !errors.Is(e, context.DeadlineExceeded) { scanFailed = true } return e diff --git a/core/stores/sqlx/stmt_test.go b/core/stores/sqlx/stmt_test.go index 84de7577b..34f67206c 100644 --- a/core/stores/sqlx/stmt_test.go +++ b/core/stores/sqlx/stmt_test.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "errors" + "strconv" "testing" "time" @@ -290,6 +291,24 @@ func TestStmtBreaker(t *testing.T) { }) } +func TestQueryScanTimeout(t *testing.T) { + dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) { + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + defer cancel() + row := sqlmock.NewRows([]string{"foo"}) + for i := 0; i < 10000; i++ { + row = row.AddRow("bar" + strconv.Itoa(i)) + } + var val []struct { + Foo int + Bar string + } + conn := NewSqlConnFromDB(db) + err := conn.QueryRowsCtx(ctx, &val, "any") + assert.ErrorIs(t, err, context.DeadlineExceeded) + }) +} + type mockedSessionConn struct { lastInsertId int64 rowsAffected int64