user_signal.patch

application/octet-stream

Filename: user_signal.patch
Type: application/octet-stream
Part: 0
Message: Re: Patch to allow users to kill their own queries

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/utils/adt/misc.c 30 21
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 63ec6fd..dc46123 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -14,6 +14,8 @@
  */
 #include "postgres.h"
 
+#include "storage/proc.h"
+
 #include <sys/file.h>
 #include <signal.h>
 #include <dirent.h>
@@ -74,13 +76,34 @@ current_query(PG_FUNCTION_ARGS)
 static bool
 pg_signal_backend(int pid, int sig)
 {
-	if (!superuser())
-		ereport(ERROR,
-				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-			(errmsg("must be superuser to signal other server processes"))));
+  PGPROC *proc = NULL;
 
-	if (!IsBackendPid(pid))
-	{
+  if (IsBackendPid(pid))
+  {
+    proc = BackendPidGetProc(pid);
+
+    if (superuser() || proc->roleId == GetUserId())
+    {
+      /* If we have setsid(), signal the backend's whole process group */
+#ifdef HAVE_SETSID
+      if (kill(-pid, sig))
+#else
+      if (kill(pid, sig))
+#endif
+      {
+        /* Just a warning to allow loops */
+        ereport(WARNING,
+            (errmsg("could not send signal to process %d: %m", pid)));
+        return false;
+      }
+      return true;
+    } else {
+      ereport(ERROR,
+          (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+        (errmsg("must be the same user or superuser to signal other server processes"))));
+      return false;
+    }
+  } else {
 		/*
 		 * This is just a warning so a loop-through-resultset will not abort
 		 * if one backend terminated on it's own during the run
@@ -88,21 +111,7 @@ pg_signal_backend(int pid, int sig)
 		ereport(WARNING,
 				(errmsg("PID %d is not a PostgreSQL server process", pid)));
 		return false;
-	}
-
-	/* If we have setsid(), signal the backend's whole process group */
-#ifdef HAVE_SETSID
-	if (kill(-pid, sig))
-#else
-	if (kill(pid, sig))
-#endif
-	{
-		/* Again, just a warning to allow loops */
-		ereport(WARNING,
-				(errmsg("could not send signal to process %d: %m", pid)));
-		return false;
-	}
-	return true;
+  }
 }
 
 Datum