JDBCドライバとバックエンドのやりとり

バッファ管理まわりはまだまだ調べることがたくさんあるけど、気分転換がてらJDBCドライバとバックエンドのやりとりを調べてみた。ちょっと推測もまじっている。

Statementを使ってもPreparedStatmentを使っても拡張問い合わせプロトコルと呼ばれるプロトコルでやりとりしている。ドキュメントだとこのあたり。http://www.postgresql.jp/document/pg835doc/html/protocol-overview.html


PreparedStatement#exequteQuery()とすると次のメッセージがバックエンドに送られる。

  • Parse
    • exec_parse_message関数に対応
    • SQLの解析がおこなわ準備された文がつくられる
    • 準備された文はバックエンドに保持される
  • Bind
    • exec_bind_message関数に対応
    • 準備された文を使ってポータル(カーソル)が作られる
    • ポータルはバックエンドに保持される
  • Describe
    • exec_describe_portal_message関数に対応
    • ResultSetのメタデータを返すため?まだちゃんと見ていない。

ResultSet#next()とすると次のメッセージがバックエンドに送られる。

  • Execute
    • exec_execute_message関数に対応
    • バックエンドに保持しておいた準備された文とポータルを使って実行
    • PreparedStatementに指定できるfetchSizeやmaxRowに従ってその数ぶんのタプルを取得して返す
    • 次のnextでは途中からタプルを返す

要確認事項

  • Executeで途中でタプルを戻す場合、どこまで読んでおくのか?
  • スクロール可能なResultSetを使った場合は、全行をクライアント側に返しているかも?

気になった点

  • 準備された文やポータルを破棄するときにPhantomReferenceを利用している。