1 /*-------------------------------------------------------------------------
4 * Functions for accessing the statistics collector data
6 * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.19 2004/10/01 21:03:42 tgl Exp $
13 *-------------------------------------------------------------------------
17 #include "access/xact.h"
18 #include "catalog/pg_shadow.h"
21 #include "miscadmin.h"
22 #include "nodes/execnodes.h"
24 #include "utils/hsearch.h"
26 /* bogus ... these externs should be in a header file */
27 extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
28 extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
29 extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
30 extern Datum pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS);
31 extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS);
32 extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS);
33 extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS);
34 extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS);
36 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
37 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
38 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
39 extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
40 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
41 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
42 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
43 extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
45 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
46 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
47 extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS);
48 extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS);
49 extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
53 pg_stat_get_numscans(PG_FUNCTION_ARGS)
55 PgStat_StatTabEntry *tabentry;
59 relid = PG_GETARG_OID(0);
61 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
64 result = (int64) (tabentry->numscans);
66 PG_RETURN_INT64(result);
71 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
73 PgStat_StatTabEntry *tabentry;
77 relid = PG_GETARG_OID(0);
79 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
82 result = (int64) (tabentry->tuples_returned);
84 PG_RETURN_INT64(result);
89 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
91 PgStat_StatTabEntry *tabentry;
95 relid = PG_GETARG_OID(0);
97 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
100 result = (int64) (tabentry->tuples_fetched);
102 PG_RETURN_INT64(result);
107 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
109 PgStat_StatTabEntry *tabentry;
113 relid = PG_GETARG_OID(0);
115 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
118 result = (int64) (tabentry->tuples_inserted);
120 PG_RETURN_INT64(result);
125 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
127 PgStat_StatTabEntry *tabentry;
131 relid = PG_GETARG_OID(0);
133 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
136 result = (int64) (tabentry->tuples_updated);
138 PG_RETURN_INT64(result);
143 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
145 PgStat_StatTabEntry *tabentry;
149 relid = PG_GETARG_OID(0);
151 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
154 result = (int64) (tabentry->tuples_deleted);
156 PG_RETURN_INT64(result);
161 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
163 PgStat_StatTabEntry *tabentry;
167 relid = PG_GETARG_OID(0);
169 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
172 result = (int64) (tabentry->blocks_fetched);
174 PG_RETURN_INT64(result);
179 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
181 PgStat_StatTabEntry *tabentry;
185 relid = PG_GETARG_OID(0);
187 if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
190 result = (int64) (tabentry->blocks_hit);
192 PG_RETURN_INT64(result);
197 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
199 FuncCallContext *funcctx;
203 /* stuff done only on the first call of the function */
204 if (SRF_IS_FIRSTCALL())
206 /* create a function context for cross-call persistence */
207 funcctx = SRF_FIRSTCALL_INIT();
209 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
211 funcctx->user_fctx = fctx;
214 fctx[1] = pgstat_fetch_stat_numbackends();
217 /* stuff done on every call of the function */
218 funcctx = SRF_PERCALL_SETUP();
219 fctx = funcctx->user_fctx;
224 if (result <= fctx[1])
226 /* do when there is more left to send */
227 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
231 /* do when there is no more left */
232 SRF_RETURN_DONE(funcctx);
238 pg_backend_pid(PG_FUNCTION_ARGS)
240 PG_RETURN_INT32(MyProcPid);
244 * Built-in function for resetting the counters
247 pg_stat_reset(PG_FUNCTION_ARGS)
249 pgstat_reset_counters();
251 PG_RETURN_BOOL(true);
255 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
257 PgStat_StatBeEntry *beentry;
260 beid = PG_GETARG_INT32(0);
262 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
265 PG_RETURN_INT32(beentry->procpid);
270 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
272 PgStat_StatBeEntry *beentry;
275 beid = PG_GETARG_INT32(0);
277 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
280 PG_RETURN_OID(beentry->databaseid);
285 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
287 PgStat_StatBeEntry *beentry;
290 beid = PG_GETARG_INT32(0);
292 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
295 PG_RETURN_INT32(beentry->userid);
300 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
302 PgStat_StatBeEntry *beentry;
308 beid = PG_GETARG_INT32(0);
310 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
311 activity = "<backend information not available>";
312 else if (!superuser() && beentry->userid != GetUserId())
313 activity = "<insufficient privilege>";
314 else if (*(beentry->activity) == '\0')
315 activity = "<command string not enabled>";
317 activity = beentry->activity;
319 len = strlen(activity);
320 result = palloc(VARHDRSZ + len);
321 VARATT_SIZEP(result) = VARHDRSZ + len;
322 memcpy(VARDATA(result), activity, len);
324 PG_RETURN_TEXT_P(result);
329 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
331 PgStat_StatBeEntry *beentry;
337 beid = PG_GETARG_INT32(0);
339 if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
342 if (!superuser() && beentry->userid != GetUserId())
345 sec = beentry->activity_start_sec;
346 usec = beentry->activity_start_usec;
349 * No time recorded for start of current query -- this is the case if
350 * the user hasn't enabled query-level stats collection.
352 if (sec == 0 && usec == 0)
355 result = AbsoluteTimeUsecToTimestampTz(sec, usec);
357 PG_RETURN_TIMESTAMPTZ(result);
362 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
364 PgStat_StatDBEntry *dbentry;
368 dbid = PG_GETARG_OID(0);
370 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
373 result = (int32) (dbentry->n_backends);
375 PG_RETURN_INT32(result);
380 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
382 PgStat_StatDBEntry *dbentry;
386 dbid = PG_GETARG_OID(0);
388 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
391 result = (int64) (dbentry->n_xact_commit);
393 PG_RETURN_INT64(result);
398 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
400 PgStat_StatDBEntry *dbentry;
404 dbid = PG_GETARG_OID(0);
406 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
409 result = (int64) (dbentry->n_xact_rollback);
411 PG_RETURN_INT64(result);
416 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
418 PgStat_StatDBEntry *dbentry;
422 dbid = PG_GETARG_OID(0);
424 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
427 result = (int64) (dbentry->n_blocks_fetched);
429 PG_RETURN_INT64(result);
434 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
436 PgStat_StatDBEntry *dbentry;
440 dbid = PG_GETARG_OID(0);
442 if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
445 result = (int64) (dbentry->n_blocks_hit);
447 PG_RETURN_INT64(result);