You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@seata.apache.org by ji...@apache.org on 2025/11/11 02:25:38 UTC

(incubator-seata-go) branch master updated: bugfix: close *sql.Rows returned by QueryContext to prevent resource leak (#989)

This is an automated email from the ASF dual-hosted git repository.

jimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-seata-go.git


The following commit(s) were added to refs/heads/master by this push:
     new b15d9d36 bugfix: close *sql.Rows returned by QueryContext to prevent resource leak (#989)
b15d9d36 is described below

commit b15d9d368d4b5951c9d7613b0bdf01fef37a9c04
Author: Eric Wang <iw...@gmail.com>
AuthorDate: Tue Nov 11 05:25:33 2025 +0300

    bugfix: close *sql.Rows returned by QueryContext to prevent resource leak (#989)
---
 pkg/datasource/sql/undo/base/undo.go      |  9 ++++--
 pkg/datasource/sql/undo/base/undo_test.go | 50 +++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/pkg/datasource/sql/undo/base/undo.go b/pkg/datasource/sql/undo/base/undo.go
index a3aab8d4..75cb4b2f 100644
--- a/pkg/datasource/sql/undo/base/undo.go
+++ b/pkg/datasource/sql/undo/base/undo.go
@@ -421,13 +421,18 @@ func (m *BaseUndoLogManager) DBType() types.DBType {
 
 // HasUndoLogTable check undo log table if exist
 func (m *BaseUndoLogManager) HasUndoLogTable(ctx context.Context, conn *sql.Conn) (res bool, err error) {
-	if _, err = conn.QueryContext(ctx, getCheckUndoLogTableExistSql()); err != nil { //nolint:rowserrcheck,sqlclosecheck
+	rows, err := conn.QueryContext(ctx, getCheckUndoLogTableExistSql())
+	if err != nil {
 		// 1146 mysql table not exist fault code
 		if e, ok := err.(*mysql.SQLError); ok && e.Code == mysql.ErrNoSuchTable {
 			return false, nil
 		}
 		log.Errorf("[HasUndoLogTable] query sql fail, err: %v", err)
-		return
+		return false, err
+	}
+
+	if rows != nil {
+		defer rows.Close()
 	}
 
 	return true, nil
diff --git a/pkg/datasource/sql/undo/base/undo_test.go b/pkg/datasource/sql/undo/base/undo_test.go
index cc6e177e..8370594f 100644
--- a/pkg/datasource/sql/undo/base/undo_test.go
+++ b/pkg/datasource/sql/undo/base/undo_test.go
@@ -1649,3 +1649,53 @@ func TestBaseUndoLogManager_Undo_EmptySQLUndoLogs(t *testing.T) {
 		assert.NoError(t, err)
 	})
 }
+
+func TestBaseUndoLogManager_HasUndoLogTable(t *testing.T) {
+	t.Run("table exists - rows should be closed", func(t *testing.T) {
+		db, mock, err := sqlmock.New()
+		require.NoError(t, err)
+		defer db.Close()
+
+		manager := NewBaseUndoLogManager()
+		ctx := context.Background()
+
+		// Mock successful query (table exists)
+		mock.ExpectQuery("SELECT 1 FROM (.+) LIMIT 1").
+			WillReturnRows(sqlmock.NewRows([]string{"1"}).AddRow(1))
+
+		conn, err := db.Conn(ctx)
+		require.NoError(t, err)
+		defer conn.Close()
+
+		exists, err := manager.HasUndoLogTable(ctx, conn)
+		assert.NoError(t, err)
+		assert.True(t, exists)
+
+		// Verify all expectations including rows.Close() was called
+		assert.NoError(t, mock.ExpectationsWereMet())
+	})
+
+	t.Run("query error - rows should still be handled", func(t *testing.T) {
+		db, mock, err := sqlmock.New()
+		require.NoError(t, err)
+		defer db.Close()
+
+		manager := NewBaseUndoLogManager()
+		ctx := context.Background()
+
+		// Mock query error (generic error)
+		mock.ExpectQuery("SELECT 1 FROM (.+) LIMIT 1").
+			WillReturnError(errors.New("connection error"))
+
+		conn, err := db.Conn(ctx)
+		require.NoError(t, err)
+		defer conn.Close()
+
+		exists, err := manager.HasUndoLogTable(ctx, conn)
+		assert.Error(t, err)
+		assert.False(t, exists)
+		assert.Contains(t, err.Error(), "connection error")
+
+		assert.NoError(t, mock.ExpectationsWereMet())
+	})
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@seata.apache.org
For additional commands, e-mail: notifications-help@seata.apache.org