PostgreSQL Source Code git master
Loading...
Searching...
No Matches
stashfuncs.c File Reference
#include "postgres.h"
#include "common/hashfn.h"
#include "fmgr.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "pg_stash_advice.h"
#include "utils/builtins.h"
#include "utils/tuplestore.h"
#include "lib/simplehash.h"
Include dependency graph for stashfuncs.c:

Go to the source code of this file.

Data Structures

struct  pgsa_stash_count
 

Macros

#define SH_PREFIX   pgsa_stash_count_table
 
#define SH_ELEMENT_TYPE   pgsa_stash_count
 
#define SH_KEY_TYPE   uint64
 
#define SH_KEY   pgsa_stash_id
 
#define SH_HASH_KEY(tb, key)   hash_bytes((const unsigned char *) &(key), sizeof(uint64))
 
#define SH_EQUAL(tb, a, b)   (a == b)
 
#define SH_SCOPE   static inline
 
#define SH_DEFINE
 
#define SH_DECLARE
 

Typedefs

typedef struct pgsa_stash_count pgsa_stash_count
 

Functions

 PG_FUNCTION_INFO_V1 (pg_create_advice_stash)
 
 PG_FUNCTION_INFO_V1 (pg_drop_advice_stash)
 
 PG_FUNCTION_INFO_V1 (pg_get_advice_stash_contents)
 
 PG_FUNCTION_INFO_V1 (pg_get_advice_stashes)
 
 PG_FUNCTION_INFO_V1 (pg_set_stashed_advice)
 
 PG_FUNCTION_INFO_V1 (pg_start_stash_advice_worker)
 
Datum pg_create_advice_stash (PG_FUNCTION_ARGS)
 
Datum pg_drop_advice_stash (PG_FUNCTION_ARGS)
 
Datum pg_get_advice_stashes (PG_FUNCTION_ARGS)
 
Datum pg_get_advice_stash_contents (PG_FUNCTION_ARGS)
 
Datum pg_set_stashed_advice (PG_FUNCTION_ARGS)
 
Datum pg_start_stash_advice_worker (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ SH_DECLARE

#define SH_DECLARE

Definition at line 44 of file stashfuncs.c.

◆ SH_DEFINE

#define SH_DEFINE

Definition at line 43 of file stashfuncs.c.

◆ SH_ELEMENT_TYPE

#define SH_ELEMENT_TYPE   pgsa_stash_count

Definition at line 37 of file stashfuncs.c.

◆ SH_EQUAL

#define SH_EQUAL (   tb,
  a,
  b 
)    (a == b)

Definition at line 41 of file stashfuncs.c.

◆ SH_HASH_KEY

#define SH_HASH_KEY (   tb,
  key 
)    hash_bytes((const unsigned char *) &(key), sizeof(uint64))

Definition at line 40 of file stashfuncs.c.

◆ SH_KEY

#define SH_KEY   pgsa_stash_id

Definition at line 39 of file stashfuncs.c.

◆ SH_KEY_TYPE

#define SH_KEY_TYPE   uint64

Definition at line 38 of file stashfuncs.c.

◆ SH_PREFIX

#define SH_PREFIX   pgsa_stash_count_table

Definition at line 36 of file stashfuncs.c.

◆ SH_SCOPE

#define SH_SCOPE   static inline

Definition at line 42 of file stashfuncs.c.

Typedef Documentation

◆ pgsa_stash_count

Function Documentation

◆ pg_create_advice_stash()

Datum pg_create_advice_stash ( PG_FUNCTION_ARGS  )

Definition at line 51 of file stashfuncs.c.

52{
53 char *stash_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
54
55 pgsa_check_stash_name(stash_name);
60 pgsa_create_stash(stash_name);
63}
#define unlikely(x)
Definition c.h:438
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_EXCLUSIVE
Definition lwlock.h:104
dshash_table * pgsa_entry_dshash
void pgsa_create_stash(char *stash_name)
void pgsa_attach(void)
void pgsa_check_stash_name(char *stash_name)
pgsa_shared_state * pgsa_state
void pgsa_check_lockout(void)
static int fb(int x)
char * text_to_cstring(const text *t)
Definition varlena.c:217

References fb(), pgsa_shared_state::lock, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PG_GETARG_TEXT_PP, PG_RETURN_VOID, pgsa_attach(), pgsa_check_lockout(), pgsa_check_stash_name(), pgsa_create_stash(), pgsa_entry_dshash, pgsa_state, text_to_cstring(), and unlikely.

◆ pg_drop_advice_stash()

◆ PG_FUNCTION_INFO_V1() [1/6]

PG_FUNCTION_INFO_V1 ( pg_create_advice_stash  )

◆ PG_FUNCTION_INFO_V1() [2/6]

PG_FUNCTION_INFO_V1 ( pg_drop_advice_stash  )

◆ PG_FUNCTION_INFO_V1() [3/6]

PG_FUNCTION_INFO_V1 ( pg_get_advice_stash_contents  )

◆ PG_FUNCTION_INFO_V1() [4/6]

