1414 * Copyright (c) 2008-2010, PostgreSQL Global Development Group
1515 *
1616 * IDENTIFICATION
17- * $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.11 2010/01/02 16:57:32 momjian Exp $
17+ * $PostgreSQL: pgsql/contrib/pg_stat_statements/pg_stat_statements.c,v 1.12 2010/01/08 00:38:19 itagaki Exp $
1818 *
1919 *-------------------------------------------------------------------------
2020 */
2626#include "catalog/pg_type.h"
2727#include "executor/executor.h"
2828#include "executor/instrument.h"
29+ #include "funcapi.h"
2930#include "mb/pg_wchar.h"
3031#include "miscadmin.h"
3132#include "pgstat.h"
@@ -44,7 +45,7 @@ PG_MODULE_MAGIC;
4445#define PGSS_DUMP_FILE "global/pg_stat_statements.stat"
4546
4647/* This constant defines the magic number in the stats file header */
47- static const uint32 PGSS_FILE_HEADER = 0x20081202 ;
48+ static const uint32 PGSS_FILE_HEADER = 0x20100108 ;
4849
4950/* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */
5051#define USAGE_EXEC (duration ) (1.0)
@@ -75,10 +76,18 @@ typedef struct pgssHashKey
7576 */
7677typedef struct Counters
7778{
78- int64 calls ; /* # of times executed */
79- double total_time ; /* total execution time in seconds */
80- int64 rows ; /* total # of retrieved or affected rows */
81- double usage ; /* usage factor */
79+ int64 calls ; /* # of times executed */
80+ double total_time ; /* total execution time in seconds */
81+ int64 rows ; /* total # of retrieved or affected rows */
82+ int64 shared_blks_hit ; /* # of shared buffer hits */
83+ int64 shared_blks_read ; /* # of shared disk blocks read */
84+ int64 shared_blks_written ;/* # of shared disk blocks written */
85+ int64 local_blks_hit ; /* # of local buffer hits */
86+ int64 local_blks_read ; /* # of local disk blocks read */
87+ int64 local_blks_written ; /* # of local disk blocks written */
88+ int64 temp_blks_read ; /* # of temp blocks read */
89+ int64 temp_blks_written ; /* # of temp blocks written */
90+ double usage ; /* usage factor */
8291} Counters ;
8392
8493/*
@@ -129,7 +138,8 @@ typedef enum
129138 PGSS_TRACK_ALL /* all statements, including nested ones */
130139} PGSSTrackLevel ;
131140
132- static const struct config_enum_entry track_options [] = {
141+ static const struct config_enum_entry track_options [] =
142+ {
133143 {"none" , PGSS_TRACK_NONE , false},
134144 {"top" , PGSS_TRACK_TOP , false},
135145 {"all" , PGSS_TRACK_ALL , false},
@@ -169,7 +179,8 @@ static void pgss_ProcessUtility(Node *parsetree,
169179 DestReceiver * dest , char * completionTag );
170180static uint32 pgss_hash_fn (const void * key , Size keysize );
171181static int pgss_match_fn (const void * key1 , const void * key2 , Size keysize );
172- static void pgss_store (const char * query , double total_time , uint64 rows );
182+ static void pgss_store (const char * query , double total_time , uint64 rows ,
183+ const BufferUsage * bufusage );
173184static Size pgss_memsize (void );
174185static pgssEntry * entry_alloc (pgssHashKey * key );
175186static void entry_dealloc (void );
@@ -558,7 +569,8 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
558569
559570 pgss_store (queryDesc -> sourceText ,
560571 queryDesc -> totaltime -> total ,
561- queryDesc -> estate -> es_processed );
572+ queryDesc -> estate -> es_processed ,
573+ & queryDesc -> totaltime -> bufusage );
562574 }
563575
564576 if (prev_ExecutorEnd )
@@ -580,7 +592,9 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
580592 instr_time start ;
581593 instr_time duration ;
582594 uint64 rows = 0 ;
595+ BufferUsage bufusage ;
583596
597+ bufusage = pgBufferUsage ;
584598 INSTR_TIME_SET_CURRENT (start );
585599
586600 nested_level ++ ;
@@ -609,7 +623,26 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
609623 sscanf (completionTag , "COPY " UINT64_FORMAT , & rows ) != 1 )
610624 rows = 0 ;
611625
612- pgss_store (queryString , INSTR_TIME_GET_DOUBLE (duration ), rows );
626+ /* calc differences of buffer counters. */
627+ bufusage .shared_blks_hit =
628+ pgBufferUsage .shared_blks_hit - bufusage .shared_blks_hit ;
629+ bufusage .shared_blks_read =
630+ pgBufferUsage .shared_blks_read - bufusage .shared_blks_read ;
631+ bufusage .shared_blks_written =
632+ pgBufferUsage .shared_blks_written - bufusage .shared_blks_written ;
633+ bufusage .local_blks_hit =
634+ pgBufferUsage .local_blks_hit - bufusage .local_blks_hit ;
635+ bufusage .local_blks_read =
636+ pgBufferUsage .local_blks_read - bufusage .local_blks_read ;
637+ bufusage .local_blks_written =
638+ pgBufferUsage .local_blks_written - bufusage .local_blks_written ;
639+ bufusage .temp_blks_read =
640+ pgBufferUsage .temp_blks_read - bufusage .temp_blks_read ;
641+ bufusage .temp_blks_written =
642+ pgBufferUsage .temp_blks_written - bufusage .temp_blks_written ;
643+
644+ pgss_store (queryString , INSTR_TIME_GET_DOUBLE (duration ), rows ,
645+ & bufusage );
613646 }
614647 else
615648 {
@@ -660,7 +693,8 @@ pgss_match_fn(const void *key1, const void *key2, Size keysize)
660693 * Store some statistics for a statement.
661694 */
662695static void
663- pgss_store (const char * query , double total_time , uint64 rows )
696+ pgss_store (const char * query , double total_time , uint64 rows ,
697+ const BufferUsage * bufusage )
664698{
665699 pgssHashKey key ;
666700 double usage ;
@@ -706,6 +740,14 @@ pgss_store(const char *query, double total_time, uint64 rows)
706740 e -> counters .calls += 1 ;
707741 e -> counters .total_time += total_time ;
708742 e -> counters .rows += rows ;
743+ e -> counters .shared_blks_hit += bufusage -> shared_blks_hit ;
744+ e -> counters .shared_blks_read += bufusage -> shared_blks_read ;
745+ e -> counters .shared_blks_written += bufusage -> shared_blks_written ;
746+ e -> counters .local_blks_hit += bufusage -> local_blks_hit ;
747+ e -> counters .local_blks_read += bufusage -> local_blks_read ;
748+ e -> counters .local_blks_written += bufusage -> local_blks_written ;
749+ e -> counters .temp_blks_read += bufusage -> temp_blks_read ;
750+ e -> counters .temp_blks_written += bufusage -> temp_blks_written ;
709751 e -> counters .usage += usage ;
710752 SpinLockRelease (& e -> mutex );
711753 }
@@ -727,7 +769,7 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
727769 PG_RETURN_VOID ();
728770}
729771
730- #define PG_STAT_STATEMENTS_COLS 6
772+ #define PG_STAT_STATEMENTS_COLS 14
731773
732774/*
733775 * Retrieve statement statistics.
@@ -761,23 +803,13 @@ pg_stat_statements(PG_FUNCTION_ARGS)
761803 errmsg ("materialize mode required, but it is not " \
762804 "allowed in this context" )));
763805
806+ /* Build a tuple descriptor for our result type */
807+ if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
808+ elog (ERROR , "return type must be a row type" );
809+
764810 per_query_ctx = rsinfo -> econtext -> ecxt_per_query_memory ;
765811 oldcontext = MemoryContextSwitchTo (per_query_ctx );
766812
767- tupdesc = CreateTemplateTupleDesc (PG_STAT_STATEMENTS_COLS , false);
768- TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "userid" ,
769- OIDOID , -1 , 0 );
770- TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "dbid" ,
771- OIDOID , -1 , 0 );
772- TupleDescInitEntry (tupdesc , (AttrNumber ) 3 , "query" ,
773- TEXTOID , -1 , 0 );
774- TupleDescInitEntry (tupdesc , (AttrNumber ) 4 , "calls" ,
775- INT8OID , -1 , 0 );
776- TupleDescInitEntry (tupdesc , (AttrNumber ) 5 , "total_time" ,
777- FLOAT8OID , -1 , 0 );
778- TupleDescInitEntry (tupdesc , (AttrNumber ) 6 , "rows" ,
779- INT8OID , -1 , 0 );
780-
781813 tupstore = tuplestore_begin_heap (true, false, work_mem );
782814 rsinfo -> returnMode = SFRM_Materialize ;
783815 rsinfo -> setResult = tupstore ;
@@ -829,6 +861,14 @@ pg_stat_statements(PG_FUNCTION_ARGS)
829861 values [i ++ ] = Int64GetDatumFast (tmp .calls );
830862 values [i ++ ] = Float8GetDatumFast (tmp .total_time );
831863 values [i ++ ] = Int64GetDatumFast (tmp .rows );
864+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_hit );
865+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_read );
866+ values [i ++ ] = Int64GetDatumFast (tmp .shared_blks_written );
867+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_hit );
868+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_read );
869+ values [i ++ ] = Int64GetDatumFast (tmp .local_blks_written );
870+ values [i ++ ] = Int64GetDatumFast (tmp .temp_blks_read );
871+ values [i ++ ] = Int64GetDatumFast (tmp .temp_blks_written );
832872
833873 Assert (i == PG_STAT_STATEMENTS_COLS );
834874
0 commit comments