From 5219ecc2f08d4fa76bc14b2c498f126ad96f0ae2 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandbossart@gmail.com>
Date: Tue, 27 Dec 2022 16:20:01 -0800
Subject: [PATCH v1 2/3] introduce pg_update_datfrozenxid

---
 doc/src/sgml/func.sgml               | 44 ++++++++++++++++++++++++++++
 src/backend/commands/vacuum.c        | 12 ++++++++
 src/include/catalog/pg_proc.dat      |  4 +++
 src/include/commands/vacuum.h        |  1 +
 src/test/regress/expected/vacuum.out |  6 ++++
 src/test/regress/sql/vacuum.sql      |  1 +
 6 files changed, 68 insertions(+)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 3bf8d021c3..a97c7794f2 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -27285,6 +27285,50 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
     </tgroup>
    </table>
 
+   <para>
+    <xref linkend="functions-admin-db"/> lists functions used to manage the
+    current database.
+   </para>
+
+   <table id="functions-admin-db">
+    <title>Database Management Functions</title>
+     <tgroup cols="1">
+      <thead>
+       <row>
+        <entry role="func_table_entry"><para role="func_signature">
+         Function
+        </para>
+        <para>
+         Description
+        </para></entry>
+       </row>
+      </thead>
+
+      <tbody>
+       <row>
+        <entry role="func_table_entry"><para role="func_signature">
+        <indexterm>
+         <primary>pg_update_datfrozenxid</primary>
+        </indexterm>
+        <function>pg_update_datfrozenxid</function> ()
+        <returnvalue>void</returnvalue>
+       </para>
+       <para>
+        Updates the current database's
+        <structname>pg_database</structname>.<structfield>datfrozenxid</structfield>
+        and
+        <structname>pg_database</structname>.<structfield>relminmxid</structfield>
+        values to the minimum of the per-table
+        <structname>pg_class</structname>.<structfield>relfrozenxid</structfield>
+        and
+        <structname>pg_class</structname>.<structfield>relminmxid</structfield>
+        values.
+       </para></entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
+
    <para>
     <xref linkend="functions-admin-collation"/> lists functions used to manage
     collations.
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 51537aa5ba..9b5049da2d 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -39,6 +39,7 @@
 #include "catalog/pg_database.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_namespace.h"
+#include "catalog/pg_proc.h"
 #include "commands/cluster.h"
 #include "commands/defrem.h"
 #include "commands/vacuum.h"
@@ -1415,6 +1416,17 @@ vac_update_relstats(Relation relation,
 }
 
 
+/*
+ * Allow calling vac_update_datfrozenxid() via SQL.
+ */
+Datum
+pg_update_datfrozenxid(PG_FUNCTION_ARGS)
+{
+	vac_update_datfrozenxid();
+	PG_RETURN_VOID();
+}
+
+
 /*
  *	vac_update_datfrozenxid() -- update pg_database.datfrozenxid for our DB
  *
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 7056c95371..23efafba49 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -11817,6 +11817,10 @@
   proargmodes => '{i,o,o,o}',
   proargnames => '{slot_name,name,size,modification}',
   prosrc => 'pg_ls_replslotdir' },
+{ oid => '2173',
+  descr => 'update datfrozenxid and datminmxid for current database',
+  proname => 'pg_update_datfrozenxid', provolatile => 'v', prorettype => 'void',
+  proargtypes => '', prosrc => 'pg_update_datfrozenxid' },
 
 # hash partitioning constraint function
 { oid => '5028', descr => 'hash partition CHECK constraint',
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index 700489040e..d594054186 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -329,6 +329,7 @@ extern void vac_update_relstats(Relation relation,
 extern bool vacuum_get_cutoffs(Relation rel, const VacuumParams *params,
 							   struct VacuumCutoffs *cutoffs);
 extern bool vacuum_xid_failsafe_check(const struct VacuumCutoffs *cutoffs);
+extern Datum pg_update_datfrozenxid(PG_FUNCTION_ARGS);
 extern void vac_update_datfrozenxid(void);
 extern void vacuum_delay_point(void);
 extern bool vacuum_is_permitted_for_relation(Oid relid, Form_pg_class reltuple,
diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out
index 19c405417d..b559d2fe84 100644
--- a/src/test/regress/expected/vacuum.out
+++ b/src/test/regress/expected/vacuum.out
@@ -284,6 +284,12 @@ VACUUM (PROCESS_TOAST FALSE, FULL) vactst;
 ERROR:  PROCESS_TOAST required with VACUUM FULL
 -- UPDATE_DATFROZENXID option
 VACUUM (UPDATE_DATFROZENXID FALSE) vactst;
+SELECT pg_update_datfrozenxid();
+ pg_update_datfrozenxid 
+------------------------
+ 
+(1 row)
+
 DROP TABLE vaccluster;
 DROP TABLE vactst;
 DROP TABLE vacparted;
diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql
index 8ab3a93459..4a19f2fa30 100644
--- a/src/test/regress/sql/vacuum.sql
+++ b/src/test/regress/sql/vacuum.sql
@@ -239,6 +239,7 @@ VACUUM (PROCESS_TOAST FALSE, FULL) vactst;
 
 -- UPDATE_DATFROZENXID option
 VACUUM (UPDATE_DATFROZENXID FALSE) vactst;
+SELECT pg_update_datfrozenxid();
 
 DROP TABLE vaccluster;
 DROP TABLE vactst;
-- 
2.25.1

