summaryrefslogtreecommitdiff
path: root/src/test/modules/injection_points/regress_injection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/modules/injection_points/regress_injection.c')
-rw-r--r--src/test/modules/injection_points/regress_injection.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/test/modules/injection_points/regress_injection.c b/src/test/modules/injection_points/regress_injection.c
new file mode 100644
index 00000000000..422f4168935
--- /dev/null
+++ b/src/test/modules/injection_points/regress_injection.c
@@ -0,0 +1,71 @@
+/*--------------------------------------------------------------------------
+ *
+ * regress_injection.c
+ * Functions supporting test-specific subject matter.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/test/modules/injection_points/regress_injection.c
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "access/table.h"
+#include "fmgr.h"
+#include "miscadmin.h"
+#include "storage/procarray.h"
+#include "utils/xid8.h"
+
+/*
+ * removable_cutoff - for syscache-update-pruned.spec
+ *
+ * Wrapper around GetOldestNonRemovableTransactionId(). In general, this can
+ * move backward. runningcheck=false isolation tests can reasonably prevent
+ * that. For the causes of backward movement, see
+ * postgr.es/m/CAEze2Wj%2BV0kTx86xB_YbyaqTr5hnE_igdWAwuhSyjXBYscf5-Q%40mail.gmail.com
+ * and the header comment for ComputeXidHorizons(). One can assume this
+ * doesn't move backward if one arranges for concurrent activity not to reach
+ * AbortTransaction() and not to allocate an XID while connected to another
+ * database. Non-runningcheck tests can control most concurrent activity,
+ * except autovacuum and the isolationtester control connection. Neither
+ * allocates XIDs, and AbortTransaction() in those would justify test failure.
+ */
+PG_FUNCTION_INFO_V1(removable_cutoff);
+Datum
+removable_cutoff(PG_FUNCTION_ARGS)
+{
+ Relation rel = NULL;
+ TransactionId xid;
+ FullTransactionId next_fxid_before,
+ next_fxid;
+
+ /* could take other relkinds callee takes, but we've not yet needed it */
+ if (!PG_ARGISNULL(0))
+ rel = table_open(PG_GETARG_OID(0), AccessShareLock);
+
+ /*
+ * No lock or snapshot necessarily prevents oldestXid from advancing past
+ * "xid" while this function runs. That concerns us only in that we must
+ * not ascribe "xid" to the wrong epoch. (That may never arise in
+ * isolation testing, but let's set a good example.) As a crude solution,
+ * retry until nextXid doesn't change.
+ */
+ next_fxid = ReadNextFullTransactionId();
+ do
+ {
+ CHECK_FOR_INTERRUPTS();
+ next_fxid_before = next_fxid;
+ xid = GetOldestNonRemovableTransactionId(rel);
+ next_fxid = ReadNextFullTransactionId();
+ } while (!FullTransactionIdEquals(next_fxid, next_fxid_before));
+
+ if (rel)
+ table_close(rel, AccessShareLock);
+
+ PG_RETURN_FULLTRANSACTIONID(FullTransactionIdFromAllowableAt(next_fxid,
+ xid));
+}