Coverage Report

Created: 2026-11-09 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/utils/activity/backend_progress.c
Line
Count
Source
1
/* ----------
2
 * backend_progress.c
3
 *
4
 *  Command progress reporting infrastructure.
5
 *
6
 *  Copyright (c) 2001-2026, PostgreSQL Global Development Group
7
 *
8
 *  src/backend/utils/activity/backend_progress.c
9
 * ----------
10
 */
11
#include "postgres.h"
12
13
#include "access/parallel.h"
14
#include "libpq/pqformat.h"
15
#include "storage/proc.h"
16
#include "utils/backend_progress.h"
17
#include "utils/backend_status.h"
18
19
20
/*-----------
21
 * pgstat_progress_start_command() -
22
 *
23
 * Set st_progress_command (and st_progress_command_target) in own backend
24
 * entry.  Also, zero-initialize st_progress_param array.
25
 *-----------
26
 */
27
void
28
pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
29
0
{
30
0
  volatile PgBackendStatus *beentry = MyBEEntry;
31
32
0
  if (!beentry || !pgstat_track_activities)
33
0
    return;
34
35
0
  PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
36
0
  beentry->st_progress_command = cmdtype;
37
0
  beentry->st_progress_command_target = relid;
38
0
  for (int i = 0; i < PGSTAT_NUM_PROGRESS_PARAM; i++)
39
0
    beentry->st_progress_param[i] = 0;
40
0
  PGSTAT_END_WRITE_ACTIVITY(beentry);
41
0
}
42
43
/*-----------
44
 * pgstat_progress_update_param() -
45
 *
46
 * Update index'th member in st_progress_param[] of own backend entry.
47
 *-----------
48
 */
49
void
50
pgstat_progress_update_param(int index, int64 val)
51
0
{
52
0
  volatile PgBackendStatus *beentry = MyBEEntry;
53
54
0
  Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM);
55
56
0
  if (!beentry || !pgstat_track_activities)
57
0
    return;
58
59
0
  PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
60
0
  beentry->st_progress_param[index] = val;
61
0
  PGSTAT_END_WRITE_ACTIVITY(beentry);
62
0
}
63
64
/*-----------
65
 * pgstat_progress_incr_param() -
66
 *
67
 * Increment index'th member in st_progress_param[] of own backend entry.
68
 *-----------
69
 */
70
void
71
pgstat_progress_incr_param(int index, int64 incr)
72
0
{
73
0
  volatile PgBackendStatus *beentry = MyBEEntry;
74
75
0
  Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM);
76
77
0
  if (!beentry || !pgstat_track_activities)
78
0
    return;
79
80
0
  PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
81
0
  beentry->st_progress_param[index] += incr;
82
0
  PGSTAT_END_WRITE_ACTIVITY(beentry);
83
0
}
84
85
/*-----------
86
 * pgstat_progress_parallel_incr_param() -
87
 *
88
 * A variant of pgstat_progress_incr_param to allow a worker to poke at
89
 * a leader to do an incremental progress update.
90
 *-----------
91
 */
92
void
93
pgstat_progress_parallel_incr_param(int index, int64 incr)
94
0
{
95
  /*
96
   * Parallel workers notify a leader through a PqParallelMsg_Progress
97
   * message to update progress, passing the progress index and incremented
98
   * value. Leaders can just call pgstat_progress_incr_param directly.
99
   */
100
0
  if (IsParallelWorker())
101
0
  {
102
0
    static StringInfoData progress_message;
103
104
0
    pq_beginmessage(&progress_message, PqParallelMsg_Progress);
105
0
    pq_sendint32(&progress_message, index);
106
0
    pq_sendint64(&progress_message, incr);
107
0
    pq_endmessage(&progress_message);
108
0
  }
109
0
  else
110
0
    pgstat_progress_incr_param(index, incr);
111
0
}
112
113
/*-----------
114
 * pgstat_progress_update_multi_param() -
115
 *
116
 * Update multiple members in st_progress_param[] of own backend entry.
117
 * This is atomic; readers won't see intermediate states.
118
 *-----------
119
 */
120
void
121
pgstat_progress_update_multi_param(int nparam, const int *index,
122
                   const int64 *val)
123
0
{
124
0
  volatile PgBackendStatus *beentry = MyBEEntry;
125
0
  int     i;
126
127
0
  if (!beentry || !pgstat_track_activities || nparam == 0)
128
0
    return;
129
130
0
  PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
131
132
0
  for (i = 0; i < nparam; ++i)
133
0
  {
134
0
    Assert(index[i] >= 0 && index[i] < PGSTAT_NUM_PROGRESS_PARAM);
135
136
0
    beentry->st_progress_param[index[i]] = val[i];
137
0
  }
138
139
0
  PGSTAT_END_WRITE_ACTIVITY(beentry);
140
0
}
141
142
/*-----------
143
 * pgstat_progress_end_command() -
144
 *
145
 * Reset st_progress_command (and st_progress_command_target) in own backend
146
 * entry.  This signals the end of the command.
147
 *-----------
148
 */
149
void
150
pgstat_progress_end_command(void)
151
0
{
152
0
  volatile PgBackendStatus *beentry = MyBEEntry;
153
154
0
  if (!beentry || !pgstat_track_activities)
155
0
    return;
156
157
0
  if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID)
158
0
    return;
159
160
0
  PGSTAT_BEGIN_WRITE_ACTIVITY(beentry);
161
0
  beentry->st_progress_command = PROGRESS_COMMAND_INVALID;
162
0
  beentry->st_progress_command_target = InvalidOid;
163
  PGSTAT_END_WRITE_ACTIVITY(beentry);
164
0
}