Files
postgresql/src/test/modules/delay_execution/delay_execution.c
Amit Langote 4f1b6e5bb4 Remove unstable test suite added by 525392d57
The 'cached-plan-inval' test suite, introduced in 525392d57 under
src/test/modules/delay_execution, aimed to verify that cached plan
invalidation triggers replanning after deferred locks are taken.
However, its ExecutorStart_hook-based approach relies on lock timing
assumptions that, in retrospect, are fragile. This instability was
exposed by failures on BF animal trilobite, which builds with
CLOBBER_CACHE_ALWAYS.

One option was to dynamically disable the cache behavior that causes
the test suite to fail by setting "debug_discard_caches = 0", but it
seems better to remove the suite. The risk of future failures due to
other cache flush hazards outweighs the benefit of catching real
breakage in the backend behavior it tests.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/2990641.1740117879@sss.pgh.pa.us
2025-02-22 15:19:23 +09:00

96 lines
2.7 KiB
C

/*-------------------------------------------------------------------------
*
* delay_execution.c
* Test module to allow delay between parsing and execution of a query.
*
* The delay is implemented by taking and immediately releasing a specified
* advisory lock. If another process has previously taken that lock, the
* current process will be blocked until the lock is released; otherwise,
* there's no effect. This allows an isolationtester script to reliably
* test behaviors where some specified action happens in another backend
* between parsing and execution of any desired query.
*
* Copyright (c) 2020-2025, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/test/modules/delay_execution/delay_execution.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <limits.h>
#include "optimizer/planner.h"
#include "utils/fmgrprotos.h"
#include "utils/guc.h"
#include "utils/inval.h"
PG_MODULE_MAGIC;
/* GUC: advisory lock ID to use. Zero disables the feature. */
static int post_planning_lock_id = 0;
/* Save previous planner hook user to be a good citizen */
static planner_hook_type prev_planner_hook = NULL;
/* planner_hook function to provide the desired delay */
static PlannedStmt *
delay_execution_planner(Query *parse, const char *query_string,
int cursorOptions, ParamListInfo boundParams)
{
PlannedStmt *result;
/* Invoke the planner, possibly via a previous hook user */
if (prev_planner_hook)
result = prev_planner_hook(parse, query_string, cursorOptions,
boundParams);
else
result = standard_planner(parse, query_string, cursorOptions,
boundParams);
/* If enabled, delay by taking and releasing the specified lock */
if (post_planning_lock_id != 0)
{
DirectFunctionCall1(pg_advisory_lock_int8,
Int64GetDatum((int64) post_planning_lock_id));
DirectFunctionCall1(pg_advisory_unlock_int8,
Int64GetDatum((int64) post_planning_lock_id));
/*
* Ensure that we notice any pending invalidations, since the advisory
* lock functions don't do this.
*/
AcceptInvalidationMessages();
}
return result;
}
/* Module load function */
void
_PG_init(void)
{
/* Set up the GUC to control which lock is used */
DefineCustomIntVariable("delay_execution.post_planning_lock_id",
"Sets the advisory lock ID to be locked/unlocked after planning.",
"Zero disables the delay.",
&post_planning_lock_id,
0,
0, INT_MAX,
PGC_USERSET,
0,
NULL,
NULL,
NULL);
MarkGUCPrefixReserved("delay_execution");
/* Install our hook */
prev_planner_hook = planner_hook;
planner_hook = delay_execution_planner;
}