]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/pgstatfuncs.c
Simplify and standardize conversions between TEXT datums and ordinary C
[postgresql] / src / backend / utils / adt / pgstatfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * pgstatfuncs.c
4  *        Functions for accessing the statistics collector data
5  *
6  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.49 2008/03/25 22:42:44 tgl Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "funcapi.h"
18 #include "miscadmin.h"
19 #include "pgstat.h"
20 #include "utils/builtins.h"
21 #include "utils/inet.h"
22 #include "libpq/ip.h"
23
24 /* bogus ... these externs should be in a header file */
25 extern Datum pg_stat_get_numscans(PG_FUNCTION_ARGS);
26 extern Datum pg_stat_get_tuples_returned(PG_FUNCTION_ARGS);
27 extern Datum pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS);
28 extern Datum pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS);
29 extern Datum pg_stat_get_tuples_updated(PG_FUNCTION_ARGS);
30 extern Datum pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS);
31 extern Datum pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS);
32 extern Datum pg_stat_get_live_tuples(PG_FUNCTION_ARGS);
33 extern Datum pg_stat_get_dead_tuples(PG_FUNCTION_ARGS);
34 extern Datum pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS);
35 extern Datum pg_stat_get_blocks_hit(PG_FUNCTION_ARGS);
36 extern Datum pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS);
37 extern Datum pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS);
38 extern Datum pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS);
39 extern Datum pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS);
40
41 extern Datum pg_stat_get_backend_idset(PG_FUNCTION_ARGS);
42 extern Datum pg_backend_pid(PG_FUNCTION_ARGS);
43 extern Datum pg_stat_get_backend_pid(PG_FUNCTION_ARGS);
44 extern Datum pg_stat_get_backend_dbid(PG_FUNCTION_ARGS);
45 extern Datum pg_stat_get_backend_userid(PG_FUNCTION_ARGS);
46 extern Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS);
47 extern Datum pg_stat_get_backend_waiting(PG_FUNCTION_ARGS);
48 extern Datum pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS);
49 extern Datum pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS);
50 extern Datum pg_stat_get_backend_start(PG_FUNCTION_ARGS);
51 extern Datum pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS);
52 extern Datum pg_stat_get_backend_client_port(PG_FUNCTION_ARGS);
53
54 extern Datum pg_stat_get_db_numbackends(PG_FUNCTION_ARGS);
55 extern Datum pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS);
56 extern Datum pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS);
57 extern Datum pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS);
58 extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
59 extern Datum pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS);
60 extern Datum pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS);
61 extern Datum pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS);
62 extern Datum pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS);
63 extern Datum pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS);
64
65 extern Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS);
66 extern Datum pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS);
67 extern Datum pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS);
68 extern Datum pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS);
69 extern Datum pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS);
70 extern Datum pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS);
71 extern Datum pg_stat_get_buf_alloc(PG_FUNCTION_ARGS);
72
73 extern Datum pg_stat_clear_snapshot(PG_FUNCTION_ARGS);
74 extern Datum pg_stat_reset(PG_FUNCTION_ARGS);
75
76 /* Global bgwriter statistics, from bgwriter.c */
77 extern PgStat_MsgBgWriter bgwriterStats;
78
79 Datum
80 pg_stat_get_numscans(PG_FUNCTION_ARGS)
81 {
82         Oid                     relid = PG_GETARG_OID(0);
83         int64           result;
84         PgStat_StatTabEntry *tabentry;
85
86         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
87                 result = 0;
88         else
89                 result = (int64) (tabentry->numscans);
90
91         PG_RETURN_INT64(result);
92 }
93
94
95 Datum
96 pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
97 {
98         Oid                     relid = PG_GETARG_OID(0);
99         int64           result;
100         PgStat_StatTabEntry *tabentry;
101
102         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
103                 result = 0;
104         else
105                 result = (int64) (tabentry->tuples_returned);
106
107         PG_RETURN_INT64(result);
108 }
109
110
111 Datum
112 pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
113 {
114         Oid                     relid = PG_GETARG_OID(0);
115         int64           result;
116         PgStat_StatTabEntry *tabentry;
117
118         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
119                 result = 0;
120         else
121                 result = (int64) (tabentry->tuples_fetched);
122
123         PG_RETURN_INT64(result);
124 }
125
126
127 Datum
128 pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
129 {
130         Oid                     relid = PG_GETARG_OID(0);
131         int64           result;
132         PgStat_StatTabEntry *tabentry;
133
134         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
135                 result = 0;
136         else
137                 result = (int64) (tabentry->tuples_inserted);
138
139         PG_RETURN_INT64(result);
140 }
141
142
143 Datum
144 pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
145 {
146         Oid                     relid = PG_GETARG_OID(0);
147         int64           result;
148         PgStat_StatTabEntry *tabentry;
149
150         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
151                 result = 0;
152         else
153                 result = (int64) (tabentry->tuples_updated);
154
155         PG_RETURN_INT64(result);
156 }
157
158
159 Datum
160 pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
161 {
162         Oid                     relid = PG_GETARG_OID(0);
163         int64           result;
164         PgStat_StatTabEntry *tabentry;
165
166         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
167                 result = 0;
168         else
169                 result = (int64) (tabentry->tuples_deleted);
170
171         PG_RETURN_INT64(result);
172 }
173
174
175 Datum
176 pg_stat_get_tuples_hot_updated(PG_FUNCTION_ARGS)
177 {
178         Oid                     relid = PG_GETARG_OID(0);
179         int64           result;
180         PgStat_StatTabEntry *tabentry;
181
182         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
183                 result = 0;
184         else
185                 result = (int64) (tabentry->tuples_hot_updated);
186
187         PG_RETURN_INT64(result);
188 }
189
190
191 Datum
192 pg_stat_get_live_tuples(PG_FUNCTION_ARGS)
193 {
194         Oid                     relid = PG_GETARG_OID(0);
195         int64           result;
196         PgStat_StatTabEntry *tabentry;
197
198         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
199                 result = 0;
200         else
201                 result = (int64) (tabentry->n_live_tuples);
202
203         PG_RETURN_INT64(result);
204 }
205
206
207 Datum
208 pg_stat_get_dead_tuples(PG_FUNCTION_ARGS)
209 {
210         Oid                     relid = PG_GETARG_OID(0);
211         int64           result;
212         PgStat_StatTabEntry *tabentry;
213
214         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
215                 result = 0;
216         else
217                 result = (int64) (tabentry->n_dead_tuples);
218
219         PG_RETURN_INT64(result);
220 }
221
222
223 Datum
224 pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
225 {
226         Oid                     relid = PG_GETARG_OID(0);
227         int64           result;
228         PgStat_StatTabEntry *tabentry;
229
230         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
231                 result = 0;
232         else
233                 result = (int64) (tabentry->blocks_fetched);
234
235         PG_RETURN_INT64(result);
236 }
237
238
239 Datum
240 pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
241 {
242         Oid                     relid = PG_GETARG_OID(0);
243         int64           result;
244         PgStat_StatTabEntry *tabentry;
245
246         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
247                 result = 0;
248         else
249                 result = (int64) (tabentry->blocks_hit);
250
251         PG_RETURN_INT64(result);
252 }
253
254 Datum
255 pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
256 {
257         Oid                     relid = PG_GETARG_OID(0);
258         TimestampTz result;
259         PgStat_StatTabEntry *tabentry;
260
261         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
262                 result = 0;
263         else
264                 result = tabentry->vacuum_timestamp;
265
266         if (result == 0)
267                 PG_RETURN_NULL();
268         else
269                 PG_RETURN_TIMESTAMPTZ(result);
270 }
271
272 Datum
273 pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
274 {
275         Oid                     relid = PG_GETARG_OID(0);
276         TimestampTz result;
277         PgStat_StatTabEntry *tabentry;
278
279         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
280                 result = 0;
281         else
282                 result = tabentry->autovac_vacuum_timestamp;
283
284         if (result == 0)
285                 PG_RETURN_NULL();
286         else
287                 PG_RETURN_TIMESTAMPTZ(result);
288 }
289
290 Datum
291 pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
292 {
293         Oid                     relid = PG_GETARG_OID(0);
294         TimestampTz result;
295         PgStat_StatTabEntry *tabentry;
296
297         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
298                 result = 0;
299         else
300                 result = tabentry->analyze_timestamp;
301
302         if (result == 0)
303                 PG_RETURN_NULL();
304         else
305                 PG_RETURN_TIMESTAMPTZ(result);
306 }
307
308 Datum
309 pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
310 {
311         Oid                     relid = PG_GETARG_OID(0);
312         TimestampTz result;
313         PgStat_StatTabEntry *tabentry;
314
315         if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
316                 result = 0;
317         else
318                 result = tabentry->autovac_analyze_timestamp;
319
320         if (result == 0)
321                 PG_RETURN_NULL();
322         else
323                 PG_RETURN_TIMESTAMPTZ(result);
324 }
325
326 Datum
327 pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
328 {
329         FuncCallContext *funcctx;
330         int                *fctx;
331         int32           result;
332
333         /* stuff done only on the first call of the function */
334         if (SRF_IS_FIRSTCALL())
335         {
336                 /* create a function context for cross-call persistence */
337                 funcctx = SRF_FIRSTCALL_INIT();
338
339                 fctx = MemoryContextAlloc(funcctx->multi_call_memory_ctx,
340                                                                   2 * sizeof(int));
341                 funcctx->user_fctx = fctx;
342
343                 fctx[0] = 0;
344                 fctx[1] = pgstat_fetch_stat_numbackends();
345         }
346
347         /* stuff done on every call of the function */
348         funcctx = SRF_PERCALL_SETUP();
349         fctx = funcctx->user_fctx;
350
351         fctx[0] += 1;
352         result = fctx[0];
353
354         if (result <= fctx[1])
355         {
356                 /* do when there is more left to send */
357                 SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
358         }
359         else
360         {
361                 /* do when there is no more left */
362                 SRF_RETURN_DONE(funcctx);
363         }
364 }
365
366
367 Datum
368 pg_backend_pid(PG_FUNCTION_ARGS)
369 {
370         PG_RETURN_INT32(MyProcPid);
371 }
372
373
374 Datum
375 pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
376 {
377         int32           beid = PG_GETARG_INT32(0);
378         PgBackendStatus *beentry;
379
380         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
381                 PG_RETURN_NULL();
382
383         PG_RETURN_INT32(beentry->st_procpid);
384 }
385
386
387 Datum
388 pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
389 {
390         int32           beid = PG_GETARG_INT32(0);
391         PgBackendStatus *beentry;
392
393         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
394                 PG_RETURN_NULL();
395
396         PG_RETURN_OID(beentry->st_databaseid);
397 }
398
399
400 Datum
401 pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
402 {
403         int32           beid = PG_GETARG_INT32(0);
404         PgBackendStatus *beentry;
405
406         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
407                 PG_RETURN_NULL();
408
409         PG_RETURN_OID(beentry->st_userid);
410 }
411
412
413 Datum
414 pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
415 {
416         int32           beid = PG_GETARG_INT32(0);
417         PgBackendStatus *beentry;
418         const char *activity;
419
420         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
421                 activity = "<backend information not available>";
422         else if (!superuser() && beentry->st_userid != GetUserId())
423                 activity = "<insufficient privilege>";
424         else if (*(beentry->st_activity) == '\0')
425                 activity = "<command string not enabled>";
426         else
427                 activity = beentry->st_activity;
428
429         PG_RETURN_TEXT_P(cstring_to_text(activity));
430 }
431
432
433 Datum
434 pg_stat_get_backend_waiting(PG_FUNCTION_ARGS)
435 {
436         int32           beid = PG_GETARG_INT32(0);
437         bool            result;
438         PgBackendStatus *beentry;
439
440         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
441                 PG_RETURN_NULL();
442
443         if (!superuser() && beentry->st_userid != GetUserId())
444                 PG_RETURN_NULL();
445
446         result = beentry->st_waiting;
447
448         PG_RETURN_BOOL(result);
449 }
450
451
452 Datum
453 pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
454 {
455         int32           beid = PG_GETARG_INT32(0);
456         TimestampTz result;
457         PgBackendStatus *beentry;
458
459         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
460                 PG_RETURN_NULL();
461
462         if (!superuser() && beentry->st_userid != GetUserId())
463                 PG_RETURN_NULL();
464
465         result = beentry->st_activity_start_timestamp;
466
467         /*
468          * No time recorded for start of current query -- this is the case if the
469          * user hasn't enabled query-level stats collection.
470          */
471         if (result == 0)
472                 PG_RETURN_NULL();
473
474         PG_RETURN_TIMESTAMPTZ(result);
475 }
476
477
478 Datum
479 pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
480 {
481         int32           beid = PG_GETARG_INT32(0);
482         TimestampTz result;
483         PgBackendStatus *beentry;
484
485         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
486                 PG_RETURN_NULL();
487
488         if (!superuser() && beentry->st_userid != GetUserId())
489                 PG_RETURN_NULL();
490
491         result = beentry->st_xact_start_timestamp;
492
493         if (result == 0)                        /* not in a transaction */
494                 PG_RETURN_NULL();
495
496         PG_RETURN_TIMESTAMPTZ(result);
497 }
498
499
500 Datum
501 pg_stat_get_backend_start(PG_FUNCTION_ARGS)
502 {
503         int32           beid = PG_GETARG_INT32(0);
504         TimestampTz result;
505         PgBackendStatus *beentry;
506
507         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
508                 PG_RETURN_NULL();
509
510         if (!superuser() && beentry->st_userid != GetUserId())
511                 PG_RETURN_NULL();
512
513         result = beentry->st_proc_start_timestamp;
514
515         if (result == 0)                        /* probably can't happen? */
516                 PG_RETURN_NULL();
517
518         PG_RETURN_TIMESTAMPTZ(result);
519 }
520
521
522 Datum
523 pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
524 {
525         int32           beid = PG_GETARG_INT32(0);
526         PgBackendStatus *beentry;
527         SockAddr        zero_clientaddr;
528         char            remote_host[NI_MAXHOST];
529         int                     ret;
530
531         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
532                 PG_RETURN_NULL();
533
534         if (!superuser() && beentry->st_userid != GetUserId())
535                 PG_RETURN_NULL();
536
537         /* A zeroed client addr means we don't know */
538         memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
539         if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
540                            sizeof(zero_clientaddr) == 0))
541                 PG_RETURN_NULL();
542
543         switch (beentry->st_clientaddr.addr.ss_family)
544         {
545                 case AF_INET:
546 #ifdef HAVE_IPV6
547                 case AF_INET6:
548 #endif
549                         break;
550                 default:
551                         PG_RETURN_NULL();
552         }
553
554         remote_host[0] = '\0';
555         ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
556                                                          beentry->st_clientaddr.salen,
557                                                          remote_host, sizeof(remote_host),
558                                                          NULL, 0,
559                                                          NI_NUMERICHOST | NI_NUMERICSERV);
560         if (ret)
561                 PG_RETURN_NULL();
562
563         clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
564
565         PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
566                                                                                  CStringGetDatum(remote_host)));
567 }
568
569 Datum
570 pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
571 {
572         int32           beid = PG_GETARG_INT32(0);
573         PgBackendStatus *beentry;
574         SockAddr        zero_clientaddr;
575         char            remote_port[NI_MAXSERV];
576         int                     ret;
577
578         if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
579                 PG_RETURN_NULL();
580
581         if (!superuser() && beentry->st_userid != GetUserId())
582                 PG_RETURN_NULL();
583
584         /* A zeroed client addr means we don't know */
585         memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
586         if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
587                            sizeof(zero_clientaddr) == 0))
588                 PG_RETURN_NULL();
589
590         switch (beentry->st_clientaddr.addr.ss_family)
591         {
592                 case AF_INET:
593 #ifdef HAVE_IPV6
594                 case AF_INET6:
595 #endif
596                         break;
597                 case AF_UNIX:
598                         PG_RETURN_INT32(-1);
599                 default:
600                         PG_RETURN_NULL();
601         }
602
603         remote_port[0] = '\0';
604         ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
605                                                          beentry->st_clientaddr.salen,
606                                                          NULL, 0,
607                                                          remote_port, sizeof(remote_port),
608                                                          NI_NUMERICHOST | NI_NUMERICSERV);
609         if (ret)
610                 PG_RETURN_NULL();
611
612         PG_RETURN_DATUM(DirectFunctionCall1(int4in,
613                                                                                 CStringGetDatum(remote_port)));
614 }
615
616
617 Datum
618 pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
619 {
620         Oid                     dbid = PG_GETARG_OID(0);
621         int32           result;
622         int                     tot_backends = pgstat_fetch_stat_numbackends();
623         int                     beid;
624
625         result = 0;
626         for (beid = 1; beid <= tot_backends; beid++)
627         {
628                 PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
629
630                 if (beentry && beentry->st_databaseid == dbid)
631                         result++;
632         }
633
634         PG_RETURN_INT32(result);
635 }
636
637
638 Datum
639 pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
640 {
641         Oid                     dbid = PG_GETARG_OID(0);
642         int64           result;
643         PgStat_StatDBEntry *dbentry;
644
645         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
646                 result = 0;
647         else
648                 result = (int64) (dbentry->n_xact_commit);
649
650         PG_RETURN_INT64(result);
651 }
652
653
654 Datum
655 pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
656 {
657         Oid                     dbid = PG_GETARG_OID(0);
658         int64           result;
659         PgStat_StatDBEntry *dbentry;
660
661         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
662                 result = 0;
663         else
664                 result = (int64) (dbentry->n_xact_rollback);
665
666         PG_RETURN_INT64(result);
667 }
668
669
670 Datum
671 pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
672 {
673         Oid                     dbid = PG_GETARG_OID(0);
674         int64           result;
675         PgStat_StatDBEntry *dbentry;
676
677         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
678                 result = 0;
679         else
680                 result = (int64) (dbentry->n_blocks_fetched);
681
682         PG_RETURN_INT64(result);
683 }
684
685
686 Datum
687 pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
688 {
689         Oid                     dbid = PG_GETARG_OID(0);
690         int64           result;
691         PgStat_StatDBEntry *dbentry;
692
693         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
694                 result = 0;
695         else
696                 result = (int64) (dbentry->n_blocks_hit);
697
698         PG_RETURN_INT64(result);
699 }
700
701
702 Datum
703 pg_stat_get_db_tuples_returned(PG_FUNCTION_ARGS)
704 {
705         Oid                     dbid = PG_GETARG_OID(0);
706         int64           result;
707         PgStat_StatDBEntry *dbentry;
708
709         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
710                 result = 0;
711         else
712                 result = (int64) (dbentry->n_tuples_returned);
713
714         PG_RETURN_INT64(result);
715 }
716
717
718 Datum
719 pg_stat_get_db_tuples_fetched(PG_FUNCTION_ARGS)
720 {
721         Oid                     dbid = PG_GETARG_OID(0);
722         int64           result;
723         PgStat_StatDBEntry *dbentry;
724
725         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
726                 result = 0;
727         else
728                 result = (int64) (dbentry->n_tuples_fetched);
729
730         PG_RETURN_INT64(result);
731 }
732
733
734 Datum
735 pg_stat_get_db_tuples_inserted(PG_FUNCTION_ARGS)
736 {
737         Oid                     dbid = PG_GETARG_OID(0);
738         int64           result;
739         PgStat_StatDBEntry *dbentry;
740
741         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
742                 result = 0;
743         else
744                 result = (int64) (dbentry->n_tuples_inserted);
745
746         PG_RETURN_INT64(result);
747 }
748
749
750 Datum
751 pg_stat_get_db_tuples_updated(PG_FUNCTION_ARGS)
752 {
753         Oid                     dbid = PG_GETARG_OID(0);
754         int64           result;
755         PgStat_StatDBEntry *dbentry;
756
757         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
758                 result = 0;
759         else
760                 result = (int64) (dbentry->n_tuples_updated);
761
762         PG_RETURN_INT64(result);
763 }
764
765
766 Datum
767 pg_stat_get_db_tuples_deleted(PG_FUNCTION_ARGS)
768 {
769         Oid                     dbid = PG_GETARG_OID(0);
770         int64           result;
771         PgStat_StatDBEntry *dbentry;
772
773         if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
774                 result = 0;
775         else
776                 result = (int64) (dbentry->n_tuples_deleted);
777
778         PG_RETURN_INT64(result);
779 }
780
781 Datum
782 pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS)
783 {
784         PG_RETURN_INT64(pgstat_fetch_global()->timed_checkpoints);
785 }
786
787 Datum
788 pg_stat_get_bgwriter_requested_checkpoints(PG_FUNCTION_ARGS)
789 {
790         PG_RETURN_INT64(pgstat_fetch_global()->requested_checkpoints);
791 }
792
793 Datum
794 pg_stat_get_bgwriter_buf_written_checkpoints(PG_FUNCTION_ARGS)
795 {
796         PG_RETURN_INT64(pgstat_fetch_global()->buf_written_checkpoints);
797 }
798
799 Datum
800 pg_stat_get_bgwriter_buf_written_clean(PG_FUNCTION_ARGS)
801 {
802         PG_RETURN_INT64(pgstat_fetch_global()->buf_written_clean);
803 }
804
805 Datum
806 pg_stat_get_bgwriter_maxwritten_clean(PG_FUNCTION_ARGS)
807 {
808         PG_RETURN_INT64(pgstat_fetch_global()->maxwritten_clean);
809 }
810
811 Datum
812 pg_stat_get_buf_written_backend(PG_FUNCTION_ARGS)
813 {
814         PG_RETURN_INT64(pgstat_fetch_global()->buf_written_backend);
815 }
816
817 Datum
818 pg_stat_get_buf_alloc(PG_FUNCTION_ARGS)
819 {
820         PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc);
821 }
822
823
824 /* Discard the active statistics snapshot */
825 Datum
826 pg_stat_clear_snapshot(PG_FUNCTION_ARGS)
827 {
828         pgstat_clear_snapshot();
829
830         PG_RETURN_VOID();
831 }
832
833
834 /* Reset all counters for the current database */
835 Datum
836 pg_stat_reset(PG_FUNCTION_ARGS)
837 {
838         pgstat_reset_counters();
839
840         PG_RETURN_VOID();
841 }