diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c
index 570feab25e6e6cb7008926ea69eb63b64f836830..856d0f0a73f2b65218a69212d33e945b79f079f9 100644
--- a/src/backend/storage/ipc/sinval.c
+++ b/src/backend/storage/ipc/sinval.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.63 2004/05/23 03:50:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/ipc/sinval.c,v 1.64 2004/06/02 21:29:28 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -463,6 +463,40 @@ TransactionIdIsInProgress(TransactionId xid)
 	return result;
 }
 
+/*
+ * IsBackendPid -- is a given pid a running backend
+ */
+bool
+IsBackendPid(int pid)
+{
+	bool		result = false;
+	SISeg	   *segP = shmInvalBuffer;
+	ProcState  *stateP = segP->procState;
+	int			index;
+
+	LWLockAcquire(SInvalLock, LW_SHARED);
+
+	for (index = 0; index < segP->lastBackend; index++)
+	{
+		SHMEM_OFFSET pOffset = stateP[index].procStruct;
+
+		if (pOffset != INVALID_OFFSET)
+		{
+			PGPROC	   *proc = (PGPROC *) MAKE_PTR(pOffset);
+
+			if (proc->pid == pid)
+			{
+				result = true;
+				break;
+			}
+		}
+	}
+
+	LWLockRelease(SInvalLock);
+
+	return result;
+}
+
 /*
  * GetOldestXmin -- returns oldest transaction that was running
  *					when any current transaction was started.
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 673b175bbc042c4a3fed81304b381d13563a3db8..8ab6953cb02c151148a9fabc449b0b9c157128b9 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -8,16 +8,18 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.33 2004/05/21 05:08:02 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/misc.c,v 1.34 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
 #include <sys/file.h>
+#include <signal.h>
 
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
+#include "storage/sinval.h"
 #include "utils/builtins.h"
 
 
@@ -57,3 +59,47 @@ current_database(PG_FUNCTION_ARGS)
 	namestrcpy(db, get_database_name(MyDatabaseId));
 	PG_RETURN_NAME(db);
 }
+
+
+/*
+ * 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 (!IsBackendPid(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));
+}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index f0c2f8269197ce965166dbd1daeb64b7275d7da3..bf6ded488cad8cfc5a0564dd794bdeb951f61d7e 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.232 2004/05/26 18:37:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.233 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200405262
+#define CATALOG_VERSION_NO	200406021
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index c87eb2155658212cc0ea0e9b4b992d474f3bd9f4..cb3279747b03a934c4d0ef4cdd96850540ca3b61 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.333 2004/05/26 18:37:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.334 2004/06/02 21:29:29 momjian Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -2808,6 +2808,11 @@ DESCR("Statistics: Blocks fetched for database");
 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_ ));
diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h
index a1c731024cf8c4d51550af8dca33e475f010384b..84769200504450f8c5089c028465e8429c9592ba 100644
--- a/src/include/storage/sinval.h
+++ b/src/include/storage/sinval.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.34 2004/05/23 03:50:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.35 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,6 +97,7 @@ extern void ReceiveSharedInvalidMessages(
 
 extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
 extern bool TransactionIdIsInProgress(TransactionId xid);
+extern bool IsBackendPid(int pid);
 extern TransactionId GetOldestXmin(bool allDbs);
 extern int	CountActiveBackends(void);
 extern int	CountEmptyBackendSlots(void);
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 267ededb1303af7684e6ecbdce148946dc1f2744..1fc26e69a1f5d59f3dce1950f2121bbd443d34b1 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.240 2004/05/26 18:35:46 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.241 2004/06/02 21:29:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -354,6 +354,8 @@ extern Datum float84ge(PG_FUNCTION_ARGS);
 extern Datum nullvalue(PG_FUNCTION_ARGS);
 extern Datum nonnullvalue(PG_FUNCTION_ARGS);
 extern Datum current_database(PG_FUNCTION_ARGS);
+extern Datum pg_terminate_backend(PG_FUNCTION_ARGS);
+extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
 
 /* not_in.c */
 extern Datum int4notin(PG_FUNCTION_ARGS);