@@ -816,6 +816,9 @@ main(int argc, char *argv[])
816816 * names matching the expectations of verify_heap_slot_handler, which will
817817 * receive and handle each row returned from the verify_heapam() function.
818818 *
819+ * The constructed SQL command will silently skip temporary tables, as checking
820+ * them would needlessly draw errors from the underlying amcheck function.
821+ *
819822 * sql: buffer into which the heap table checking command will be written
820823 * rel: relation information for the heap table to be checked
821824 * conn: the connection to be used, for string escaping purposes
@@ -825,10 +828,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
825828{
826829 resetPQExpBuffer (sql );
827830 appendPQExpBuffer (sql ,
828- "SELECT blkno, offnum, attnum, msg FROM %s.verify_heapam("
829- "\nrelation := %u, on_error_stop := %s, check_toast := %s, skip := '%s'" ,
831+ "SELECT v.blkno, v.offnum, v.attnum, v.msg "
832+ "FROM pg_catalog.pg_class c, %s.verify_heapam("
833+ "\nrelation := c.oid, on_error_stop := %s, check_toast := %s, skip := '%s'" ,
830834 rel -> datinfo -> amcheck_schema ,
831- rel -> reloid ,
832835 opts .on_error_stop ? "true" : "false" ,
833836 opts .reconcile_toast ? "true" : "false" ,
834837 opts .skip );
@@ -838,7 +841,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
838841 if (opts .endblock >= 0 )
839842 appendPQExpBuffer (sql , ", endblock := " INT64_FORMAT , opts .endblock );
840843
841- appendPQExpBufferChar (sql , ')' );
844+ appendPQExpBuffer (sql ,
845+ "\n) v WHERE c.oid = %u "
846+ "AND c.relpersistence != 't'" ,
847+ rel -> reloid );
842848}
843849
844850/*
@@ -849,6 +855,10 @@ prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
849855 * functions do not return any, but rather return corruption information by
850856 * raising errors, which verify_btree_slot_handler expects.
851857 *
858+ * The constructed SQL command will silently skip temporary indexes, and
859+ * indexes being reindexed concurrently, as checking them would needlessly draw
860+ * errors from the underlying amcheck functions.
861+ *
852862 * sql: buffer into which the heap table checking command will be written
853863 * rel: relation information for the index to be checked
854864 * conn: the connection to be used, for string escaping purposes
@@ -858,27 +868,31 @@ prepare_btree_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn)
858868{
859869 resetPQExpBuffer (sql );
860870
861- /*
862- * Embed the database, schema, and relation name in the query, so if the
863- * check throws an error, the user knows which relation the error came
864- * from.
865- */
866871 if (opts .parent_check )
867872 appendPQExpBuffer (sql ,
868- "SELECT * FROM %s.bt_index_parent_check("
869- "index := '%u'::regclass, heapallindexed := %s, "
870- "rootdescend := %s)" ,
873+ "SELECT %s.bt_index_parent_check("
874+ "index := c.oid, heapallindexed := %s, rootdescend := %s)"
875+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_index i "
876+ "WHERE c.oid = %u "
877+ "AND c.oid = i.indexrelid "
878+ "AND c.relpersistence != 't' "
879+ "AND i.indisready AND i.indisvalid AND i.indislive" ,
871880 rel -> datinfo -> amcheck_schema ,
872- rel -> reloid ,
873881 (opts .heapallindexed ? "true" : "false" ),
874- (opts .rootdescend ? "true" : "false" ));
882+ (opts .rootdescend ? "true" : "false" ),
883+ rel -> reloid );
875884 else
876885 appendPQExpBuffer (sql ,
877- "SELECT * FROM %s.bt_index_check("
878- "index := '%u'::regclass, heapallindexed := %s)" ,
886+ "SELECT %s.bt_index_check("
887+ "index := c.oid, heapallindexed := %s)"
888+ "\nFROM pg_catalog.pg_class c, pg_catalog.pg_index i "
889+ "WHERE c.oid = %u "
890+ "AND c.oid = i.indexrelid "
891+ "AND c.relpersistence != 't' "
892+ "AND i.indisready AND i.indisvalid AND i.indislive" ,
879893 rel -> datinfo -> amcheck_schema ,
880- rel -> reloid ,
881- ( opts . heapallindexed ? "true" : "false" ) );
894+ ( opts . heapallindexed ? "true" : "false" ) ,
895+ rel -> reloid );
882896}
883897
884898/*
@@ -1086,15 +1100,17 @@ verify_btree_slot_handler(PGresult *res, PGconn *conn, void *context)
10861100
10871101 if (PQresultStatus (res ) == PGRES_TUPLES_OK )
10881102 {
1089- int ntups = PQntuples (res );
1103+ int ntups = PQntuples (res );
10901104
1091- if (ntups != 1 )
1105+ if (ntups > 1 )
10921106 {
10931107 /*
10941108 * We expect the btree checking functions to return one void row
1095- * each, so we should output some sort of warning if we get
1096- * anything else, not because it indicates corruption, but because
1097- * it suggests a mismatch between amcheck and pg_amcheck versions.
1109+ * each, or zero rows if the check was skipped due to the object
1110+ * being in the wrong state to be checked, so we should output some
1111+ * sort of warning if we get anything more, not because it
1112+ * indicates corruption, but because it suggests a mismatch between
1113+ * amcheck and pg_amcheck versions.
10981114 *
10991115 * In conjunction with --progress, anything written to stderr at
11001116 * this time would present strangely to the user without an extra
@@ -1889,10 +1905,16 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
18891905 "\nAND (c.relam = %u OR NOT ep.btree_only OR ep.rel_regex IS NULL)" ,
18901906 HEAP_TABLE_AM_OID , BTREE_AM_OID );
18911907
1908+ /*
1909+ * Exclude temporary tables and indexes, which must necessarily belong to
1910+ * other sessions. (We don't create any ourselves.) We must ultimately
1911+ * exclude indexes marked invalid or not ready, but we delay that decision
1912+ * until firing off the amcheck command, as the state of an index may
1913+ * change by then.
1914+ */
1915+ appendPQExpBufferStr (& sql , "\nWHERE c.relpersistence != 't'" );
18921916 if (opts .excludetbl || opts .excludeidx || opts .excludensp )
1893- appendPQExpBufferStr (& sql , "\nWHERE ep.pattern_id IS NULL" );
1894- else
1895- appendPQExpBufferStr (& sql , "\nWHERE true" );
1917+ appendPQExpBufferStr (& sql , "\nAND ep.pattern_id IS NULL" );
18961918
18971919 /*
18981920 * We need to be careful not to break the --no-dependent-toast and
@@ -1944,7 +1966,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
19441966 "\nON ('pg_toast' ~ ep.nsp_regex OR ep.nsp_regex IS NULL)"
19451967 "\nAND (t.relname ~ ep.rel_regex OR ep.rel_regex IS NULL)"
19461968 "\nAND ep.heap_only"
1947- "\nWHERE ep.pattern_id IS NULL" );
1969+ "\nWHERE ep.pattern_id IS NULL"
1970+ "\nAND t.relpersistence != 't'" );
19481971 appendPQExpBufferStr (& sql ,
19491972 "\n)" );
19501973 }
@@ -1962,7 +1985,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
19621985 "\nINNER JOIN pg_catalog.pg_index i "
19631986 "ON r.oid = i.indrelid "
19641987 "INNER JOIN pg_catalog.pg_class c "
1965- "ON i.indexrelid = c.oid" );
1988+ "ON i.indexrelid = c.oid "
1989+ "AND c.relpersistence != 't'" );
19661990 if (opts .excludeidx || opts .excludensp )
19671991 appendPQExpBufferStr (& sql ,
19681992 "\nINNER JOIN pg_catalog.pg_namespace n "
@@ -2000,7 +2024,8 @@ compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations,
20002024 "INNER JOIN pg_catalog.pg_index i "
20012025 "ON t.oid = i.indrelid"
20022026 "\nINNER JOIN pg_catalog.pg_class c "
2003- "ON i.indexrelid = c.oid" );
2027+ "ON i.indexrelid = c.oid "
2028+ "AND c.relpersistence != 't'" );
20042029 if (opts .excludeidx )
20052030 appendPQExpBufferStr (& sql ,
20062031 "\nLEFT OUTER JOIN exclude_pat ep "
0 commit comments