1997-11-06 05:38:25 +08:00
|
|
|
/*
|
1998-08-31 03:37:51 +08:00
|
|
|
* misc_utils.c --
|
1997-11-06 05:38:25 +08:00
|
|
|
*
|
1998-08-31 03:37:51 +08:00
|
|
|
* This file defines miscellaneous PostgreSQL utility functions.
|
1997-11-06 05:38:25 +08:00
|
|
|
*
|
1999-09-28 04:04:14 +08:00
|
|
|
* Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
|
1998-08-31 03:37:51 +08:00
|
|
|
*
|
|
|
|
* This file is distributed under the GNU General Public License
|
|
|
|
* either version 2, or (at your option) any later version.
|
1997-11-06 05:38:25 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <unistd.h>
|
1999-06-06 03:09:48 +08:00
|
|
|
#include <signal.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
1997-11-06 05:38:25 +08:00
|
|
|
|
|
|
|
#include "postgres.h"
|
1999-06-06 03:09:48 +08:00
|
|
|
#include "access/heapam.h"
|
|
|
|
#include "access/htup.h"
|
|
|
|
#include "access/relscan.h"
|
|
|
|
#include "access/skey.h"
|
|
|
|
#include "access/tupdesc.h"
|
|
|
|
#include "catalog/catname.h"
|
|
|
|
#include "catalog/pg_listener.h"
|
|
|
|
#include "storage/lmgr.h"
|
|
|
|
#include "utils/fmgr.h"
|
1997-11-06 05:38:25 +08:00
|
|
|
#include "utils/palloc.h"
|
1999-06-06 03:09:48 +08:00
|
|
|
#include "utils/rel.h"
|
|
|
|
#include "utils/tqual.h"
|
1997-11-06 05:38:25 +08:00
|
|
|
|
|
|
|
#include "misc_utils.h"
|
1999-06-06 03:09:48 +08:00
|
|
|
|
|
|
|
#define MIN(x,y) ((x)<=(y) ? (x) : (y))
|
1997-11-06 05:38:25 +08:00
|
|
|
|
1998-02-26 12:46:47 +08:00
|
|
|
extern int ExecutorLimit(int limit);
|
1997-11-06 05:38:25 +08:00
|
|
|
extern void Async_Unlisten(char *relname, int pid);
|
1998-08-31 03:37:51 +08:00
|
|
|
extern int assertTest(int val);
|
|
|
|
|
|
|
|
#ifdef ASSERT_CHECKING_TEST
|
|
|
|
extern int assertEnable(int val);
|
2000-04-13 01:17:23 +08:00
|
|
|
|
1998-08-31 03:37:51 +08:00
|
|
|
#endif
|
1997-11-06 05:38:25 +08:00
|
|
|
|
|
|
|
int
|
|
|
|
query_limit(int limit)
|
|
|
|
{
|
1998-02-26 12:46:47 +08:00
|
|
|
return ExecutorLimit(limit);
|
1997-11-06 05:38:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
backend_pid()
|
|
|
|
{
|
1998-02-26 12:46:47 +08:00
|
|
|
return getpid();
|
1997-11-06 05:38:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
unlisten(char *relname)
|
|
|
|
{
|
1998-02-26 12:46:47 +08:00
|
|
|
Async_Unlisten(relname, getpid());
|
|
|
|
return 0;
|
1997-11-06 05:38:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
max(int x, int y)
|
|
|
|
{
|
1998-02-26 12:46:47 +08:00
|
|
|
return ((x > y) ? x : y);
|
1997-11-06 05:38:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
min(int x, int y)
|
|
|
|
{
|
1998-02-26 12:46:47 +08:00
|
|
|
return ((x < y) ? x : y);
|
1997-11-06 05:38:25 +08:00
|
|
|
}
|
|
|
|
|
1999-06-06 03:09:48 +08:00
|
|
|
/*
|
|
|
|
* Return the number of active listeners on a relation name.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
active_listeners(text *relname)
|
|
|
|
{
|
|
|
|
HeapTuple lTuple;
|
|
|
|
Relation lRel;
|
|
|
|
HeapScanDesc sRel;
|
|
|
|
TupleDesc tdesc;
|
|
|
|
ScanKeyData key;
|
|
|
|
Datum d;
|
|
|
|
bool isnull;
|
2000-04-13 01:17:23 +08:00
|
|
|
int len,
|
|
|
|
pid;
|
1999-06-06 03:09:48 +08:00
|
|
|
int count = 0;
|
|
|
|
int ourpid = getpid();
|
|
|
|
char listen_name[NAMEDATALEN];
|
|
|
|
|
1999-09-19 03:08:25 +08:00
|
|
|
lRel = heap_openr(ListenerRelationName, AccessShareLock);
|
1999-06-06 03:09:48 +08:00
|
|
|
tdesc = RelationGetDescr(lRel);
|
|
|
|
|
2000-04-13 01:17:23 +08:00
|
|
|
if (relname && (VARSIZE(relname) > VARHDRSZ))
|
|
|
|
{
|
|
|
|
len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
|
1999-06-06 03:09:48 +08:00
|
|
|
strncpy(listen_name, VARDATA(relname), len);
|
|
|
|
listen_name[len] = '\0';
|
|
|
|
ScanKeyEntryInitialize(&key, 0,
|
|
|
|
Anum_pg_listener_relname,
|
|
|
|
F_NAMEEQ,
|
|
|
|
PointerGetDatum(listen_name));
|
|
|
|
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, &key);
|
|
|
|
}
|
2000-04-13 01:17:23 +08:00
|
|
|
else
|
|
|
|
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
|
1999-06-06 03:09:48 +08:00
|
|
|
|
|
|
|
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
|
|
|
|
{
|
|
|
|
d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
|
|
|
|
pid = DatumGetInt32(d);
|
2000-04-13 01:17:23 +08:00
|
|
|
if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0))
|
|
|
|
{
|
1999-06-06 03:09:48 +08:00
|
|
|
/* elog(NOTICE, "%d ok", pid); */
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
heap_endscan(sRel);
|
|
|
|
|
1999-09-19 03:08:25 +08:00
|
|
|
heap_close(lRel, AccessShareLock);
|
1999-06-06 03:09:48 +08:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2000-02-14 02:59:53 +08:00
|
|
|
#ifdef USE_ASSERT_CHECKING
|
1998-08-31 03:37:51 +08:00
|
|
|
int
|
|
|
|
assert_enable(int val)
|
|
|
|
{
|
|
|
|
return assertEnable(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ASSERT_CHECKING_TEST
|
|
|
|
int
|
|
|
|
assert_test(int val)
|
|
|
|
{
|
|
|
|
return assertTest(val);
|
|
|
|
}
|
2000-04-13 01:17:23 +08:00
|
|
|
|
1998-08-31 03:37:51 +08:00
|
|
|
#endif
|
2000-02-14 02:59:53 +08:00
|
|
|
#endif
|
1998-08-31 03:37:51 +08:00
|
|
|
|
1997-11-06 05:38:25 +08:00
|
|
|
/* end of file */
|
1998-08-31 03:37:51 +08:00
|
|
|
|
|
|
|
/*
|
1999-06-06 03:09:48 +08:00
|
|
|
* Local Variables:
|
2000-04-13 01:17:23 +08:00
|
|
|
* tab-width: 4
|
|
|
|
* c-indent-level: 4
|
|
|
|
* c-basic-offset: 4
|
1998-08-31 03:37:51 +08:00
|
|
|
* End:
|
|
|
|
*/
|