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