public inbox for [email protected]  
help / color / mirror / Atom feed
From: Alena Rybakina <[email protected]>
To: Alexander Korotkov <[email protected]>
To: jian he <[email protected]>
To: Kirill Reshke <[email protected]>
Cc: Ilia Evdokimov <[email protected]>
Cc: Andrei Zubkov <[email protected]>
Cc: Alena Rybakina <[email protected]>
Cc: pgsql-hackers <[email protected]>
Cc: [email protected]
Subject: Re: Vacuum statistics
Date: Mon, 26 Aug 2024 14:55:13 +0300
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
References: <[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<[email protected]>
	<CACJufxHb_YGCp=pVH6DZcpk9yML+SueffPeaRbX2LzXZVahd_w@mail.gmail.com>
	<CACJufxE6yAP+jUm4_GyKp7gUCkzbuJ9HGB-rR=92_hcLLZ9KTg@mail.gmail.com>
	<[email protected]>
	<[email protected]>
	<CAPpHfdug0s2MD7bBf-5nDQGn1WBxCKiTmZyGfxHz_7P0CDOjbg@mail.gmail.com>
	<[email protected]>

Just in case, I have attached a diff file to show the changes for the 
latest version attached here [0] to make the review process easier.

[0] 
https://www.postgresql.org/message-id/c4e4e305-7119-4183-b49a-d7092f4efba3%40postgrespro.ru

-- 
Regards,
Alena Rybakina
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 42d3ad21486..8cbccdc4a4d 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -5360,7 +5360,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
         Number of times blocks of this index were already found
         in the buffer cache by vacuum operations, so that a read was not necessary
         (this only includes hits in the
-        &project; buffer cache, not the operating system's file system cache)
+        project; buffer cache, not the operating system's file system cache)
       </para></entry>
      </row>
 
@@ -5601,7 +5601,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
         Number of times blocks of this table were already found
         in the buffer cache by vacuum operations, so that a read was not necessary
         (this only includes hits in the
-        &project; buffer cache, not the operating system's file system cache)
+        project; buffer cache, not the operating system's file system cache)
       </para></entry>
      </row>
 
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ca3ad09727e..76a2ffff2bb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1420,7 +1420,7 @@ FROM
   pg_database db,
   pg_class rel,
   pg_namespace ns,
-  pg_stat_vacuum_tables(db.oid, rel.oid) stats
+  pg_stat_vacuum_tables(rel.oid) stats
 WHERE
   db.datname = current_database() AND
   rel.oid = stats.relid AND
@@ -1460,7 +1460,7 @@ FROM
   pg_database db,
   pg_class rel,
   pg_namespace ns,
-  pg_stat_vacuum_indexes(db.oid, rel.oid) stats
+  pg_stat_vacuum_indexes(rel.oid) stats
 WHERE
   db.datname = current_database() AND
   rel.oid = stats.relid AND
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 3c50bea379c..b633408777e 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -146,6 +146,34 @@
 #define PGSTAT_FILE_ENTRY_HASH	'S' /* stats entry identified by
 									 * PgStat_HashKey */
 
+/* hash table for statistics snapshots entry */
+typedef struct PgStat_SnapshotEntry
+{
+	PgStat_HashKey key;
+	char		status;			/* for simplehash use */
+	void	   *data;			/* the stats data itself */
+} PgStat_SnapshotEntry;
+
+
+/* ----------
+ * Backend-local Hash Table Definitions
+ * ----------
+ */
+
+/* for stats snapshot entries */
+#define SH_PREFIX pgstat_snapshot
+#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
+#define SH_KEY_TYPE PgStat_HashKey
+#define SH_KEY key
+#define SH_HASH_KEY(tb, key) \
+	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
+#define SH_EQUAL(tb, a, b) \
+	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
+#define SH_SCOPE static inline
+#define SH_DEFINE
+#define SH_DECLARE
+#include "lib/simplehash.h"
+
 
 /* ----------
  * Local function forward declarations
@@ -232,7 +260,6 @@ static bool pgstat_is_initialized = false;
 static bool pgstat_is_shutdown = false;
 #endif
 
-
 /*
  * The different kinds of built-in statistics.
  *
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0c490ba5f1a..9a9b6f807bf 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -33,6 +33,41 @@
 #include "utils/timestamp.h"
 #include "utils/pgstat_internal.h"
 
+/* hash table for statistics snapshots entry */
+typedef struct PgStat_SnapshotEntry
+{
+	PgStat_HashKey key;
+	char		status;			/* for simplehash use */
+	void	   *data;			/* the stats data itself */
+} PgStat_SnapshotEntry;
+
+/* ----------
+ * Backend-local Hash Table Definitions
+ * ----------
+ */
+
+/* for stats snapshot entries */
+#define SH_PREFIX pgstat_snapshot
+#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
+#define SH_KEY_TYPE PgStat_HashKey
+#define SH_KEY key
+#define SH_HASH_KEY(tb, key) \
+	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
+#define SH_EQUAL(tb, a, b) \
+	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
+#define SH_SCOPE static inline
+#define SH_DEFINE
+#define SH_DECLARE
+#include "lib/simplehash.h"
+
+typedef pgstat_snapshot_iterator SnapshotIterator;
+
+#define InitSnapshotIterator(htable, iter) \
+	pgstat_snapshot_start_iterate(htable, iter);
+#define ScanStatSnapshot(htable, iter) \
+	pgstat_snapshot_iterate(htable, iter)
+
+
 #define UINT32_ACCESS_ONCE(var)		 ((uint32)(*((volatile uint32 *)&(var))))
 
 #define HAS_PGSTAT_PERMISSIONS(role)	 (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
@@ -2039,47 +2074,9 @@ pg_stat_have_stats(PG_FUNCTION_ARGS)
 #define EXTVACDBSTAT_COLUMNS	15
 #define EXTVACSTAT_COLUMNS Max(EXTVACHEAPSTAT_COLUMNS, EXTVACIDXSTAT_COLUMNS)
 
-static Oid CurrentDatabaseId = InvalidOid;
-
-
-/*
- * Fetch stat collector data for specific database and table, which loading from disc.
- * It is maybe expensive, but i guess we won't use that machinery often.
- * The kind of bufferization is based on CurrentDatabaseId value.
- */
-static PgStat_StatTabEntry *
-fetch_dbstat_tabentry(Oid dbid, Oid relid)
-{
-	Oid						storedMyDatabaseId = MyDatabaseId;
-	PgStat_StatTabEntry 	*tabentry = NULL;
-
-	if (OidIsValid(CurrentDatabaseId) && CurrentDatabaseId == dbid)
-		/* Quick path when we read data from the same database */
-		return pgstat_fetch_stat_tabentry(relid);
-
-	pgstat_clear_snapshot();
-
-	/* Tricky turn here: enforce pgstat to think that our database has dbid */
-
-	MyDatabaseId = dbid;
-
-	PG_TRY();
-	{
-		tabentry = pgstat_fetch_stat_tabentry(relid);
-		MyDatabaseId = storedMyDatabaseId;
-	}
-	PG_CATCH();
-	{
-		MyDatabaseId = storedMyDatabaseId;
-	}
-	PG_END_TRY();
-
-	return tabentry;
-}
-
 static void
-tuplestore_put_for_database(Oid dbid, Tuplestorestate *tupstore,
-			   TupleDesc tupdesc, PgStatShared_Database *dbentry, int ncolumns)
+tuplestore_put_for_database(Oid dbid, ReturnSetInfo *rsinfo,
+							PgStatShared_Database *dbentry)
 {
 	Datum		values[EXTVACDBSTAT_COLUMNS];
 	bool		nulls[EXTVACDBSTAT_COLUMNS];
@@ -2113,15 +2110,13 @@ tuplestore_put_for_database(Oid dbid, Tuplestorestate *tupstore,
 	values[i++] = Float8GetDatum(dbentry->stats.vacuum_ext.total_time);
 	values[i++] = Int32GetDatum(dbentry->stats.vacuum_ext.interrupts);
 
-
-	Assert(i == ncolumns);
-
-	tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+	Assert(i == rsinfo->setDesc->natts);
+	tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
 }
 
 static void
-tuplestore_put_for_relation(Oid relid, Tuplestorestate *tupstore,
-			   TupleDesc tupdesc, PgStat_StatTabEntry *tabentry, int ncolumns)
+tuplestore_put_for_relation(Oid relid, ReturnSetInfo *rsinfo,
+							PgStat_StatTabEntry *tabentry)
 {
 	Datum		values[EXTVACSTAT_COLUMNS];
 	bool		nulls[EXTVACSTAT_COLUMNS];
@@ -2179,23 +2174,17 @@ tuplestore_put_for_relation(Oid relid, Tuplestorestate *tupstore,
 	values[i++] = Float8GetDatum(tabentry->vacuum_ext.total_time);
 	values[i++] = Int32GetDatum(tabentry->vacuum_ext.interrupts);
 
-	Assert(i == ncolumns);
-
-	tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+	Assert(i == rsinfo->setDesc->natts);
+	tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
 }
 
 /*
  * Get the vacuum statistics for the heap tables or indexes.
  */
-static Datum
+static void
 pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 {
 	ReturnSetInfo		   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
-	MemoryContext			per_query_ctx;
-	MemoryContext			oldcontext;
-	Tuplestorestate		   *tupstore;
-	TupleDesc				tupdesc;
-	Oid						dbid = PG_GETARG_OID(0);
 	PgStat_StatTabEntry    *tabentry;
 
 	InitMaterializedSRF(fcinfo, 0);
@@ -2205,61 +2194,39 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("set-valued function called in context that cannot accept a set")));
-	/* Switch to long-lived context to create the returned data structures */
-	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
-	oldcontext = MemoryContextSwitchTo(per_query_ctx);
-
-	/* Build a tuple descriptor for our result type */
-	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
-		elog(ERROR, "return type must be a row type");
-
-	Assert(tupdesc->natts == ncolumns);
-
-	tupstore = tuplestore_begin_heap(true, false, work_mem);
-	Assert (tupstore != NULL);
-	rsinfo->setResult = tupstore;
-	rsinfo->setDesc = tupdesc;
-
-	MemoryContextSwitchTo(oldcontext);
+	Assert(rsinfo->setDesc->natts == ncolumns);
+	Assert(rsinfo->setResult != NULL);
 
 	if (type == PGSTAT_EXTVAC_INDEX || type == PGSTAT_EXTVAC_HEAP)
 	{
-		Oid					relid = PG_GETARG_OID(1);
+		Oid					relid = PG_GETARG_OID(0);
 
-		/* Load table statistics for specified database. */
+		/* Load table statistics for specified relation. */
 		if (OidIsValid(relid))
 		{
-			tabentry = fetch_dbstat_tabentry(dbid, relid);
+			tabentry = pgstat_fetch_stat_tabentry(relid);
 			if (tabentry == NULL || tabentry->vacuum_ext.type != type)
 				/* Table don't exists or isn't an heap relation. */
-				PG_RETURN_NULL();
+				return;
 
-			tuplestore_put_for_relation(relid, tupstore, tupdesc, tabentry, ncolumns);
+			tuplestore_put_for_relation(relid, rsinfo, tabentry);
 		}
 		else
 		{
 			SnapshotIterator		hashiter;
 			PgStat_SnapshotEntry   *entry;
-			Oid						storedMyDatabaseId = MyDatabaseId;
-
-			pgstat_update_snapshot(PGSTAT_KIND_RELATION);
-			MyDatabaseId = storedMyDatabaseId;
-
 
 			/* Iterate the snapshot */
 			InitSnapshotIterator(pgStatLocal.snapshot.stats, &hashiter);
 
 			while ((entry = ScanStatSnapshot(pgStatLocal.snapshot.stats, &hashiter)) != NULL)
 			{
-				Oid	reloid;
-
 				CHECK_FOR_INTERRUPTS();
 
 				tabentry = (PgStat_StatTabEntry *) entry->data;
-				reloid = entry->key.objoid;
 
 				if (tabentry != NULL && tabentry->vacuum_ext.type == type)
-					tuplestore_put_for_relation(reloid, tupstore, tupdesc, tabentry, ncolumns);
+					tuplestore_put_for_relation(relid, rsinfo, tabentry);
 			}
 		}
 	}
@@ -2267,10 +2234,7 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 	{
 		PgStatShared_Database	   *dbentry;
 		PgStat_EntryRef 		   *entry_ref;
-		Oid						storedMyDatabaseId = MyDatabaseId;
-
-		pgstat_update_snapshot(PGSTAT_KIND_DATABASE);
-		MyDatabaseId = storedMyDatabaseId;
+		Oid							dbid = PG_GETARG_OID(0);
 
 		if (OidIsValid(dbid))
 		{
@@ -2280,15 +2244,12 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 
 			if (dbentry == NULL)
 				/* Table doesn't exist or isn't a heap relation */
-				PG_RETURN_NULL();
+				return;
 
-			tuplestore_put_for_database(dbid, tupstore, tupdesc, dbentry, ncolumns);
+			tuplestore_put_for_database(dbid, rsinfo, dbentry);
 			pgstat_unlock_entry(entry_ref);
 		}
-		else
-			PG_RETURN_NULL();
 	}
-	PG_RETURN_NULL();
 }
 
 /*
@@ -2297,9 +2258,9 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 Datum
 pg_stat_vacuum_tables(PG_FUNCTION_ARGS)
 {
-	return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_HEAP, EXTVACHEAPSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_HEAP, EXTVACHEAPSTAT_COLUMNS);
 
-	PG_RETURN_NULL();
+	PG_RETURN_VOID();
 }
 
 /*
@@ -2308,10 +2269,11 @@ pg_stat_vacuum_tables(PG_FUNCTION_ARGS)
 Datum
 pg_stat_vacuum_indexes(PG_FUNCTION_ARGS)
 {
-	return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_INDEX, EXTVACIDXSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_INDEX, EXTVACIDXSTAT_COLUMNS);
+
+ 	PG_RETURN_VOID();
+ }
 
-	PG_RETURN_NULL();
-}
 
 /*
  * Get the vacuum statistics for the database.
@@ -2319,7 +2281,7 @@ pg_stat_vacuum_indexes(PG_FUNCTION_ARGS)
 Datum
 pg_stat_vacuum_database(PG_FUNCTION_ARGS)
 {
-		return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_DB, EXTVACDBSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_DB, EXTVACDBSTAT_COLUMNS);
 
-	PG_RETURN_NULL();
-}
+	PG_RETURN_VOID();
+}
\ No newline at end of file
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index b2e881aa89d..d4696d0c055 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12258,20 +12258,20 @@
   descr => 'pg_stat_vacuum_tables return stats values',
   proname => 'pg_stat_vacuum_tables', provolatile => 's', prorettype => 'record',proisstrict => 'f',
   proretset => 't',
-  proargtypes => 'oid oid',
-  proallargtypes => '{oid,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
-  proargmodes => '{i,i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{dboid,reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_scanned,pages_removed,pages_frozen,pages_all_visible,tuples_deleted,tuples_frozen,dead_tuples,index_vacuum_count,rev_all_frozen_pages,rev_all_visible_pages,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
+  proargtypes => 'oid',
+  proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
+  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_scanned,pages_removed,pages_frozen,pages_all_visible,tuples_deleted,tuples_frozen,dead_tuples,index_vacuum_count,rev_all_frozen_pages,rev_all_visible_pages,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
   prosrc => 'pg_stat_vacuum_tables' },
 { oid => '8002',
   descr => 'pg_stat_vacuum_indexes return stats values',
   proname => 'pg_stat_vacuum_indexes', provolatile => 's', prorettype => 'record',proisstrict => 'f',
   proretset => 't',
-  proargtypes => 'oid oid',
-  proallargtypes => '{oid,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
-  proargmodes => '{i,i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{dboid,reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_deleted,tuples_deleted,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
-  prosrc => 'pg_stat_vacuum_indexes' }
+  proargtypes => 'oid',
+  proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
+  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_deleted,tuples_deleted,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
+  prosrc => 'pg_stat_vacuum_indexes' },
 { oid => '8003',
   descr => 'pg_stat_vacuum_database return stats values',
   proname => 'pg_stat_vacuum_database', provolatile => 's', prorettype => 'record',proisstrict => 'f',
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 715ae1b6fd4..24ab3ceb717 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -874,38 +874,4 @@ pgstat_get_custom_snapshot_data(PgStat_Kind kind)
 	return pgStatLocal.snapshot.custom_data[idx];
 }
 
-/* hash table for statistics snapshots entry */
-typedef struct PgStat_SnapshotEntry
-{
-	PgStat_HashKey key;
-	char		status;			/* for simplehash use */
-	void	   *data;			/* the stats data itself */
-} PgStat_SnapshotEntry;
-
-/* ----------
- * Backend-local Hash Table Definitions
- * ----------
- */
-
-/* for stats snapshot entries */
-#define SH_PREFIX pgstat_snapshot
-#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
-#define SH_KEY_TYPE PgStat_HashKey
-#define SH_KEY key
-#define SH_HASH_KEY(tb, key) \
-	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
-#define SH_EQUAL(tb, a, b) \
-	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
-#define SH_SCOPE static inline
-#define SH_DEFINE
-#define SH_DECLARE
-#include "lib/simplehash.h"
-
-typedef pgstat_snapshot_iterator SnapshotIterator;
-
-#define InitSnapshotIterator(htable, iter) \
-	pgstat_snapshot_start_iterate(htable, iter);
-#define ScanStatSnapshot(htable, iter) \
-	pgstat_snapshot_iterate(htable, iter)
-
 #endif							/* PGSTAT_INTERNAL_H */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index c4388dd0da1..5d7f73c25fd 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2271,7 +2271,7 @@ pg_stat_vacuum_indexes| SELECT rel.oid AS relid,
    FROM pg_database db,
     pg_class rel,
     pg_namespace ns,
-    LATERAL pg_stat_vacuum_indexes(db.oid, rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
+    LATERAL pg_stat_vacuum_indexes(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
   WHERE ((db.datname = current_database()) AND (rel.oid = stats.relid) AND (ns.oid = rel.relnamespace));
 pg_stat_vacuum_tables| SELECT rel.oid AS relid,
     ns.nspname AS schema,
@@ -2305,7 +2305,7 @@ pg_stat_vacuum_tables| SELECT rel.oid AS relid,
    FROM pg_database db,
     pg_class rel,
     pg_namespace ns,
-    LATERAL pg_stat_vacuum_tables(db.oid, rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, pages_frozen, pages_all_visible, tuples_deleted, tuples_frozen, dead_tuples, index_vacuum_count, rev_all_frozen_pages, rev_all_visible_pages, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
+    LATERAL pg_stat_vacuum_tables(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, pages_frozen, pages_all_visible, tuples_deleted, tuples_frozen, dead_tuples, index_vacuum_count, rev_all_frozen_pages, rev_all_visible_pages, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
   WHERE ((db.datname = current_database()) AND (rel.oid = stats.relid) AND (ns.oid = rel.relnamespace));
 pg_stat_wal| SELECT wal_records,
     wal_fpi,
diff --git a/src/test/regress/expected/vacuum_tables_and_db_statistics.out b/src/test/regress/expected/vacuum_tables_and_db_statistics.out
index f0537aac430..ec0cf97e2da 100644
--- a/src/test/regress/expected/vacuum_tables_and_db_statistics.out
+++ b/src/test/regress/expected/vacuum_tables_and_db_statistics.out
@@ -6,9 +6,9 @@
 -- number of frozen and visible pages removed by backend.
 -- Statistic wal_fpi is not displayed in this test because its behavior is unstable.
 --
-CREATE DATABASE statistic_vacuum_database;
-CREATE DATABASE statistic_vacuum_database1;
-\c statistic_vacuum_database;
+CREATE DATABASE regression_statistic_vacuum_db;
+CREATE DATABASE regression_statistic_vacuum_db1;
+\c regression_statistic_vacuum_db;
 -- conditio sine qua non
 SHOW track_counts;  -- must be on
  track_counts 
@@ -212,9 +212,9 @@ SELECT dbname,
 FROM
 pg_stat_vacuum_database
 WHERE dbname = current_database();
-          dbname           | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
----------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
- statistic_vacuum_database | t           | t                  | t                  | t           | t       | t         | t         | t
+             dbname             | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
+--------------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
+ regression_statistic_vacuum_db | t           | t                  | t                  | t           | t       | t         | t         | t
 (1 row)
 
 DROP TABLE vestat CASCADE;
@@ -230,7 +230,7 @@ INSERT INTO vestat SELECT x FROM generate_series(1,:sample_size) as x;
 ANALYZE vestat;
 UPDATE vestat SET x = 10001;
 VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 -- Now check vacuum statistics for postgres database from another database
 SELECT dbname,
        db_blks_hit > 0 AS db_blks_hit,
@@ -243,20 +243,20 @@ SELECT dbname,
        total_time > 0 AS total_time
 FROM
 pg_stat_vacuum_database
-WHERE dbname = 'statistic_vacuum_database';
-          dbname           | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
----------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
- statistic_vacuum_database | t           | t                  | t                  | t           | t       | t         | t         | t
+WHERE dbname = 'regression_statistic_vacuum_db';
+             dbname             | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
+--------------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
+ regression_statistic_vacuum_db | t           | t                  | t                  | t           | t       | t         | t         | t
 (1 row)
 
-\c statistic_vacuum_database
+\c regression_statistic_vacuum_db
 RESET vacuum_freeze_min_age;
 RESET vacuum_freeze_table_age;
 DROP TABLE vestat CASCADE;
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 SELECT count(*)
 FROM pg_database d
-CROSS JOIN pg_stat_vacuum_tables(d.oid, 0)
+CROSS JOIN pg_stat_vacuum_tables(0)
 WHERE oid = 0; -- must be 0
  count 
 -------
@@ -273,5 +273,5 @@ WHERE oid = 0; -- must be 0
 (1 row)
 
 \c postgres
-DROP DATABASE statistic_vacuum_database1;
-DROP DATABASE statistic_vacuum_database;
+DROP DATABASE regression_statistic_vacuum_db1;
+DROP DATABASE regression_statistic_vacuum_db;
diff --git a/src/test/regress/sql/vacuum_tables_and_db_statistics.sql b/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
index 43cc8068b0f..ed9bb852625 100644
--- a/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
+++ b/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
@@ -7,9 +7,9 @@
 -- Statistic wal_fpi is not displayed in this test because its behavior is unstable.
 --
 
-CREATE DATABASE statistic_vacuum_database;
-CREATE DATABASE statistic_vacuum_database1;
-\c statistic_vacuum_database;
+CREATE DATABASE regression_statistic_vacuum_db;
+CREATE DATABASE regression_statistic_vacuum_db1;
+\c regression_statistic_vacuum_db;
 
 -- conditio sine qua non
 SHOW track_counts;  -- must be on
@@ -184,7 +184,7 @@ ANALYZE vestat;
 UPDATE vestat SET x = 10001;
 VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
 
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 
 -- Now check vacuum statistics for postgres database from another database
 SELECT dbname,
@@ -198,18 +198,18 @@ SELECT dbname,
        total_time > 0 AS total_time
 FROM
 pg_stat_vacuum_database
-WHERE dbname = 'statistic_vacuum_database';
+WHERE dbname = 'regression_statistic_vacuum_db';
 
-\c statistic_vacuum_database
+\c regression_statistic_vacuum_db
 
 RESET vacuum_freeze_min_age;
 RESET vacuum_freeze_table_age;
 DROP TABLE vestat CASCADE;
 
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 SELECT count(*)
 FROM pg_database d
-CROSS JOIN pg_stat_vacuum_tables(d.oid, 0)
+CROSS JOIN pg_stat_vacuum_tables(0)
 WHERE oid = 0; -- must be 0
 
 SELECT count(*)
@@ -218,5 +218,5 @@ CROSS JOIN pg_stat_vacuum_database(0)
 WHERE oid = 0; -- must be 0
 
 \c postgres
-DROP DATABASE statistic_vacuum_database1;
-DROP DATABASE statistic_vacuum_database;
+DROP DATABASE regression_statistic_vacuum_db1;
+DROP DATABASE regression_statistic_vacuum_db;


Attachments:

  [text/plain] diff_vacuum.diff.no-cfbot (24.4K, 2-diff_vacuum.diff.no-cfbot)
  download | inline diff:
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
index 42d3ad21486..8cbccdc4a4d 100644
--- a/doc/src/sgml/system-views.sgml
+++ b/doc/src/sgml/system-views.sgml
@@ -5360,7 +5360,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
         Number of times blocks of this index were already found
         in the buffer cache by vacuum operations, so that a read was not necessary
         (this only includes hits in the
-        &project; buffer cache, not the operating system's file system cache)
+        project; buffer cache, not the operating system's file system cache)
       </para></entry>
      </row>
 
@@ -5601,7 +5601,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
         Number of times blocks of this table were already found
         in the buffer cache by vacuum operations, so that a read was not necessary
         (this only includes hits in the
-        &project; buffer cache, not the operating system's file system cache)
+        project; buffer cache, not the operating system's file system cache)
       </para></entry>
      </row>
 
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index ca3ad09727e..76a2ffff2bb 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1420,7 +1420,7 @@ FROM
   pg_database db,
   pg_class rel,
   pg_namespace ns,
-  pg_stat_vacuum_tables(db.oid, rel.oid) stats
+  pg_stat_vacuum_tables(rel.oid) stats
 WHERE
   db.datname = current_database() AND
   rel.oid = stats.relid AND
@@ -1460,7 +1460,7 @@ FROM
   pg_database db,
   pg_class rel,
   pg_namespace ns,
-  pg_stat_vacuum_indexes(db.oid, rel.oid) stats
+  pg_stat_vacuum_indexes(rel.oid) stats
 WHERE
   db.datname = current_database() AND
   rel.oid = stats.relid AND
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 3c50bea379c..b633408777e 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -146,6 +146,34 @@
 #define PGSTAT_FILE_ENTRY_HASH	'S' /* stats entry identified by
 									 * PgStat_HashKey */
 
+/* hash table for statistics snapshots entry */
+typedef struct PgStat_SnapshotEntry
+{
+	PgStat_HashKey key;
+	char		status;			/* for simplehash use */
+	void	   *data;			/* the stats data itself */
+} PgStat_SnapshotEntry;
+
+
+/* ----------
+ * Backend-local Hash Table Definitions
+ * ----------
+ */
+
+/* for stats snapshot entries */
+#define SH_PREFIX pgstat_snapshot
+#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
+#define SH_KEY_TYPE PgStat_HashKey
+#define SH_KEY key
+#define SH_HASH_KEY(tb, key) \
+	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
+#define SH_EQUAL(tb, a, b) \
+	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
+#define SH_SCOPE static inline
+#define SH_DEFINE
+#define SH_DECLARE
+#include "lib/simplehash.h"
+
 
 /* ----------
  * Local function forward declarations
@@ -232,7 +260,6 @@ static bool pgstat_is_initialized = false;
 static bool pgstat_is_shutdown = false;
 #endif
 
-
 /*
  * The different kinds of built-in statistics.
  *
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 0c490ba5f1a..9a9b6f807bf 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -33,6 +33,41 @@
 #include "utils/timestamp.h"
 #include "utils/pgstat_internal.h"
 
+/* hash table for statistics snapshots entry */
+typedef struct PgStat_SnapshotEntry
+{
+	PgStat_HashKey key;
+	char		status;			/* for simplehash use */
+	void	   *data;			/* the stats data itself */
+} PgStat_SnapshotEntry;
+
+/* ----------
+ * Backend-local Hash Table Definitions
+ * ----------
+ */
+
+/* for stats snapshot entries */
+#define SH_PREFIX pgstat_snapshot
+#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
+#define SH_KEY_TYPE PgStat_HashKey
+#define SH_KEY key
+#define SH_HASH_KEY(tb, key) \
+	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
+#define SH_EQUAL(tb, a, b) \
+	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
+#define SH_SCOPE static inline
+#define SH_DEFINE
+#define SH_DECLARE
+#include "lib/simplehash.h"
+
+typedef pgstat_snapshot_iterator SnapshotIterator;
+
+#define InitSnapshotIterator(htable, iter) \
+	pgstat_snapshot_start_iterate(htable, iter);
+#define ScanStatSnapshot(htable, iter) \
+	pgstat_snapshot_iterate(htable, iter)
+
+
 #define UINT32_ACCESS_ONCE(var)		 ((uint32)(*((volatile uint32 *)&(var))))
 
 #define HAS_PGSTAT_PERMISSIONS(role)	 (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
@@ -2039,47 +2074,9 @@ pg_stat_have_stats(PG_FUNCTION_ARGS)
 #define EXTVACDBSTAT_COLUMNS	15
 #define EXTVACSTAT_COLUMNS Max(EXTVACHEAPSTAT_COLUMNS, EXTVACIDXSTAT_COLUMNS)
 
-static Oid CurrentDatabaseId = InvalidOid;
-
-
-/*
- * Fetch stat collector data for specific database and table, which loading from disc.
- * It is maybe expensive, but i guess we won't use that machinery often.
- * The kind of bufferization is based on CurrentDatabaseId value.
- */
-static PgStat_StatTabEntry *
-fetch_dbstat_tabentry(Oid dbid, Oid relid)
-{
-	Oid						storedMyDatabaseId = MyDatabaseId;
-	PgStat_StatTabEntry 	*tabentry = NULL;
-
-	if (OidIsValid(CurrentDatabaseId) && CurrentDatabaseId == dbid)
-		/* Quick path when we read data from the same database */
-		return pgstat_fetch_stat_tabentry(relid);
-
-	pgstat_clear_snapshot();
-
-	/* Tricky turn here: enforce pgstat to think that our database has dbid */
-
-	MyDatabaseId = dbid;
-
-	PG_TRY();
-	{
-		tabentry = pgstat_fetch_stat_tabentry(relid);
-		MyDatabaseId = storedMyDatabaseId;
-	}
-	PG_CATCH();
-	{
-		MyDatabaseId = storedMyDatabaseId;
-	}
-	PG_END_TRY();
-
-	return tabentry;
-}
-
 static void
-tuplestore_put_for_database(Oid dbid, Tuplestorestate *tupstore,
-			   TupleDesc tupdesc, PgStatShared_Database *dbentry, int ncolumns)
+tuplestore_put_for_database(Oid dbid, ReturnSetInfo *rsinfo,
+							PgStatShared_Database *dbentry)
 {
 	Datum		values[EXTVACDBSTAT_COLUMNS];
 	bool		nulls[EXTVACDBSTAT_COLUMNS];
@@ -2113,15 +2110,13 @@ tuplestore_put_for_database(Oid dbid, Tuplestorestate *tupstore,
 	values[i++] = Float8GetDatum(dbentry->stats.vacuum_ext.total_time);
 	values[i++] = Int32GetDatum(dbentry->stats.vacuum_ext.interrupts);
 
-
-	Assert(i == ncolumns);
-
-	tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+	Assert(i == rsinfo->setDesc->natts);
+	tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
 }
 
 static void
-tuplestore_put_for_relation(Oid relid, Tuplestorestate *tupstore,
-			   TupleDesc tupdesc, PgStat_StatTabEntry *tabentry, int ncolumns)
+tuplestore_put_for_relation(Oid relid, ReturnSetInfo *rsinfo,
+							PgStat_StatTabEntry *tabentry)
 {
 	Datum		values[EXTVACSTAT_COLUMNS];
 	bool		nulls[EXTVACSTAT_COLUMNS];
@@ -2179,23 +2174,17 @@ tuplestore_put_for_relation(Oid relid, Tuplestorestate *tupstore,
 	values[i++] = Float8GetDatum(tabentry->vacuum_ext.total_time);
 	values[i++] = Int32GetDatum(tabentry->vacuum_ext.interrupts);
 
-	Assert(i == ncolumns);
-
-	tuplestore_putvalues(tupstore, tupdesc, values, nulls);
+	Assert(i == rsinfo->setDesc->natts);
+	tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
 }
 
 /*
  * Get the vacuum statistics for the heap tables or indexes.
  */
-static Datum
+static void
 pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 {
 	ReturnSetInfo		   *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
-	MemoryContext			per_query_ctx;
-	MemoryContext			oldcontext;
-	Tuplestorestate		   *tupstore;
-	TupleDesc				tupdesc;
-	Oid						dbid = PG_GETARG_OID(0);
 	PgStat_StatTabEntry    *tabentry;
 
 	InitMaterializedSRF(fcinfo, 0);
@@ -2205,61 +2194,39 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("set-valued function called in context that cannot accept a set")));
-	/* Switch to long-lived context to create the returned data structures */
-	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
-	oldcontext = MemoryContextSwitchTo(per_query_ctx);
-
-	/* Build a tuple descriptor for our result type */
-	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
-		elog(ERROR, "return type must be a row type");
-
-	Assert(tupdesc->natts == ncolumns);
-
-	tupstore = tuplestore_begin_heap(true, false, work_mem);
-	Assert (tupstore != NULL);
-	rsinfo->setResult = tupstore;
-	rsinfo->setDesc = tupdesc;
-
-	MemoryContextSwitchTo(oldcontext);
+	Assert(rsinfo->setDesc->natts == ncolumns);
+	Assert(rsinfo->setResult != NULL);
 
 	if (type == PGSTAT_EXTVAC_INDEX || type == PGSTAT_EXTVAC_HEAP)
 	{
-		Oid					relid = PG_GETARG_OID(1);
+		Oid					relid = PG_GETARG_OID(0);
 
-		/* Load table statistics for specified database. */
+		/* Load table statistics for specified relation. */
 		if (OidIsValid(relid))
 		{
-			tabentry = fetch_dbstat_tabentry(dbid, relid);
+			tabentry = pgstat_fetch_stat_tabentry(relid);
 			if (tabentry == NULL || tabentry->vacuum_ext.type != type)
 				/* Table don't exists or isn't an heap relation. */
-				PG_RETURN_NULL();
+				return;
 
-			tuplestore_put_for_relation(relid, tupstore, tupdesc, tabentry, ncolumns);
+			tuplestore_put_for_relation(relid, rsinfo, tabentry);
 		}
 		else
 		{
 			SnapshotIterator		hashiter;
 			PgStat_SnapshotEntry   *entry;
-			Oid						storedMyDatabaseId = MyDatabaseId;
-
-			pgstat_update_snapshot(PGSTAT_KIND_RELATION);
-			MyDatabaseId = storedMyDatabaseId;
-
 
 			/* Iterate the snapshot */
 			InitSnapshotIterator(pgStatLocal.snapshot.stats, &hashiter);
 
 			while ((entry = ScanStatSnapshot(pgStatLocal.snapshot.stats, &hashiter)) != NULL)
 			{
-				Oid	reloid;
-
 				CHECK_FOR_INTERRUPTS();
 
 				tabentry = (PgStat_StatTabEntry *) entry->data;
-				reloid = entry->key.objoid;
 
 				if (tabentry != NULL && tabentry->vacuum_ext.type == type)
-					tuplestore_put_for_relation(reloid, tupstore, tupdesc, tabentry, ncolumns);
+					tuplestore_put_for_relation(relid, rsinfo, tabentry);
 			}
 		}
 	}
@@ -2267,10 +2234,7 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 	{
 		PgStatShared_Database	   *dbentry;
 		PgStat_EntryRef 		   *entry_ref;
-		Oid						storedMyDatabaseId = MyDatabaseId;
-
-		pgstat_update_snapshot(PGSTAT_KIND_DATABASE);
-		MyDatabaseId = storedMyDatabaseId;
+		Oid							dbid = PG_GETARG_OID(0);
 
 		if (OidIsValid(dbid))
 		{
@@ -2280,15 +2244,12 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 
 			if (dbentry == NULL)
 				/* Table doesn't exist or isn't a heap relation */
-				PG_RETURN_NULL();
+				return;
 
-			tuplestore_put_for_database(dbid, tupstore, tupdesc, dbentry, ncolumns);
+			tuplestore_put_for_database(dbid, rsinfo, dbentry);
 			pgstat_unlock_entry(entry_ref);
 		}
-		else
-			PG_RETURN_NULL();
 	}
-	PG_RETURN_NULL();
 }
 
 /*
@@ -2297,9 +2258,9 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, ExtVacReportType type, int ncolumns)
 Datum
 pg_stat_vacuum_tables(PG_FUNCTION_ARGS)
 {
-	return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_HEAP, EXTVACHEAPSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_HEAP, EXTVACHEAPSTAT_COLUMNS);
 
-	PG_RETURN_NULL();
+	PG_RETURN_VOID();
 }
 
 /*
@@ -2308,10 +2269,11 @@ pg_stat_vacuum_tables(PG_FUNCTION_ARGS)
 Datum
 pg_stat_vacuum_indexes(PG_FUNCTION_ARGS)
 {
-	return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_INDEX, EXTVACIDXSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_INDEX, EXTVACIDXSTAT_COLUMNS);
+
+ 	PG_RETURN_VOID();
+ }
 
-	PG_RETURN_NULL();
-}
 
 /*
  * Get the vacuum statistics for the database.
@@ -2319,7 +2281,7 @@ pg_stat_vacuum_indexes(PG_FUNCTION_ARGS)
 Datum
 pg_stat_vacuum_database(PG_FUNCTION_ARGS)
 {
-		return pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_DB, EXTVACDBSTAT_COLUMNS);
+	pg_stats_vacuum(fcinfo, PGSTAT_EXTVAC_DB, EXTVACDBSTAT_COLUMNS);
 
-	PG_RETURN_NULL();
-}
+	PG_RETURN_VOID();
+}
\ No newline at end of file
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index b2e881aa89d..d4696d0c055 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12258,20 +12258,20 @@
   descr => 'pg_stat_vacuum_tables return stats values',
   proname => 'pg_stat_vacuum_tables', provolatile => 's', prorettype => 'record',proisstrict => 'f',
   proretset => 't',
-  proargtypes => 'oid oid',
-  proallargtypes => '{oid,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
-  proargmodes => '{i,i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{dboid,reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_scanned,pages_removed,pages_frozen,pages_all_visible,tuples_deleted,tuples_frozen,dead_tuples,index_vacuum_count,rev_all_frozen_pages,rev_all_visible_pages,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
+  proargtypes => 'oid',
+  proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
+  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_scanned,pages_removed,pages_frozen,pages_all_visible,tuples_deleted,tuples_frozen,dead_tuples,index_vacuum_count,rev_all_frozen_pages,rev_all_visible_pages,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
   prosrc => 'pg_stat_vacuum_tables' },
 { oid => '8002',
   descr => 'pg_stat_vacuum_indexes return stats values',
   proname => 'pg_stat_vacuum_indexes', provolatile => 's', prorettype => 'record',proisstrict => 'f',
   proretset => 't',
-  proargtypes => 'oid oid',
-  proallargtypes => '{oid,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
-  proargmodes => '{i,i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
-  proargnames => '{dboid,reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_deleted,tuples_deleted,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
-  prosrc => 'pg_stat_vacuum_indexes' }
+  proargtypes => 'oid',
+  proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,numeric,float8,float8,float8,float8,float8,float8,int4}',
+  proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+  proargnames => '{reloid,relid,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,rel_blks_read,rel_blks_hit,pages_deleted,tuples_deleted,wal_records,wal_fpi,wal_bytes,blk_read_time,blk_write_time,delay_time,system_time,user_time,total_time,interrupts}',
+  prosrc => 'pg_stat_vacuum_indexes' },
 { oid => '8003',
   descr => 'pg_stat_vacuum_database return stats values',
   proname => 'pg_stat_vacuum_database', provolatile => 's', prorettype => 'record',proisstrict => 'f',
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 715ae1b6fd4..24ab3ceb717 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -874,38 +874,4 @@ pgstat_get_custom_snapshot_data(PgStat_Kind kind)
 	return pgStatLocal.snapshot.custom_data[idx];
 }
 
-/* hash table for statistics snapshots entry */
-typedef struct PgStat_SnapshotEntry
-{
-	PgStat_HashKey key;
-	char		status;			/* for simplehash use */
-	void	   *data;			/* the stats data itself */
-} PgStat_SnapshotEntry;
-
-/* ----------
- * Backend-local Hash Table Definitions
- * ----------
- */
-
-/* for stats snapshot entries */
-#define SH_PREFIX pgstat_snapshot
-#define SH_ELEMENT_TYPE PgStat_SnapshotEntry
-#define SH_KEY_TYPE PgStat_HashKey
-#define SH_KEY key
-#define SH_HASH_KEY(tb, key) \
-	pgstat_hash_hash_key(&key, sizeof(PgStat_HashKey), NULL)
-#define SH_EQUAL(tb, a, b) \
-	pgstat_cmp_hash_key(&a, &b, sizeof(PgStat_HashKey), NULL) == 0
-#define SH_SCOPE static inline
-#define SH_DEFINE
-#define SH_DECLARE
-#include "lib/simplehash.h"
-
-typedef pgstat_snapshot_iterator SnapshotIterator;
-
-#define InitSnapshotIterator(htable, iter) \
-	pgstat_snapshot_start_iterate(htable, iter);
-#define ScanStatSnapshot(htable, iter) \
-	pgstat_snapshot_iterate(htable, iter)
-
 #endif							/* PGSTAT_INTERNAL_H */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index c4388dd0da1..5d7f73c25fd 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2271,7 +2271,7 @@ pg_stat_vacuum_indexes| SELECT rel.oid AS relid,
    FROM pg_database db,
     pg_class rel,
     pg_namespace ns,
-    LATERAL pg_stat_vacuum_indexes(db.oid, rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
+    LATERAL pg_stat_vacuum_indexes(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
   WHERE ((db.datname = current_database()) AND (rel.oid = stats.relid) AND (ns.oid = rel.relnamespace));
 pg_stat_vacuum_tables| SELECT rel.oid AS relid,
     ns.nspname AS schema,
@@ -2305,7 +2305,7 @@ pg_stat_vacuum_tables| SELECT rel.oid AS relid,
    FROM pg_database db,
     pg_class rel,
     pg_namespace ns,
-    LATERAL pg_stat_vacuum_tables(db.oid, rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, pages_frozen, pages_all_visible, tuples_deleted, tuples_frozen, dead_tuples, index_vacuum_count, rev_all_frozen_pages, rev_all_visible_pages, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
+    LATERAL pg_stat_vacuum_tables(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, pages_frozen, pages_all_visible, tuples_deleted, tuples_frozen, dead_tuples, index_vacuum_count, rev_all_frozen_pages, rev_all_visible_pages, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, system_time, user_time, total_time, interrupts)
   WHERE ((db.datname = current_database()) AND (rel.oid = stats.relid) AND (ns.oid = rel.relnamespace));
 pg_stat_wal| SELECT wal_records,
     wal_fpi,
diff --git a/src/test/regress/expected/vacuum_tables_and_db_statistics.out b/src/test/regress/expected/vacuum_tables_and_db_statistics.out
index f0537aac430..ec0cf97e2da 100644
--- a/src/test/regress/expected/vacuum_tables_and_db_statistics.out
+++ b/src/test/regress/expected/vacuum_tables_and_db_statistics.out
@@ -6,9 +6,9 @@
 -- number of frozen and visible pages removed by backend.
 -- Statistic wal_fpi is not displayed in this test because its behavior is unstable.
 --
-CREATE DATABASE statistic_vacuum_database;
-CREATE DATABASE statistic_vacuum_database1;
-\c statistic_vacuum_database;
+CREATE DATABASE regression_statistic_vacuum_db;
+CREATE DATABASE regression_statistic_vacuum_db1;
+\c regression_statistic_vacuum_db;
 -- conditio sine qua non
 SHOW track_counts;  -- must be on
  track_counts 
@@ -212,9 +212,9 @@ SELECT dbname,
 FROM
 pg_stat_vacuum_database
 WHERE dbname = current_database();
-          dbname           | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
----------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
- statistic_vacuum_database | t           | t                  | t                  | t           | t       | t         | t         | t
+             dbname             | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
+--------------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
+ regression_statistic_vacuum_db | t           | t                  | t                  | t           | t       | t         | t         | t
 (1 row)
 
 DROP TABLE vestat CASCADE;
@@ -230,7 +230,7 @@ INSERT INTO vestat SELECT x FROM generate_series(1,:sample_size) as x;
 ANALYZE vestat;
 UPDATE vestat SET x = 10001;
 VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 -- Now check vacuum statistics for postgres database from another database
 SELECT dbname,
        db_blks_hit > 0 AS db_blks_hit,
@@ -243,20 +243,20 @@ SELECT dbname,
        total_time > 0 AS total_time
 FROM
 pg_stat_vacuum_database
-WHERE dbname = 'statistic_vacuum_database';
-          dbname           | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
----------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
- statistic_vacuum_database | t           | t                  | t                  | t           | t       | t         | t         | t
+WHERE dbname = 'regression_statistic_vacuum_db';
+             dbname             | db_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes | user_time | total_time 
+--------------------------------+-------------+--------------------+--------------------+-------------+---------+-----------+-----------+------------
+ regression_statistic_vacuum_db | t           | t                  | t                  | t           | t       | t         | t         | t
 (1 row)
 
-\c statistic_vacuum_database
+\c regression_statistic_vacuum_db
 RESET vacuum_freeze_min_age;
 RESET vacuum_freeze_table_age;
 DROP TABLE vestat CASCADE;
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 SELECT count(*)
 FROM pg_database d
-CROSS JOIN pg_stat_vacuum_tables(d.oid, 0)
+CROSS JOIN pg_stat_vacuum_tables(0)
 WHERE oid = 0; -- must be 0
  count 
 -------
@@ -273,5 +273,5 @@ WHERE oid = 0; -- must be 0
 (1 row)
 
 \c postgres
-DROP DATABASE statistic_vacuum_database1;
-DROP DATABASE statistic_vacuum_database;
+DROP DATABASE regression_statistic_vacuum_db1;
+DROP DATABASE regression_statistic_vacuum_db;
diff --git a/src/test/regress/sql/vacuum_tables_and_db_statistics.sql b/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
index 43cc8068b0f..ed9bb852625 100644
--- a/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
+++ b/src/test/regress/sql/vacuum_tables_and_db_statistics.sql
@@ -7,9 +7,9 @@
 -- Statistic wal_fpi is not displayed in this test because its behavior is unstable.
 --
 
-CREATE DATABASE statistic_vacuum_database;
-CREATE DATABASE statistic_vacuum_database1;
-\c statistic_vacuum_database;
+CREATE DATABASE regression_statistic_vacuum_db;
+CREATE DATABASE regression_statistic_vacuum_db1;
+\c regression_statistic_vacuum_db;
 
 -- conditio sine qua non
 SHOW track_counts;  -- must be on
@@ -184,7 +184,7 @@ ANALYZE vestat;
 UPDATE vestat SET x = 10001;
 VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
 
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 
 -- Now check vacuum statistics for postgres database from another database
 SELECT dbname,
@@ -198,18 +198,18 @@ SELECT dbname,
        total_time > 0 AS total_time
 FROM
 pg_stat_vacuum_database
-WHERE dbname = 'statistic_vacuum_database';
+WHERE dbname = 'regression_statistic_vacuum_db';
 
-\c statistic_vacuum_database
+\c regression_statistic_vacuum_db
 
 RESET vacuum_freeze_min_age;
 RESET vacuum_freeze_table_age;
 DROP TABLE vestat CASCADE;
 
-\c statistic_vacuum_database1;
+\c regression_statistic_vacuum_db1;
 SELECT count(*)
 FROM pg_database d
-CROSS JOIN pg_stat_vacuum_tables(d.oid, 0)
+CROSS JOIN pg_stat_vacuum_tables(0)
 WHERE oid = 0; -- must be 0
 
 SELECT count(*)
@@ -218,5 +218,5 @@ CROSS JOIN pg_stat_vacuum_database(0)
 WHERE oid = 0; -- must be 0
 
 \c postgres
-DROP DATABASE statistic_vacuum_database1;
-DROP DATABASE statistic_vacuum_database;
+DROP DATABASE regression_statistic_vacuum_db1;
+DROP DATABASE regression_statistic_vacuum_db;


view thread (34+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected]
  Subject: Re: Vacuum statistics
  In-Reply-To: <[email protected]>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox