PostgreSQL 15.8 に関する技術情報

このリリースは 15.7 からの修正リリース(2024年 8月 8日リリース)です。
15.X からのアップデートではダンプ、リストアは不要です。

ただし、15.7 よりも前のバージョンからアップデートする場合には、15.7 のリリース情報も参照してください。

PostgreSQL 15.7 から 15.8 への変更点

16.4、15.8、14.13、13.16、12.20 の各バージョンが同時にリリースされており、本ページでは共通の記載としています。各修正項目が適用されるバージョン系列番号を項目末尾に括弧書きで記載しています。

  1. pg_dump 実行時の権限のないコードの実行が防止されました。 (Masahiko Sawada) (16)(15)(14)(13)(12)
  2. 永続オブジェクトの作成、削除ができる攻撃者により、SQLコードのインジェクションが可能でした。そのコードは pg_dump を起動するロール(しばしばスーパーユーザです)の権限で、並列 pg_dump のセッションから実行されます。シーケンスのようなオブジェクトを悪意のコードを実行するビューや外部テーブルで置き換えることで、攻撃が行われます。これを防ぐため、ビルトインでないビューの展開および外部テーブルへのアクセスを無効にできる新たな設定パラメータ restrict_nonsystem_relation_kind が導入されました。デフォルトは ''(空文字列)で、カンマ区切りで view や foreign-table を指定します。この設定が pg_dumpコマンド内で SET で指定されるようになります。攻撃を防ぐにはサーバと pg_dumpコマンドの両方のアップデートが必要です。(CVE-2024-7348)

  3. Merge Anti Join を使う実行プランから誤った問い合わせ結果が生じることがあり、修正されました。 (Richard Guo) (16)
  4. 内側のリレーションが制約でユニークな結合キーを持つと分かっている場合に、外側のリレーションに結合キーの重複した行があるとき、マージが誤動作を起こす可能性がありました。

    (誤動作例)
    db1=# CREATE TABLE t2 (a int UNIQUE, b int);
    db1=# INSERT INTO t2 SELECT g, g % 100 FROM generate_series(1,1000) g;
    db1=# CREATE INDEX ON t2 (b);
    db1=# ANALYZE t2;
    db1=# SET enable_hashjoin TO off;
    db1=# SET enable_nestloop TO off;
    db1=# SELECT * FROM t2 t2out WHERE NOT EXISTS
            (SELECT 1 FROM t2 t2in WHERE t2in.b = t2out.a) AND t2out.b < 2;
    
    → Nested Loop Anti Join や Hash Right Anti Join の場合には正しく動作するが、
       Merge Right Anti Join を使った実行プランでは少ない件数が返る。
    
  5. VACUUM での無限ループが防止されました。 (Melanie Plageman) (16)(15)(14)
  6. 長時間実行中のトランザクションを伴う切断されたスタンバイサーバがプライマリサーバに再接続した後に、プライマリでの VACUUM 処理が、どのタプルが除去可能かについて混乱する可能性があり、その結果、無限ループに陥ることがありました。

  7. 以前に継承ツリーの子テーブルを持っていたテーブルをパーティションとしてアタッチした場合に、後で生じる障害が修正されました。 (Álvaro Herrera) (16)(15)(14)(13)(12)
  8. アサート失敗が報告されました。アサートを無効にした実稼働むけビルドでは、クラッシュや誤動作が生じる可能性があります。

    (障害発生例)
    db1=# CREATE TABLE t_inh_p (a int);
    db1=# CREATE TABLE t_inh_c () INHERITS (t_inh_p);
    db1=# DROP TABLE t_inh_c;
    db1=# CREATE TABLE pt (a int) PARTITION BY LIST (a);
    db1=# ALTER TABLE pt ATTACH PARTITION t_inh_p FOR VALUES IN (1);
    db1=# INSERT INTO t_inh_p VALUES (1);
    db1=# UPDATE t_inh_p SET a = 2 WHERE a = 1;
    → ここでアサート失敗が生じる(正常動作はパーティション制約違反のエラー)
    
  9. 一貫性に欠けた、インデックスによる制約を伴うパーティションテーブルへのALTER TABLE .. DETACH PARTITION .. での障害が修正されました。 (Álvaro Herrera, Tender Wang) (16)(15)(14)(13)(12)
  10. パーティションテーブル(親テーブル)に制約と関連付かないインデックスがあって、そのパーティション(子テーブル)に同等の制約のインデックスがある場合、パーティションをデタッチするときにアサート失敗が生じたり、システムテーブル pg_constraint の coninhcount列が誤った値になりました。

    db1=# CREATE TABLE pt5 (a int) PARTITION BY LIST (a);
    db1=# CREATE TABLE p5 PARTITION OF pt5 FOR VALUES IN (1);
    db1=# ALTER TABLE p5 ADD PRIMARY KEY (a);
    db1=# CREATE UNIQUE INDEX ON pt5 (a);
    db1=# ALTER TABLE pt5 DETACH PARTITION p5;
    → ここでアサート失敗か、以下が 0 ではなく -1 になる。
    db1=# SELECT coninhcount FROM pg_constraint WHERE conname = 'p5_pkey';
    
  11. ALTER TABLE .. DETACH PARTITION .. CONCURRENTLY と並行するパーティションプルーニングの調整について修正されました。 (Álvaro Herrera) (16)(15)(14)
  12. エグゼキュータはプラン作成と実行の間でパーティションがデタッチされないと想定していましたが、CONCURRENTLY指定を使う場合にはその前提は成り立ちません。パーティションテーブルに対する問い合わせ実行で、そのようなタイミングのときに、アサート失敗や以下のようなエラーが発生しました。

    ERROR:  missing relpartbound for relation ..
    ERROR:  could not match partition child tables to plan elements
    
  13. パーティションテーブルから最後のパーティション(子テーブル)がDROP された後、pg_class.reltuples を正しく 0 に更新するようになりました。(Noah Misch) (16)(15)(14)
  14. パーティションが無くなったパーティションテーブルに対する最初の ANALYZE でrelhassubclass = f の変更をするときに reltuples = 0 の変更が失われていました。

  15. プロシージャの多様OUT引数の処理が修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  16. SQL の CALL文は多様OUT引数に対して正しいデータ型を解決できず、「ERROR: cannot display a value of type anyelement」などのエラーや、クラッシュを引き起こしました。

    なお、PL/pgSQL 内の CALL は問題ありません。

    (障害動作例)
    db1=# CREATE PROCEDURE pro1 (i1 IN anynonarray, o1 OUT anynonarray)
            LANGUAGE sql AS $$ SELECT i1; $$;
    db1=# CALL pro1('aa'::text, NULL);
    ERROR:  cannot display a value of type anynonarray
    
  17. PL/pgSQL で CALL 文の引数リストから呼び出された STABLE関数の振る舞いが修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  18. CALL が、トランザクションブロック内のアトミックなコンテキストで実行された場合に、誤って外側トランザクションの開始時点のスナップショットが STABLE関数に渡されて、古い値が参照されていました。

    (誤動作例)
    db1=# CREATE TABLE t9 AS SELECT 0 AS x;
    db1=# CREATE FUNCTION f_get_x() RETURNS int STABLE LANGUAGE plpgsql AS
          $$ DECLARE r int; BEGIN SELECT x INTO r FROM t9; RETURN r; END; $$;
    db1=# CREATE PROCEDURE f_print_x(x int) LANGUAGE plpgsql AS 
          $$ BEGIN RAISE NOTICE 'f_print_x(%)', x; END; $$;
    db1=# BEGIN;
    db1=# DO $$ BEGIN
                UPDATE t9 SET x = x + 1;
                RAISE NOTICE 'f_get_x(%)', f_get_x();
                CALL f_print_x(f_get_x());
                UPDATE t9 SET x = x + 1;
                RAISE NOTICE 'f_get_x(%)', f_get_x();
                CALL f_print_x(f_get_x());
                END $$;
    NOTICE:  f_get_x(1)
    NOTICE:  f_print_x(0)   (← 正しくは 1)
    NOTICE:  f_get_x(2)
    NOTICE:  f_print_x(0)   (← 正しくは 2)
    db1=# ROLLBACK;
    
  19. time型、timetz型に対する ISO-8601拡張時刻書式の入力について修正されました。 (Tom Lane) (16)
  20. 'T12:34:56' のような書き方を再び許容するようになりました。PostgreSQL 15.x 以前では受け入れられていましたが、16.0 以降で「ERROR: invalid input syntax for type ...」のエラーになっていました。

  21. money型の計算で整数オーバーフローを検知するようになりました。 (Joseph Koshakow) (16)(15)(14)(13)(12)
  22. money型に対する算術関数はこれまでオーバーフロー検査をしていませんでした。そのため、オーバーフローする場合に誤った問い合わせ結果が生じていました。

    (誤動作例)
    db1=# SELECT '92233720368547758.07'::money + '0.01'::money;
              ?column?
    -----------------------------
     -$92,233,720,368,547,758.08
    (1 row)
    → 修正後は「ERROR:  money out of range」エラーが出る。
    
  23. round(numeric, int) および trunc(numeric, int) 関数で、スケール引数の過剰な制限が修正されました。 (Dean Rasheed) (16)(15)(14)(13)(12)
  24. これまでスケール引数は(文書に記載なく)正負 2000桁までに制限されていて、それを越える場合には、誤った問い合わせ結果が返っていました。numeric型の上限に合わせた桁数を上限とするように修正されました。

    (誤動作例 - 本来全て「1000」にならないといけない)
    db1=# SELECT substr(round(1.234e1999, -1999)::text, 1, 4);
     substr
    --------
     1000
    (1 row)
    
    db1=# SELECT substr(round(1.234e2000, -2000)::text, 1, 4);
     substr
    --------
     1000
    (1 row)
    
    db1=# SELECT substr(round(1.234e2001, -2001)::text, 1, 4);
     substr
    --------
     1200
    (1 row)
    
  25. 最小 bigint値に対する pg_size_pretty() の出力が修正されました。 (Joseph Koshakow) (16)(15)
  26. (誤動作ケース - 期待される正しい出力は「-8192PB」)
    db1=# SELECT pg_size_pretty('-9223372036854775808'::bigint);
           pg_size_pretty
    ----------------------------
     -9223372036854775808 bytes
    (1 row)
    
  27. スタンバイサーバ上の UNLOGGED のシーケンスと、他セッションの一時シーケンスについて、pg_sequence_last_value() が ERROR を起こさないように修正されました。 (Nathan Bossart) (16)(15)(14)(13)(12)
  28. このような場合に、これからは NULL を返すようになります。本関数は pg_sequences ビューの中で使われるもので文書化されていません。

    (プライマリサーバで実行 - これで UNLOGGED のシーケンスが作られる)
    db1=# CREATE UNLOGGED TABLE t14 (id serial);
    
    (スタンバイサーバで実行 - 修正前バージョンではエラーになる)
    db1=# SELECT * FROM pg_sequences ;
    ERROR:  could not open file "base/18077/18108": No such file or directory
    
  29. websearch_to_tsquery() で無視される演算子のパースが修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  30. マニュアルでは websearch_to_tsquery() の入力中の記号は、ダッシュ(-) と引用符(") の特別な場合を除き無視されることになっています。しかしながら、括弧といくつかの記号が or の直前に現れた場合、or が演算子ではなく or という単語として扱われる動作がありました。

    (or は引用符で囲わない限り演算子)
    db1=# select websearch_to_tsquery('simple', 'cat or dog');
     websearch_to_tsquery
    ----------------------
     'cat' | 'dog'
    (1 row)
    
    (誤動作例 - 括弧があると or が演算子として扱われない)
    db1=# select websearch_to_tsquery('simple', '(tom cat) or dog');
         websearch_to_tsquery
    ------------------------------
     'tom' & 'cat' & 'or' & 'dog'
    (1 row)
    
  31. 新たな配列次元を計算するときの整数オーバーフローを検出できるようになりました。 (Joseph Koshakow) (16)(15)(14)(13)(12)
  32. 以下の INSERT が正しくエラーになるようになりました。

    (修正前バージョンでは a = '{}' で行が挿入される)
    db1=# CREATE TABLE t16 (a int[]);
    db1=# INSERT INTO t16 (a[-2147483648:2147483647]) VALUES ('{}');
    ERROR:  array size exceeds the maximum allowed (134217727)
    

    バージョン 16.1、15.5、14.10、13.13、12.17、11.22 で修正された、CVE-2023-5869 の件と似ていますが、本障害では配列は空で終わるので無害です。

  33. ライブラリ関数 strnxfrm() の移植性に欠ける使い方が修正されました。 (Jeff Davis) (16)
  34. 一部のコードパスでは、非決定的な照合順序の使用において「ERROR: pg_strnxfrm() returned unexpected result」のエラーが発生する可能性がありました。

  35. TOAST化されたフィールドを展開するときに、新たなカタログキャッシュエントリが古くなったことを検知するようになりました。 (Noah Misch) (16)(15)(14)(13)(12)
  36. TOASTテーブルを持つシステムカタログにインプレース更新を行う場合に問題が発生します。該当するのは pg_database だけです。pg_database の情報を使う SQL (例えば GRANT .. ON DATABASE .. など) で古い情報が使われてしまう可能性がありました。

  37. DEFAULT を伴う INSERT について、ビューの列が更新可能であるかを正しく検査するようになりました。 (Tom Lane) (16)(15)(14)(13)(12)
  38. 対象の列が更新不能である場合、その旨のエラーを出すべきですが、検査が漏れており、後のコードから「ERROR: attribute number N not found in view targetlist」という意味が理解しにくいエラーメッセージが生じていました。

    (修正前の動作例)
    db1=# CREATE TABLE t19 (id int);
    db1=# CREATE VIEW v19 AS SELECT id, id * 2 AS c_2id FROM t19;
    db1=# INSERT INTO v19 VALUES (1, 2);
    ERROR:  cannot insert into column "c_2id" of view "v19"
    DETAIL:  View columns that are not columns of their base relation are not updatable.
    db1=# INSERT INTO v19 VALUES (1, DEFAULT);
    ERROR:  attribute number 2 not found in view targetlist
    
  39. 不正な再帰問い合わせに対して、エラー報告内容が改善されました。 (Tom Lane) (16)(15)(14)(13)(12)
  40. これまで、WITH RECURSIVE の問い合わせで UNION の 2つ目の枝に自己参照が無いけれども ORDER BY のような別の場所に自己参照がある場合に、役に立たない内部的なエラーメッセージが出ていました。

    (修正前の動作例)
    db1=# WITH RECURSIVE x(n) AS (WITH x1 AS (SELECT 1 FROM x)
            SELECT 0 UNION SELECT * FROM x1) SELECT * FROM x;
    ERROR:  missing recursive reference
    (→ 修正後のメッセージは以下)
    ERROR:  recursive reference to query "x" must not appear within a subquery
    
    db1=# WITH RECURSIVE x(n) AS (
            SELECT 0 UNION SELECT 1 ORDER BY (SELECT n FROM x)) SELECT * FROM x;
    ERROR:  missing recursive reference
    (→ 修正後のメッセージは以下)
    ERROR:  ORDER BY in a recursive query is not implemented
    
  41. ALTER TABLE .. SET LOGGED/UNLOGGED で、テーブルが所有するシーケンスにもロック取得するように修正されました。 (Noah Misch) (16)(15)
  42. このコマンドは(通常は serial型の列により)テーブルに紐づくシーケンスについても LOGGED と UNLOGGED の切り替えを行いますが、シーケンスについてロック取得されていませんでした。このため、同時に実行される nextval() の結果が失われる可能性がありました。

  43. キューに入っていた AFTER トリガが実行時には無くなっていた場合に、エラーを出さないようになりました。 (Tom Lane) (16)(15)(14)(13)(12)
  44. トランザクションで遅延された AFTERトリガを発生させる操作を実行して、その後、トリガ実行に至る前にそのトリガが DROP された場合に該当します。これまでは「ERROR: could not find trigger NNNN」エラーを出していましたが、動作が変更されました。この場合は何もしない方が良いと判断されました。

  45. テーブルが削除されたときに、列単位の権限についてシステムカタログ pg_init_privs のエントリの削除に失敗していたものが、修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  46. ある拡張が作成したテーブルの列単位権限を GRANT した場合に、関連する pg_init_privs のエントリが拡張を削除した後にも残っていました。これはテーブルの OID が再利用されない限りは無害です。pg_init_privs に残ったエントリは、OID が一致するテーブルの pg_dump 出力に影響を与える可能性があります。

  47. 望ましいインデックスが式や述語を持つときに、ON CONFLICT に対する競合解決インデックスの選択が修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  48. 問い合わせ(INSERT)が更新可能ビューを通してターゲットテーブルにON CONFLICT を用いたアクセスする場合、利用可能なインデックスがある場合でも、それが無いというエラーが生じていました。

    (エラー発生例)
    db1=# CREATE TABLE t24 (js jsonb);
    db1=# CREATE UNIQUE INDEX ON t24 ((js ->> 'key'));
    db1=# CREATE VIEW v24 AS SELECT * FROM t24;
    db1=# INSERT INTO v24 VALUES ('{"key": "value"}')
            ON CONFLICT ((js ->> 'key')) DO NOTHING;
    ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
    
  49. ALTER TABLE で他セッションの一時テーブルを書き換えることが禁止されました。 (Tom Lane) (16)(15)(14)(13)(12)
  50. 権限チェックにより、通常は他セッションの一時テーブルの行を参照・更新することは防止されますが、ALTER TABLE で定義変更をすることは可能でした。永続テーブルを継承する一時テーブルを作ることで、スキーマ pg_temp_NNN を指定することなく、他セッション一時テーブルの ALTER TABLE を試みることができてしまいました。

    (現象再現例)
    db1=> CREATE TABLE t25(i int);
    db1=> CREATE TEMP TABLE t25tt () INHERITS (t25);
    
    (別セッションで実行)
    db1=> ALTER TABLE t25 ADD c text;
    ERROR:  could not open file "base/18077/18239": No such file or directory
     → アサート有のビルドならアサート失敗/列追加に成功してしまう場合もある
    
    (修正後のエラー)
    ERROR:  cannot alter temporary tables of other sessions
    
  51. CREATE TABLE ... LIKE ... STATISTICS での式の拡張統計の処理が修正されました。 (Tom Lane) (16)(15)(14)
  52. このような CREATEコマンドは、統計情報の式の列参照で列番号を適切に調整できませんでした。その結果、無効な統計オブジェクトが作られて、後で問題が生じました。典型的には元テーブルが削除された列を持っていて、列番号の付け直しが必要になる場合です。

    (障害発生例)
    db1=# CREATE TABLE t26s (a text, b text, c text);
    db1=# CREATE STATISTICS es26 ON (a || c) FROM t26s;
    db1=# ALTER TABLE t26s DROP COLUMN b;
    db1=# CREATE TABLE t26t (LIKE t26s INCLUDING STATISTICS);
    db1=# \d t26t
    ERROR:  invalid attnum 3 for relation "t26t"
    
  53. min() または max() 集約から生成された副問い合わせの再計算に失敗していたものが修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  54. 一部の場合では、外側の問い合わせのある行で計算された集約結果が、後の行でそうすべきでないときに再利用されるおそれがありました。これは外側の問い合わせがハッシュ集約で実装された DISTINCT を用いているときだけ起きると見られていますが、他の場合もありえます。

    本障害により誤った問い合わせ結果が生じます。

    (誤動作例 - min も 1、2、3 となるのが正しい結果)
    db1(5432)=# CREATE TABLE t27 (f1 int4);
    db1(5432)=# INSERT INTO t27 VALUES (1),(2),(3);
    db1(5432)=# SET enable_sort TO off;
    db1(5432)=# SELECT f1, (SELECT DISTINCT min(t27in.f1) FROM t27 t27in
                  WHERE t27in.f1 = t27out.f1) FROM t27 t27out;
     f1 | min
    ----+-----
      1 |   1
      2 |   1
      3 |   1
    (3 rows)
    
  55. 位置パラメータでアンダースコア(_) が再び禁止されました。 (Erik Wienhold) (16)
  56. バージョン 16.0 で整数リテラルがアンダースコアを含むことが可能になりました。この変更で「$1_234」などを単一トークンとして扱うようになりましたが、これは正しく機能しませんでした。位置パラメータのシンボルは $ とそれに続く数字のみに戻されました。

  57. JIT でインライン化されたバックエンド関数がエラーを出すときのクラッシュが回避されました。 (Tom Lane) (16)(15)(14)(13)(12)
  58. エラー状態は(エラー位置を示す文字列のために)JITコンパイルされたコードを持つ動的にロードされたモジュールへのポインタを含むことができます。一部のコードパスでモジュールはエラー報告が処理される前にモジュールがアンロードされる可能性があり、エラー位置を示す文字列にアクセスがあったとき、SIGSEGV がもたらされました。

  59. libxml2 ライブラリ バージョン 2.13.x での振る舞い変更に対応しました。 (Erik Wienhold, Tom Lane) (16)(15)(14)(13)(12)
  60. 報告されたエラーがそれだけでない限り、libxml2 からの「chunk is not well balanced」エラーを抑止するようになりました。これにより 2.13.x とそれ以前のバージョンとのエラー報告の一貫性を保ちます。以前のバージョンではこのメッセージは冗長であったり、完全に間違っていたりしたので、2.13.x では報告されるケースの数が大幅に減りました。

  61. ホットスタンバイサーバを起動するときに、準備されたトランザクションのサブトランザクションの処理が修正されました。 (Heikki Linnakangas) (16)(15)(14)(13)(12)
  62. シャットダウン時のチェックポイント の WALレコードでスタンバイのリプレイを開始すると、プライマリで準備されているがまだコミットされていないトランザクションは、進行中であると正しく認識されます。しかし、サブトランザクション(セーブポイントまたは PL/pgSQL の例外ブロックで生じる)については考慮されず、中止されたものとして扱われていました。

    これにより、準備されたトランザクションが後でコミットされた場合に、コミットされた内容が REPEATABLE READ 分離レベルの別トランザクションにおいて途中から参照可能になる、といった不整合が発生していました。

  63. 論理レプリケーションスロットの誤った初期化が防止されました。 (Masahiko Sawada) (16)(15)(14)(13)(12)
  64. 場合によっては、WALストリーム内のレプリケーションスロットの開始ポイントがトランザクション内のポイントに設定され、アサート失敗が発生したり、デコード結果が不正確になったりすることがありました。

  65. レプリケーションスロットの作成と削除中に「ERROR: can only drop stats once」エラーが生じることが回避されました。 (Floris Van Nee) (16)(15)
  66. 同時にスロットの作成・削除を行うとタイミングによって現象が発生しました。アサートが有効なビルドではアサート失敗も発生します。

  67. 論理レプリケーションで WAL sender のリソースリークが修正されました。 (Hou Zhijie) (16)(15)
  68. パーティションテーブル(親テーブル)が、列が追加されている等、物理的に異なる行タイプのパーティション(子テーブル)を持つとして、そのようなパーティションテーブルの変更をパブリッシュするときに、wal sender プロセスでメモリリークが生じました。

  69. NOTIFY または sinval割り込み(共有キャッシュ無効化)を処理した後のメモリリークを回避するようになりました。 (Tom Lane) (16)(15)(14)(13)(12)
  70. これらのイベントの処理関数では現在メモリコンテキストを TopMemoryContext に切り替える可能性があり、その結果、切り替え前に割り当てられたデータについて、セッション存続期間でのリークが発生しました。少なくとも、受信した問い合わせと Bind メッセージに付加されたパラメータのエンコード変換でリークが観察されました。

  71. 実行時統計情報に使用される共有メモリブロックの参照カウントの漏洩が防止されるようになりました。 (Anthonin Bonnefoy) (16)(15)
  72. 統計情報の共有メモリにアタッチされた新しいバックエンドプロセスは参照カウントを増加させましたが、終了時にカウントを減少させていませんでした。2^32 セッションが作られた後、参照カウントが 0 にオーバーフローして、その後のバックエンドプロセス起動が「ERROR: could not attach to ...」エラーで失敗する可能性がありました。

  73. マルチトランザクションの SLRU ログを切り捨てるときの、デッドロックとアサート失敗の発生が防止されました。 (Heikki Linnakangas) (16)(15)(14)
  74. SLRUセグメントを削除しようとするプロセスは、checkpointerプロセスとデッドロックする可能性がありました。

  75. Windowsソケットで入力終了イベントが失われる可能性を回避するようになりました。 (Thomas Munro) (16)(15)(14)(13)(12)
  76. Windowsは接続のリモート側が切断された後に FD_CLOSE イベントを1回だけ報告します。タイミングが悪いと、その報告を見逃し、さらに入力を期待して無期限に、または少なくともタイムアウトが経過するまで待機する可能性がありました。

    結果としてクライアント側が切断したことの検知が遅れて、「FATAL: sorry, too many clients already」などが生じる原因となりました。

  77. JSON 解析のエラー報告における、不完全なバイトシーケンスのバッファオーバーラン読み出しが修正されました。 (Jacob Champion) (16)(15)(14)(13)
  78. 最後のバイトが不完全なマルチバイト文字で構成されている場合、入力バッファの末尾から数バイト離れる可能性がありました。通常は無害ですが、原理的にはクラッシュを引き起こす可能性がありました。

  79. OpenSSL でステートフルTLSセッションチケットの作成が無効になりました。 (Daniel Gustafsson) (16)(15)(14)(13)(12)
  80. セッションチケットの受信が TLSセッション再開がサポートされていることを意味すると考えるクライアントで発生するおそれのある障害を、これにより回避できます。

    これまでも無効にしていましたが、OpenSSL 1.1.1 以降の TLSv1.3 に対応した無効化の指定が必要でした。

  81. PL/pgSQL の「単純な式」を再計画するときに、それがまだ単純であることを確認するようになりました。 (Tom Lane) (16)(15)(14)(13)(12)
  82. 参照された関数を削除して集約として再作成するなど、大がかりな変更を行った際に、「ERROR: unexpected plan node type ..」などの予期せぬエラーが発生する可能性がありました。

    (障害動作例 - 単純なSQL関数を PL/pgSQL関数から呼び出す)
    db1=# CREATE FUNCTION f41() RETURNS int LANGUAGE sql AS $$ SELECT 1 + 1 $$;
    db1=# CREATE FUNCTION f41caller() RETURNS int LANGUAGE plpgsql AS $$
            DECLARE x int; BEGIN x := f41simple(); RETURN x; END $$;
    db1=# SELECT f41caller();
     f41caller
    -----------
             2
    (1 row)
    
    (単純な関数を作り直して同セッション内で再度実行するとエラーになる)
    db1=# DROP FUNCTION f41;
    db1=# CREATE FUNCTION f41() RETURNS SETOF int LANGUAGE sql AS
            $$ SELECT g FROM (VALUES (1),(2)) AS g (g) LIMIT 1; $$;
    db1=# SELECT f41caller();
    ERROR:  unexpected plan node type: 311
    CONTEXT:  PL/pgSQL function f41caller() line 1 at assignment
    
  83. PL/pgSQL で、アンダースコア(_)を含む整数範囲の処理が修正されました。 (Erik Wienhold) (16)
  84. PostgreSQL 16.x では整数リテラルにアンダースコアを含めることができますが、PL/pgSQL は「FOR i IN 1_001..1_003」ような文を正しく処理できていませんでした。

    (エラー発生例 - 「1_001」と「..」の間に空白がない場合にエラーとなる)
    db1=# CREATE FUNCTION test(cnt int) RETURNS int LANGUAGE plpgsql AS $$
          DECLARE i integer;
          BEGIN
            FOR i IN 1_001..1_005 LOOP
              cnt := cnt + 1;
            END LOOP;
            RETURN cnt;
         END; $$;
    ERROR:  syntax error at or near "1_001."
    
  85. PL/Python で再帰的に RECORD を返す関数の処理が修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  86. AS句で異なる列定義リストを渡す関数内で、その関数の再帰的な呼び出しを行った場合、内部呼び出しによって外部呼び出しの返す行型を上書きしてしまうため、エラーが発生しました。

    (障害発生例 - 内部で int型列のレコードを返す再帰呼び出しがある)
    db1=# CREATE FUNCTION f43(t text) RETURNS record LANGUAGE plpython3u AS $$
          if t == "text":
              plpy.execute("SELECT * FROM f43('int') AS (a int)");
              return { "a": "x" }
          elif t == "int":
              return { "a": 1 }
          $$;
    
    db1=# SELECT * FROM f43('text') AS (a text);
    ERROR:  invalid input syntax for type integer: "x"
    CONTEXT:  while creating return value
    PL/Python function "f43"
    → 修正後は列名a、値「x」を持つレコードが返る
    
  87. PL/Python で再帰的なトリガーの呼び出し中に TD辞書を破損しないように処理が修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  88. PL/Python のトリガーによって別のトリガーが呼び出された場合、内側のトリガー用に作成された TD辞書によって外側のトリガーの TD辞書が上書きされてしまっていました。

    TD辞書はトリガとして PL/Python 関数を使用した場合に、関連する値を格納するために使われます。

  89. PL/Tcl で、タプルを返す関数の結果で無効なリスト構文を報告する問題が修正されました。 (Erik Wienhold, Tom Lane) (16)(15)(14)(13)(12)
  90. これにより、クラッシュが生じたり、以前の Tclエラーを指す誤ったコンテキスト情報が出力されたりする可能性がありました。

  91. libpq でライブラリ関数 strerror() の非スレッドセーフ利用を回避しました。 (Peter Eisentraut) (16)(15)(14)(13)(12)
  92. マルチスレッドアプリケーションにおいて、OpenSSL から返るエラーメッセージがおかしくなる可能性がありました。

    (以下のようにメッセージがエラーコード表示になってしまうケースが報告された)
    FATAL:  could not load root certificate file "root_ca.crl": SSL error code 2147483650
    
  93. pg_dump でバイナリアップグレード処理中のメモリリークが回避されました。 (Daniel Gustafsson) (16)(15)
  94. pg_dump で --binary-upgrade オプションを指定した場合に該当します。通常、このオプションを使用するのは pg_upgrade コマンドだけです。

  95. 「pg_restore -l」が依存している TOCエントリを正しく報告するようになりました。 (Tom Lane) (16)(15)(14)(13)(12)
  96. pg_restore の「-l」が「-n」や「-N」などの選択的なリストアのオプションと共に指定された場合、コメントなど依存しているオブジェクトが、実際にはダンプに含まれていてリストアされるものであっても、TOC エントリ一覧から省かれていました。

  97. contrib/pg_stat_statements が SQL言語の関数内のユーティリティ命令を識別できるようになりました。 (Anthonin Bonnefoy) (16)
  98. SQL言語の関数のエグゼキュータは、ユーティリティ命令(SELECT/INSERT/UPDATE/DELETE/MERGE 以外)に対して計算したクエリID を伝えそこなっていました。

  99. contrib/postgres_fdw で「ERROR: cursor can only scan forward」エラーが回避されました。 (Etsuro Fujita) (16)(15)
  100. リモートサーバが PostgreSQL 15 以降であって、リモートの単純ではないビューに対して作った外部テーブルを参照する場合に、本エラーが発生します。

  101. contrib/postgres_fdw が SELECT文の FETCH FIRST WITH TIES句をリモートサーバに送出しないようになりました。 (Japin Li) (16)(15)(14)(13)
  102. リモートサーバはこの構文を実装していないか、ローカルサーバとは異なる解釈をするかもしれないため、あえてリモートサーバでの実行を試みることはないと判断されました。

    本構文がサポートされたのは PostgreSQL 13.x 以降です。

  103. OS が提供する ヘッダファイルによる衝突が回避されました。 (Thomas Munro) (16)(15)(14)(13)(12)
  104. maxOS バージョン 15 以降でのコンパイル失敗が修正されます。

  105. プラン要素 Memoize のコスト見積での無害なアサート失敗が修正されました。 (David Rowley) (16)(15)(14)
  106. SP-GiST インデックスに対する REINDEX CONCURRENTLY 実行での無害なアサート失敗が修正されました。 (Tom Lane) (16)(15)(14)(13)(12)
  107. PL/Perl と Perl 5.40 との非互換性が修正されました。 (Andrew Dunstan) (15)(14)(13)(12)
  108. この修正は 9.2.x から 11.x のリポジトリでも修正適用されています。