PostgreSQL 14の新しい構文により、状況によっては、公式の.NETとJavaデータベースドライバが破損する可能性がある。具体的には、BEGIN ATOMIC ... ENDを使ってSQL関数を作成するために、どちらかを使う場合である。NpgsqlあるいはPgJDBC経由でデータベーススキーマを変更していない場合は、心配する必要はない。
JavaのJDBCと.NETのADO.NETデータベースドライバフレームワークには共通の機能がある。それはどちらもセミコロンを使ったSQLステートメントのバッチ処理をサポートしているということである。これは、パフォーマンス上の理由から必要であると考えられていた。一度に1つのコマンドを送信する場合は、コマンドごとに遅延コストを払う必要がある。逆に、バッチを送信することにより、コストを払うのは1回だけとなる。
SQL Serverなどの一部のデータベースでは、バッチ全体を1つの大きなSQL文字列として文字通り送信する。しかし、PostgreSQLの送信フォーマットはこのように機能しない。クライアントは、バッチを個々のコマンドに分割する必要がある。たとえ、分割された個々のコマンドを集合として送信する場合でもである。
この単純な実装は、各セミコロンがバッチの終わりを意味すると単純に仮定することである。もちろん、セミコロンがステートメントの終わりを表しておらず、リテラル文字列の一部となっているだけの可能性がある。NpgsqlパーサーとPgJDBCパーサーはこのことを考慮している。
ここまでは順調である。しかし、複数のステートメントで構成されるSQL関数を新たに定義している場合はどうか。関数の本体はドル引用符を使ってエスケープされるため、これはまだ問題とはならない。$$トークンのペア内のセミコロンは、他のリテラル文字列と同じように扱われる。
その後、PostgreSQL 14が登場し、「SQL標準構文」としても知られるBEGIN ATOMIC ... ENDが追加された。リリースノートには次のように記載されている。
関数またはプロシージャをSQL標準構文で記述する場合、本体はすぐに解析され、解析ツリーとして格納されます。これにより、関数の依存関係をより適切に追跡でき、セキュリティ上のメリットが得られます。
セミコロンは、BEGIN ATOMIC ... ENDブロック内のどこにでも現れる可能性があり、引用符で囲まれた文字列内には現れないため、パーサーは現在のアプローチを使って、どこでバッチをステートメントに分割すべきかを決定できません。これを完全にサポートするには、APIを変更するか、はるかに複雑なパーサーを新たに構築する必要がある。
現在のパーサーによるオーバーヘッドをすでに懸念していたため、NpgsqlはAPIを変更することに決定した。彼らは、未加工SQLモードと呼ぶものをライブラリに追加した。このモードでは、名前付きパラメーターでなく位置パラメーターを使用する必要がある。
PgJDBCチームは、どちらのアプローチを取るかを決定していない。「新たなPG14 SQL標準関数本体がSQLパーサーを破壊」というタイトルのバグレポートで進行状況を追跡できる。