PostgreSQL Source Code git master
delay_execution.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * delay_execution.c
4 * Test module to allow delay between parsing and execution of a query.
5 *
6 * The delay is implemented by taking and immediately releasing a specified
7 * advisory lock. If another process has previously taken that lock, the
8 * current process will be blocked until the lock is released; otherwise,
9 * there's no effect. This allows an isolationtester script to reliably
10 * test behaviors where some specified action happens in another backend
11 * between parsing and execution of any desired query.
12 *
13 * Copyright (c) 2020-2025, PostgreSQL Global Development Group
14 *
15 * IDENTIFICATION
16 * src/test/modules/delay_execution/delay_execution.c
17 *
18 *-------------------------------------------------------------------------
19 */
20
21#include "postgres.h"
22
23#include <limits.h>
24
25#include "optimizer/planner.h"
26#include "utils/fmgrprotos.h"
27#include "utils/guc.h"
28#include "utils/inval.h"
29
30
32
33/* GUC: advisory lock ID to use. Zero disables the feature. */
34static int post_planning_lock_id = 0;
35
36/* Save previous planner hook user to be a good citizen */
38
39
40/* planner_hook function to provide the desired delay */
41static PlannedStmt *
42delay_execution_planner(Query *parse, const char *query_string,
43 int cursorOptions, ParamListInfo boundParams,
44 ExplainState *es)
45{
46 PlannedStmt *result;
47
48 /* Invoke the planner, possibly via a previous hook user */
50 result = prev_planner_hook(parse, query_string, cursorOptions,
51 boundParams, es);
52 else
53 result = standard_planner(parse, query_string, cursorOptions,
54 boundParams, es);
55
56 /* If enabled, delay by taking and releasing the specified lock */
57 if (post_planning_lock_id != 0)
58 {
63
64 /*
65 * Ensure that we notice any pending invalidations, since the advisory
66 * lock functions don't do this.
67 */
69 }
70
71 return result;
72}
73
74/* Module load function */
75void
77{
78 /* Set up the GUC to control which lock is used */
79 DefineCustomIntVariable("delay_execution.post_planning_lock_id",
80 "Sets the advisory lock ID to be locked/unlocked after planning.",
81 "Zero disables the delay.",
83 0,
84 0, INT_MAX,
86 0,
87 NULL,
88 NULL,
89 NULL);
90
91 MarkGUCPrefixReserved("delay_execution");
92
93 /* Install our hook */
96}
int64_t int64
Definition: c.h:540
static planner_hook_type prev_planner_hook
void _PG_init(void)
static PlannedStmt * delay_execution_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
PG_MODULE_MAGIC
static int post_planning_lock_id
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
void MarkGUCPrefixReserved(const char *className)
Definition: guc.c:5148
void DefineCustomIntVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:5035
@ PGC_USERSET
Definition: guc.h:79
void AcceptInvalidationMessages(void)
Definition: inval.c:930
Datum pg_advisory_unlock_int8(PG_FUNCTION_ARGS)
Definition: lockfuncs.c:772
Datum pg_advisory_lock_int8(PG_FUNCTION_ARGS)
Definition: lockfuncs.c:626
planner_hook_type planner_hook
Definition: planner.c:74
PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition: planner.c:333
PlannedStmt *(* planner_hook_type)(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)
Definition: planner.h:28
static Datum Int64GetDatum(int64 X)
Definition: postgres.h:403
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
Definition: regcomp.c:717