PG_FUNCTION_INFO_V1 ( pg_get_advice_stashes  )

◆ PG_FUNCTION_INFO_V1() [5/6]

PG_FUNCTION_INFO_V1 ( pg_set_stashed_advice  )

◆ PG_FUNCTION_INFO_V1() [6/6]

PG_FUNCTION_INFO_V1 ( pg_start_stash_advice_worker  )

◆ pg_get_advice_stash_contents()

Datum pg_get_advice_stash_contents ( PG_FUNCTION_ARGS  )

Definition at line 150 of file stashfuncs.c.

151{
152 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
154 char *stash_name = NULL;
156 uint64 stash_id = 0;
157 pgsa_entry *entry;
158
159 InitMaterializedSRF(fcinfo, 0);
160
161 /* Attach to dynamic shared memory if not already done. */
163 pgsa_attach();
164
165 /* If stash data is still being restored from disk, ignore. */
167 return (Datum) 0;
168
169 /* User can pass NULL for all stashes, or the name of a specific stash. */
170 if (!PG_ARGISNULL(0))
171 {
172 stash_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
173 pgsa_check_stash_name(stash_name);
174 stash_id = pgsa_lookup_stash_id(stash_name);
175
176 /* If the user specified a stash name, it should exist. */
177 if (stash_id == 0)
180 errmsg("advice stash \"%s\" does not exist", stash_name));
181 }
182 else
183 {
185
186 /*
187 * If we're dumping data about all stashes, we need an ID->name lookup
188 * table.
189 */
192 while ((stash = dshash_seq_next(&iterator)) != NULL)
193 {
195 bool found;
196
198 stash->pgsa_stash_id,
199 &found);
200 Assert(!found);
201 n->name = pstrdup(stash->name);
202 }
204 }
205
206 /* Now iterate over all the entries. */
208 while ((entry = dshash_seq_next(&iterator)) != NULL)
209 {
210 Datum values[3];
211 bool nulls[3];
212 char *this_stash_name;
213 char *advice_string;
214
215 /* Skip incomplete entries where the advice string was never set. */
216 if (entry->advice_string == InvalidDsaPointer)
217 continue;
218
219 if (stash_id != 0)
220 {
221 /*
222 * We're only dumping data for one particular stash, so skip
223 * entries for any other stash and use the stash name specified by
224 * the user.
225 */
226 if (stash_id != entry->key.pgsa_stash_id)
227 continue;
228 this_stash_name = stash_name;
229 }
230 else
231 {
233
234 /*
235 * We're dumping data for all stashes, so look up the correct name
236 * to use in the hash table. If nothing is found, which is
237 * possible due to race conditions, make up a string to use.
238 */
240 if (n != NULL)
242 else
243 this_stash_name = psprintf("<stash %" PRIu64 ">",
244 entry->key.pgsa_stash_id);
245 }
246
247 /* Work out tuple values. */
249 nulls[0] = false;
250 values[1] = Int64GetDatum(entry->key.queryId);
251 nulls[1] = false;
252 advice_string = dsa_get_address(pgsa_dsa_area, entry->advice_string);
253 values[2] = CStringGetTextDatum(advice_string);
254 nulls[2] = false;
255
256 /* Emit the tuple. */
257 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values,
258 nulls);
259 }
261
262 return (Datum) 0;
263}
static bool pg_atomic_unlocked_test_flag(volatile pg_atomic_flag *ptr)
Definition atomics.h:194
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define Assert(condition)
Definition c.h:943
uint64_t uint64
Definition c.h:625
void * dsa_get_address(dsa_area *area, dsa_pointer dp)
Definition dsa.c:957
#define InvalidDsaPointer
Definition dsa.h:78
void dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table, bool exclusive)
Definition dshash.c:659
void dshash_seq_term(dshash_seq_status *status)
Definition dshash.c:768
void * dshash_seq_next(dshash_seq_status *status)
Definition dshash.c:678
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
#define PG_ARGISNULL(n)
Definition fmgr.h:209
void InitMaterializedSRF(FunctionCallInfo fcinfo, uint32 flags)
Definition funcapi.c:76
char * pstrdup(const char *in)
Definition mcxt.c:1781
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
static char * errmsg
dshash_table * pgsa_stash_dshash
dsa_area * pgsa_dsa_area
uint64 pgsa_lookup_stash_id(char *stash_name)
static Datum Int64GetDatum(int64 X)
Definition postgres.h:426
uint64_t Datum
Definition postgres.h:70
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
int64 queryId
uint64 pgsa_stash_id
pgsa_entry_key key
dsa_pointer advice_string
pg_atomic_flag stashes_ready
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition tuplestore.c:785

