@@ -85,6 +85,8 @@ typedef struct Counters
8585int64 local_blks_written ;/* # of local disk blocks written */
8686int64 temp_blks_read ;/* # of temp blocks read */
8787int64 temp_blks_written ;/* # of temp blocks written */
88+ double time_read ;/* time spent reading in seconds */
89+ double time_write ;/* time spent writing in seconds */
8890double usage ;/* usage factor */
8991}Counters ;
9092
@@ -618,9 +620,9 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
618620instr_time start ;
619621instr_time duration ;
620622uint64 rows = 0 ;
621- BufferUsage bufusage ;
623+ BufferUsage bufusage_start , bufusage ;
622624
623- bufusage = pgBufferUsage ;
625+ bufusage_start = pgBufferUsage ;
624626INSTR_TIME_SET_CURRENT (start );
625627
626628nested_level ++ ;
@@ -651,25 +653,29 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
651653
652654/* calc differences of buffer counters. */
653655bufusage .shared_blks_hit =
654- pgBufferUsage .shared_blks_hit - bufusage .shared_blks_hit ;
656+ pgBufferUsage .shared_blks_hit - bufusage_start .shared_blks_hit ;
655657bufusage .shared_blks_read =
656- pgBufferUsage .shared_blks_read - bufusage .shared_blks_read ;
658+ pgBufferUsage .shared_blks_read - bufusage_start .shared_blks_read ;
657659bufusage .shared_blks_dirtied =
658- pgBufferUsage .shared_blks_dirtied - bufusage .shared_blks_dirtied ;
660+ pgBufferUsage .shared_blks_dirtied - bufusage_start .shared_blks_dirtied ;
659661bufusage .shared_blks_written =
660- pgBufferUsage .shared_blks_written - bufusage .shared_blks_written ;
662+ pgBufferUsage .shared_blks_written - bufusage_start .shared_blks_written ;
661663bufusage .local_blks_hit =
662- pgBufferUsage .local_blks_hit - bufusage .local_blks_hit ;
664+ pgBufferUsage .local_blks_hit - bufusage_start .local_blks_hit ;
663665bufusage .local_blks_read =
664- pgBufferUsage .local_blks_read - bufusage .local_blks_read ;
666+ pgBufferUsage .local_blks_read - bufusage_start .local_blks_read ;
665667bufusage .local_blks_dirtied =
666- pgBufferUsage .local_blks_dirtied - bufusage .local_blks_dirtied ;
668+ pgBufferUsage .local_blks_dirtied - bufusage_start .local_blks_dirtied ;
667669bufusage .local_blks_written =
668- pgBufferUsage .local_blks_written - bufusage .local_blks_written ;
670+ pgBufferUsage .local_blks_written - bufusage_start .local_blks_written ;
669671bufusage .temp_blks_read =
670- pgBufferUsage .temp_blks_read - bufusage .temp_blks_read ;
672+ pgBufferUsage .temp_blks_read - bufusage_start .temp_blks_read ;
671673bufusage .temp_blks_written =
672- pgBufferUsage .temp_blks_written - bufusage .temp_blks_written ;
674+ pgBufferUsage .temp_blks_written - bufusage_start .temp_blks_written ;
675+ bufusage .time_read = pgBufferUsage .time_read ;
676+ INSTR_TIME_SUBTRACT (bufusage .time_read ,bufusage_start .time_read );
677+ bufusage .time_write = pgBufferUsage .time_write ;
678+ INSTR_TIME_SUBTRACT (bufusage .time_write ,bufusage_start .time_write );
673679
674680pgss_store (queryString ,INSTR_TIME_GET_DOUBLE (duration ),rows ,
675681& bufusage );
@@ -780,6 +786,8 @@ pgss_store(const char *query, double total_time, uint64 rows,
780786e -> counters .local_blks_written += bufusage -> local_blks_written ;
781787e -> counters .temp_blks_read += bufusage -> temp_blks_read ;
782788e -> counters .temp_blks_written += bufusage -> temp_blks_written ;
789+ e -> counters .time_read += INSTR_TIME_GET_DOUBLE (bufusage -> time_read );
790+ e -> counters .time_write += INSTR_TIME_GET_DOUBLE (bufusage -> time_write );
783791e -> counters .usage += usage ;
784792SpinLockRelease (& e -> mutex );
785793}
@@ -802,7 +810,7 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS)
802810}
803811
804812#define PG_STAT_STATEMENTS_COLS_V1_0 14
805- #define PG_STAT_STATEMENTS_COLS 16
813+ #define PG_STAT_STATEMENTS_COLS 18
806814
807815/*
808816 * Retrieve statement statistics.
@@ -819,7 +827,7 @@ pg_stat_statements(PG_FUNCTION_ARGS)
819827bool is_superuser = superuser ();
820828HASH_SEQ_STATUS hash_seq ;
821829pgssEntry * entry ;
822- bool sql_supports_dirty_counters = true;
830+ bool sql_supports_v1_1_counters = true;
823831
824832if (!pgss || !pgss_hash )
825833ereport (ERROR ,
@@ -841,7 +849,7 @@ pg_stat_statements(PG_FUNCTION_ARGS)
841849if (get_call_result_type (fcinfo ,NULL ,& tupdesc )!= TYPEFUNC_COMPOSITE )
842850elog (ERROR ,"return type must be a row type" );
843851if (tupdesc -> natts == PG_STAT_STATEMENTS_COLS_V1_0 )
844- sql_supports_dirty_counters = false;
852+ sql_supports_v1_1_counters = false;
845853
846854per_query_ctx = rsinfo -> econtext -> ecxt_per_query_memory ;
847855oldcontext = MemoryContextSwitchTo (per_query_ctx );
@@ -899,18 +907,23 @@ pg_stat_statements(PG_FUNCTION_ARGS)
899907values [i ++ ]= Int64GetDatumFast (tmp .rows );
900908values [i ++ ]= Int64GetDatumFast (tmp .shared_blks_hit );
901909values [i ++ ]= Int64GetDatumFast (tmp .shared_blks_read );
902- if (sql_supports_dirty_counters )
910+ if (sql_supports_v1_1_counters )
903911values [i ++ ]= Int64GetDatumFast (tmp .shared_blks_dirtied );
904912values [i ++ ]= Int64GetDatumFast (tmp .shared_blks_written );
905913values [i ++ ]= Int64GetDatumFast (tmp .local_blks_hit );
906914values [i ++ ]= Int64GetDatumFast (tmp .local_blks_read );
907- if (sql_supports_dirty_counters )
915+ if (sql_supports_v1_1_counters )
908916values [i ++ ]= Int64GetDatumFast (tmp .local_blks_dirtied );
909917values [i ++ ]= Int64GetDatumFast (tmp .local_blks_written );
910918values [i ++ ]= Int64GetDatumFast (tmp .temp_blks_read );
911919values [i ++ ]= Int64GetDatumFast (tmp .temp_blks_written );
920+ if (sql_supports_v1_1_counters )
921+ {
922+ values [i ++ ]= Float8GetDatumFast (tmp .time_read );
923+ values [i ++ ]= Float8GetDatumFast (tmp .time_write );
924+ }
912925
913- Assert (i == sql_supports_dirty_counters ? \
926+ Assert (i == sql_supports_v1_1_counters ? \
914927PG_STAT_STATEMENTS_COLS :PG_STAT_STATEMENTS_COLS_V1_0 );
915928
916929tuplestore_putvalues (tupstore ,tupdesc ,values ,nulls );