[インデックス 16273] ファイルの概要
このコミットは、Go言語の標準ライブラリである database/sql
パッケージ内の src/pkg/database/sql/sql.go
ファイルに対する変更です。このファイルは、Goアプリケーションがリレーショナルデータベースと対話するための汎用インターフェースを提供します。具体的には、SQLクエリの実行、結果セットの処理、トランザクション管理など、データベース操作の基盤となる機能が実装されています。
コミット
commit e85016f81f91268e3155f9024702ae9205ad2dd1
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Mon May 6 15:16:47 2013 -0700
database/sql: remove an unused field from Rows
Found while debugging memory usage. Nobody accesses this field
anymore.
R=golang-dev, i.caught.air, adg, r
CC=golang-dev
https://golang.org/cl/9108043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e85016f81f91268e3155f9024702ae9205ad2dd1
元コミット内容
database/sql
: Rows
から未使用フィールドを削除
メモリ使用量のデバッグ中に発見されました。このフィールドはもはや誰もアクセスしていません。
変更の背景
このコミットの背景には、Go言語の database/sql
パッケージにおけるメモリ使用量の最適化があります。コミットメッセージに明記されている通り、開発者がメモリ使用量のデバッグを行っていた際に、Rows
構造体内に存在していた db
フィールドが、コードベースのどこからも参照されていない「未使用」の状態であることが判明しました。
未使用のフィールドが存在することは、以下のような問題を引き起こす可能性があります。
- メモリの無駄遣い: フィールドが使用されなくても、そのフィールドのためにメモリが割り当てられます。特に
Rows
のような、クエリ結果の行を反復処理する際に多数生成される可能性のあるオブジェクトの場合、わずかなメモリの無駄でも全体として大きな影響を与える可能性があります。 - コードの複雑性: 未使用のコードやデータ構造は、コードベースを不必要に複雑にし、可読性を低下させます。将来のメンテナンスやデバッグの際に、そのフィールドがなぜ存在するのか、どのような目的で使われていたのかを理解するのに余計な労力が必要になります。
- 潜在的なバグのリスク: 未使用のフィールドが誤って参照されたり、将来の変更で意図せず利用されたりすることで、予期せぬ動作やバグを引き起こす可能性があります。
これらの理由から、Go言語の標準ライブラリのような、パフォーマンスと堅牢性が極めて重視される環境では、未使用のコードやデータ構造は積極的に削除されるべきであるという方針があります。このコミットは、その方針に基づき、コードベースの健全性を保ち、効率を向上させるための典型的なクリーンアップ作業の一環として行われました。
前提知識の解説
このコミットを理解するためには、Go言語の database/sql
パッケージの基本的な構造と、特に Rows
および DB
構造体の役割について理解しておく必要があります。
database/sql
パッケージ
database/sql
パッケージは、GoプログラムからSQLデータベースにアクセスするための標準インターフェースを提供します。このパッケージ自体は特定のデータベースドライバーを含んでおらず、データベース固有の操作は、database/sql/driver
インターフェースを実装した外部のドライバーパッケージ(例: github.com/go-sql-driver/mysql
や github.com/lib/pq
)によって提供されます。
主要な概念:
DB
構造体: データベースへのオープンな接続プールを表します。sql.Open()
関数によって作成され、データベースとのやり取りの主要なエントリポイントとなります。DB
オブジェクトは複数のゴルーチンから安全に利用できます。Conn
構造体:DB
から取得される単一のデータベース接続を表します。通常、ユーザーが直接扱うことは少なく、DB
が内部的に接続プールを管理します。Stmt
構造体: プリペアドステートメント(Prepared Statement)を表します。SQLインジェクション攻撃を防ぎ、同じクエリを複数回実行する際のパフォーマンスを向上させます。Rows
構造体:Query
メソッドの実行結果である行のセットを表します。結果セットを反復処理し、各行のデータをスキャンするために使用されます。
Rows
構造体
Rows
構造体は、DB.Query()
や Stmt.Query()
などのメソッドがSQLクエリを実行した結果として返されるオブジェクトです。この構造体は、データベースから取得された結果セットの各行を順に処理するための機能を提供します。
Rows
の主なメソッド:
Next()
: 結果セットの次の行に進みます。新しい行が利用可能であればtrue
を返し、それ以上行がなければfalse
を返します。Scan()
: 現在の行のデータをGoの変数にスキャンします。Close()
: 結果セットを閉じ、関連するリソース(データベース接続など)を解放します。結果セットの処理が完了したら、必ずdefer rows.Close()
を使用して呼び出すべきです。Err()
:Next()
の反復中に発生したエラーを返します。
DB
構造体と driverConn
DB
構造体は、データベース接続のプールを管理します。driverConn
は、database/sql/driver
パッケージで定義されている driver.Conn
インターフェースをラップした内部構造体で、実際のデータベースドライバーとの低レベルなやり取りをカプセル化します。
Rows
構造体は、その結果セットを生成した driverConn
への参照を保持し、結果セットが閉じられたときにその接続をプールに解放する責任を負います。
このコミットで削除された db
フィールドは、Rows
構造体がどの DB
オブジェクトから生成されたかを示すためのものでしたが、コードの進化の過程でその参照が不要になった、あるいは別の方法で関連付けが管理されるようになったため、未使用となりました。
技術的詳細
このコミットは、database/sql
パッケージ内の Rows
構造体から db *DB
フィールドを削除するという、一見すると小さな変更です。しかし、その背後にはGoのメモリ管理とコードの効率性に関する考慮があります。
Rows
構造体は、SQLクエリの結果セットを表現し、その行を反復処理するために使用されます。元の実装では、Rows
構造体は以下のようなフィールドを持っていました(関連部分のみ抜粋):
type Rows struct {
db *DB // 削除対象
dc *driverConn
releaseConn func(error)
rowsi driver.Rows
// ... その他のフィールド
}
ここで db *DB
フィールドは、Rows
オブジェクトがどの DB
接続プールから生成されたかを示すためのポインタでした。しかし、コミットメッセージが示唆するように、このフィールドはもはやコードのどこからもアクセスされていませんでした。
なぜこのフィールドが未使用になったのか、具体的なコードの変遷を追うことはこのコミット情報だけでは難しいですが、一般的に考えられる理由は以下の通りです。
- 設計の変更:
database/sql
パッケージの内部設計が進化し、Rows
がDB
オブジェクトへの直接的な参照を必要としなくなった可能性があります。例えば、Rows
がdriverConn
を介してのみ必要な情報(接続の解放など)を取得するようになり、DB
オブジェクト自体への参照は冗長になったのかもしれません。 - リソース管理の委譲:
Rows
が閉じられる際に接続を解放するロジックが、releaseConn
関数ポインタによって完全にカプセル化されるようになり、DB
オブジェクトの知識が不要になった可能性があります。releaseConn
は、Rows
が生成される時点で適切なDB
プールへの接続解放ロジックを持つクロージャとして設定されるため、Rows
自身がDB
へのポインタを持つ必要がなくなります。 - メモリ効率の追求: Goのガベージコレクタは非常に効率的ですが、不要なポインタを保持することは、オブジェクトのライフタイムを不必要に延長させたり、メモリフットプリントを増加させたりする可能性があります。特に
Rows
のように短命で多数生成される可能性のあるオブジェクトの場合、ポインタ一つ分のメモリでも全体として無視できない影響を与えることがあります。
この変更は、Rows
構造体のインスタンスが占めるメモリ量をわずかに削減し、コードベースのクリーンさを向上させます。ポインタのサイズはアーキテクチャに依存しますが、通常は4バイト(32ビットシステム)または8バイト(64ビットシステム)です。この小さな削減が、多数の Rows
オブジェクトが同時に存在する場合や、頻繁に生成・破棄される場合に、累積的なパフォーマンス向上に寄与します。
また、未使用のフィールドを削除することは、コードの意図を明確にし、将来の開発者がそのフィールドの目的を誤解するリスクを排除します。これは、大規模なオープンソースプロジェクトにおいて、コードベースの健全性を維持するための重要なプラクティスです。
コアとなるコードの変更箇所
変更は src/pkg/database/sql/sql.go
ファイルに対して行われました。
diff --git a/src/pkg/database/sql/sql.go b/src/pkg/database/sql/sql.go
index 0646fb796f..a80782bfed 100644
--- a/src/pkg/database/sql/sql.go
+++ b/src/pkg/database/sql/sql.go
@@ -735,7 +735,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a
// Note: ownership of dc passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: db,
dc: dc,
releaseConn: releaseConn,
rowsi: rowsi,
@@ -765,7 +764,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a
// Note: ownership of ci passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: db,
dc: dc,
releaseConn: releaseConn,
rowsi: rowsi,
@@ -1181,7 +1179,6 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
// Note: ownership of ci passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: s.db,
dc: dc,
rowsi: rowsi,
// releaseConn set below
@@ -1286,7 +1283,6 @@ func (s *Stmt) finalClose() error {
// err = rows.Err() // get any error encountered during iteration
// ...
type Rows struct {
-\tdb *DB
\tdc *driverConn // owned; must call releaseConn when closed to release
\treleaseConn func(error)
\trowsi driver.Rows
コアとなるコードの解説
このコミットは、src/pkg/database/sql/sql.go
ファイル内の Rows
構造体とその初期化箇所から、db *DB
フィールドを削除しています。
具体的には、以下の変更が行われています。
-
Rows
構造体定義からのdb
フィールドの削除:--- a/src/pkg/database/sql/sql.go +++ b/src/pkg/database/sql/sql.go @@ -1286,7 +1283,6 @@ func (s *Stmt) finalClose() error { // err = rows.Err() // get any error encountered during iteration // ... type Rows struct { -\tdb *DB \tdc *driverConn // owned; must call releaseConn when closed to release \treleaseConn func(error) \trowsi driver.Rows
この変更は、
Rows
構造体自体からdb
という名前の*DB
型のフィールドを完全に削除します。これにより、Rows
オブジェクトがインスタンス化される際に、このフィールドのためにメモリが割り当てられることがなくなります。 -
Rows
構造体の初期化箇所からのdb
フィールドの削除:Rows
構造体が初期化される複数の場所で、db
フィールドへの値の割り当てが削除されています。これは、構造体定義からフィールドが削除されたため、コンパイルエラーを避けるために必須の変更です。-
func (db *DB) queryConn(...)
内のRows
初期化:@@ -735,7 +735,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a // Note: ownership of dc passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: db, dc: dc, releaseConn: releaseConn, rowsi: rowsi,
queryConn
メソッドは、DB
オブジェクトのコンテキストでクエリを実行し、Rows
オブジェクトを生成します。ここでは、rows.db
に現在のdb
オブジェクト自身が割り当てられていました。 -
同じく
func (db *DB) queryConn(...)
内の別のRows
初期化:@@ -765,7 +764,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: db, dc: dc, releaseConn: releaseConn, rowsi: rowsi,
これも同様に、
queryConn
内でのRows
の初期化です。 -
func (s *Stmt) Query(...)
内のRows
初期化:@@ -1181,7 +1179,6 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) { // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: s.db, dc: dc, rowsi: rowsi, // releaseConn set below
Stmt.Query
メソッドは、プリペアドステートメントからクエリを実行し、Rows
オブジェクトを生成します。ここでは、rows.db
にs.db
(ステートメントが関連付けられているDB
オブジェクト) が割り当てられていました。
-
これらの変更は、Rows
構造体から db
フィールドが完全に削除され、そのフィールドへの参照や初期化がコードベースから一掃されたことを示しています。これにより、Rows
オブジェクトのメモリフットプリントが削減され、コードの冗長性が排除されました。
関連リンク
- Go CL 9108043: https://golang.org/cl/9108043
参考にした情報源リンク
- Go
database/sql
パッケージ公式ドキュメント: https://pkg.go.dev/database/sql - Go
database/sql/driver
パッケージ公式ドキュメント: https://pkg.go.dev/database/sql/driver - A Tour of Go:
database/sql
(非公式ながら概念理解に役立つ): https://go.dev/doc/database/ (これはGo公式ブログのデータベースチュートリアルへのリンクです。より一般的な情報源として記載しました。) - Go言語のメモリ管理とガベージコレクションに関する一般的な情報源 (例: Go公式ブログのGCに関する記事など) - 特定のURLは挙げませんが、Goのメモリ効率に関する議論は、このコミットの背景を理解する上で重要です。# [インデックス 16273] ファイルの概要
このコミットは、Go言語の標準ライブラリである database/sql
パッケージ内の src/pkg/database/sql/sql.go
ファイルに対する変更です。このファイルは、Goアプリケーションがリレーショナルデータベースと対話するための汎用インターフェースを提供します。具体的には、SQLクエリの実行、結果セットの処理、トランザクション管理など、データベース操作の基盤となる機能が実装されています。
コミット
commit e85016f81f91268e3155f9024702ae9205ad2dd1
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Mon May 6 15:16:47 2013 -0700
database/sql: remove an unused field from Rows
Found while debugging memory usage. Nobody accesses this field
anymore.
R=golang-dev, i.caught.air, adg, r
CC=golang-dev
https://golang.org/cl/9108043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/e85016f81f91268e3155f9024702ae9205ad2dd1
元コミット内容
database/sql
: Rows
から未使用フィールドを削除
メモリ使用量のデバッグ中に発見されました。このフィールドはもはや誰もアクセスしていません。
変更の背景
このコミットの背景には、Go言語の database/sql
パッケージにおけるメモリ使用量の最適化があります。コミットメッセージに明記されている通り、開発者がメモリ使用量のデバッグを行っていた際に、Rows
構造体内に存在していた db
フィールドが、コードベースのどこからも参照されていない「未使用」の状態であることが判明しました。
未使用のフィールドが存在することは、以下のような問題を引き起こす可能性があります。
- メモリの無駄遣い: フィールドが使用されなくても、そのフィールドのためにメモリが割り当てられます。特に
Rows
のような、クエリ結果の行を反復処理する際に多数生成される可能性のあるオブジェクトの場合、わずかなメモリの無駄でも全体として大きな影響を与える可能性があります。 - コードの複雑性: 未使用のコードやデータ構造は、コードベースを不必要に複雑にし、可読性を低下させます。将来のメンテナンスやデバッグの際に、そのフィールドがなぜ存在するのか、どのような目的で使われていたのかを理解するのに余計な労力が必要になります。
- 潜在的なバグのリスク: 未使用のフィールドが誤って参照されたり、将来の変更で意図せず利用されたりすることで、予期せぬ動作やバグを引き起こす可能性があります。
これらの理由から、Go言語の標準ライブラリのような、パフォーマンスと堅牢性が極めて重視される環境では、未使用のコードやデータ構造は積極的に削除されるべきであるという方針があります。このコミットは、その方針に基づき、コードベースの健全性を保ち、効率を向上させるための典型的なクリーンアップ作業の一環として行われました。
前提知識の解説
このコミットを理解するためには、Go言語の database/sql
パッケージの基本的な構造と、特に Rows
および DB
構造体の役割について理解しておく必要があります。
database/sql
パッケージ
database/sql
パッケージは、GoプログラムからSQLデータベースにアクセスするための標準インターフェースを提供します。このパッケージ自体は特定のデータベースドライバーを含んでおらず、データベース固有の操作は、database/sql/driver
インターフェースを実装した外部のドライバーパッケージ(例: github.com/go-sql-driver/mysql
や github.com/lib/pq
)によって提供されます。
主要な概念:
DB
構造体: データベースへのオープンな接続プールを表します。sql.Open()
関数によって作成され、データベースとのやり取りの主要なエントリポイントとなります。DB
オブジェクトは複数のゴルーチンから安全に利用できます。Conn
構造体:DB
から取得される単一のデータベース接続を表します。通常、ユーザーが直接扱うことは少なく、DB
が内部的に接続プールを管理します。Stmt
構造体: プリペアドステートメント(Prepared Statement)を表します。SQLインジェクション攻撃を防ぎ、同じクエリを複数回実行する際のパフォーマンスを向上させます。Rows
構造体:Query
メソッドの実行結果である行のセットを表します。結果セットを反復処理し、各行のデータをスキャンするために使用されます。
Rows
構造体
Rows
構造体は、DB.Query()
や Stmt.Query()
などのメソッドがSQLクエリを実行した結果として返されるオブジェクトです。この構造体は、データベースから取得された結果セットの各行を順に処理するための機能を提供します。
Rows
の主なメソッド:
Next()
: 結果セットの次の行に進みます。新しい行が利用可能であればtrue
を返し、それ以上行がなければfalse
を返します。Scan()
: 現在の行のデータをGoの変数にスキャンします。Close()
: 結果セットを閉じ、関連するリソース(データベース接続など)を解放します。結果セットの処理が完了したら、必ずdefer rows.Close()
を使用して呼び出すべきです。Err()
:Next()
の反復中に発生したエラーを返します。
DB
構造体と driverConn
DB
構造体は、データベース接続のプールを管理します。driverConn
は、database/sql/driver
パッケージで定義されている driver.Conn
インターフェースをラップした内部構造体で、実際のデータベースドライバーとの低レベルなやり取りをカプセル化します。
Rows
構造体は、その結果セットを生成した driverConn
への参照を保持し、結果セットが閉じられたときにその接続をプールに解放する責任を負います。
このコミットで削除された db
フィールドは、Rows
構造体がどの DB
オブジェクトから生成されたかを示すためのものでしたが、コードの進化の過程でその参照が不要になった、あるいは別の方法で関連付けが管理されるようになったため、未使用となりました。
技術的詳細
このコミットは、database/sql
パッケージ内の Rows
構造体から db *DB
フィールドを削除するという、一見すると小さな変更です。しかし、その背後にはGoのメモリ管理とコードの効率性に関する考慮があります。
Rows
構造体は、SQLクエリの結果セットを表現し、その行を反復処理するために使用されます。元の実装では、Rows
構造体は以下のようなフィールドを持っていました(関連部分のみ抜粋):
type Rows struct {
db *DB // 削除対象
dc *driverConn
releaseConn func(error)
rowsi driver.Rows
// ... その他のフィールド
}
ここで db *DB
フィールドは、Rows
オブジェクトがどの DB
接続プールから生成されたかを示すためのポインタでした。しかし、コミットメッセージが示唆するように、このフィールドはもはやコードのどこからもアクセスされていませんでした。
なぜこのフィールドが未使用になったのか、具体的なコードの変遷を追うことはこのコミット情報だけでは難しいですが、一般的に考えられる理由は以下の通りです。
- 設計の変更:
database/sql
パッケージの内部設計が進化し、Rows
がDB
オブジェクトへの直接的な参照を必要としなくなった可能性があります。例えば、Rows
がdriverConn
を介してのみ必要な情報(接続の解放など)を取得するようになり、DB
オブジェクト自体への参照は冗長になったのかもしれません。 - リソース管理の委譲:
Rows
が閉じられる際に接続を解放するロジックが、releaseConn
関数ポインタによって完全にカプセル化されるようになり、DB
オブジェクトの知識が不要になった可能性があります。releaseConn
は、Rows
が生成される時点で適切なDB
プールへの接続解放ロジックを持つクロージャとして設定されるため、Rows
自身がDB
へのポインタを持つ必要がなくなります。 - メモリ効率の追求: Goのガベージコレクタは非常に効率的ですが、不要なポインタを保持することは、オブジェクトのライフタイムを不必要に延長させたり、メモリフットプリントを増加させたりする可能性があります。特に
Rows
のように短命で多数生成される可能性のあるオブジェクトの場合、ポインタ一つ分のメモリでも全体として無視できない影響を与えることがあります。
この変更は、Rows
構造体のインスタンスが占めるメモリ量をわずかに削減し、コードベースのクリーンさを向上させます。ポインタのサイズはアーキテクチャに依存しますが、通常は4バイト(32ビットシステム)または8バイト(64ビットシステム)です。この小さな削減が、多数の Rows
オブジェクトが同時に存在する場合や、頻繁に生成・破棄される場合に、累積的なパフォーマンス向上に寄与します。
また、未使用のフィールドを削除することは、コードの意図を明確にし、将来の開発者がそのフィールドの目的を誤解するリスクを排除します。これは、大規模なオープンソースプロジェクトにおいて、コードベースの健全性を維持するための重要なプラクティスです。
コアとなるコードの変更箇所
変更は src/pkg/database/sql/sql.go
ファイルに対して行われました。
diff --git a/src/pkg/database/sql/sql.go b/src/pkg/database/sql/sql.go
index 0646fb796f..a80782bfed 100644
--- a/src/pkg/database/sql/sql.go
+++ b/src/pkg/database/sql/sql.go
@@ -735,7 +735,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a
// Note: ownership of dc passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: db,
dc: dc,
releaseConn: releaseConn,
rowsi: rowsi,
@@ -765,7 +764,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a
// Note: ownership of ci passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: db,
dc: dc,
releaseConn: releaseConn,
rowsi: rowsi,
@@ -1181,7 +1179,6 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
// Note: ownership of ci passes to the *Rows, to be freed
// with releaseConn.
rows := &Rows{
- db: s.db,
dc: dc,
rowsi: rowsi,
// releaseConn set below
@@ -1286,7 +1283,6 @@ func (s *Stmt) finalClose() error {
// err = rows.Err() // get any error encountered during iteration
// ...
type Rows struct {
-\tdb *DB
\tdc *driverConn // owned; must call releaseConn when closed to release
\treleaseConn func(error)
\trowsi driver.Rows
コアとなるコードの解説
このコミットは、src/pkg/database/sql/sql.go
ファイル内の Rows
構造体とその初期化箇所から、db *DB
フィールドを削除しています。
具体的には、以下の変更が行われています。
-
Rows
構造体定義からのdb
フィールドの削除:--- a/src/pkg/database/sql/sql.go +++ b/src/pkg/database/sql/sql.go @@ -1286,7 +1283,6 @@ func (s *Stmt) finalClose() error { // err = rows.Err() // get any error encountered during iteration // ... type Rows struct { -\tdb *DB \tdc *driverConn // owned; must call releaseConn when closed to release \treleaseConn func(error) \trowsi driver.Rows
この変更は、
Rows
構造体自体からdb
という名前の*DB
型のフィールドを完全に削除します。これにより、Rows
オブジェクトがインスタンス化される際に、このフィールドのためにメモリが割り当てられることがなくなります。 -
Rows
構造体の初期化箇所からのdb
フィールドの削除:Rows
構造体が初期化される複数の場所で、db
フィールドへの値の割り当てが削除されています。これは、構造体定義からフィールドが削除されたため、コンパイルエラーを避けるために必須の変更です。-
func (db *DB) queryConn(...)
内のRows
初期化:@@ -735,7 +735,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a // Note: ownership of dc passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: db, dc: dc, releaseConn: releaseConn, rowsi: rowsi,
queryConn
メソッドは、DB
オブジェクトのコンテキストでクエリを実行し、Rows
オブジェクトを生成します。ここでは、rows.db
に現在のdb
オブジェクト自身が割り当てられていました。 -
同じく
func (db *DB) queryConn(...)
内の別のRows
初期化:@@ -765,7 +764,6 @@ func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, a // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: db, dc: dc, releaseConn: releaseConn, rowsi: rowsi,
これも同様に、
queryConn
内でのRows
の初期化です。 -
func (s *Stmt) Query(...)
内のRows
初期化:@@ -1181,7 +1179,6 @@ func (s *Stmt) Query(args ...interface{}) (*Rows, error) { // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ - db: s.db, dc: dc, rowsi: rowsi, // releaseConn set below
Stmt.Query
メソッドは、プリペアドステートメントからクエリを実行し、Rows
オブジェクトを生成します。ここでは、rows.db
にs.db
(ステートメントが関連付けられているDB
オブジェクト) が割り当てられていました。
-
これらの変更は、Rows
構造体から db
フィールドが完全に削除され、そのフィールドへの参照や初期化がコードベースから一掃されたことを示しています。これにより、Rows
オブジェクトのメモリフットプリントが削減され、コードの冗長性が排除されました。
関連リンク
- Go CL 9108043: https://golang.org/cl/9108043
参考にした情報源リンク
- Go
database/sql
パッケージ公式ドキュメント: https://pkg.go.dev/database/sql - Go
database/sql/driver
パッケージ公式ドキュメント: https://pkg.go.dev/database/sql/driver - A Tour of Go:
database/sql
(非公式ながら概念理解に役立つ): https://go.dev/doc/database/ (これはGo公式ブログのデータベースチュートリアルへのリンクです。より一般的な情報源として記載しました。) - Go言語のメモリ管理とガベージコレクションに関する一般的な情報源 (例: Go公式ブログのGCに関する記事など) - 特定のURLは挙げませんが、Goのメモリ効率に関する議論は、このコミットの背景を理解する上で重要です。