diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 89a609f..b405876 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -16508,7 +16508,7 @@ SELECT set_config('log_statement_stats', 'off', false); - pg_cancel_backend(pid int) + pg_cancel_backend(pid int, skip_my_pid boolean ) boolean Cancel a backend's current query. This is also allowed if the @@ -16532,7 +16532,7 @@ SELECT set_config('log_statement_stats', 'off', false); - pg_terminate_backend(pid int) + pg_terminate_backend(pid int, skip_my_pid boolean ) boolean Terminate a backend. This is also allowed if the calling role @@ -16562,6 +16562,10 @@ SELECT set_config('log_statement_stats', 'off', false); The role of an active backend can be found from the usename column of the pg_stat_activity view. + + There is an optional second parameter of type boolean. If + true (the default), pg_cancel_backend and + pg_terminate_backend will not signal the current backend. diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 18921c4..a0cc975 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -869,6 +869,14 @@ COMMENT ON FUNCTION ts_debug(text) IS -- CREATE OR REPLACE FUNCTION + pg_cancel_backend(pid int, skip_my_pid boolean DEFAULT true) + RETURNS boolean STRICT VOLATILE LANGUAGE internal AS 'pg_cancel_backend'; + +CREATE OR REPLACE FUNCTION + pg_terminate_backend(pid int, skip_my_pid boolean DEFAULT true) + RETURNS boolean STRICT VOLATILE LANGUAGE internal AS 'pg_terminate_backend'; + +CREATE OR REPLACE FUNCTION pg_start_backup(label text, fast boolean DEFAULT false) RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup'; diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 61d609f..dce8498 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -94,8 +94,12 @@ current_query(PG_FUNCTION_ARGS) #define SIGNAL_BACKEND_NOPERMISSION 2 #define SIGNAL_BACKEND_NOSUPERUSER 3 static int -pg_signal_backend(int pid, int sig) +pg_signal_backend(int pid, int sig, bool skip_own_pid) { + /* Skip our own pid unless we're told not to */ + if (skip_own_pid && pid == MyProcPid) + return SIGNAL_BACKEND_SUCCESS; + PGPROC *proc = BackendPidGetProc(pid); /* @@ -158,7 +162,7 @@ pg_signal_backend(int pid, int sig) Datum pg_cancel_backend(PG_FUNCTION_ARGS) { - int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT); + int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT, PG_GETARG_BOOL(1)); if (r == SIGNAL_BACKEND_NOSUPERUSER) ereport(ERROR, @@ -182,7 +186,7 @@ pg_cancel_backend(PG_FUNCTION_ARGS) Datum pg_terminate_backend(PG_FUNCTION_ARGS) { - int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM); + int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM, PG_GETARG_BOOL(1)); if (r == SIGNAL_BACKEND_NOSUPERUSER) ereport(ERROR, diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index b5b9345..475545b 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3128,9 +3128,9 @@ DESCR("get OID of current session's temp schema, if any"); DATA(insert OID = 2855 ( pg_is_other_temp_schema PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ pg_is_other_temp_schema _null_ _null_ _null_ )); DESCR("is schema another session's temp schema?"); -DATA(insert OID = 2171 ( pg_cancel_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 16 "23" _null_ _null_ _null_ _null_ _null_ pg_cancel_backend _null_ _null_ _null_ )); +DATA(insert OID = 2171 ( pg_cancel_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 16 "23 16" _null_ _null_ _null_ _null_ _null_ pg_cancel_backend _null_ _null_ _null_ )); DESCR("cancel a server process' current query"); -DATA(insert OID = 2096 ( pg_terminate_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 16 "23" _null_ _null_ _null_ _null_ _null_ pg_terminate_backend _null_ _null_ _null_ )); +DATA(insert OID = 2096 ( pg_terminate_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 16 "23 16" _null_ _null_ _null_ _null_ _null_ pg_terminate_backend _null_ _null_ _null_ )); DESCR("terminate a server process"); DATA(insert OID = 2172 ( pg_start_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 3220 "25 16" _null_ _null_ _null_ _null_ _null_ pg_start_backup _null_ _null_ _null_ )); DESCR("prepare for taking an online backup"); diff --git a/src/test/regress/expected/hs_standby_functions.out b/src/test/regress/expected/hs_standby_functions.out index 16d50a8..7ab98a6 100644 --- a/src/test/regress/expected/hs_standby_functions.out +++ b/src/test/regress/expected/hs_standby_functions.out @@ -36,5 +36,5 @@ from pg_locks where virtualxid = '1/1'; (1 row) -- suicide is painless -select pg_cancel_backend(pg_backend_pid()); +select pg_cancel_backend(pg_backend_pid(), false); ERROR: canceling statement due to user request diff --git a/src/test/regress/sql/hs_standby_functions.sql b/src/test/regress/sql/hs_standby_functions.sql index 7577045..e953de2 100644 --- a/src/test/regress/sql/hs_standby_functions.sql +++ b/src/test/regress/sql/hs_standby_functions.sql @@ -21,4 +21,4 @@ select locktype, virtualxid, virtualtransaction, mode, granted from pg_locks where virtualxid = '1/1'; -- suicide is painless -select pg_cancel_backend(pg_backend_pid()); +select pg_cancel_backend(pg_backend_pid(), false);