References pgsa_entry::advice_string, Assert, CStringGetTextDatum, CurrentMemoryContext, dsa_get_address(), dshash_seq_init(), dshash_seq_next(), dshash_seq_term(), ereport, errcode(), errmsg, ERROR, fb(), InitMaterializedSRF(), Int64GetDatum(), InvalidDsaPointer, pgsa_entry::key, pgsa_stash_name::name, PG_ARGISNULL, pg_atomic_unlocked_test_flag(), PG_GETARG_TEXT_PP, pgsa_attach(), pgsa_check_stash_name(), pgsa_dsa_area, pgsa_entry_dshash, pgsa_lookup_stash_id(), pgsa_stash_dshash, pgsa_entry_key::pgsa_stash_id, pgsa_state, psprintf(), pstrdup(), pgsa_entry_key::queryId, pgsa_shared_state::stashes_ready, text_to_cstring(), tuplestore_putvalues(), unlikely, and values.

◆ pg_get_advice_stashes()

Datum pg_get_advice_stashes ( PG_FUNCTION_ARGS  )

Definition at line 87 of file stashfuncs.c.

88{
89 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
91 pgsa_entry *entry;
94
95 InitMaterializedSRF(fcinfo, 0);
96
97 /* Attach to dynamic shared memory if not already done. */
100
101 /* If stash data is still being restored from disk, ignore. */
103 return (Datum) 0;
104
105 /* Tally up the number of entries per stash. */
108 while ((entry = dshash_seq_next(&iterator)) != NULL)
109 {
111 bool found;
112
114 entry->key.pgsa_stash_id,
115 &found);
116 if (!found)
117 c->num_entries = 1;
118 else
119 c->num_entries++;
120 }
122
123 /* Emit results. */
125 while ((stash = dshash_seq_next(&iterator)) != NULL)
126 {
127 Datum values[2];
128 bool nulls[2];
130
131 values[0] = CStringGetTextDatum(stash->name);
132 nulls[0] = false;
133
134 c = pgsa_stash_count_table_lookup(chash, stash->pgsa_stash_id);
135 values[1] = Int64GetDatum(c == NULL ? 0 : c->num_entries);
136 nulls[1] = false;
137
138 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values,
139 nulls);
140 }
142
143 return (Datum) 0;
144}
char * c

References CStringGetTextDatum, CurrentMemoryContext, dshash_seq_init(), dshash_seq_next(), dshash_seq_term(), fb(), InitMaterializedSRF(), Int64GetDatum(), pgsa_entry::key, pg_atomic_unlocked_test_flag(), pgsa_attach(), pgsa_entry_dshash, pgsa_stash_dshash, pgsa_entry_key::pgsa_stash_id, pgsa_state, pgsa_shared_state::stashes_ready, tuplestore_putvalues(), unlikely, and values.

◆ pg_set_stashed_advice()

Datum pg_set_stashed_advice ( PG_FUNCTION_ARGS  )

Definition at line 274 of file stashfuncs.c.

275{
276 char *stash_name;
277 int64 queryId;
278
279 if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
281
282 /* Get and check advice stash name. */
283 stash_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
284 pgsa_check_stash_name(stash_name);
285
286 /*
287 * Get and check query ID.
288 *
289 * Query ID 0 means no query ID was computed, so reject that.
290 */
291 queryId = PG_GETARG_INT64(1);
292 if (queryId == 0)
295 errmsg("cannot set advice string for query ID 0"));
296
297 /* Attach to dynamic shared memory if not already done. */
299 pgsa_attach();
300
301 /* Don't allow writes if stash data is still being restored from disk. */
303
304 /* Now call the appropriate function to do the real work. */
305 if (PG_ARGISNULL(2))
306 {
308 pgsa_clear_advice_string(stash_name, queryId);
310 }
311 else
312 {
313 char *advice_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
314
316 pgsa_set_advice_string(stash_name, queryId, advice_string);
318 }
319
321}
int64_t int64
Definition c.h:621
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
@ LW_SHARED
Definition lwlock.h:105
void pgsa_set_advice_string(char *stash_name, int64 queryId, char *advice_string)
void pgsa_clear_advice_string(char *stash_name, int64 queryId)

References ereport, errcode(), errmsg, ERROR, fb(), pgsa_shared_state::lock, LW_SHARED, LWLockAcquire(), LWLockRelease(), PG_ARGISNULL, PG_GETARG_INT64, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_VOID, pgsa_attach(), pgsa_check_lockout(), pgsa_check_stash_name(), pgsa_clear_advice_string(), pgsa_entry_dshash, pgsa_set_advice_string(), pgsa_state, text_to_cstring(), and unlikely.

◆ pg_start_stash_advice_worker()

Datum pg_start_stash_advice_worker ( PG_FUNCTION_ARGS  )

Definition at line 327 of file stashfuncs.c.

328{
329 pid_t pid;
330
332 pgsa_attach();
333
337
338 if (pid != InvalidPid)
341 errmsg("pg_stash_advice worker is already running under PID %d",
342 (int) pid)));
343
345
347}
#define InvalidPid
Definition miscadmin.h:32
void pgsa_start_worker(void)

References pgsa_shared_state::bgworker_pid, ereport, errcode(), errmsg, ERROR, fb(), InvalidPid, pgsa_shared_state::lock, LW_SHARED, LWLockAcquire(), LWLockRelease(), PG_RETURN_VOID, pgsa_attach(), pgsa_entry_dshash, pgsa_start_worker(), pgsa_state, and unlikely.