diff -cprN head/contrib/pg_stat_statements/pg_stat_statements.c work/contrib/pg_stat_statements/pg_stat_statements.c
*** head/contrib/pg_stat_statements/pg_stat_statements.c	2009-07-27 13:09:55.000000000 +0900
--- work/contrib/pg_stat_statements/pg_stat_statements.c	2009-10-21 09:47:01.625232564 +0900
***************
*** 32,37 ****
--- 32,38 ----
  #include "storage/fd.h"
  #include "storage/ipc.h"
  #include "storage/spin.h"
+ #include "tcop/utility.h"
  #include "utils/builtins.h"
  #include "utils/hsearch.h"
  #include "utils/guc.h"
*************** static shmem_startup_hook_type prev_shme
*** 113,118 ****
--- 114,120 ----
  static ExecutorStart_hook_type prev_ExecutorStart = NULL;
  static ExecutorRun_hook_type prev_ExecutorRun = NULL;
  static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
+ static ProcessUtility_hook_type prev_ProcessUtility = NULL;
  
  /* Links to shared memory state */
  static pgssSharedState *pgss = NULL;
*************** static bool pgss_save;			/* whether to s
*** 146,152 ****
--- 148,156 ----
  /*---- Function declarations ----*/
  
  void		_PG_init(void);
+ #ifdef NOT_USED
  void		_PG_fini(void);
+ #endif
  
  Datum		pg_stat_statements_reset(PG_FUNCTION_ARGS);
  Datum		pg_stat_statements(PG_FUNCTION_ARGS);
*************** static void pgss_ExecutorRun(QueryDesc *
*** 161,170 ****
  				 ScanDirection direction,
  				 long count);
  static void pgss_ExecutorEnd(QueryDesc *queryDesc);
  static uint32 pgss_hash_fn(const void *key, Size keysize);
  static int	pgss_match_fn(const void *key1, const void *key2, Size keysize);
! static void pgss_store(const char *query,
! 		   const Instrumentation *instr, uint32 rows);
  static Size pgss_memsize(void);
  static pgssEntry *entry_alloc(pgssHashKey *key);
  static void entry_dealloc(void);
--- 165,176 ----
  				 ScanDirection direction,
  				 long count);
  static void pgss_ExecutorEnd(QueryDesc *queryDesc);
+ static void pgss_ProcessUtility(Node *parsetree,
+ 			   const char *queryString, ParamListInfo params, bool isTopLevel,
+ 			   DestReceiver *dest, char *completionTag);
  static uint32 pgss_hash_fn(const void *key, Size keysize);
  static int	pgss_match_fn(const void *key1, const void *key2, Size keysize);
! static void pgss_store(const char *query, double total_time, uint32 rows);
  static Size pgss_memsize(void);
  static pgssEntry *entry_alloc(pgssHashKey *key);
  static void entry_dealloc(void);
*************** _PG_init(void)
*** 245,252 ****
--- 251,261 ----
  	ExecutorRun_hook = pgss_ExecutorRun;
  	prev_ExecutorEnd = ExecutorEnd_hook;
  	ExecutorEnd_hook = pgss_ExecutorEnd;
+ 	prev_ProcessUtility = ProcessUtility_hook;
+ 	ProcessUtility_hook = pgss_ProcessUtility;
  }
  
+ #ifdef NOT_USED
  /*
   * Module unload callback
   */
*************** _PG_fini(void)
*** 257,264 ****
--- 266,275 ----
  	ExecutorStart_hook = prev_ExecutorStart;
  	ExecutorRun_hook = prev_ExecutorRun;
  	ExecutorEnd_hook = prev_ExecutorEnd;
+ 	ProcessUtility_hook = prev_ProcessUtility;
  	shmem_startup_hook = prev_shmem_startup_hook;
  }
+ #endif
  
  /*
   * shmem_startup hook: allocate or attach to shared memory,
*************** pgss_ExecutorEnd(QueryDesc *queryDesc)
*** 539,545 ****
  		InstrEndLoop(queryDesc->totaltime);
  
  		pgss_store(queryDesc->sourceText,
! 				   queryDesc->totaltime,
  				   queryDesc->estate->es_processed);
  	}
  
--- 550,556 ----
  		InstrEndLoop(queryDesc->totaltime);
  
  		pgss_store(queryDesc->sourceText,
! 				   queryDesc->totaltime->total,
  				   queryDesc->estate->es_processed);
  	}
  
*************** pgss_ExecutorEnd(QueryDesc *queryDesc)
*** 550,555 ****
--- 561,611 ----
  }
  
  /*
+  * ProcessUtility hook
+  */
+ static void
+ pgss_ProcessUtility(Node *parsetree, const char *queryString,
+ 					ParamListInfo params, bool isTopLevel,
+ 					DestReceiver *dest, char *completionTag)
+ {
+ 	if (pgss_enabled())
+ 	{
+ 		instr_time	start;
+ 		instr_time	duration;
+ 
+ 		INSTR_TIME_SET_CURRENT(start);
+ 
+ 		nested_level++;
+ 		PG_TRY();
+ 		{
+ 			if (prev_ProcessUtility)
+ 				prev_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+ 			else
+ 				standard_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+ 			nested_level--;
+ 		}
+ 		PG_CATCH();
+ 		{
+ 			nested_level--;
+ 			PG_RE_THROW();
+ 		}
+ 		PG_END_TRY();
+ 
+ 		INSTR_TIME_SET_CURRENT(duration);
+ 		INSTR_TIME_SUBTRACT(duration, start);
+ 
+ 		pgss_store(queryString, INSTR_TIME_GET_DOUBLE(duration), 0);
+ 	}
+ 	else
+ 	{
+ 		if (prev_ProcessUtility)
+ 			prev_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+ 		else
+ 			standard_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+ 	}
+ }
+ 
+ /*
   * Calculate hash value for a key
   */
  static uint32
*************** pgss_match_fn(const void *key1, const vo
*** 587,593 ****
   * Store some statistics for a statement.
   */
  static void
! pgss_store(const char *query, const Instrumentation *instr, uint32 rows)
  {
  	pgssHashKey key;
  	double		usage;
--- 643,649 ----
   * Store some statistics for a statement.
   */
  static void
! pgss_store(const char *query, double total_time, uint32 rows)
  {
  	pgssHashKey key;
  	double		usage;
*************** pgss_store(const char *query, const Inst
*** 631,637 ****
  
  		SpinLockAcquire(&e->mutex);
  		e->counters.calls += 1;
! 		e->counters.total_time += instr->total;
  		e->counters.rows += rows;
  		e->counters.usage += usage;
  		SpinLockRelease(&e->mutex);
--- 687,693 ----
  
  		SpinLockAcquire(&e->mutex);
  		e->counters.calls += 1;
! 		e->counters.total_time += total_time;
  		e->counters.rows += rows;
  		e->counters.usage += usage;
  		SpinLockRelease(&e->mutex);
