diff -cprN head/src/backend/tcop/utility.c work/src/backend/tcop/utility.c
*** head/src/backend/tcop/utility.c	2009-10-06 04:24:41.000000000 +0900
--- work/src/backend/tcop/utility.c	2009-10-21 09:35:09.521278492 +0900
***************
*** 58,63 ****
--- 58,66 ----
  #include "utils/syscache.h"
  
  
+ /* Hooks for plugins to get control in ProcessUtility() */
+ ProcessUtility_hook_type ProcessUtility_hook = NULL;
+ 
  /*
   * Verify user has ownership of specified relation, else ereport.
   *
*************** check_xact_readonly(Node *parsetree)
*** 244,249 ****
--- 247,256 ----
   * completionTag is only set nonempty if we want to return a nondefault status.
   *
   * completionTag may be NULL if caller doesn't want a status string.
+  *
+  * We provide a function hook variable that lets loadable plugins
+  * get control when ProcessUtility is called.  Such a plugin would
+  * normally call standard_ProcessUtility().
   */
  void
  ProcessUtility(Node *parsetree,
*************** ProcessUtility(Node *parsetree,
*** 260,265 ****
--- 267,286 ----
  	if (completionTag)
  		completionTag[0] = '\0';
  
+ 	if (ProcessUtility_hook)
+ 		(*ProcessUtility_hook) (parsetree, queryString, params, isTopLevel, dest, completionTag);
+ 	else
+ 		standard_ProcessUtility(parsetree, queryString, params, isTopLevel, dest, completionTag);
+ }
+ 
+ void
+ standard_ProcessUtility(Node *parsetree,
+ 			   const char *queryString,
+ 			   ParamListInfo params,
+ 			   bool isTopLevel,
+ 			   DestReceiver *dest,
+ 			   char *completionTag)
+ {
  	switch (nodeTag(parsetree))
  	{
  			/*
diff -cprN head/src/include/tcop/utility.h work/src/include/tcop/utility.h
*** head/src/include/tcop/utility.h	2009-01-02 02:24:01.000000000 +0900
--- work/src/include/tcop/utility.h	2009-10-21 09:35:09.522175826 +0900
***************
*** 17,25 ****
--- 17,34 ----
  #include "tcop/tcopprot.h"
  
  
+ /* Hook for plugins to get control in ProcessUtility() */
+ typedef void (*ProcessUtility_hook_type) (Node *parsetree,
+ 			   const char *queryString, ParamListInfo params, bool isTopLevel,
+ 			   DestReceiver *dest, char *completionTag);
+ extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook;
+ 
  extern void ProcessUtility(Node *parsetree, const char *queryString,
  			   ParamListInfo params, bool isTopLevel,
  			   DestReceiver *dest, char *completionTag);
+ extern void standard_ProcessUtility(Node *parsetree, const char *queryString,
+ 			   ParamListInfo params, bool isTopLevel,
+ 			   DestReceiver *dest, char *completionTag);
  
  extern bool UtilityReturnsTuples(Node *parsetree);
  
