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 #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_ ));