Check if ii_AmCache is NULL in aminsertcleanup
authorTomas Vondra <tomas.vondra@postgresql.org>
Mon, 27 Nov 2023 15:52:59 +0000 (16:52 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Mon, 27 Nov 2023 15:53:06 +0000 (16:53 +0100)
Fix a bug introduced by c1ec02be1d79. It may happen that the executor
opens indexes on the result relation, but no rows end up being inserted.
Then the index_insert_cleanup still gets executed, but passes down NULL
to the AM callback. The AM callback may not expect this, as is the case
of brininsertcleanup, leading to a crash.

Fixed by only calling the cleanup callback if (ii_AmCache != NULL). This
way the AM can simply assume to only see a valid cache.

Reported-by: Richard Guo
Discussion: https://postgr.es/m/CAMbWs4-w9qC-o9hQox9UHvdVZAYTp8OrPQOKtwbvzWaRejTT=Q@mail.gmail.com

src/backend/access/index/indexam.c
src/test/regress/expected/brin.out
src/test/regress/sql/brin.sql

index 597b763d1f68ed1926bcd27921244b9053b00997..f23e0199f08ec36aed1142dc37381fa193ffa3fd 100644 (file)
@@ -207,7 +207,7 @@ index_insert_cleanup(Relation indexRelation,
    RELATION_CHECKS;
    Assert(indexInfo);
 
-   if (indexRelation->rd_indam->aminsertcleanup)
+   if (indexRelation->rd_indam->aminsertcleanup && indexInfo->ii_AmCache)
        indexRelation->rd_indam->aminsertcleanup(indexInfo);
 }
 
index f0b7de5bf76bae7a95a6bf4d707dc68404dc1fbc..2662bb6ed43b0062bf4a02022d172c3b42eb6113 100644 (file)
@@ -572,3 +572,9 @@ CREATE UNLOGGED TABLE brintest_unlogged (n numrange);
 CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n);
 INSERT INTO brintest_unlogged VALUES (numrange(0, 2^1000::numeric));
 DROP TABLE brintest_unlogged;
+-- test that the insert optimization works if no rows end up inserted
+CREATE TABLE brin_insert_optimization (a int);
+INSERT INTO brin_insert_optimization VALUES (1);
+CREATE INDEX ON brin_insert_optimization USING brin (a);
+UPDATE brin_insert_optimization SET a = a;
+DROP TABLE brin_insert_optimization;
index 929a087a25d44c97d21eb2f63cff93f0569263bc..0d3beabb3d7f306fc6a6902beeebf2a534556a68 100644 (file)
@@ -515,3 +515,10 @@ CREATE UNLOGGED TABLE brintest_unlogged (n numrange);
 CREATE INDEX brinidx_unlogged ON brintest_unlogged USING brin (n);
 INSERT INTO brintest_unlogged VALUES (numrange(0, 2^1000::numeric));
 DROP TABLE brintest_unlogged;
+
+-- test that the insert optimization works if no rows end up inserted
+CREATE TABLE brin_insert_optimization (a int);
+INSERT INTO brin_insert_optimization VALUES (1);
+CREATE INDEX ON brin_insert_optimization USING brin (a);
+UPDATE brin_insert_optimization SET a = a;
+DROP TABLE brin_insert_optimization;