LCOV - code coverage report
Current view: top level - src/test/modules/delay_execution - delay_execution.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.8 % 16 15
Test Date: 2026-03-12 08:14:54 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       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-2026, 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              : 
      31            2 : PG_MODULE_MAGIC;
      32              : 
      33              : /* GUC: advisory lock ID to use.  Zero disables the feature. */
      34              : static int  post_planning_lock_id = 0;
      35              : 
      36              : /* Save previous planner hook user to be a good citizen */
      37              : static planner_hook_type prev_planner_hook = NULL;
      38              : 
      39              : 
      40              : /* planner_hook function to provide the desired delay */
      41              : static PlannedStmt *
      42           15 : delay_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 */
      49           15 :     if (prev_planner_hook)
      50            0 :         result = prev_planner_hook(parse, query_string, cursorOptions,
      51              :                                    boundParams, es);
      52              :     else
      53           15 :         result = standard_planner(parse, query_string, cursorOptions,
      54              :                                   boundParams, es);
      55              : 
      56              :     /* If enabled, delay by taking and releasing the specified lock */
      57           15 :     if (post_planning_lock_id != 0)
      58              :     {
      59           15 :         DirectFunctionCall1(pg_advisory_lock_int8,
      60              :                             Int64GetDatum((int64) post_planning_lock_id));
      61           15 :         DirectFunctionCall1(pg_advisory_unlock_int8,
      62              :                             Int64GetDatum((int64) post_planning_lock_id));
      63              : 
      64              :         /*
      65              :          * Ensure that we notice any pending invalidations, since the advisory
      66              :          * lock functions don't do this.
      67              :          */
      68           15 :         AcceptInvalidationMessages();
      69              :     }
      70              : 
      71           15 :     return result;
      72              : }
      73              : 
      74              : /* Module load function */
      75              : void
      76            2 : _PG_init(void)
      77              : {
      78              :     /* Set up the GUC to control which lock is used */
      79            2 :     DefineCustomIntVariable("delay_execution.post_planning_lock_id",
      80              :                             "Sets the advisory lock ID to be locked/unlocked after planning.",
      81              :                             "Zero disables the delay.",
      82              :                             &post_planning_lock_id,
      83              :                             0,
      84              :                             0, INT_MAX,
      85              :                             PGC_USERSET,
      86              :                             0,
      87              :                             NULL,
      88              :                             NULL,
      89              :                             NULL);
      90              : 
      91            2 :     MarkGUCPrefixReserved("delay_execution");
      92              : 
      93              :     /* Install our hook */
      94            2 :     prev_planner_hook = planner_hook;
      95            2 :     planner_hook = delay_execution_planner;
      96            2 : }
        

Generated by: LCOV version 2.0-1