Index: src/backend/postmaster/pgstat.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v
retrieving revision 1.70
diff -c -r1.70 pgstat.c
*** src/backend/postmaster/pgstat.c	18 May 2004 03:36:30 -0000	1.70
--- src/backend/postmaster/pgstat.c	21 May 2004 18:58:44 -0000
***************
*** 1391,1396 ****
--- 1391,1423 ----
  	return pgStatNumBackends;
  }
  
+ /* ----------
+  * pgstat_is_backendpid()
+  *
+  *	Support function for the SQL-callable functions. Returns 
+  *	true if the specified PID is a postgresql backend.
+  * ----------
+  */
+ bool
+ pgstat_is_backendpid(int pid)
+ {
+ 	int i;
+ 
+ 	if (!TransactionIdEquals(pgStatDBHashXact, GetCurrentTransactionId()))
+ 	{
+ 		pgstat_read_statsfile(&pgStatDBHash, MyDatabaseId,
+ 							  &pgStatBeTable, &pgStatNumBackends);
+ 		pgStatDBHashXact = GetCurrentTransactionId();
+ 	}
+ 	
+ 	for (i=0; i < pgStatNumBackends; i++) 
+ 	{
+ 		if (pgStatBeTable[i].procpid == pid)
+ 			return true;
+ 	}
+ 
+ 	return false;
+ }
  
  
  /* ------------------------------------------------------------
Index: src/backend/utils/adt/pgstatfuncs.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/pgstatfuncs.c,v
retrieving revision 1.18
diff -c -r1.18 pgstatfuncs.c
*** src/backend/utils/adt/pgstatfuncs.c	12 Feb 2004 01:44:22 -0000	1.18
--- src/backend/utils/adt/pgstatfuncs.c	21 May 2004 18:59:53 -0000
***************
*** 6,11 ****
--- 6,12 ----
  #include "access/xact.h"
  #include "catalog/pg_shadow.h"
  #include "nodes/execnodes.h"
+ #include <signal.h>
  
  #include "pgstat.h"
  
***************
*** 429,432 ****
--- 430,478 ----
  		result = (int64) (dbentry->n_blocks_hit);
  
  	PG_RETURN_INT64(result);
+ }
+ 
+ 
+ 
+ /*
+  * Functions to terminate a backend or cancel a query running on
+  * a different backend.
+  */
+ 
+ static int pg_signal_backend(int pid, int sig) 
+ {
+ 	if (!superuser()) 
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 				 (errmsg("only superuser can signal other backends"))));
+ 	
+ 	if (!pgstat_is_backendpid(pid))
+ 	{
+ 		/* This is just a warning so a loop-through-resultset will not abort
+ 		 * if one backend terminated on it's own during the run */
+ 		ereport(WARNING,
+ 				(errmsg("pid %i is not a postgresql backend",pid)));
+ 		return 0;
+ 	}
+ 
+ 	if (kill(pid, sig)) 
+ 	{
+ 		/* Again, just a warning to allow loops */
+ 		ereport(WARNING,
+ 				(errmsg("failed to send signal to backend %i: %m",pid)));
+ 		return 0;
+ 	}
+ 	return 1;
+ }
+ 
+ Datum
+ pg_terminate_backend(PG_FUNCTION_ARGS)
+ {
+ 	PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
+ }
+ 
+ Datum
+ pg_cancel_backend(PG_FUNCTION_ARGS)
+ {
+ 	PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
  }
Index: src/include/pgstat.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/pgstat.h,v
retrieving revision 1.21
diff -c -r1.21 pgstat.h
*** src/include/pgstat.h	9 Mar 2004 05:11:53 -0000	1.21
--- src/include/pgstat.h	21 May 2004 18:56:23 -0000
***************
*** 487,491 ****
--- 487,492 ----
  extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid);
  extern PgStat_StatBeEntry *pgstat_fetch_stat_beentry(int beid);
  extern int	pgstat_fetch_stat_numbackends(void);
+ extern bool pgstat_is_backendpid(int pid);
  
  #endif   /* PGSTAT_H */
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v
retrieving revision 1.329
diff -c -r1.329 pg_proc.h
*** src/include/catalog/pg_proc.h	14 May 2004 21:42:28 -0000	1.329
--- src/include/catalog/pg_proc.h	21 May 2004 18:57:12 -0000
***************
*** 2797,2802 ****
--- 2797,2807 ----
  DATA(insert OID = 1945 (  pg_stat_get_db_blocks_hit		PGNSP PGUID 12 f f t f s 1 20 "26" _null_	pg_stat_get_db_blocks_hit - _null_ ));
  DESCR("Statistics: Blocks found in cache for database");
  
+ DATA(insert OID = 2171 ( pg_terminate_backend           PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_terminate_backend - _null_ ));
+ DESCR("Terminate a backend process");
+ DATA(insert OID = 2172 ( pg_cancel_backend              PGNSP PGUID 12 f f t f s 1 23 "23" _null_ pg_cancel_backend - _null_ ));
+ DESCR("Cancel running query on a backend process");
+ 
  DATA(insert OID = 1946 (  encode						PGNSP PGUID 12 f f t f i 2 25 "17 25" _null_  binary_encode - _null_ ));
  DESCR("Convert bytea value into some ascii-only text string");
  DATA(insert OID = 1947 (  decode						PGNSP PGUID 12 f f t f i 2 17 "25 25" _null_  binary_decode - _null_ ));
