The heralded `Grand Unified Configuration scheme' (GUC)

That means you can now set your options in either or all of $PGDATA/configuration,
some postmaster option (--enable-fsync=off), or set a SET command. The list of
options is in backend/utils/misc/guc.c, documentation will be written post haste.

pg_options is gone, so is that pq_geqo config file. Also removed were backend -K,
-Q, and -T options (no longer applicable, although -d0 does the same as -Q).

Added to configure an --enable-syslog option.

changed all callers from TPRINTF to elog(DEBUG)
This commit is contained in:
Peter Eisentraut 2000-05-31 00:28:42 +00:00
parent 5e4d554bae
commit 6a68f42648
54 changed files with 2584 additions and 3290 deletions

View File

@ -34,7 +34,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/Makefile,v 1.51 2000/05/30 16:36:14 momjian Exp $
# $Header: /cvsroot/pgsql/src/backend/Makefile,v 1.52 2000/05/31 00:28:13 petere Exp $
#
#-------------------------------------------------------------------------
@ -205,9 +205,7 @@ endif
install-templates: $(TEMPLATEDIR) \
global1.bki.source local1_template1.bki.source \
global1.description local1_template1.description \
libpq/pg_hba.conf.sample libpq/pg_ident.conf.sample \
optimizer/geqo/pg_geqo.sample \
pg_options.sample
libpq/pg_hba.conf.sample libpq/pg_ident.conf.sample
$(INSTALL) $(INSTLOPTS) global1.bki.source \
$(TEMPLATEDIR)/global1.bki.source
$(INSTALL) $(INSTLOPTS) global1.description \
@ -220,10 +218,6 @@ install-templates: $(TEMPLATEDIR) \
$(TEMPLATEDIR)/pg_hba.conf.sample
$(INSTALL) $(INSTLOPTS) libpq/pg_ident.conf.sample \
$(TEMPLATEDIR)/pg_ident.conf.sample
$(INSTALL) $(INSTLOPTS) optimizer/geqo/pg_geqo.sample \
$(TEMPLATEDIR)/pg_geqo.sample
$(INSTALL) $(INSTLOPTS) pg_options.sample \
$(TEMPLATEDIR)/pg_options.sample
install-headers: prebuildheaders $(SRCDIR)/include/config.h
-@if [ ! -d $(HEADERDIR) ]; then mkdir $(HEADERDIR); fi

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.54 2000/04/12 17:14:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.55 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -25,11 +25,8 @@
#include "catalog/index.h"
#include "executor/executor.h"
#include "miscadmin.h"
#ifdef BTREE_BUILD_STATS
#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
#endif
#include "tcop/tcopprot.h"
#include "utils/guc.h"
bool BuildingBtree = false; /* see comment in btbuild() */
bool FastBuild = true; /* use sort/build instead of insertion
@ -96,9 +93,9 @@ btbuild(Relation heap,
usefast = (FastBuild && IsNormalProcessingMode());
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
ResetUsage();
#endif
#endif /* BTREE_BUILD_STATS */
/* see if index is unique */
isunique = IndexIsUniqueNoCache(RelationGetRelid(index));
@ -287,13 +284,13 @@ btbuild(Relation heap,
}
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
{
fprintf(stderr, "! BtreeBuild Stats:\n");
fprintf(stderr, "BTREE BUILD STATS\n");
ShowUsage();
ResetUsage();
}
#endif
#endif /* BTREE_BUILD_STATS */
/*
* Since we just counted the tuples in the heap, we update its stats

View File

@ -28,7 +28,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.52 2000/04/12 17:14:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.53 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -36,13 +36,11 @@
#include "postgres.h"
#include "access/nbtree.h"
#include "tcop/tcopprot.h"
#include "utils/guc.h"
#include "utils/tuplesort.h"
#ifdef BTREE_BUILD_STATS
#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
#endif
/*
* turn on debugging output.
*
@ -136,13 +134,13 @@ void
_bt_leafbuild(BTSpool *btspool)
{
#ifdef BTREE_BUILD_STATS
if (ShowExecutorStats)
if (Show_btree_build_stats)
{
fprintf(stderr, "! BtreeBuild (Spool) Stats:\n");
fprintf(StatFp, "BTREE BUILD (Spool) STATISTICS\n");
ShowUsage();
ResetUsage();
}
#endif
#endif /* BTREE_BUILD_STATS */
tuplesort_performsort(btspool->sortstate);
_bt_load(btspool->index, btspool);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.83 2000/05/30 04:24:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.84 2000/05/31 00:28:14 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -267,7 +267,7 @@ BootstrapMain(int argc, char *argv[])
Noversion = true;
break;
case 'F':
disableFsync = true;
enableFsync = false;
break;
case 'Q':
Quiet = true;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.61 2000/05/28 17:55:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.62 2000/05/31 00:28:15 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -90,7 +90,7 @@
#include "utils/fmgroids.h"
#include "utils/ps_status.h"
#include "utils/syscache.h"
#include "utils/trace.h"
/* stuff that we really ought not be touching directly :-( */
extern TransactionState CurrentTransactionState;
@ -128,6 +128,8 @@ static void NotifyMyFrontEnd(char *relname, int32 listenerPID);
static int AsyncExistsPendingNotify(char *relname);
static void ClearPendingNotifies(void);
bool Trace_notify = false;
/*
*--------------------------------------------------------------
@ -149,7 +151,8 @@ Async_Notify(char *relname)
{
char *notifyName;
TPRINTF(TRACE_NOTIFY, "Async_Notify: %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Notify: %s", relname);
if (!pendingNotifies)
pendingNotifies = DLNewList();
@ -202,7 +205,8 @@ Async_Listen(char *relname, int pid)
int alreadyListener = 0;
TupleDesc tupDesc;
TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
@ -304,7 +308,8 @@ Async_Unlisten(char *relname, int pid)
return;
}
TPRINTF(TRACE_NOTIFY, "Async_Unlisten %s", relname);
if (Trace_notify)
elog(DEBUG, "Async_Unlisten %s", relname);
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
/* Note we assume there can be only one matching tuple. */
@ -346,7 +351,8 @@ Async_UnlistenAll()
HeapTuple lTuple;
ScanKeyData key[1];
TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll");
if (Trace_notify)
elog(DEBUG, "Async_UnlistenAll");
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
@ -452,7 +458,8 @@ AtCommit_Notify()
return;
}
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify");
lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
@ -485,13 +492,16 @@ AtCommit_Notify()
* be bad for applications that ignore self-notify
* messages.
*/
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: notifying self");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying self");
NotifyMyFrontEnd(relname, listenerPID);
}
else
{
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: notifying pid %d",
listenerPID);
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: notifying pid %d", listenerPID);
/*
* If someone has already notified this listener, we don't
@ -551,7 +561,8 @@ AtCommit_Notify()
ClearPendingNotifies();
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify: done");
if (Trace_notify)
elog(DEBUG, "AtCommit_Notify: done");
}
/*
@ -624,10 +635,13 @@ Async_NotifyHandler(SIGNAL_ARGS)
if (notifyInterruptOccurred)
{
/* Here, it is finally safe to do stuff. */
TPRINTF(TRACE_NOTIFY,
"Async_NotifyHandler: perform async notify");
if (Trace_notify)
elog(DEBUG, "Async_NotifyHandler: perform async notify");
ProcessIncomingNotify();
TPRINTF(TRACE_NOTIFY, "Async_NotifyHandler: done");
if (Trace_notify)
elog(DEBUG, "Async_NotifyHandler: done");
}
}
}
@ -693,10 +707,13 @@ EnableNotifyInterrupt(void)
notifyInterruptEnabled = 0;
if (notifyInterruptOccurred)
{
TPRINTF(TRACE_NOTIFY,
"EnableNotifyInterrupt: perform async notify");
if (Trace_notify)
elog(DEBUG, "EnableNotifyInterrupt: perform async notify");
ProcessIncomingNotify();
TPRINTF(TRACE_NOTIFY, "EnableNotifyInterrupt: done");
if (Trace_notify)
elog(DEBUG, "EnableNotifyInterrupt: done");
}
}
}
@ -751,7 +768,9 @@ ProcessIncomingNotify(void)
char *relname;
int32 sourcePID;
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify");
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify");
PS_SET_STATUS("async_notify");
notifyInterruptOccurred = 0;
@ -784,8 +803,11 @@ ProcessIncomingNotify(void)
d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
relname = (char *) DatumGetPointer(d);
/* Notify the frontend */
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify: received %s from %d",
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify: received %s from %d",
relname, (int) sourcePID);
NotifyMyFrontEnd(relname, sourcePID);
/* Rewrite the tuple with 0 in notification column */
rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
@ -820,7 +842,9 @@ ProcessIncomingNotify(void)
pq_flush();
PS_SET_STATUS("idle");
TPRINTF(TRACE_NOTIFY, "ProcessIncomingNotify: done");
if (Trace_notify)
elog(DEBUG, "ProcessIncomingNotify: done");
}
/* Send NOTIFY message to my front end. */

View File

@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.34 2000/04/12 17:15:00 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/variable.c,v 1.35 2000/05/31 00:28:15 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,17 +27,14 @@
#include "optimizer/paths.h"
#include "parser/parse_expr.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/tqual.h"
#include "utils/trace.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
/* XXX should be in a header file */
extern bool _use_keyset_query_optimizer;
static bool show_date(void);
static bool reset_date(void);
@ -45,51 +42,7 @@ static bool parse_date(char *);
static bool show_timezone(void);
static bool reset_timezone(void);
static bool parse_timezone(char *);
static bool show_effective_cache_size(void);
static bool reset_effective_cache_size(void);
static bool parse_effective_cache_size(char *);
static bool show_random_page_cost(void);
static bool reset_random_page_cost(void);
static bool parse_random_page_cost(char *);
static bool show_cpu_tuple_cost(void);
static bool reset_cpu_tuple_cost(void);
static bool parse_cpu_tuple_cost(char *);
static bool show_cpu_index_tuple_cost(void);
static bool reset_cpu_index_tuple_cost(void);
static bool parse_cpu_index_tuple_cost(char *);
static bool show_cpu_operator_cost(void);
static bool reset_cpu_operator_cost(void);
static bool parse_cpu_operator_cost(char *);
static bool reset_enable_seqscan(void);
static bool show_enable_seqscan(void);
static bool parse_enable_seqscan(char *);
static bool reset_enable_indexscan(void);
static bool show_enable_indexscan(void);
static bool parse_enable_indexscan(char *);
static bool reset_enable_tidscan(void);
static bool show_enable_tidscan(void);
static bool parse_enable_tidscan(char *);
static bool reset_enable_sort(void);
static bool show_enable_sort(void);
static bool parse_enable_sort(char *);
static bool reset_enable_nestloop(void);
static bool show_enable_nestloop(void);
static bool parse_enable_nestloop(char *);
static bool reset_enable_mergejoin(void);
static bool show_enable_mergejoin(void);
static bool parse_enable_mergejoin(char *);
static bool reset_enable_hashjoin(void);
static bool show_enable_hashjoin(void);
static bool parse_enable_hashjoin(char *);
static bool reset_geqo(void);
static bool show_geqo(void);
static bool parse_geqo(char *);
static bool show_ksqo(void);
static bool reset_ksqo(void);
static bool parse_ksqo(char *);
static bool reset_max_expr_depth(void);
static bool show_max_expr_depth(void);
static bool parse_max_expr_depth(char *);
static bool show_XactIsoLevel(void);
static bool reset_XactIsoLevel(void);
static bool parse_XactIsoLevel(char *);
@ -97,6 +50,7 @@ static bool parse_random_seed(char *);
static bool show_random_seed(void);
static bool reset_random_seed(void);
/*
* get_token
* Obtain the next item in a comma-separated list of items,
@ -210,447 +164,6 @@ get_token(char **tok, char **val, char *str)
return str;
}
/*
* Generic parse routine for boolean ON/OFF variables
*/
static bool
parse_boolean_var(char *value,
bool *variable, const char *varname, bool defaultval)
{
if (value == NULL)
{
*variable = defaultval;
return TRUE;
}
if (strcasecmp(value, "on") == 0)
*variable = true;
else if (strcasecmp(value, "off") == 0)
*variable = false;
else
elog(ERROR, "Bad value for %s (%s)", varname, value);
return TRUE;
}
/*
* ENABLE_SEQSCAN
*/
static bool
parse_enable_seqscan(char *value)
{
return parse_boolean_var(value, &enable_seqscan,
"ENABLE_SEQSCAN", true);
}
static bool
show_enable_seqscan()
{
elog(NOTICE, "ENABLE_SEQSCAN is %s",
enable_seqscan ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_seqscan()
{
enable_seqscan = true;
return TRUE;
}
/*
* ENABLE_INDEXSCAN
*/
static bool
parse_enable_indexscan(char *value)
{
return parse_boolean_var(value, &enable_indexscan,
"ENABLE_INDEXSCAN", true);
}
static bool
show_enable_indexscan()
{
elog(NOTICE, "ENABLE_INDEXSCAN is %s",
enable_indexscan ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_indexscan()
{
enable_indexscan = true;
return TRUE;
}
/*
* ENABLE_TIDSCAN
*/
static bool
parse_enable_tidscan(char *value)
{
return parse_boolean_var(value, &enable_tidscan,
"ENABLE_TIDSCAN", true);
}
static bool
show_enable_tidscan()
{
elog(NOTICE, "ENABLE_TIDSCAN is %s",
enable_tidscan ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_tidscan()
{
enable_tidscan = true;
return TRUE;
}
/*
* ENABLE_SORT
*/
static bool
parse_enable_sort(char *value)
{
return parse_boolean_var(value, &enable_sort,
"ENABLE_SORT", true);
}
static bool
show_enable_sort()
{
elog(NOTICE, "ENABLE_SORT is %s",
enable_sort ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_sort()
{
enable_sort = true;
return TRUE;
}
/*
* ENABLE_NESTLOOP
*/
static bool
parse_enable_nestloop(char *value)
{
return parse_boolean_var(value, &enable_nestloop,
"ENABLE_NESTLOOP", true);
}
static bool
show_enable_nestloop()
{
elog(NOTICE, "ENABLE_NESTLOOP is %s",
enable_nestloop ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_nestloop()
{
enable_nestloop = true;
return TRUE;
}
/*
* ENABLE_MERGEJOIN
*/
static bool
parse_enable_mergejoin(char *value)
{
return parse_boolean_var(value, &enable_mergejoin,
"ENABLE_MERGEJOIN", true);
}
static bool
show_enable_mergejoin()
{
elog(NOTICE, "ENABLE_MERGEJOIN is %s",
enable_mergejoin ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_mergejoin()
{
enable_mergejoin = true;
return TRUE;
}
/*
* ENABLE_HASHJOIN
*/
static bool
parse_enable_hashjoin(char *value)
{
return parse_boolean_var(value, &enable_hashjoin,
"ENABLE_HASHJOIN", true);
}
static bool
show_enable_hashjoin()
{
elog(NOTICE, "ENABLE_HASHJOIN is %s",
enable_hashjoin ? "ON" : "OFF");
return TRUE;
}
static bool
reset_enable_hashjoin()
{
enable_hashjoin = true;
return TRUE;
}
/*
*
* GEQO
*
*/
static bool
parse_geqo(char *value)
{
char *tok,
*val,
*rest;
if (value == NULL)
{
reset_geqo();
return TRUE;
}
rest = get_token(&tok, &val, value);
/* expect one and only one item */
if (tok == NULL)
elog(ERROR, "Value undefined");
if (rest && *rest != '\0')
elog(ERROR, "Unable to parse '%s'", rest);
if (strcasecmp(tok, "on") == 0)
{
int new_geqo_rels = GEQO_RELS;
if (val != NULL)
{
new_geqo_rels = pg_atoi(val, sizeof(int), '\0');
if (new_geqo_rels <= 1)
elog(ERROR, "Bad value for # of relations (%s)", val);
}
enable_geqo = true;
geqo_rels = new_geqo_rels;
}
else if (strcasecmp(tok, "off") == 0)
{
if (val != NULL)
elog(ERROR, "%s does not allow a parameter", tok);
enable_geqo = false;
}
else
elog(ERROR, "Bad value for GEQO (%s)", value);
return TRUE;
}
static bool
show_geqo()
{
if (enable_geqo)
elog(NOTICE, "GEQO is ON beginning with %d relations", geqo_rels);
else
elog(NOTICE, "GEQO is OFF");
return TRUE;
}
static bool
reset_geqo(void)
{
#ifdef GEQO
enable_geqo = true;
#else
enable_geqo = false;
#endif
geqo_rels = GEQO_RELS;
return TRUE;
}
/*
* EFFECTIVE_CACHE_SIZE
*/
static bool
parse_effective_cache_size(char *value)
{
float64 res;
if (value == NULL)
{
reset_effective_cache_size();
return TRUE;
}
res = float8in((char *) value);
effective_cache_size = *res;
return TRUE;
}
static bool
show_effective_cache_size()
{
elog(NOTICE, "EFFECTIVE_CACHE_SIZE is %g (%dK pages)",
effective_cache_size, BLCKSZ / 1024);
return TRUE;
}
static bool
reset_effective_cache_size()
{
effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
return TRUE;
}
/*
* RANDOM_PAGE_COST
*/
static bool
parse_random_page_cost(char *value)
{
float64 res;
if (value == NULL)
{
reset_random_page_cost();
return TRUE;
}
res = float8in((char *) value);
random_page_cost = *res;
return TRUE;
}
static bool
show_random_page_cost()
{
elog(NOTICE, "RANDOM_PAGE_COST is %g", random_page_cost);
return TRUE;
}
static bool
reset_random_page_cost()
{
random_page_cost = DEFAULT_RANDOM_PAGE_COST;
return TRUE;
}
/*
* CPU_TUPLE_COST
*/
static bool
parse_cpu_tuple_cost(char *value)
{
float64 res;
if (value == NULL)
{
reset_cpu_tuple_cost();
return TRUE;
}
res = float8in((char *) value);
cpu_tuple_cost = *res;
return TRUE;
}
static bool
show_cpu_tuple_cost()
{
elog(NOTICE, "CPU_TUPLE_COST is %g", cpu_tuple_cost);
return TRUE;
}
static bool
reset_cpu_tuple_cost()
{
cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
return TRUE;
}
/*
* CPU_INDEX_TUPLE_COST
*/
static bool
parse_cpu_index_tuple_cost(char *value)
{
float64 res;
if (value == NULL)
{
reset_cpu_index_tuple_cost();
return TRUE;
}
res = float8in((char *) value);
cpu_index_tuple_cost = *res;
return TRUE;
}
static bool
show_cpu_index_tuple_cost()
{
elog(NOTICE, "CPU_INDEX_TUPLE_COST is %g", cpu_index_tuple_cost);
return TRUE;
}
static bool
reset_cpu_index_tuple_cost()
{
cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
return TRUE;
}
/*
* CPU_OPERATOR_COST
*/
static bool
parse_cpu_operator_cost(char *value)
{
float64 res;
if (value == NULL)
{
reset_cpu_operator_cost();
return TRUE;
}
res = float8in((char *) value);
cpu_operator_cost = *res;
return TRUE;
}
static bool
show_cpu_operator_cost()
{
elog(NOTICE, "CPU_OPERATOR_COST is %g", cpu_operator_cost);
return TRUE;
}
static bool
reset_cpu_operator_cost()
{
cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
return TRUE;
}
/*
* DATE_STYLE
@ -917,71 +430,7 @@ reset_timezone()
return TRUE;
} /* reset_timezone() */
/*-----------------------------------------------------------------------
KSQO code will one day be unnecessary when the optimizer makes use of
indexes when multiple ORs are specified in the where clause.
See optimizer/prep/prepkeyset.c for more on this.
daveh@insightdist.com 6/16/98
-----------------------------------------------------------------------*/
static bool
parse_ksqo(char *value)
{
return parse_boolean_var(value, &_use_keyset_query_optimizer,
"KSQO", false);
}
static bool
show_ksqo()
{
elog(NOTICE, "KSQO is %s",
_use_keyset_query_optimizer ? "ON" : "OFF");
return TRUE;
}
static bool
reset_ksqo()
{
_use_keyset_query_optimizer = false;
return TRUE;
}
/*
* MAX_EXPR_DEPTH
*/
static bool
parse_max_expr_depth(char *value)
{
int newval;
if (value == NULL)
{
reset_max_expr_depth();
return TRUE;
}
newval = pg_atoi(value, sizeof(int), '\0');
if (newval < 10) /* somewhat arbitrary limit */
elog(ERROR, "Bad value for MAX_EXPR_DEPTH (%s)", value);
max_expr_depth = newval;
return TRUE;
}
static bool
show_max_expr_depth()
{
elog(NOTICE, "MAX_EXPR_DEPTH is %d", max_expr_depth);
return TRUE;
}
static bool
reset_max_expr_depth(void)
{
max_expr_depth = DEFAULT_MAX_EXPR_DEPTH;
return TRUE;
}
/* SET TRANSACTION */
@ -1038,37 +487,6 @@ reset_XactIsoLevel()
return TRUE;
}
/*
* Pg_options
*/
static bool
parse_pg_options(char *value)
{
if (!superuser())
elog(ERROR, "Only users with superuser privilege can set pg_options");
if (value == NULL)
read_pg_options(0);
else
parse_options((char *) value, TRUE);
return (TRUE);
}
static bool
show_pg_options(void)
{
show_options();
return (TRUE);
}
static bool
reset_pg_options(void)
{
if (!superuser())
elog(ERROR, "Only users with superuser privilege can set pg_options");
read_pg_options(0);
return (TRUE);
}
/*
* Random number seed
@ -1105,157 +523,75 @@ reset_random_seed(void)
}
/*-----------------------------------------------------------------------*/
static struct VariableParsers
{
const char *name;
bool (*parser) (char *);
bool (*show) ();
bool (*reset) ();
} VariableParsers[] =
{
{
"datestyle", parse_date, show_date, reset_date
},
{
"timezone", parse_timezone, show_timezone, reset_timezone
},
{
"effective_cache_size", parse_effective_cache_size,
show_effective_cache_size, reset_effective_cache_size
},
{
"random_page_cost", parse_random_page_cost,
show_random_page_cost, reset_random_page_cost
},
{
"cpu_tuple_cost", parse_cpu_tuple_cost,
show_cpu_tuple_cost, reset_cpu_tuple_cost
},
{
"cpu_index_tuple_cost", parse_cpu_index_tuple_cost,
show_cpu_index_tuple_cost, reset_cpu_index_tuple_cost
},
{
"cpu_operator_cost", parse_cpu_operator_cost,
show_cpu_operator_cost, reset_cpu_operator_cost
},
{
"enable_seqscan", parse_enable_seqscan,
show_enable_seqscan, reset_enable_seqscan
},
{
"enable_indexscan", parse_enable_indexscan,
show_enable_indexscan, reset_enable_indexscan
},
{
"enable_tidscan", parse_enable_tidscan,
show_enable_tidscan, reset_enable_tidscan
},
{
"enable_sort", parse_enable_sort,
show_enable_sort, reset_enable_sort
},
{
"enable_nestloop", parse_enable_nestloop,
show_enable_nestloop, reset_enable_nestloop
},
{
"enable_mergejoin", parse_enable_mergejoin,
show_enable_mergejoin, reset_enable_mergejoin
},
{
"enable_hashjoin", parse_enable_hashjoin,
show_enable_hashjoin, reset_enable_hashjoin
},
{
"geqo", parse_geqo, show_geqo, reset_geqo
},
#ifdef MULTIBYTE
{
"client_encoding", parse_client_encoding, show_client_encoding, reset_client_encoding
},
{
"server_encoding", parse_server_encoding, show_server_encoding, reset_server_encoding
},
#endif
{
"ksqo", parse_ksqo, show_ksqo, reset_ksqo
},
{
"max_expr_depth", parse_max_expr_depth,
show_max_expr_depth, reset_max_expr_depth
},
{
"XactIsoLevel", parse_XactIsoLevel, show_XactIsoLevel, reset_XactIsoLevel
},
{
"pg_options", parse_pg_options, show_pg_options, reset_pg_options
},
{
"seed", parse_random_seed, show_random_seed, reset_random_seed
},
{
NULL, NULL, NULL, NULL
}
};
/*-----------------------------------------------------------------------*/
/*
* Set the named variable, or reset to default value if value is NULL
*/
bool
void
SetPGVariable(const char *name, const char *value)
{
struct VariableParsers *vp;
char *val;
/* Make a modifiable copy for convenience of get_token */
val = value ? pstrdup(value) : ((char *) NULL);
for (vp = VariableParsers; vp->name; vp++)
{
if (!strcasecmp(vp->name, name))
return (vp->parser) (val);
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
/*
* Special cases ought to be removed are handled separately
* by TCOP
*/
if (strcasecmp(name, "datestyle")==0)
parse_date(pstrdup(value));
else if (strcasecmp(name, "timezone")==0)
parse_timezone(pstrdup(value));
else if (strcasecmp(name, "XactIsoLevel")==0)
parse_XactIsoLevel(pstrdup(value));
#ifdef MULTIBYTE
else if (strcasecmp(name, "client_encoding")==0)
parse_client_encoding(pstrdup(value));
else if (strcasecmp(name, "server_encoding")==0)
parse_server_encoding(pstrdup(value));
#endif
else if (strcasecmp(name, "random_seed")==0)
parse_random_seed(pstrdup(value));
else
SetConfigOption(name, value, superuser() ? PGC_SUSET : PGC_USERSET);
}
/*-----------------------------------------------------------------------*/
bool
void
GetPGVariable(const char *name)
{
struct VariableParsers *vp;
if (strcasecmp(name, "datestyle")==0)
show_date();
else if (strcasecmp(name, "timezone")==0)
show_timezone();
else if (strcasecmp(name, "XactIsoLevel")==0)
show_XactIsoLevel();
#ifdef MULTIBYTE
else if (strcasecmp(name, "client_encoding")==0)
show_client_encoding();
else if (strcasecmp(name, "server_encoding")==0)
show_server_encoding();
#endif
else if (strcasecmp(name, "random_seed")==0)
show_random_seed();
else
{
const char * val = GetConfigOption(name, superuser());
elog(NOTICE, "%s = %s", name, val);
}
}
for (vp = VariableParsers; vp->name; vp++)
{
if (!strcasecmp(vp->name, name))
return (vp->show) ();
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
}
/*-----------------------------------------------------------------------*/
bool
void
ResetPGVariable(const char *name)
{
struct VariableParsers *vp;
for (vp = VariableParsers; vp->name; vp++)
{
if (!strcasecmp(vp->name, name))
return (vp->reset) ();
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
}
if (strcasecmp(name, "datestyle")==0)
reset_date();
else if (strcasecmp(name, "timezone")==0)
reset_timezone();
else if (strcasecmp(name, "XactIsoLevel")==0)
reset_XactIsoLevel();
#ifdef MULTIBYTE
else if (strcasecmp(name, "client_encoding")==0)
reset_client_encoding();
else if (strcasecmp(name, "server_encoding")==0)
reset_server_encoding();
#endif
else if (strcasecmp(name, "random_seed")==0)
reset_random_seed();
else
SetConfigOption(name, NULL, superuser() ? PGC_SUSET : PGC_USERSET);
}

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: nodeHash.c,v 1.45 2000/04/18 05:43:01 tgl Exp $
* $Id: nodeHash.c,v 1.46 2000/05/31 00:28:17 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -27,10 +27,9 @@
#include "executor/executor.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "miscadmin.h"
#include "utils/portal.h"
extern int SortMem;
static int hashFunc(Datum key, int len, bool byVal);
/* ----------------------------------------------------------------

View File

@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pqcomm.c,v 1.92 2000/05/26 01:26:19 tgl Exp $
* $Id: pqcomm.c,v 1.93 2000/05/31 00:28:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -75,7 +75,6 @@
#include "postgres.h"
#include "libpq/libpq.h"
#include "utils/trace.h" /* needed for HAVE_FCNTL_SETLK */
#include "miscadmin.h"
@ -130,7 +129,7 @@ pq_getport(void)
if (envport)
return atoi(envport);
return atoi(DEF_PGPORT);
return DEF_PGPORT;
}
/* --------------------------------
@ -246,13 +245,8 @@ StreamServerPort(char *hostName, unsigned short portName, int *fdP)
lck.l_whence = SEEK_SET;
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) == 0)
{
TPRINTF(TRACE_VERBOSE, "flock on %s, deleting", sock_path);
if (fcntl(lock_fd, F_SETLK, &lck) != -1)
unlink(sock_path);
}
else
TPRINTF(TRACE_VERBOSE, "flock failed for %s", sock_path);
close(lock_fd);
}
#endif /* HAVE_FCNTL_SETLK */
@ -305,7 +299,7 @@ StreamServerPort(char *hostName, unsigned short portName, int *fdP)
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) != 0)
TPRINTF(TRACE_VERBOSE, "flock error for %s", sock_path);
elog(DEBUG, "flock error on %s: %s", sock_path, strerror(errno));
}
#endif /* HAVE_FCNTL_SETLK */
}

View File

@ -5,7 +5,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $Id: Makefile,v 1.14 2000/05/29 05:44:48 tgl Exp $
# $Id: Makefile,v 1.15 2000/05/31 00:28:19 petere Exp $
#
#-------------------------------------------------------------------------
@ -17,7 +17,7 @@ CFLAGS+= -Wno-error
endif
OBJS = geqo_copy.o geqo_eval.o geqo_main.o geqo_misc.o \
geqo_params.o geqo_pool.o geqo_recombination.o \
geqo_pool.o geqo_recombination.o \
geqo_selection.o \
geqo_erx.o geqo_pmx.o geqo_cx.o geqo_px.o geqo_ox1.o geqo_ox2.o

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_main.c,v 1.20 2000/01/26 05:56:33 momjian Exp $
* $Id: geqo_main.c,v 1.21 2000/05/31 00:28:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -23,12 +23,30 @@
/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */
#include "postgres.h"
#include <time.h>
#include <math.h>
#include "optimizer/geqo.h"
#include "optimizer/geqo_misc.h"
#include "optimizer/geqo_pool.h"
#include "optimizer/geqo_selection.h"
/*
* Configuration options
*/
int Geqo_pool_size;
int Geqo_effort;
int Geqo_generations;
double Geqo_selection_bias;
int Geqo_random_seed;
static int gimme_pool_size(int nr_rel);
static int gimme_number_generations(int pool_size, int effort);
/* define edge recombination crossover [ERX] per default */
#if !defined(ERX) && \
!defined(PMX) && \
@ -81,13 +99,16 @@ geqo(Query *root)
number_of_rels = length(root->base_rel_list);
/* set GA parameters */
geqo_params(number_of_rels);/* read "$PGDATA/pg_geqo" file */
pool_size = PoolSize;
number_generations = Generations;
pool_size = gimme_pool_size(number_of_rels);
number_generations = gimme_number_generations(pool_size, Geqo_effort);
status_interval = 10;
/* seed random number generator */
srandom(RandomSeed);
/* XXX why is this done every time around? */
if (Geqo_random_seed >= 0)
srandom(Geqo_random_seed);
else
srandom(time(NULL));
/* initialize plan evaluator */
geqo_eval_startup();
@ -146,7 +167,7 @@ geqo(Query *root)
{
/* SELECTION */
geqo_selection(momma, daddy, pool, SelectionBias); /* using linear bias
geqo_selection(momma, daddy, pool, Geqo_selection_bias);/* using linear bias
* function */
@ -263,3 +284,52 @@ print_plan(best_plan, root);
return best_rel;
}
/*
* Return either configured pool size or
* a good default based on query size (no. of relations)
* = 2^(QS+1)
* also constrain between 128 and 1024
*/
static int
gimme_pool_size(int nr_rel)
{
double size;
if (Geqo_pool_size != 0)
{
if (Geqo_pool_size < MIN_GEQO_POOL_SIZE)
return MIN_GEQO_POOL_SIZE;
else if (Geqo_pool_size > MAX_GEQO_POOL_SIZE)
return MAX_GEQO_POOL_SIZE;
else
return Geqo_pool_size;
}
size = pow(2.0, nr_rel + 1.0);
if (size < MIN_GEQO_POOL_SIZE)
return MIN_GEQO_POOL_SIZE;
else if (size > MAX_GEQO_POOL_SIZE)
return MAX_GEQO_POOL_SIZE;
else
return (int) ceil(size);
}
/*
* Return either configured number of generations or
* some reasonable default calculated on the fly.
* = Effort * Log2(PoolSize)
*/
static int
gimme_number_generations(int pool_size, int effort)
{
if (Geqo_generations <= 0)
return effort * (int) ceil(log((double) pool_size) / log(2.0));
else
return Geqo_generations;
}

View File

@ -1,350 +0,0 @@
/*------------------------------------------------------------------------
*
* geqo_params.c
* routines for determining necessary genetic optimization parameters
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_params.c,v 1.22 2000/01/26 05:56:33 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/* contributed by:
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
* Martin Utesch * Institute of Automatic Control *
= = University of Mining and Technology =
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
*/
#include <time.h>
#include <math.h>
#include <ctype.h>
#include "postgres.h"
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "nodes/primnodes.h"
#include "nodes/relation.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
#include "optimizer/geqo_gene.h"
#include "optimizer/internal.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "storage/fd.h"
/*
* Parameter values read from the config file (or defaulted) are stored here
* by geqo_params().
*/
int PoolSize;
int Generations;
long RandomSeed;
double SelectionBias;
#define POOL_TAG "Pool_Size"
#define TRIAL_TAG "Generations"
#define RAND_TAG "Random_Seed"
#define BIAS_TAG "Selection_Bias"
#define EFFORT_TAG "Effort"/* optimization effort and */
#define LOW "low" /* corresponding tags */
#define MEDIUM "medium"
#define HIGH "high"
#define MAX_TOKEN 80 /* Maximum size of one token in the *
* configuration file */
static int gimme_pool_size(int string_length);
static int gimme_number_generations(int pool_size, int effort);
static int next_token(FILE *, char *, int);
static double geqo_log(double x, double b);
/*
* geqo_param
* get ga parameters out of "$PGDATA/pg_geqo" file.
*/
void
geqo_params(int string_length)
{
int i;
char buf[MAX_TOKEN];
FILE *file;
char *conf_file;
/* these flag variables signal that a value has been set from the file */
int pool_size = 0;
int number_trials = 0;
int random_seed = 0;
int selection_bias = 0;
int effort = 0;
/* put together the full pathname to the config file */
conf_file = (char *) palloc((strlen(DataDir) + strlen(GEQO_FILE) + 2) * sizeof(char));
sprintf(conf_file, "%s/%s", DataDir, GEQO_FILE);
/* open the config file */
#ifndef __CYGWIN32__
file = AllocateFile(conf_file, "r");
#else
file = AllocateFile(conf_file, "rb");
#endif
if (file)
{
/*
* empty and comment line stuff
*/
while ((i = next_token(file, buf, sizeof(buf))) != EOF)
{
/* If only token on the line, ignore */
if (i == '\n')
continue;
/* Comment -- read until end of line then next line */
if (buf[0] == '#')
{
while (next_token(file, buf, sizeof(buf)) == 0);
continue;
}
/*
* get ga parameters by parsing
*/
/*------------------------------------------------- pool size */
if (strcmp(buf, POOL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf)); /* get next token */
if (i != EOF) /* only ignore if we got no text at all */
{
if (sscanf(buf, "%d", &PoolSize) == 1)
pool_size = 1;
}
}
/*------------------------------------------------- number of trials */
else if (strcmp(buf, TRIAL_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%d", &Generations) == 1)
number_trials = 1;
}
}
/*------------------------------------------------- optimization effort */
else if (strcmp(buf, EFFORT_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (strcmp(buf, LOW) == 0)
effort = LOW_EFFORT;
else if (strcmp(buf, MEDIUM) == 0)
effort = MEDIUM_EFFORT;
else if (strcmp(buf, HIGH) == 0)
effort = HIGH_EFFORT;
/* undocumented extension: specify effort numerically */
else if (isdigit(buf[0]))
effort = atoi(buf);
}
}
/*------------------------------------------- random seed */
else if (strcmp(buf, RAND_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%ld", &RandomSeed) == 1)
random_seed = 1;
}
}
/*------------------------------------------- selection bias */
else if (strcmp(buf, BIAS_TAG) == 0)
{
i = next_token(file, buf, sizeof(buf));
if (i != EOF)
{
if (sscanf(buf, "%lf", &SelectionBias) == 1)
selection_bias = 1;
}
}
/* unrecognized tags */
else
{
if (i != EOF)
{
}
elog(DEBUG, "geqo_params: unknown parameter type \"%s\"\nin file \'%s\'", buf, conf_file);
/* if not at end-of-line, keep reading til we are */
while (i == 0)
i = next_token(file, buf, sizeof(buf));
}
}
FreeFile(file);
pfree(conf_file);
}
else
elog(DEBUG, "geqo_params: ga parameter file\n\'%s\'\ndoes not exist or permissions are not setup correctly", conf_file);
/*
* parameter checkings follow
*/
/**************** PoolSize: essential ****************/
if (!(pool_size))
{
PoolSize = gimme_pool_size(string_length);
elog(DEBUG, "geqo_params: no pool size specified;\nusing computed value of %d", PoolSize);
}
/**************** Effort: essential ****************/
if (!(effort))
{
effort = MEDIUM_EFFORT;
elog(DEBUG, "geqo_params: no optimization effort specified;\nusing value of %d", effort);
}
/**************** Generations: essential ****************/
if (!(number_trials))
{
Generations = gimme_number_generations(PoolSize, effort);
elog(DEBUG, "geqo_params: no number of trials specified;\nusing computed value of %d", Generations);
}
/* RandomSeed: */
if (!(random_seed))
{
RandomSeed = (long) time(NULL);
elog(DEBUG, "geqo_params: no random seed specified;\nusing computed value of %ld", RandomSeed);
}
/* SelectionBias: */
if (!(selection_bias))
{
SelectionBias = SELECTION_BIAS;
elog(DEBUG, "geqo_params: no selection bias specified;\nusing default value of %f", SelectionBias);
}
}
/*
* Grab one token out of fp. Defined as the next string of non-whitespace
* in the file. After we get the token, continue reading until EOF, end of
* line or the next token. If it's the last token on the line, return '\n'
* for the value. If we get EOF before reading a token, return EOF. In all
* other cases return 0.
*/
static int
next_token(FILE *fp, char *buf, int bufsz)
{
int c;
char *eb = buf + (bufsz - 1);
/* Discard inital whitespace */
while (isspace(c = getc(fp)));
/* EOF seen before any token so return EOF */
if (c == EOF)
return -1;
/* Form a token in buf */
do
{
if (buf < eb)
*buf++ = c;
c = getc(fp);
} while (!isspace(c) && c != EOF);
*buf = '\0';
/* Discard trailing tabs and spaces */
while (c == ' ' || c == '\t')
c = getc(fp);
/* Put back the char that was non-whitespace (putting back EOF is ok) */
ungetc(c, fp);
/* If we ended with a newline, return that, otherwise return 0 */
return c == '\n' ? '\n' : 0;
}
/* gimme_pool_size
* compute good estimation for pool size
* according to number of involved rels in a query
*/
static int
gimme_pool_size(int string_length)
{
double exponent;
double size;
exponent = (double) string_length + 1.0;
size = pow(2.0, exponent);
if (size < MIN_POOL)
return MIN_POOL;
else if (size > MAX_POOL)
return MAX_POOL;
else
return (int) ceil(size);
}
/* gimme_number_generations
* compute good estimation for number of generations size
* for convergence
*/
static int
gimme_number_generations(int pool_size, int effort)
{
int number_gens;
number_gens = (int) ceil(geqo_log((double) pool_size, 2.0));
return effort * number_gens;
}
static double
geqo_log(double x, double b)
{
return (log(x) / log(b));
}

View File

@ -1,72 +0,0 @@
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# pg_geqo *
# ------- =
# *
# Example Genetic Algorithm config file =
# for the PostgreSQL *
# Genetic Query Optimization (GEQO) module =
# *
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# Martin Utesch * Institute of Automatic Control *
# = University of Mining and Technology =
# utesch@aut.tu-freiberg.de * Freiberg, Germany *
#*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
# To make this file do something, copy it to '$PGDATA/pg_geqo'
# and edit parameters to taste.
# If '$PGDATA/pg_geqo' doesn't exist, the system will use default parameters.
# The file is re-read for every GEQO optimization, if it does exist.
# comment character is '#'
#
# separator between recognized tag and possible value
# must be white space
# QS: means query size, which is the number of relations
# contained in a query
#=================+===================+=============================+
# RECOGNIZED TAGS | POSSIBLE VALUES | DEFAULTS |
#=================+===================+=============================+
# 'Pool_Size' | positive int | 2^(QS+1), but not less than |
# | | 128 nor more than 1024. |
#-----------------+-------------------+-----------------------------+
# 'Effort' | [low,medium,high] | medium |
#-----------------+-------------------+-----------------------------+
# 'Generations' | positive int | Effort * log2(Pool_Size) |
#-----------------+-------------------+-----------------------------+
# 'Selection_Bias'| [1.50 .. 2.00] | 2.0 |
#-----------------+-------------------+-----------------------------+
# 'Random_Seed' | positive long | time(NULL) |
#=================+===================+=============================+
# 'Pool_Size' is essential for the genetic algorithm performance.
# It gives us the number of individuals within one population.
#
# 'Effort' 'low' means integer value of 1, 'medium' 40, and 'high' 80.
# Note: Effort is *only* used to derive a default value for Generations
# --- if you specify Generations then Effort does not matter.
#
# 'Generations' specifies the number of iterations in the genetic algorithm.
#
# GEQO runtime is roughly proportional to Pool_Size + Generations.
#
# 'Selection_Bias' gives us the selective pressure within the
# population.
#
# 'Random_Seed' is the random seed for the random() function.
# You don't have to set it. If you do set it, then successive GEQO
# runs will produce repeatable results, whereas if you don't set it
# there will be some randomness in the results...
# All parameters will be computed within the GEQO module when they
# are not set in the pg_geqo file.
# Example pg_geqo settings:
#
#Pool_Size 128
#Effort low
#Generations 200
#Random_Seed 830518260
#Selection_Bias 1.750000

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.61 2000/05/30 00:49:46 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.62 2000/05/31 00:28:22 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -21,15 +21,8 @@
#include "optimizer/paths.h"
#ifdef GEQO
bool enable_geqo = true;
#else
bool enable_geqo = false;
#endif
int geqo_rels = GEQO_RELS;
int geqo_rels = DEFAULT_GEQO_RELS;
static void set_base_rel_pathlist(Query *root);

View File

@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.60 2000/05/30 04:24:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.61 2000/05/31 00:28:22 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -63,11 +63,11 @@
#define LOG6(x) (log(x) / 1.79175946922805)
double effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
Cost random_page_cost = DEFAULT_RANDOM_PAGE_COST;
Cost cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
Cost cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
Cost cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
double effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE;
double random_page_cost = DEFAULT_RANDOM_PAGE_COST;
double cpu_tuple_cost = DEFAULT_CPU_TUPLE_COST;
double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST;
double cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST;
Cost disable_cost = 100000000.0;

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.168 2000/05/25 22:42:17 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.169 2000/05/31 00:28:24 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -323,7 +323,8 @@ static void doNegateFloat(Value *v);
IMMEDIATE, INITIALLY,
PENDANT,
RESTRICT,
TRIGGER
TRIGGER,
OFF
/* Keywords (in SQL92 non-reserved words) */
%token COMMITTED, SERIALIZABLE, TYPE_P
@ -715,67 +716,63 @@ opt_level: READ COMMITTED { $$ = "committed"; }
| SERIALIZABLE { $$ = "serializable"; }
;
var_value: Sconst
{
/* Plain old string (pointer to char) */
$$ = $1;
}
| FCONST
{
/* Floating numeric argument.
* This recently changed to preserve "stringiness",
* so we don't have any work to do at all. Nice.
* - thomas 2000-03-29
*/
$$ = $1;
}
| Iconst
{
char buf[64];
var_value: SCONST { $$ = $1; }
| ICONST
{
char buf[64];
sprintf(buf, "%d", $1);
$$ = pstrdup(buf);
}
| '-' ICONST
{
char buf[64];
sprintf(buf, "%d", -($2));
$$ = pstrdup(buf);
}
| FCONST { $$ = $1; }
| '-' FCONST
{
char * s = palloc(strlen($2)+2);
s[0] = '-';
strcpy(s + 1, $2);
$$ = s;
}
| TRUE_P { $$ = "true"; }
| FALSE_P { $$ = "false"; }
| ON { $$ = "on"; }
| OFF { $$ = "off"; }
/* Integer numeric argument.
*/
sprintf(buf, "%d", $1);
$$ = pstrdup(buf);
}
| name_list
{
List *n;
int slen = 0;
char *result;
| name_list
{
List *n;
int slen = 0;
char *result;
/* List of words? Then concatenate together */
if ($1 == NIL)
elog(ERROR, "SET must have at least one argument");
/* List of words? Then concatenate together */
if ($1 == NIL)
elog(ERROR, "SET must have at least one argument");
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
Assert(IsA(p, String));
/* keep track of room for string and trailing comma */
slen += (strlen(p->val.str) + 1);
}
result = palloc(slen + 1);
*result = '\0';
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
strcat(result, p->val.str);
strcat(result, ",");
}
/* remove the trailing comma from the last element */
*(result+strlen(result)-1) = '\0';
$$ = result;
}
/* "OFF" is not a token, so it is handled by the name_list production */
| ON
{
$$ = "on";
}
| DEFAULT
{
$$ = NULL;
}
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
Assert(IsA(p, String));
/* keep track of room for string and trailing comma */
slen += (strlen(p->val.str) + 1);
}
result = palloc(slen + 1);
*result = '\0';
foreach (n, $1)
{
Value *p = (Value *) lfirst(n);
strcat(result, p->val.str);
strcat(result, ",");
}
/* remove the trailing comma from the last element */
*(result+strlen(result)-1) = '\0';
$$ = result;
}
| DEFAULT { $$ = NULL; }
;
zone_value: Sconst { $$ = $1; }
@ -5534,6 +5531,7 @@ ColLabel: ColId { $$ = $1; }
| NULLIF { $$ = "nullif"; }
| NULL_P { $$ = "null"; }
| NUMERIC { $$ = "numeric"; }
| OFF { $$ = "off"; }
| OFFSET { $$ = "offset"; }
| ON { $$ = "on"; }
| OR { $$ = "or"; }

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.72 2000/05/29 05:44:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.73 2000/05/31 00:28:24 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -176,6 +176,7 @@ static ScanKeyword ScanKeywords[] = {
{"nullif", NULLIF},
{"numeric", NUMERIC},
{"of", OF},
{"off", OFF},
{"offset", OFFSET},
{"oids", OIDS},
{"old", CURRENT},

View File

@ -1,249 +0,0 @@
# pg_options file
# Documented for Debian release 7.0-0.beta4-1
# Copyright (c) Oliver Elphick <olly@lfix.co.uk>
# Licence: May be used without any payment or restriction, except that
# the copyright and licence must be preserved.
# pg_options controls certain options and tracing features of the
# PostgreSQL backend. It is read by postmaster and postgres before
# command line arguments are examined, so command line arguments
# will override any settings here.
# This file should be located at $PGDATA/pg_options. In Debian, this is
# a symbolic link to /etc/postgresql/pg_options.
# The capitalised words refer to the internal #defines in the source code
# which use these options. Options can be turned on and off while the
# postmaster is running by editing this file and sending a SIGHUP to
# the postmaster.
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# File format #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# option = integer : set option to the specified value
# option + : set option to 1
# option - : set option to 0
#
# Comments begin with #, whitespace is ignored completely.
# Options are separated by newlines (or by commas -- but why make it
# needlessly difficult to read the file?)
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Tracing options #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# all [TRACE_ALL]
# This governs what tracing occurs. If it is 0, tracing is
# controlled by the more specific options listed below. Set this to 1
# to trace everything, regardless of the settings below; set to -1 to
# turn off all tracing.
#
# Any of these tracing options can be turned on with the command line
# option `-T "option[,...]"'
all = 0
# verbose [TRACE_VERBOSE] -- command line option `-d n' with n >= 1
# Turns on verbose tracing of various events
verbose = 0
# query [TRACE_QUERY] -- command line option `-d n' with n >= 2
# Traces the query string before and after rewriting
query = 0
# plan [TRACE_PLAN] -- command line option `-d n' with n >= 4
# Traces plan trees in raw output format (see also pretty_plan)
plan = 0
# parse [TRACE_PARSE] -- command line option `-d n' with n >= 3
# Traces the parser output in raw form (see also pretty_parse)
parse = 0
# rewritten [TRACE_REWRITTEN]
# Traces the query after rewriting, in raw form (see also pretty_rewritten)
rewritten = 0
# pretty_plan [TRACE_PRETTY_PLAN]
# shows indented multiline versions of plan trees (see also plan)
pretty_plan = 0
# pretty_parse [TRACE_PRETTY_PARSE]
# Traces the parser output in a readable form (see also parse)
pretty_parse = 0
# pretty_rewritten [TRACE_PRETTY_REWRITTEN]
# -- command line option `-d n' with n >= 5
# Traces the query after rewriting, in a readable form (see also rewritten)
pretty_rewritten = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Locks #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# TRACE_SHORTLOCKS
# This value is currently unused but needed as an index placeholder.
# It must be left set to 0, or mayhem may result, including segmentation
# violations, perhaps.
shortlocks = 0
# TRACE_LOCKS
# Enable or disable tracing of ordinary locks
locks = 0
# TRACE_USERLOCKS
# Enable or disable tracing of user (advisory) locks
userlocks = 0
# TRACE_SPINLOCKS
# Enables or disables tracing of spinlocks, but only if LOCKDEBUG was
# defined when PostgreSQL was compiled. (In the Debian release,
# LOCKDEBUG is not defined, so this option is inoperative.)
spinlocks = 0
# TRACE_LOCKOIDMIN
# This option is is used to avoid tracing locks on system relations, which
# would produce a lot of output. You should specify a value greater than
# the maximum oid of system relations, which can be found with the
# following query:
#
# select max(int4in(int4out(oid))) from pg_class where relname ~ '^pg_';
#
# To get a useful lock trace you can set the following pg_options:
#
# verbose+, query+, locks+, userlocks+, lock_debug_oidmin=17500
lock_debug_oidmin = 0
# TRACE_LOCKRELATION
# This option can be used to trace unconditionally a single relation,
# for example pg_listener, if you suspect there are locking problems.
lock_debug_relid = 0
# TRACE_NOTIFY
# Turn on tracing of asynchronous notifications from the backend.
notify = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Memory Allocation #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# These do not appear to be used at 7.0beta4
# TRACE_MALLOC
malloc = 0
# TRACE_PALLOC
palloc = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# Statistics #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# The statistics options are not controlled by either TRACE_ALL, or
# by USE_SYSLOG. These options cannot be used togther with the
# command line option `-s'.
# TRACE_PARSERSTATS
# Prints parser statistics to standard error -- command line `-tpa[rser]'
parserstats = 0
# TRACE_PLANNERSTATS
# Prints planner statistics to standard error -- command line `-tpl[anner]'
plannerstats = 0
# TRACE_EXECUTORSTATS
# Prints executor statistics to standard error -- command line `-te[xecutor]'
executorstats = 0
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# options controlling run-time behaviour #
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#
# OPT_LOCKREADPRIORITY
# lock priority, see lock.c -- Does not appear to be used
lock_read_priority = 0
# OPT_DEADLOCKTIMEOUT
# deadlock timeout; set this to a non-zero integer, which is the number
# of seconds that the backend should wait before deciding that it is in
# a deadlock and timing out. The system default is 1 second.
deadlock_timeout = 0
# nofsync [OPT_NOFSYNC] -- command line option `-F'
# If this is non-zero, fsync will be turned off; this means that saving
# to disk will be left to the normal operating system sync. If this
# option is zero, every transaction will trigger a sync to disk; this
# gives increased safety at the expense of performance.
nofsync = 0
# OPT_SYSLOG
# This controls the destination of [many] messages and traces:
# 0 : write to stdout or stderr
# 1 : write to stdout or stderr, and also through syslogd
# 2 : log only through syslogd
# [Not all messages have been converted to use routines controlled by
# this parameter; unconverted ones will print to stdout or stderr
# unconditionally and never to syslogd.]
syslog = 0
# OPT_HOSTLOOKUP
# enable hostname lookup in ps_status. If this is set, a reverse
# lookup will be done on the connecting IP address (for TCP/IP
# connections) for inclusion in the ps_status display.
hostlookup = 0
# OPT_SHOWPORTNUMBER
# show port number in ps_status. If this is set, the TCP port number
# will be included in the ps_status display (for TCP/IP connections).
showportnumber = 0

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.143 2000/05/26 01:38:08 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.144 2000/05/31 00:28:25 petere Exp $
*
* NOTES
*
@ -90,7 +90,7 @@
#include "storage/proc.h"
#include "access/xlog.h"
#include "tcop/tcopprot.h"
#include "utils/trace.h"
#include "utils/guc.h"
#include "version.h"
/*
@ -136,7 +136,7 @@ static Dllist *BackendList;
/* list of ports associated with still open, but incomplete connections */
static Dllist *PortList;
static unsigned short PostPortName = 0;
int PostPortName = DEF_PGPORT;
/*
* This is a boolean indicating that there is at least one backend that
@ -167,7 +167,7 @@ static IpcMemoryKey ipc_key;
* adding to this.
*/
static int MaxBackends = DEF_MAXBACKENDS;
int MaxBackends = DEF_MAXBACKENDS;
/*
* MaxBackends is the actual limit on the number of backends we will
@ -185,6 +185,9 @@ static int real_argc;
static time_t tnow;
/* flag to indicate that SIGHUP arrived during server loop */
static volatile bool got_SIGHUP = false;
/*
* Default Values
*/
@ -217,8 +220,7 @@ static char ExtraOptions[MAXPGPATH];
static bool Reinit = true;
static int SendStop = false;
static bool NetServer = false; /* if not zero, postmaster listen for
* non-local connections */
bool NetServer = false; /* listen on TCP/IP */
#ifdef USE_SSL
static bool SecureNetServer = false; /* if not zero, postmaster listens
@ -256,7 +258,8 @@ extern int optind,
static void pmdaemonize(char *extraoptions);
static Port *ConnCreate(int serverFd);
static void ConnFree(Port *port);
static void reset_shared(unsigned short port);
static void reset_shared(int port);
static void SIGHUP_handler(SIGNAL_ARGS);
static void pmdie(SIGNAL_ARGS);
static void reaper(SIGNAL_ARGS);
static void dumpstatus(SIGNAL_ARGS);
@ -368,7 +371,6 @@ checkDataDir(const char *DataDir, bool *DataDirOK)
int
PostmasterMain(int argc, char *argv[])
{
extern int NBuffers; /* from buffer/bufmgr.c */
int opt;
char *hostName;
int status;
@ -431,6 +433,8 @@ PostmasterMain(int argc, char *argv[])
*/
umask((mode_t) 0077);
ResetAllOptions();
if (!(hostName = getenv("PGHOST")))
{
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
@ -441,9 +445,38 @@ PostmasterMain(int argc, char *argv[])
MyProcPid = getpid();
DataDir = getenv("PGDATA"); /* default value */
opterr = 0;
/*
* First we must scan for a -D argument to get the data dir. Then
* read the config file. Finally, scan all the other arguments.
* (Command line switches override config file.)
*
* Note: The two lists of options must be exactly the same, even
* though perhaps the first one would only have to be "D:" with
* opterr turned off. But some versions of getopt (notably GNU)
* are going to arbitrarily permute some "non-options" (according
* to the local world view) which will result in some switches
* being associated with the wrong argument. Death and destruction
* will occur.
*/
opterr = 1;
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:Film:MN:no:p:Ss-:")) != EOF)
{
if (opt == 'D')
DataDir = optarg;
}
optind = 1; /* start over */
checkDataDir(DataDir, &DataDirOK); /* issues error messages */
if (!DataDirOK)
{
fprintf(stderr, "No data directory -- can't proceed.\n");
exit(2);
}
ProcessConfigFile(PGC_POSTMASTER);
IgnoreSystemIndexes(false);
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:ilm:MN:no:p:Ss")) != EOF)
while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:d:Film:MN:no:p:Ss-:")) != EOF)
{
switch (opt)
{
@ -464,15 +497,7 @@ PostmasterMain(int argc, char *argv[])
/* Can no longer set authentication method. */
break;
case 'B':
/*
* The number of buffers to create. Setting this option
* means we have to start each backend with a -B # to make
* sure they know how many buffers were allocated.
*/
NBuffers = atoi(optarg);
strcat(ExtraOptions, " -B ");
strcat(ExtraOptions, optarg);
break;
case 'b':
/* Set the backend executable file to use. */
@ -486,8 +511,7 @@ PostmasterMain(int argc, char *argv[])
}
break;
case 'D':
/* Set PGDATA from the command line. */
DataDir = optarg;
/* already done above */
break;
case 'd':
@ -496,8 +520,10 @@ PostmasterMain(int argc, char *argv[])
* servers descended from it.
*/
DebugLvl = atoi(optarg);
pg_options[TRACE_VERBOSE] = DebugLvl;
break;
case 'F':
enableFsync = false;
break;
case 'i':
NetServer = true;
break;
@ -545,7 +571,7 @@ PostmasterMain(int argc, char *argv[])
break;
case 'p':
/* Set PGPORT by hand. */
PostPortName = (unsigned short) atoi(optarg);
PostPortName = atoi(optarg);
break;
case 'S':
@ -567,6 +593,21 @@ PostmasterMain(int argc, char *argv[])
*/
SendStop = true;
break;
case '-':
{
/* A little 'long argument' simulation */
size_t equal_pos = strcspn(optarg, "=");
char *cp;
if (optarg[equal_pos] != '=')
elog(ERROR, "--%s requires argument", optarg);
optarg[equal_pos] = '\0';
for(cp = optarg; *cp; cp++)
if (*cp == '-')
*cp = '_';
SetConfigOption(optarg, optarg + equal_pos + 1, PGC_POSTMASTER);
break;
}
default:
/* usage() never returns */
usage(progname);
@ -574,11 +615,8 @@ PostmasterMain(int argc, char *argv[])
}
}
/*
* Select default values for switches where needed
*/
if (PostPortName == 0)
PostPortName = (unsigned short) pq_getport();
PostPortName = pq_getport();
/*
* Check for invalid combinations of switches
@ -596,13 +634,6 @@ PostmasterMain(int argc, char *argv[])
exit(1);
}
checkDataDir(DataDir, &DataDirOK); /* issues error messages */
if (!DataDirOK)
{
fprintf(stderr, "No data directory -- can't proceed.\n");
exit(2);
}
if (!Execfile[0] && FindExec(Execfile, argv[0], "postgres") < 0)
{
fprintf(stderr, "%s: could not find backend to execute...\n",
@ -622,7 +653,7 @@ PostmasterMain(int argc, char *argv[])
if (NetServer)
{
status = StreamServerPort(hostName, PostPortName, &ServerSock_INET);
status = StreamServerPort(hostName, (unsigned short)PostPortName, &ServerSock_INET);
if (status != STATUS_OK)
{
fprintf(stderr, "%s: cannot create INET stream port\n",
@ -632,7 +663,7 @@ PostmasterMain(int argc, char *argv[])
}
#if !defined(__CYGWIN32__) && !defined(__QNX__)
status = StreamServerPort(NULL, PostPortName, &ServerSock_UNIX);
status = StreamServerPort(NULL, (unsigned short)PostPortName, &ServerSock_UNIX);
if (status != STATUS_OK)
{
fprintf(stderr, "%s: cannot create UNIX stream port\n",
@ -707,7 +738,7 @@ PostmasterMain(int argc, char *argv[])
PG_INITMASK();
PG_SETMASK(&BlockSig);
pqsignal(SIGHUP, pmdie); /* send SIGHUP, don't die */
pqsignal(SIGHUP, SIGHUP_handler); /* reread config file and have children do same */
pqsignal(SIGINT, pmdie); /* send SIGTERM and ShutdownDataBase */
pqsignal(SIGQUIT, pmdie); /* send SIGUSR1 and die */
pqsignal(SIGTERM, pmdie); /* wait for children and ShutdownDataBase */
@ -1066,6 +1097,12 @@ ServerLoop(void)
curr = next;
}
if (got_SIGHUP)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
}
}
}
@ -1321,7 +1358,7 @@ ConnFree(Port *conn)
* reset_shared -- reset shared memory and semaphores
*/
static void
reset_shared(unsigned short port)
reset_shared(int port)
{
ipc_key = port * 1000 + shmem_seq * 100;
CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends);
@ -1330,6 +1367,23 @@ reset_shared(unsigned short port)
shmem_seq -= 10;
}
/*
* set flag is SIGHUP was detected so config file can be reread in
* main loop
*/
static void
SIGHUP_handler(SIGNAL_ARGS)
{
got_SIGHUP = true;
if (Shutdown > SmartShutdown)
return;
got_SIGHUP = true;
SignalChildren(SIGHUP);
}
/*
* pmdie -- signal handler for cleaning up after a kill signal.
*/
@ -1338,19 +1392,11 @@ pmdie(SIGNAL_ARGS)
{
PG_SETMASK(&BlockSig);
TPRINTF(TRACE_VERBOSE, "pmdie %d", postgres_signal_arg);
if (DebugLvl >= 1)
elog(DEBUG, "pmdie %d", postgres_signal_arg);
switch (postgres_signal_arg)
{
case SIGHUP:
/*
* Send SIGHUP to all children (update options flags)
*/
if (Shutdown > SmartShutdown)
return;
SignalChildren(SIGHUP);
return;
case SIGUSR2:
/*
@ -1679,9 +1725,10 @@ SignalChildren(int signal)
if (bp->pid != mypid)
{
TPRINTF(TRACE_VERBOSE,
"SignalChildren: sending signal %d to process %d",
signal, bp->pid);
if (DebugLvl >= 1)
elog(DEBUG, "SignalChildren: sending signal %d to process %d",
signal, bp->pid);
kill(bp->pid, signal);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.34 2000/04/12 17:15:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.35 2000/05/31 00:28:26 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -48,7 +48,6 @@ long *CurTraceBuf;
#endif /* BMTRACE */
int ShowPinTrace = 0;
int NBuffers = DEF_NBUFFERS; /* default is set in config.h */
int Data_Descriptors;
int Free_List_Descriptor;
int Lookup_List_Descriptor;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.56 2000/04/12 17:15:35 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.57 2000/05/31 00:28:27 petere Exp $
*
* NOTES:
*
@ -196,7 +196,10 @@ static long pg_nofile(void);
int
pg_fsync(int fd)
{
return disableFsync ? 0 : fsync(fd);
if (enableFsync)
return fsync(fd);
else
return 0;
}
/*
@ -916,7 +919,7 @@ FileSync(File file)
/* Need not sync if file is not dirty. */
returnCode = 0;
}
else if (disableFsync)
else if (!enableFsync)
{
/* Don't force the file open if pg_fsync isn't gonna sync it. */
returnCode = 0;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.47 2000/05/16 20:48:48 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipc.c,v 1.48 2000/05/31 00:28:29 petere Exp $
*
* NOTES
*
@ -36,9 +36,9 @@
/* In Ultrix, sem.h and shm.h must be included AFTER ipc.h */
#include <sys/sem.h>
#include <sys/shm.h>
#include "miscadmin.h"
#include "utils/memutils.h"
#include "libpq/libpq.h"
#include "utils/trace.h"
#if defined(solaris_sparc)
#include <sys/ipc.h>
@ -124,7 +124,8 @@ proc_exit(int code)
*/
proc_exit_inprogress = true;
TPRINTF(TRACE_VERBOSE, "proc_exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "proc_exit(%d)", code);
/* do our shared memory exits first */
shmem_exit(code);
@ -143,7 +144,8 @@ proc_exit(int code)
(*on_proc_exit_list[on_proc_exit_index].function) (code,
on_proc_exit_list[on_proc_exit_index].arg);
TPRINTF(TRACE_VERBOSE, "exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "exit(%d)", code);
exit(code);
}
@ -156,7 +158,8 @@ proc_exit(int code)
void
shmem_exit(int code)
{
TPRINTF(TRACE_VERBOSE, "shmem_exit(%d)", code);
if (DebugLvl > 1)
elog(DEBUG, "shmem_exit(%d)", code);
/* ----------------
* call all the registered callbacks.
@ -297,18 +300,16 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
if (semId == -1)
{
#ifdef DEBUG_IPC
EPRINTF("calling semget with %d, %d , %d\n",
semKey,
semNum,
IPC_CREAT | permission);
fprintf(stderr, "calling semget(%d, %d, 0%o)\n",
semKey, semNum, (unsigned)(IPC_CREAT|permission));
#endif
semId = semget(semKey, semNum, IPC_CREAT | permission);
if (semId < 0)
{
EPRINTF("IpcSemaphoreCreate: semget failed (%s) "
"key=%d, num=%d, permission=%o",
strerror(errno), semKey, semNum, permission);
fprintf(stderr, "IpcSemaphoreCreate: semget(%d, %d, 0%o) failed: %s\n",
semKey, semNum, (unsigned)(permission|IPC_CREAT),
strerror(errno));
IpcConfigTip();
return (-1);
}
@ -318,8 +319,8 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
errStatus = semctl(semId, 0, SETALL, semun);
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreCreate: semctl failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreCreate: semctl(id=%d) failed: %s\n",
semId, strerror(errno));
semctl(semId, 0, IPC_RMID, semun);
IpcConfigTip();
return (-1);
@ -330,10 +331,11 @@ IpcSemaphoreCreate(IpcSemaphoreKey semKey,
}
#ifdef DEBUG_IPC
EPRINTF("\nIpcSemaphoreCreate, returns %d\n", semId);
fprintf(stderr, "IpcSemaphoreCreate returns %d\n", semId);
fflush(stdout);
fflush(stderr);
#endif
return semId;
}
@ -357,13 +359,11 @@ IpcSemaphoreSet(int semId, int semno, int value)
IpcSemaphoreSet_return = errStatus;
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreSet: semctl failed (%s) id=%d",
strerror(errno), semId);
}
fprintf(stderr, "IpcSemaphoreSet: semctl(id=%d) failed: %s\n",
semId, strerror(errno));
}
#endif
#endif /* NOT_USED */
/****************************************************************************/
/* IpcSemaphoreKill(key) - removes a semaphore */
@ -421,8 +421,8 @@ IpcSemaphoreLock(IpcSemaphoreId semId, int sem, int lock)
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreLock: semop failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreLock: semop(id=%d) failed: %s\n",
semId, strerror(errno));
proc_exit(255);
}
}
@ -466,8 +466,8 @@ IpcSemaphoreUnlock(IpcSemaphoreId semId, int sem, int lock)
if (errStatus == -1)
{
EPRINTF("IpcSemaphoreUnlock: semop failed (%s) id=%d",
strerror(errno), semId);
fprintf(stderr, "IpcSemaphoreUnlock: semop(id=%d) failed: %s\n",
semId, strerror(errno));
proc_exit(255);
}
}
@ -516,9 +516,8 @@ IpcMemoryCreate(IpcMemoryKey memKey, uint32 size, int permission)
if (shmid < 0)
{
EPRINTF("IpcMemoryCreate: shmget failed (%s) "
"key=%d, size=%d, permission=%o",
strerror(errno), memKey, size, permission);
fprintf(stderr, "IpcMemoryCreate: shmget(%d, %d, 0%o) failed: %s\n",
memKey, size, (unsigned)(IPC_CREAT|permission), strerror(errno));
IpcConfigTip();
return IpcMemCreationFailed;
}
@ -542,9 +541,8 @@ IpcMemoryIdGet(IpcMemoryKey memKey, uint32 size)
if (shmid < 0)
{
EPRINTF("IpcMemoryIdGet: shmget failed (%s) "
"key=%d, size=%d, permission=%o",
strerror(errno), memKey, size, 0);
fprintf(stderr, "IpcMemoryIdGet: shmget(%d, %d, 0) failed: %s\n",
memKey, size, strerror(errno));
return IpcMemIdGetFailed;
}
@ -583,8 +581,8 @@ IpcMemoryAttach(IpcMemoryId memId)
/* if ( *memAddress == -1) { XXX ??? */
if (memAddress == (char *) -1)
{
EPRINTF("IpcMemoryAttach: shmat failed (%s) id=%d",
strerror(errno), memId);
fprintf(stderr, "IpcMemoryAttach: shmat(id=%d) failed: %s\n",
memId, strerror(errno));
return IpcMemAttachFailed;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.31 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.32 2000/05/31 00:28:29 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -268,8 +268,8 @@ SIInsertDataEntry(SISeg *segP, SharedInvalidData *data)
if (numMsgs == (MAXNUMMESSAGES * 70 / 100) &&
IsUnderPostmaster)
{
TPRINTF(TRACE_VERBOSE,
"SIInsertDataEntry: table is 70%% full, signaling postmaster");
if (DebugLvl >= 1)
elog(DEBUG, "SIInsertDataEntry: table is 70%% full, signaling postmaster");
kill(getppid(), SIGUSR2);
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.24 2000/04/12 17:15:37 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/Attic/spin.c,v 1.25 2000/05/31 00:28:29 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -35,6 +35,7 @@
#include "storage/proc.h"
#include "storage/s_lock.h"
/* globals used in this file */
IpcSemaphoreId SpinLockId;
@ -84,14 +85,23 @@ InitSpinLocks(void)
return;
}
#ifdef LOCKDEBUG
#define PRINT_LOCK(LOCK) \
TPRINTF(TRACE_SPINLOCKS, \
"(locklock = %d, flag = %d, nshlocks = %d, shlock = %d, " \
"exlock =%d)\n", LOCK->locklock, \
LOCK->flag, LOCK->nshlocks, LOCK->shlock, \
LOCK->exlock)
#endif
#ifdef LOCK_DEBUG
bool Trace_spinlocks = false;
inline static void
PRINT_SLDEBUG(const char * where, SPINLOCK lockid, const SLock * lock)
{
if (Trace_spinlocks)
elog(DEBUG,
"%s: id=%d (locklock=%d, flag=%d, nshlocks=%d, shlock=%d, exlock=%d)",
where, lockid,
lock->locklock, lock->flag, lock->nshlocks, lock->shlock, lock->exlock);
}
#else /* not LOCK_DEBUG */
#define PRINT_SLDEBUG(a,b,c)
#endif /* not LOCK_DEBUG */
/* from ipc.c */
extern SLock *SLockArray;
@ -103,10 +113,7 @@ SpinAcquire(SPINLOCK lockid)
/* This used to be in ipc.c, but move here to reduce function calls */
slckP = &(SLockArray[lockid]);
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: %d", lockid);
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("SpinAcquire", lockid, slckP);
ex_try_again:
S_LOCK(&(slckP->locklock));
switch (slckP->flag)
@ -116,10 +123,7 @@ ex_try_again:
S_LOCK(&(slckP->exlock));
S_LOCK(&(slckP->shlock));
S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "OUT: ");
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("OUT", lockid, slckP);
break;
case SHAREDLOCK:
case EXCLUSIVELOCK:
@ -129,9 +133,7 @@ ex_try_again:
goto ex_try_again;
}
PROC_INCR_SLOCK(lockid);
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinAcquire: got %d", lockid);
#endif
PRINT_SLDEBUG("SpinAcquire/success", lockid, slckP);
}
void
@ -142,23 +144,16 @@ SpinRelease(SPINLOCK lockid)
/* This used to be in ipc.c, but move here to reduce function calls */
slckP = &(SLockArray[lockid]);
#ifdef USE_ASSERT_CHECKING
/*
* Check that we are actually holding the lock we are releasing. This
* can be done only after MyProc has been initialized.
*/
if (MyProc)
Assert(MyProc->sLocks[lockid] > 0);
Assert(!MyProc || MyProc->sLocks[lockid] > 0);
Assert(slckP->flag != NOLOCK);
#endif
PROC_DECR_SLOCK(lockid);
#ifdef LOCKDEBUG
TPRINTF("SpinRelease: %d\n", lockid);
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("SpinRelease", lockid, slckP);
S_LOCK(&(slckP->locklock));
/* -------------
* give favor to read processes
@ -178,13 +173,10 @@ SpinRelease(SPINLOCK lockid)
S_UNLOCK(&(slckP->shlock));
S_UNLOCK(&(slckP->exlock));
S_UNLOCK(&(slckP->locklock));
#ifdef LOCKDEBUG
TPRINTF(TRACE_SPINLOCKS, "SpinRelease: released %d", lockid);
PRINT_LOCK(slckP);
#endif
PRINT_SLDEBUG("SpinRelease/released", lockid, slckP);
}
#else /* HAS_TEST_AND_SET */
#else /* !HAS_TEST_AND_SET */
/* Spinlocks are implemented using SysV semaphores */
static bool AttachSpinLocks(IPCKey key);
@ -290,4 +282,4 @@ InitSpinLocks(void)
return;
}
#endif /* HAS_TEST_AND_SET */
#endif /* !HAS_TEST_AND_SET */

View File

@ -8,17 +8,10 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.39 2000/04/12 17:15:38 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.40 2000/05/31 00:28:30 petere Exp $
*
*-------------------------------------------------------------------------
*/
/* #define LOCKDEBUGALL 1 */
/* #define LOCKDEBUG 1 */
#ifdef LOCKDEBUGALL
#define LOCKDEBUG 1
#endif /* LOCKDEBUGALL */
#include "postgres.h"

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.67 2000/04/30 21:23:31 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.68 2000/05/31 00:28:30 petere Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@ -39,106 +39,11 @@
#include "miscadmin.h"
#include "storage/proc.h"
#include "utils/ps_status.h"
#include "utils/trace.h"
static int WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode);
/*
* lockDebugRelation can be used to trace unconditionally a single relation,
* for example pg_listener, if you suspect there are locking problems.
*
* lockDebugOidMin is is used to avoid tracing postgres relations, which
* would produce a lot of output. Unfortunately most system relations are
* created after bootstrap and have oid greater than BootstrapObjectIdData.
* If you are using tprintf you should specify a value greater than the max
* oid of system relations, which can be found with the following query:
*
* select max(int4in(int4out(oid))) from pg_class where relname ~ '^pg_';
*
* To get a useful lock trace you can use the following pg_options:
*
* -T "verbose,query,locks,userlocks,lock_debug_oidmin=17500"
*/
#define LOCKDEBUG(lockmethod) (pg_options[TRACE_SHORTLOCKS+lockmethod])
#define lockDebugRelation (pg_options[TRACE_LOCKRELATION])
#define lockDebugOidMin (pg_options[TRACE_LOCKOIDMIN])
#define lockReadPriority (pg_options[OPT_LOCKREADPRIORITY])
#ifdef LOCK_MGR_DEBUG
#define LOCK_PRINT(where,lock,type) \
if (((LOCKDEBUG(LOCK_LOCKMETHOD(*(lock))) >= 1) \
&& (lock->tag.relId >= lockDebugOidMin)) \
|| \
(lockDebugRelation && (lock->tag.relId == lockDebugRelation))) \
LOCK_PRINT_AUX(where,lock,type)
#define LOCK_PRINT_AUX(where,lock,type) \
TPRINTF(TRACE_ALL, \
"%s: lock(%x) tbl(%d) rel(%u) db(%u) obj(%u) mask(%x) " \
"hold(%d,%d,%d,%d,%d,%d,%d)=%d " \
"act(%d,%d,%d,%d,%d,%d,%d)=%d wait(%d) type(%s)", \
where, \
MAKE_OFFSET(lock), \
lock->tag.lockmethod, \
lock->tag.relId, \
lock->tag.dbId, \
lock->tag.objId.blkno, \
lock->mask, \
lock->holders[1], \
lock->holders[2], \
lock->holders[3], \
lock->holders[4], \
lock->holders[5], \
lock->holders[6], \
lock->holders[7], \
lock->nHolding, \
lock->activeHolders[1], \
lock->activeHolders[2], \
lock->activeHolders[3], \
lock->activeHolders[4], \
lock->activeHolders[5], \
lock->activeHolders[6], \
lock->activeHolders[7], \
lock->nActive, \
lock->waitProcs.size, \
lock_types[type])
#define XID_PRINT(where,xidentP) \
if (((LOCKDEBUG(XIDENT_LOCKMETHOD(*(xidentP))) >= 1) \
&& (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId \
>= lockDebugOidMin)) \
|| (lockDebugRelation && \
(((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId \
== lockDebugRelation))) \
XID_PRINT_AUX(where,xidentP)
#define XID_PRINT_AUX(where,xidentP) \
TPRINTF(TRACE_ALL, \
"%s: xid(%x) lock(%x) tbl(%d) pid(%d) xid(%u) " \
"hold(%d,%d,%d,%d,%d,%d,%d)=%d", \
where, \
MAKE_OFFSET(xidentP), \
xidentP->tag.lock, \
XIDENT_LOCKMETHOD(*(xidentP)), \
xidentP->tag.pid, \
xidentP->tag.xid, \
xidentP->holders[1], \
xidentP->holders[2], \
xidentP->holders[3], \
xidentP->holders[4], \
xidentP->holders[5], \
xidentP->holders[6], \
xidentP->holders[7], \
xidentP->nHolding)
#else /* !LOCK_MGR_DEBUG */
#define LOCK_PRINT(where,lock,type)
#define LOCK_PRINT_AUX(where,lock,type)
#define XID_PRINT(where,xidentP)
#define XID_PRINT_AUX(where,xidentP)
#endif /* !LOCK_MGR_DEBUG */
static char *lock_types[] = {
static char *lock_types[] =
{
"INVALID",
"AccessShareLock",
"RowShareLock",
@ -149,6 +54,89 @@ static char *lock_types[] = {
"AccessExclusiveLock"
};
#ifdef LOCK_DEBUG
/*------
* The following configuration options are available for lock debugging:
*
* trace_locks -- give a bunch of output what's going on in this file
* trace_userlocks -- same but for user locks
* trace_lock_oidmin-- do not trace locks for tables below this oid
* (use to avoid output on system tables)
* trace_lock_table -- trace locks on this table (oid) unconditionally
* debug_deadlocks -- currently dumps locks at untimely occasions ;)
* Furthermore, but in storage/ipc/spin.c:
* trace_spinlocks -- trace spinlocks (pretty useless)
*
* Define LOCK_DEBUG at compile time to get all this enabled.
*/
int Trace_lock_oidmin = BootstrapObjectIdData;
bool Trace_locks = false;
bool Trace_userlocks = false;
int Trace_lock_table = 0;
bool Debug_deadlocks = false;
inline static bool
LOCK_DEBUG_ENABLED(const LOCK * lock)
{
return
(((LOCK_LOCKMETHOD(*lock) == DEFAULT_LOCKMETHOD && Trace_locks)
|| (LOCK_LOCKMETHOD(*lock) == USER_LOCKMETHOD && Trace_userlocks))
&& (lock->tag.relId >= Trace_lock_oidmin))
|| (Trace_lock_table && (lock->tag.relId == Trace_lock_table));
}
inline static void
LOCK_PRINT(const char * where, const LOCK * lock, LOCKMODE type)
{
if (LOCK_DEBUG_ENABLED(lock))
elog(DEBUG,
"%s: lock(%lx) tbl(%d) rel(%u) db(%u) obj(%u) mask(%x) "
"hold(%d,%d,%d,%d,%d,%d,%d)=%d "
"act(%d,%d,%d,%d,%d,%d,%d)=%d wait(%d) type(%s)",
where, MAKE_OFFSET(lock),
lock->tag.lockmethod, lock->tag.relId, lock->tag.dbId,
lock->tag.objId.blkno, lock->mask,
lock->holders[1], lock->holders[2], lock->holders[3], lock->holders[4],
lock->holders[5], lock->holders[6], lock->holders[7], lock->nHolding,
lock->activeHolders[1], lock->activeHolders[2], lock->activeHolders[3],
lock->activeHolders[4], lock->activeHolders[5], lock->activeHolders[6],
lock->activeHolders[7], lock->nActive,
lock->waitProcs.size, lock_types[type]);
}
inline static void
XID_PRINT(const char * where, const XIDLookupEnt * xidentP)
{
if (
(((XIDENT_LOCKMETHOD(*xidentP) == DEFAULT_LOCKMETHOD && Trace_locks)
|| (XIDENT_LOCKMETHOD(*xidentP) == USER_LOCKMETHOD && Trace_userlocks))
&& (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId >= Trace_lock_oidmin))
|| (Trace_lock_table && (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId == Trace_lock_table))
)
elog(DEBUG,
"%s: xid(%lx) lock(%lx) tbl(%d) pid(%d) xid(%u) hold(%d,%d,%d,%d,%d,%d,%d)=%d",
where, MAKE_OFFSET(xidentP), xidentP->tag.lock, XIDENT_LOCKMETHOD(*(xidentP)),
xidentP->tag.pid, xidentP->tag.xid,
xidentP->holders[1], xidentP->holders[2], xidentP->holders[3], xidentP->holders[4],
xidentP->holders[5], xidentP->holders[6], xidentP->holders[7], xidentP->nHolding);
}
#else /* not LOCK_DEBUG */
#define LOCK_PRINT(where, lock, type)
#define XID_PRINT(where, xidentP)
#endif /* not LOCK_DEBUG */
SPINLOCK LockMgrLock; /* in Shmem or created in
* CreateSpinlocks() */
@ -192,16 +180,6 @@ InitLocks()
BITS_ON[i] = bit;
BITS_OFF[i] = ~bit;
}
#ifdef LOCK_MGR_DEBUG
/*
* If lockDebugOidMin value has not been specified in pg_options set a
* default value.
*/
if (!lockDebugOidMin)
lockDebugOidMin = BootstrapObjectIdData;
#endif
}
/* -------------------
@ -488,18 +466,9 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
int status;
TransactionId xid;
#ifdef USER_LOCKS
int is_user_lock;
is_user_lock = (lockmethod == USER_LOCKMETHOD);
#ifdef USER_LOCKS_DEBUG
if (is_user_lock)
{
TPRINTF(TRACE_USERLOCKS, "LockAcquire: user lock [%u] %s",
locktag->objId.blkno,
lock_types[lockmode]);
}
#endif
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD && Trace_userlocks)
elog(DEBUG, "LockAcquire: user lock [%u] %s", locktag->objId.blkno, lock_types[lockmode]);
#endif
/* ???????? This must be changed when short term locks will be used */
@ -573,8 +542,9 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
#ifdef USE_XIDTAG_LOCKMETHOD
item.tag.lockmethod = lockmethod;
#endif
#ifdef USER_LOCKS
if (is_user_lock)
if (lockmethod == USER_LOCKMETHOD)
{
item.tag.pid = MyProcPid;
item.tag.xid = xid = 0;
@ -584,10 +554,10 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
xid = GetCurrentTransactionId();
TransactionIdStore(xid, &item.tag.xid);
}
#else
#else /* not USER_LOCKS */
xid = GetCurrentTransactionId();
TransactionIdStore(xid, &item.tag.xid);
#endif
#endif /* not USER_LOCKS */
/*
* Find or create an xid entry with this tag
@ -688,7 +658,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
* User locks are non blocking. If we can't acquire a lock we must
* remove the xid entry and return FALSE without waiting.
*/
if (is_user_lock)
if (lockmethod == USER_LOCKMETHOD)
{
if (!result->nHolding)
{
@ -700,7 +670,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
elog(NOTICE, "LockAcquire: remove xid, table corrupted");
}
else
XID_PRINT_AUX("LockAcquire: NHOLDING", result);
XID_PRINT("LockAcquire: NHOLDING", result);
lock->nHolding--;
lock->holders[lockmode]--;
LOCK_PRINT("LockAcquire: user lock failed", lock, lockmode);
@ -709,7 +679,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
SpinRelease(masterLock);
return FALSE;
}
#endif
#endif /* USER_LOCKS */
/*
* Construct bitmask of locks we hold before going to sleep.
@ -737,8 +707,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
*/
if (!((result->nHolding > 0) && (result->holders[lockmode] > 0)))
{
XID_PRINT_AUX("LockAcquire: INCONSISTENT ", result);
LOCK_PRINT_AUX("LockAcquire: INCONSISTENT ", lock, lockmode);
XID_PRINT("LockAcquire: INCONSISTENT", result);
LOCK_PRINT("LockAcquire: INCONSISTENT", lock, lockmode);
/* Should we retry ? */
SpinRelease(masterLock);
return FALSE;
@ -781,11 +751,6 @@ LockResolveConflicts(LOCKMETHOD lockmethod,
int i,
tmpMask;
#ifdef USER_LOCKS
int is_user_lock;
#endif
numLockModes = LockMethodTable[lockmethod]->ctl->numLockModes;
xidTable = LockMethodTable[lockmethod]->xidHash;
@ -814,17 +779,14 @@ LockResolveConflicts(LOCKMETHOD lockmethod,
item.tag.lockmethod = lockmethod;
#endif
#ifdef USER_LOCKS
is_user_lock = (lockmethod == 2);
if (is_user_lock)
if (lockmethod == USER_LOCKMETHOD)
{
item.tag.pid = MyProcPid;
item.tag.xid = 0;
}
else
TransactionIdStore(xid, &item.tag.xid);
#else
TransactionIdStore(xid, &item.tag.xid);
#endif
TransactionIdStore(xid, &item.tag.xid);
/*
* Find or create an xid entry with this tag
@ -851,7 +813,7 @@ LockResolveConflicts(LOCKMETHOD lockmethod,
*/
MemSet(result->holders, 0, numLockModes * sizeof(*(lock->holders)));
result->nHolding = 0;
XID_PRINT_AUX("LockResolveConflicts: NOT FOUND", result);
XID_PRINT("LockResolveConflicts: NOT FOUND", result);
}
else
XID_PRINT("LockResolveConflicts: found", result);
@ -946,7 +908,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode)
* synchronization for this queue. That will not be true if/when
* people can be deleted from the queue by a SIGINT or something.
*/
LOCK_PRINT_AUX("WaitOnLock: sleeping on lock", lock, lockmode);
LOCK_PRINT("WaitOnLock: sleeping on lock", lock, lockmode);
strcpy(old_status, PS_STATUS);
strcpy(new_status, PS_STATUS);
strcat(new_status, " waiting");
@ -965,7 +927,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode)
*/
lock->nHolding--;
lock->holders[lockmode]--;
LOCK_PRINT_AUX("WaitOnLock: aborting on lock", lock, lockmode);
LOCK_PRINT("WaitOnLock: aborting on lock", lock, lockmode);
Assert((lock->nHolding >= 0) && (lock->holders[lockmode] >= 0));
Assert(lock->nActive <= lock->nHolding);
if (lock->activeHolders[lockmode] == lock->holders[lockmode])
@ -979,7 +941,7 @@ WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode)
if (lock->activeHolders[lockmode] == lock->holders[lockmode])
lock->waitMask &= BITS_OFF[lockmode];
PS_SET_STATUS(old_status);
LOCK_PRINT_AUX("WaitOnLock: wakeup on lock", lock, lockmode);
LOCK_PRINT("WaitOnLock: wakeup on lock", lock, lockmode);
return STATUS_OK;
}
@ -1005,30 +967,15 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
HTAB *xidTable;
TransactionId xid;
bool wakeupNeeded = true;
int trace_flag;
#ifdef USER_LOCKS
int is_user_lock;
is_user_lock = (lockmethod == USER_LOCKMETHOD);
if (is_user_lock)
{
TPRINTF(TRACE_USERLOCKS, "LockRelease: user lock tag [%u] %d",
locktag->objId.blkno,
lockmode);
}
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD && Trace_userlocks)
elog(DEBUG, "LockRelease: user lock tag [%u] %d", locktag->objId.blkno, lockmode);
#endif
/* ???????? This must be changed when short term locks will be used */
locktag->lockmethod = lockmethod;
#ifdef USER_LOCKS
trace_flag = \
(lockmethod == USER_LOCKMETHOD) ? TRACE_USERLOCKS : TRACE_LOCKS;
#else
trace_flag = TRACE_LOCKS;
#endif
Assert(lockmethod < NumLockMethods);
lockMethodTable = LockMethodTable[lockmethod];
if (!lockMethodTable)
@ -1064,14 +1011,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
if (!found)
{
SpinRelease(masterLock);
#ifdef USER_LOCKS
if (is_user_lock)
{
TPRINTF(TRACE_USERLOCKS, "LockRelease: no lock with this tag");
return FALSE;
}
#endif
elog(NOTICE, "LockRelease: locktable lookup failed, no lock");
elog(NOTICE, "LockRelease: no such lock");
return FALSE;
}
LOCK_PRINT("LockRelease: found", lock, lockmode);
@ -1091,7 +1031,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
item.tag.lockmethod = lockmethod;
#endif
#ifdef USER_LOCKS
if (is_user_lock)
if (lockmethod == USER_LOCKMETHOD)
{
item.tag.pid = MyProcPid;
item.tag.xid = xid = 0;
@ -1116,8 +1056,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
{
SpinRelease(masterLock);
#ifdef USER_LOCKS
if (!found && is_user_lock)
TPRINTF(TRACE_USERLOCKS, "LockRelease: no lock with this tag");
if (!found && lockmethod == USER_LOCKMETHOD)
elog(NOTICE, "LockRelease: no lock with this tag");
else
#endif
elog(NOTICE, "LockRelease: xid table corrupted");
@ -1133,7 +1073,7 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
if (!(result->holders[lockmode] > 0))
{
SpinRelease(masterLock);
XID_PRINT_AUX("LockAcquire: WRONGTYPE", result);
XID_PRINT("LockAcquire: WRONGTYPE", result);
elog(NOTICE, "LockRelease: you don't own a lock of type %s",
lock_types[lockmode]);
Assert(result->holders[lockmode] >= 0);
@ -1234,14 +1174,10 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
if (wakeupNeeded)
ProcLockWakeup(&(lock->waitProcs), lockmethod, lock);
else
{
if (((LOCKDEBUG(LOCK_LOCKMETHOD(*(lock))) >= 1) \
&&(lock->tag.relId >= lockDebugOidMin)) \
||\
(lockDebugRelation && (lock->tag.relId == lockDebugRelation)))
TPRINTF(TRACE_ALL, "LockRelease: no wakeup needed");
}
#ifdef LOCK_DEBUG
else if (LOCK_DEBUG_ENABLED(lock))
elog(DEBUG, "LockRelease: no wakeup needed");
#endif
SpinRelease(masterLock);
return TRUE;
@ -1265,20 +1201,13 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
numLockModes;
LOCK *lock;
bool found;
int trace_flag;
int xidtag_lockmethod,
nleft;
#ifdef USER_LOCKS
int is_user_lock_table;
is_user_lock_table = (lockmethod == USER_LOCKMETHOD);
trace_flag = (lockmethod == 2) ? TRACE_USERLOCKS : TRACE_LOCKS;
#else
trace_flag = TRACE_LOCKS;
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
elog(DEBUG, "LockReleaseAll: lockmethod=%d, pid=%d", lockmethod, MyProcPid);
#endif
TPRINTF(trace_flag, "LockReleaseAll: lockmethod=%d, pid=%d",
lockmethod, MyProcPid);
nleft = 0;
@ -1313,7 +1242,7 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
xidtag_lockmethod = XIDENT_LOCKMETHOD(*xidLook);
if ((xidtag_lockmethod == lockmethod) && pg_options[trace_flag])
if (xidtag_lockmethod == lockmethod)
{
XID_PRINT("LockReleaseAll", xidLook);
LOCK_PRINT("LockReleaseAll", lock, 0);
@ -1324,9 +1253,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
elog(NOTICE, "LockReleaseAll: xid/lock method mismatch: %d != %d",
xidtag_lockmethod, lock->tag.lockmethod);
#endif
if ((xidtag_lockmethod != lockmethod) && (trace_flag >= 2))
if (xidtag_lockmethod != lockmethod)
{
TPRINTF(trace_flag, "LockReleaseAll: skipping other table");
nleft++;
goto next_item;
}
@ -1338,13 +1266,15 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
Assert(xidLook->nHolding <= lock->nHolding);
#ifdef USER_LOCKS
if (is_user_lock_table)
if (lockmethod == USER_LOCKMETHOD)
{
if ((xidLook->tag.pid == 0) || (xidLook->tag.xid != 0))
{
TPRINTF(TRACE_USERLOCKS,
"LockReleaseAll: skiping normal lock [%d,%d,%d]",
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#ifdef LOCK_DEBUG
if (Trace_userlocks)
elog(DEBUG, "LockReleaseAll: skiping normal lock [%ld,%d,%d]",
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif /* LOCK_DEBUG */
nleft++;
goto next_item;
}
@ -1358,29 +1288,29 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
nleft++;
goto next_item;
}
TPRINTF(TRACE_USERLOCKS,
"LockReleaseAll: releasing user lock [%u] [%d,%d,%d]",
lock->tag.objId.blkno,
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#ifdef LOCK_DEBUG
if (Trace_userlocks)
elog(DEBUG, "LockReleaseAll: releasing user lock [%u] [%ld,%d,%d]",
lock->tag.objId.blkno, xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif /* LOCK_DEBUG */
}
else
{
/*
* Can't check xidLook->tag.xid, can be 0 also for normal
* locks
* Can't check xidLook->tag.xid, can be 0 also for normal locks
*/
if (xidLook->tag.pid != 0)
{
TPRINTF(TRACE_LOCKS,
"LockReleaseAll: skiping user lock [%u] [%d,%d,%d]",
lock->tag.objId.blkno,
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#ifdef LOCK_DEBUG
if (Trace_userlocks)
elog(DEBUG, "LockReleaseAll: skiping user lock [%u] [%ld,%d,%d]",
lock->tag.objId.blkno, xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
#endif /* LOCK_DEBUG */
nleft++;
goto next_item;
}
}
#endif
#endif /* USER_LOCKS */
/* ------------------
* fix the general lock stats
@ -1486,12 +1416,18 @@ next_item:
*/
if (nleft == 0)
{
TPRINTF(trace_flag, "LockReleaseAll: reinitializing lockQueue");
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
elog(DEBUG, "LockReleaseAll: reinitializing lockQueue");
#endif
SHMQueueInit(lockQueue);
}
SpinRelease(masterLock);
TPRINTF(trace_flag, "LockReleaseAll: done");
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
elog(DEBUG, "LockReleaseAll: done");
#endif
return TRUE;
}
@ -1753,10 +1689,7 @@ DeadLockCheck(void *proc, LOCK *findlock)
/*
* Blocked by others - no deadlock...
*/
#ifdef DEADLOCK_DEBUG
LOCK_PRINT("DeadLockCheck: blocked by others",
lock, waitProc->token);
#endif
LOCK_PRINT("DeadLockCheck: blocked by others", lock, waitProc->token);
waitProc = (PROC *) MAKE_PTR(waitProc->links.prev);
continue;
}
@ -1817,15 +1750,9 @@ LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag)
/* Assume that no one will modify the result */
static int empty_array[] = {20, 1, 0, 0, 0};
#ifdef USER_LOCKS
int is_user_lock;
is_user_lock = (lockmethod == USER_LOCKMETHOD);
if (is_user_lock)
{
TPRINTF(TRACE_USERLOCKS, "LockOwners: user lock tag [%u]",
locktag->objId.blkno);
}
#ifdef LOCK_DEBUG
if (lockmethod == USER_LOCKMETHOD && Trace_userlocks)
elog(DEBUG, "LockOwners: user lock tag [%u]", locktag->objId.blkno);
#endif
/* This must be changed when short term locks will be used */
@ -1865,14 +1792,7 @@ LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag)
if (!found)
{
SpinRelease(masterLock);
#ifdef USER_LOCKS
if (is_user_lock)
{
TPRINTF(TRACE_USERLOCKS, "LockOwners: no lock with this tag");
return (ArrayType *) &empty_array;
}
#endif
elog(NOTICE, "LockOwners: locktable lookup failed, no lock");
elog(NOTICE, "LockOwners: no such lock");
return (ArrayType *) &empty_array;
}
LOCK_PRINT("LockOwners: found", lock, 0);
@ -1974,9 +1894,9 @@ LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag)
return array;
}
#endif
#endif /* NOT_USED */
#ifdef DEADLOCK_DEBUG
#ifdef LOCK_DEBUG
/*
* Dump all locks in the proc->lockQueue. Must have already acquired
* the masterLock.
@ -2016,7 +1936,7 @@ DumpLocks()
end = MAKE_OFFSET(lockQueue);
if (MyProc->waitLock)
LOCK_PRINT_AUX("DumpLocks: waiting on", MyProc->waitLock, 0);
LOCK_PRINT("DumpLocks: waiting on", MyProc->waitLock, 0);
for (;;)
{
@ -2035,8 +1955,8 @@ DumpLocks()
done = (xidLook->queue.next == end);
lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
XID_PRINT_AUX("DumpLocks", xidLook);
LOCK_PRINT_AUX("DumpLocks", lock, 0);
XID_PRINT("DumpLocks", xidLook);
LOCK_PRINT("DumpLocks", lock, 0);
if (done)
break;
@ -2078,18 +1998,18 @@ DumpAllLocks()
xidTable = lockMethodTable->xidHash;
if (MyProc->waitLock)
LOCK_PRINT_AUX("DumpAllLocks: waiting on", MyProc->waitLock, 0);
LOCK_PRINT("DumpAllLocks: waiting on", MyProc->waitLock, 0);
hash_seq(NULL);
while ((xidLook = (XIDLookupEnt *) hash_seq(xidTable)) &&
(xidLook != (XIDLookupEnt *) TRUE))
{
XID_PRINT_AUX("DumpAllLocks", xidLook);
XID_PRINT("DumpAllLocks", xidLook);
if (xidLook->tag.lock)
{
lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
LOCK_PRINT_AUX("DumpAllLocks", lock, 0);
LOCK_PRINT("DumpAllLocks", lock, 0);
}
else
elog(DEBUG, "DumpAllLocks: xidLook->tag.lock = NULL");
@ -2102,4 +2022,4 @@ DumpAllLocks()
}
}
#endif
#endif /* LOCK_DEBUG */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.73 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.74 2000/05/31 00:28:30 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -47,7 +47,7 @@
* This is so that we can support more backends. (system-wide semaphore
* sets run out pretty fast.) -ay 4/95
*
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.73 2000/05/30 00:49:52 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.74 2000/05/31 00:28:30 petere Exp $
*/
#include <sys/time.h>
#include <unistd.h>
@ -66,13 +66,14 @@
/* In Ultrix and QNX, sem.h must be included after ipc.h */
#include <sys/sem.h>
#include "storage/lock.h"
#include "storage/proc.h"
void HandleDeadLock(SIGNAL_ARGS);
static void ProcFreeAllSemaphores(void);
static bool GetOffWaitqueue(PROC *);
#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
int DeadlockTimeout = 1000;
/* --------------------
* Spin lock for manipulating the shared process data structure:
@ -633,8 +634,8 @@ ins:;
* --------------
*/
MemSet(&timeval, 0, sizeof(struct itimerval));
timeval.it_value.tv_sec = \
(DeadlockCheckTimer ? DeadlockCheckTimer : DEADLOCK_CHECK_TIMER);
timeval.it_value.tv_sec = DeadlockTimeout / 1000;
timeval.it_value.tv_usec = (DeadlockTimeout % 1000) * 1000;
SetWaitingForLock(true);
do
@ -663,6 +664,7 @@ ins:;
* ---------------
*/
timeval.it_value.tv_sec = 0;
timeval.it_value.tv_usec = 0;
if (setitimer(ITIMER_REAL, &timeval, &dummy))
elog(FATAL, "ProcSleep: Unable to diable timer for process wakeup");
@ -675,7 +677,7 @@ ins:;
rt:;
#ifdef LOCK_MGR_DEBUG
#ifdef LOCK_DEBUG
/* Just to get meaningful debug messages from DumpLocks() */
MyProc->waitLock = (LOCK *) NULL;
#endif
@ -723,7 +725,6 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
{
PROC *proc;
int count = 0;
int trace_flag;
int last_locktype = 0;
int queue_size = queue->size;
@ -783,14 +784,13 @@ ProcLockWakeup(PROC_QUEUE *queue, LOCKMETHOD lockmethod, LOCK *lock)
else
{
/* Something is still blocking us. May have deadlocked. */
trace_flag = (lock->tag.lockmethod == USER_LOCKMETHOD) ? \
TRACE_USERLOCKS : TRACE_LOCKS;
TPRINTF(trace_flag,
"ProcLockWakeup: lock(%x) can't wake up any process",
MAKE_OFFSET(lock));
#ifdef DEADLOCK_DEBUG
if (pg_options[trace_flag] >= 2)
#ifdef LOCK_DEBUG
if (lock->tag.lockmethod == USER_LOCKMETHOD ? Trace_userlocks : Trace_locks)
{
elog(DEBUG, "ProcLockWakeup: lock(%lx) can't wake up any process", MAKE_OFFSET(lock));
if (Debug_deadlocks)
DumpAllLocks();
}
#endif
return STATUS_NOT_FOUND;
}
@ -803,7 +803,7 @@ ProcAddLock(SHM_QUEUE *elem)
}
/* --------------------
* We only get to this routine if we got SIGALRM after DEADLOCK_CHECK_TIMER
* We only get to this routine if we got SIGALRM after DeadlockTimeout
* while waiting for a lock to be released by some other process. If we have
* a real deadlock, we must also indicate that I'm no longer waiting
* on a lock so that other processes don't try to wake me up and screw
@ -852,8 +852,9 @@ HandleDeadLock(SIGNAL_ARGS)
return;
}
#ifdef DEADLOCK_DEBUG
DumpAllLocks();
#ifdef LOCK_DEBUG
if (Debug_deadlocks)
DumpAllLocks();
#endif
MyProc->errType = STATUS_NOT_FOUND;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.156 2000/05/29 05:45:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.157 2000/05/31 00:28:31 petere Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -58,40 +58,25 @@
#include "storage/proc.h"
#include "utils/ps_status.h"
#include "utils/temprel.h"
#include "utils/trace.h"
#include "utils/guc.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
/*
* Trace flags, see backend/utils/misc/trace.c
*/
#define Verbose pg_options[TRACE_VERBOSE]
#define DebugPrintQuery pg_options[TRACE_QUERY]
#define DebugPrintPlan pg_options[TRACE_PLAN]
#define DebugPrintParse pg_options[TRACE_PARSE]
#define DebugPrintRewrittenParsetree \
pg_options[TRACE_REWRITTEN]
#define DebugPPrintPlan pg_options[TRACE_PRETTY_PLAN]
#define DebugPPrintParse pg_options[TRACE_PRETTY_PARSE]
#define DebugPPrintRewrittenParsetree \
pg_options[TRACE_PRETTY_REWRITTEN]
#define ShowParserStats pg_options[TRACE_PARSERSTATS]
#define ShowPlannerStats pg_options[TRACE_PLANNERSTATS]
#define ShowExecutorStats pg_options[TRACE_EXECUTORSTATS]
#ifdef LOCK_MGR_DEBUG
#define LockDebug pg_options[TRACE_LOCKS]
#endif
#define DeadlockCheckTimer pg_options[OPT_DEADLOCKTIMEOUT]
#define HostnameLookup pg_options[OPT_HOSTLOOKUP]
#define ShowPortNumber pg_options[OPT_SHOWPORTNUMBER]
/* ----------------
* global variables
* ----------------
*/
/*
* XXX For ps display. That stuff needs to be cleaned up.
*/
bool HostnameLookup;
bool ShowPortNumber;
bool Log_connections = false;
CommandDest whereToSendOutput = Debug;
/* Define status buffer needed by PS_SET_STATUS */
@ -112,7 +97,6 @@ extern int lockingOff;
extern int NBuffers;
int dontExecute = 0;
static int ShowStats;
static bool IsEmptyQuery = false;
/* note: these declarations had better match tcopprot.h */
@ -155,6 +139,14 @@ static int InteractiveBackend(StringInfo inBuf);
static int SocketBackend(StringInfo inBuf);
static int ReadCommand(StringInfo inBuf);
static void pg_exec_query(char *query_string);
static void SigHupHandler(SIGNAL_ARGS);
/*
* Flag to mark SIGHUP. Whenever the main loop comes around it
* will reread the configuration file. (Better than doing the
* reading in the signal handler, ey?)
*/
static volatile bool got_SIGHUP = false;
/* ----------------------------------------------------------------
@ -240,11 +232,7 @@ InteractiveBackend(StringInfo inBuf)
}
if (end)
{
if (Verbose)
puts("EOF");
return EOF;
}
/* ----------------
* otherwise we have a user query so process it.
@ -380,21 +368,21 @@ pg_parse_and_rewrite(char *query_string, /* string to execute */
Query *querytree;
List *new_list;
if (DebugPrintQuery)
TPRINTF(TRACE_QUERY, "query: %s", query_string);
if (Debug_print_query)
elog(DEBUG, "query: %s", query_string);
/* ----------------
* (1) parse the request string into a list of parse trees
* ----------------
*/
if (ShowParserStats)
if (Show_parser_stats)
ResetUsage();
querytree_list = parser(query_string, typev, nargs);
if (ShowParserStats)
if (Show_parser_stats)
{
fprintf(stderr, "! Parser Stats:\n");
fprintf(StatFp, "PARSER STATISTICS\n");
ShowUsage();
}
@ -410,18 +398,15 @@ pg_parse_and_rewrite(char *query_string, /* string to execute */
{
querytree = (Query *) lfirst(querytree_list_item);
if (DebugPrintParse || DebugPPrintParse)
if (Debug_print_parse)
{
if (DebugPPrintParse)
if (Debug_pretty_print)
{
TPRINTF(TRACE_PRETTY_PARSE, "parser outputs:");
elog(DEBUG, "parse tree:");
nodeDisplay(querytree);
}
else
{
TPRINTF(TRACE_PARSE, "parser outputs:");
printf("\n%s\n\n", nodeToString(querytree));
}
elog(DEBUG, "parse tree: %s", nodeToString(querytree));
}
if (querytree->commandType == CMD_UTILITY)
@ -464,12 +449,11 @@ pg_parse_and_rewrite(char *query_string, /* string to execute */
}
}
if (DebugPrintRewrittenParsetree || DebugPPrintRewrittenParsetree)
if (Debug_print_rewritten)
{
if (DebugPPrintRewrittenParsetree)
if (Debug_pretty_print)
{
TPRINTF(TRACE_PRETTY_REWRITTEN, "after rewriting:");
elog(DEBUG, "rewritten parse tree:");
foreach(querytree_list_item, querytree_list)
{
querytree = (Query *) lfirst(querytree_list_item);
@ -479,12 +463,12 @@ pg_parse_and_rewrite(char *query_string, /* string to execute */
}
else
{
TPRINTF(TRACE_REWRITTEN, "after rewriting:");
elog(DEBUG, "rewritten parse tree:");
foreach(querytree_list_item, querytree_list)
{
querytree = (Query *) lfirst(querytree_list_item);
printf("\n%s\n\n", nodeToString(querytree));
elog(DEBUG, "%s", nodeToString(querytree));
}
}
}
@ -503,15 +487,15 @@ pg_plan_query(Query *querytree)
if (querytree->commandType == CMD_UTILITY)
return NULL;
if (ShowPlannerStats)
if (Show_planner_stats)
ResetUsage();
/* call that optimizer */
plan = planner(querytree);
if (ShowPlannerStats)
if (Show_planner_stats)
{
fprintf(stderr, "! Planner Stats:\n");
fprintf(stderr, "PLANNER STATISTICS\n");
ShowUsage();
}
@ -519,18 +503,15 @@ pg_plan_query(Query *querytree)
* Print plan if debugging.
* ----------------
*/
if (DebugPrintPlan || DebugPPrintPlan)
if (Debug_print_plan)
{
if (DebugPPrintPlan)
if (Debug_pretty_print)
{
TPRINTF(TRACE_PRETTY_PLAN, "plan:");
elog(DEBUG, "plan:");
nodeDisplay(plan);
}
else
{
TPRINTF(TRACE_PLAN, "plan:");
printf("\n%s\n\n", nodeToString(plan));
}
elog(DEBUG, "plan: %s", nodeToString(plan));
}
return plan;
@ -607,10 +588,10 @@ pg_exec_query_dest(char *query_string, /* string to execute */
* because that is done in ProcessUtility.
* ----------------
*/
if (DebugPrintQuery)
TPRINTF(TRACE_QUERY, "ProcessUtility: %s", query_string);
else if (Verbose)
TPRINTF(TRACE_VERBOSE, "ProcessUtility");
if (Debug_print_query)
elog(DEBUG, "ProcessUtility: %s", query_string);
else if (DebugLvl > 1)
elog(DEBUG, "ProcessUtility");
ProcessUtility(querytree->utilityStmt, dest);
}
@ -653,16 +634,16 @@ pg_exec_query_dest(char *query_string, /* string to execute */
/*
* execute the plan
*/
if (ShowExecutorStats)
if (Show_executor_stats)
ResetUsage();
if (Verbose)
TPRINTF(TRACE_VERBOSE, "ProcessQuery");
if (DebugLvl > 1)
elog(DEBUG, "ProcessQuery");
ProcessQuery(querytree, plan, dest);
if (ShowExecutorStats)
if (Show_executor_stats)
{
fprintf(stderr, "! Executor Stats:\n");
fprintf(stderr, "EXECUTOR STATISTICS\n");
ShowUsage();
}
}
@ -772,6 +753,12 @@ CancelQuery(void)
elog(ERROR, "Query was cancelled.");
}
static void
SigHupHandler(SIGNAL_ARGS)
{
got_SIGHUP = true;
}
static void
usage(char *progname)
@ -785,10 +772,7 @@ usage(char *progname)
fprintf(stderr, "\t-C \t\tsuppress version info\n");
fprintf(stderr, "\t-D dir\t\tdata directory\n");
fprintf(stderr, "\t-E \t\techo query before execution\n");
fprintf(stderr, "\t-F \t\tturn off fsync\n");
#ifdef LOCK_MGR_DEBUG
fprintf(stderr, "\t-K lev\t\tset locking debug level [0|1|2]\n");
#endif
fprintf(stderr, "\t-F \t\tturn fsync off\n");
fprintf(stderr, "\t-L \t\tturn off locking\n");
fprintf(stderr, "\t-N \t\tdon't use newline as interactive query delimiter\n");
fprintf(stderr, "\t-O \t\tallow system table structure changes\n");
@ -844,27 +828,19 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* Set default values for command-line options.
*/
IsUnderPostmaster = false;
ShowStats = 0;
ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
DeadlockCheckTimer = DEADLOCK_CHECK_TIMER;
Noversion = false;
EchoQuery = false;
#ifdef LOCK_MGR_DEBUG
LockDebug = 0;
#endif
DataDir = getenv("PGDATA");
StatFp = stderr;
SetProcessingMode(InitProcessing);
/* Check for PGDATESTYLE environment variable */
set_default_datestyle();
/*
* Read default pg_options from file $DATADIR/pg_options.
*/
if (DataDir)
read_pg_options(0);
/* ----------------
* parse command line arguments
*
@ -884,9 +860,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
optind = 1; /* reset after postmaster's usage */
while ((flag = getopt(argc, argv,
"A:B:CD:d:EeFf:iK:LNOPo:p:QS:sT:t:v:W:x:"))
!= EOF)
while ((flag = getopt(argc, argv, "A:B:CD:d:Eef:FiLNOPo:p:S:st:v:W:x:-:")) != EOF)
switch (flag)
{
case 'A':
@ -920,29 +894,21 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
case 'D': /* PGDATA directory */
if (secure)
{
if (!DataDir)
{
DataDir = optarg;
/* must be done after DataDir is defined */
read_pg_options(0);
}
DataDir = optarg;
}
break;
case 'd': /* debug level */
DebugLvl = atoi(optarg);
if (DebugLvl >= 1)
Verbose = true;
if (DebugLvl >= 1);
Log_connections = true;
if (DebugLvl >= 2)
DebugPrintQuery = true;
Debug_print_query = true;
if (DebugLvl >= 3)
DebugPrintParse = true;
Debug_print_parse = true;
if (DebugLvl >= 4)
DebugPrintPlan = true;
Debug_print_plan = true;
if (DebugLvl >= 5)
DebugPPrintRewrittenParsetree = true;
Debug_print_rewritten = true;
break;
case 'E':
@ -970,7 +936,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* to be "if (secure)".
* --------------------
*/
disableFsync = true;
enableFsync = false;
break;
case 'f':
@ -1007,14 +973,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
dontExecute = 1;
break;
case 'K':
#ifdef LOCK_MGR_DEBUG
LockDebug = atoi(optarg);
#else
fprintf(stderr, "Lock debug not compiled in\n");
#endif
break;
case 'L':
/* --------------------
* turn off locking
@ -1074,14 +1032,6 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
}
break;
case 'Q':
/* ----------------
* Q - set Quiet mode (reduce debugging output)
* ----------------
*/
Verbose = false;
break;
case 'S':
/* ----------------
* S - amount of sort memory to use in 1k bytes
@ -1101,15 +1051,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* s - report usage statistics (timings) after each query
* ----------------
*/
ShowStats = 1;
break;
case 'T':
/* ----------------
* T - tracing options
* ----------------
*/
parse_options(optarg, secure);
Show_query_stats = 1;
break;
case 't':
@ -1127,14 +1069,14 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
{
case 'p':
if (optarg[1] == 'a')
ShowParserStats = 1;
Show_parser_stats = 1;
else if (optarg[1] == 'l')
ShowPlannerStats = 1;
Show_planner_stats = 1;
else
errs++;
break;
case 'e':
ShowExecutorStats = 1;
Show_executor_stats = 1;
break;
default:
errs++;
@ -1188,6 +1130,23 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
#endif
break;
case '-':
{
/* A little 'long argument' simulation */
/* (copy&pasted from PostmasterMain() */
size_t equal_pos = strcspn(optarg, "=");
char *cp;
if (optarg[equal_pos] != '=')
elog(ERROR, "--%s requires argument", optarg);
optarg[equal_pos] = '\0';
for(cp = optarg; *cp; cp++)
if (*cp == '-')
*cp = '_';
SetConfigOption(optarg, optarg + equal_pos + 1, PGC_BACKEND);
break;
}
default:
/* ----------------
* default: bad command line option
@ -1197,11 +1156,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
break;
}
if (ShowStats &&
(ShowParserStats || ShowPlannerStats || ShowExecutorStats))
if (Show_query_stats &&
(Show_parser_stats || Show_planner_stats || Show_executor_stats))
{
fprintf(stderr, "-s can not be used together with -t.\n");
proc_exit(0);
elog(NOTICE, "Query statistics are disabled because parser, planner, or executor statistics are on.");
Show_query_stats = false;
}
if (!DataDir)
@ -1233,7 +1192,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
BlockSig &= ~(sigmask(SIGUSR1));
#endif
pqsignal(SIGHUP, read_pg_options); /* update pg_options from file */
pqsignal(SIGHUP, SigHupHandler); /* set flag to read config file */
pqsignal(SIGINT, QueryCancelHandler); /* cancel current query */
pqsignal(SIGQUIT, handle_warn); /* handle error */
pqsignal(SIGTERM, die);
@ -1373,53 +1332,22 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
PS_SET_STATUS("startup");
}
/* ----------------
* print flags
* ----------------
*/
if (Verbose)
{
if (Verbose)
{
TPRINTF(TRACE_VERBOSE, "started: host=%s user=%s database=%s",
remote_host, userName, DBName);
}
else
{
TPRINTF(TRACE_VERBOSE, "debug info:");
TPRINTF(TRACE_VERBOSE, "\tUser = %s", userName);
TPRINTF(TRACE_VERBOSE, "\tRemoteHost = %s", remote_host);
TPRINTF(TRACE_VERBOSE, "\tRemotePort = %d", remote_port);
TPRINTF(TRACE_VERBOSE, "\tDatabaseName = %s", DBName);
TPRINTF(TRACE_VERBOSE, "\tDebug Level = %d", DebugLvl);
TPRINTF(TRACE_VERBOSE, "\tNoversion = %c", Noversion ? 't' : 'f');
TPRINTF(TRACE_VERBOSE, "\ttimings = %c", ShowStats ? 't' : 'f');
TPRINTF(TRACE_VERBOSE, "\tdates = %s",
EuroDates ? "European" : "Normal");
TPRINTF(TRACE_VERBOSE, "\tbufsize = %d", NBuffers);
TPRINTF(TRACE_VERBOSE, "\tsortmem = %d", SortMem);
TPRINTF(TRACE_VERBOSE, "\tquery echo = %c", EchoQuery ? 't' : 'f');
}
}
if (Log_connections)
elog(DEBUG, "connection: host=%s user=%s database=%s",
remote_host, userName, DBName);
/*
* general initialization
*/
if (Verbose)
TPRINTF(TRACE_VERBOSE, "InitPostgres");
if (DebugLvl > 1)
elog(DEBUG, "InitPostgres");
InitPostgres(DBName);
#ifdef MULTIBYTE
/* set default client encoding */
if (Verbose)
TPRINTF(TRACE_VERBOSE, "reset_client_encoding()..");
if (DebugLvl > 1)
elog(DEBUG, "reset_client_encoding");
reset_client_encoding();
if (Verbose)
TPRINTF(TRACE_VERBOSE, "reset_client_encoding() done.");
#endif
on_shmem_exit(remove_all_temp_relations, NULL);
@ -1450,7 +1378,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.156 $ $Date: 2000/05/29 05:45:16 $\n");
puts("$Revision: 1.157 $ $Date: 2000/05/31 00:28:31 $\n");
}
/*
@ -1473,9 +1401,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
/* Make sure we are in a valid memory context */
MemoryContextSwitchTo(TopMemoryContext);
if (Verbose)
TPRINTF(TRACE_VERBOSE, "AbortCurrentTransaction");
if (DebugLvl >= 1)
elog(DEBUG, "AbortCurrentTransaction");
AbortCurrentTransaction();
InError = false;
if (ExitAfterAbort)
@ -1497,6 +1424,14 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
{
PS_SET_STATUS("idle");
/* XXX this could be moved after ReadCommand below to get more
* sensical behaviour */
if (got_SIGHUP)
{
got_SIGHUP = false;
ProcessConfigFile(PGC_SIGHUP);
}
/* ----------------
* (1) tell the frontend we're ready for a new query.
*
@ -1516,7 +1451,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
EnableNotifyInterrupt();
/* ----------------
* (3) read a command.
* (3) read a command (loop blocks here)
* ----------------
*/
firstchar = ReadCommand(parser_input);
@ -1544,8 +1479,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
IsEmptyQuery = false;
/* start an xact for this function invocation */
if (Verbose)
TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
if (DebugLvl >= 1)
elog(DEBUG, "StartTransactionCommand");
StartTransactionCommand();
if (HandleFunctionRequest() == EOF)
@ -1577,12 +1512,12 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
* ----------------
*/
IsEmptyQuery = false;
if (ShowStats)
if (Show_query_stats)
ResetUsage();
/* start an xact for this query */
if (Verbose)
TPRINTF(TRACE_VERBOSE, "StartTransactionCommand");
if (DebugLvl >= 1)
elog(DEBUG, "StartTransactionCommand");
StartTransactionCommand();
pg_exec_query(parser_input->data);
@ -1593,8 +1528,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
*/
DeferredTriggerEndQuery();
if (ShowStats)
if (Show_query_stats)
{
fprintf(StatFp, "QUERY STATISTICS\n");
ShowUsage();
}
}
break;
@ -1625,8 +1563,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
*/
if (!IsEmptyQuery)
{
if (Verbose)
TPRINTF(TRACE_VERBOSE, "CommitTransactionCommand");
if (DebugLvl >= 1)
elog(DEBUG, "CommitTransactionCommand");
PS_SET_STATUS("commit");
CommitTransactionCommand();
#ifdef SHOW_MEMORY_STATS

View File

@ -8,19 +8,19 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.17 2000/01/26 05:57:20 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/assert.c,v 1.18 2000/05/31 00:28:31 petere Exp $
*
* NOTE
* This should eventually work with elog(), dlog(), etc.
*
*-------------------------------------------------------------------------
*/
#include <unistd.h>
#include "postgres.h"
#include <stdio.h>
#include <unistd.h>
#include "utils/exc.h"
#include "utils/trace.h"
int
ExceptionalCondition(char *conditionName,
@ -39,7 +39,7 @@ ExceptionalCondition(char *conditionName,
|| !PointerIsValid(fileName)
|| !PointerIsValid(exceptionP))
{
EPRINTF("TRAP: ExceptionalCondition: bad arguments\n");
fprintf(stderr, "TRAP: ExceptionalCondition: bad arguments\n");
ExcAbort(exceptionP,
(ExcDetail) detail,
@ -48,7 +48,7 @@ ExceptionalCondition(char *conditionName,
}
else
{
EPRINTF("TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
fprintf(stderr, "TRAP: %s(\"%s:%s\", File: \"%s\", Line: %d)\n",
exceptionP->message, conditionName,
(detail == NULL ? "" : detail),
fileName, lineNumber);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.58 2000/05/30 00:49:55 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.59 2000/05/31 00:28:32 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -24,8 +24,10 @@
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#include <sys/time.h>
#include <ctype.h>
#ifdef ENABLE_SYSLOG
# include <syslog.h>
#endif
#include "libpq/libpq.h"
@ -40,20 +42,31 @@ extern int sys_nerr;
extern CommandDest whereToSendOutput;
#ifdef USE_SYSLOG
#ifdef ENABLE_SYSLOG
/*
* Global option to control the use of syslog(3) for logging:
*
* 0 stdout/stderr only
* 1 stdout/stderr + syslog
* 2 syslog only
* 0 = only stdout/stderr
* 1 = stdout+stderr and syslog
* 2 = syslog only
* ... in theory anyway
*/
#define UseSyslog pg_options[OPT_SYSLOG]
#define PG_LOG_FACILITY LOG_LOCAL0
int Use_syslog = 0;
static void write_syslog(int level, const char *line);
#else
#define UseSyslog 0
# define Use_syslog 0
#endif
#ifdef ELOG_TIMESTAMPS
static const char * print_timestamp(void);
# define TIMESTAMP_SIZE 28
#else
# define TIMESTAMP_SIZE 0
#endif
static int Debugfile = -1;
static int Err_file = -1;
static int ElogDebugIndentLevel = 0;
@ -182,7 +195,7 @@ elog(int lev, const char *fmt,...)
}
}
#ifdef ELOG_TIMESTAMPS
strcpy(fmt_buf, tprintf_timestamp());
strcpy(fmt_buf, print_timestamp());
strcat(fmt_buf, prefix);
#else
strcpy(fmt_buf, prefix);
@ -265,7 +278,7 @@ elog(int lev, const char *fmt,...)
msg_buf = msg_fixedbuf;
lev = REALLYFATAL;
#ifdef ELOG_TIMESTAMPS
strcpy(msg_buf, tprintf_timestamp());
strcpy(msg_buf, print_timestamp());
strcat(msg_buf, "FATAL: elog: out of memory");
#else
strcpy(msg_buf, "FATAL: elog: out of memory");
@ -278,35 +291,43 @@ elog(int lev, const char *fmt,...)
* Message prepared; send it where it should go
*/
#ifdef USE_SYSLOG
switch (lev)
#ifdef ENABLE_SYSLOG
if (Use_syslog >= 1)
{
case NOIND:
log_level = LOG_DEBUG;
break;
case DEBUG:
log_level = LOG_DEBUG;
break;
case NOTICE:
log_level = LOG_NOTICE;
break;
case ERROR:
log_level = LOG_WARNING;
break;
case FATAL:
default:
log_level = LOG_ERR;
break;
int syslog_level;
switch (lev)
{
case NOIND:
syslog_level = LOG_DEBUG;
break;
case DEBUG:
syslog_level = LOG_DEBUG;
break;
case NOTICE:
syslog_level = LOG_NOTICE;
break;
case ERROR:
syslog_level = LOG_WARNING;
break;
case FATAL:
syslog_level = LOG_ERR;
break;
case REALLYFATAL:
default:
syslog_level = LOG_CRIT;
}
write_syslog(syslog_level, msg_buf + TIMESTAMP_SIZE);
}
write_syslog(log_level, msg_buf + TIMESTAMP_SIZE);
#endif
#endif /* ENABLE_SYSLOG */
/* syslog doesn't want a trailing newline, but other destinations do */
strcat(msg_buf, "\n");
len = strlen(msg_buf);
if (Debugfile >= 0 && UseSyslog <= 1)
if (Debugfile >= 0 && Use_syslog <= 1)
write(Debugfile, msg_buf, len);
/*
@ -321,7 +342,7 @@ elog(int lev, const char *fmt,...)
* does anyone still use ultrix?)
*/
if (lev > DEBUG && Err_file >= 0 &&
Debugfile != Err_file && UseSyslog <= 1)
Debugfile != Err_file && Use_syslog <= 1)
{
if (write(Err_file, msg_buf, len) < 0)
{
@ -502,3 +523,124 @@ DebugFileOpen(void)
}
#endif
#ifdef ELOG_TIMESTAMPS
/*
* Return a timestamp string like "980119.17:25:59.902 [21974] "
*/
static const char *
print_timestamp()
{
struct timeval tv;
struct timezone tz = { 0, 0 };
struct tm *time;
time_t tm;
static char timestamp[32],
pid[8];
gettimeofday(&tv, &tz);
tm = tv.tv_sec;
time = localtime(&tm);
sprintf(pid, "[%d]", MyProcPid);
sprintf(timestamp, "%02d%02d%02d.%02d:%02d:%02d.%03d %7s ",
time->tm_year % 100, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec,
(int) (tv.tv_usec/1000), pid);
return timestamp;
}
#endif
#ifdef ENABLE_SYSLOG
/*
* Write a message line to syslog if the syslog option is set.
*
* Our problem here is that many syslog implementations don't handle
* long messages in an acceptable manner. While this function doesn't
* help that fact, it does work around by splitting up messages into
* smaller pieces.
*/
static void
write_syslog(int level, const char *line)
{
#ifndef PG_SYSLOG_LIMIT
# define PG_SYSLOG_LIMIT 128
#endif
static bool openlog_done = false;
static unsigned long seq = 0;
int len = strlen(line);
if (Use_syslog == 0)
return;
if (!openlog_done)
{
openlog("postgres", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
openlog_done = true;
}
/*
* We add a sequence number to each log message to suppress "same"
* messages.
*/
seq++;
/* divide into multiple syslog() calls if message is too long */
if (len > PG_SYSLOG_LIMIT)
{
static char buf[PG_SYSLOG_LIMIT+1];
int chunk_nr = 0;
int buflen;
while (len > 0)
{
int l;
int i;
strncpy(buf, line, PG_SYSLOG_LIMIT);
buf[PG_SYSLOG_LIMIT] = '\0';
l = strlen(buf);
#ifdef MULTIBYTE
/* trim to multibyte letter boundary */
buflen = pg_mbcliplen(buf, l, l);
buf[buflen] = '\0';
l = strlen(buf);
#endif
/* already word boundary? */
if (isspace(line[l]) || line[l] == '\0')
buflen = l;
else
{
/* try to divide in word boundary */
i = l - 1;
while(i > 0 && !isspace(buf[i]))
i--;
if (i <= 0) /* couldn't divide word boundary */
buflen = l;
else
{
buflen = i;
buf[i] = '\0';
}
}
chunk_nr++;
syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
line += buflen;
len -= buflen;
}
}
/* message short enough */
else
syslog(level, "[%lu] %s", seq, line);
}
#endif /* ENABLE_SYSLOG */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.44 2000/05/30 00:49:56 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.45 2000/05/31 00:28:32 petere Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
@ -77,8 +77,11 @@ char DateFormat[20] = "%d-%m-%Y"; /* mjl: sizes! or better
* malloc? XXX */
char FloatFormat[20] = "%f";
bool enableFsync = true;
bool allowSystemTableMods = false;
int SortMem = 512;
int NBuffers = DEF_NBUFFERS;
char *IndexedCatalogNames[] = {
AttributeRelationName,

View File

@ -4,27 +4,38 @@
# Makefile for utils/misc
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.13 2000/05/29 05:45:37 tgl Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/misc/Makefile,v 1.14 2000/05/31 00:28:34 petere Exp $
#
#-------------------------------------------------------------------------
SRCDIR = ../../..
include ../../../Makefile.global
OBJS = database.o superuser.o trace.o
OBJS = database.o superuser.o guc.o guc-file.o
all: SUBSYS.o
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
.SECONDARY: guc-file.c
.INTERMEDIATE: lex.yy.c
guc-file.c: lex.yy.c
sed -e 's/lex\.yy\.c/guc-file\.c/g' \
-e 's/^yy/GUC_yy/g' \
-e 's/\([^a-zA-Z0-9_]\)yy/\1GUC_yy/g' < $< > $@
lex.yy.c: guc-file.l
$(LEX) $(LFLAGS) $<
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
clean:
rm -f SUBSYS.o $(OBJS)
rm -f SUBSYS.o $(OBJS) lex.yy.c
ifeq (depend,$(wildcard depend))
include depend
endif

View File

@ -0,0 +1,282 @@
/* -*-pgsql-c-*- */
/*
* Scanner for the configuration file
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc-file.l,v 1.1 2000/05/31 00:28:34 petere Exp $
*/
%{
#include "postgres.h"
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/elog.h"
#include "utils/guc.h"
static unsigned ConfigFileLineno;
enum {
GUC_ID = 1,
GUC_STRING = 2,
GUC_INTEGER = 3,
GUC_REAL = 4,
GUC_EQUALS = 5,
GUC_EOL = 99,
GUC_ERROR = 100,
};
#if defined(yywrap)
#undef yywrap
#endif /* yywrap */
#define YY_USER_INIT (ConfigFileLineno = 1)
#define YY_NO_UNPUT
%}
SIGN ("-"|"+")
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+)
EXPONENT [Ee]{SIGN}?{DIGIT}+
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
LETTER [A-Za-z_\200-\377]
LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
ID {LETTER}{LETTER_OR_DIGIT}*
/*
* FIXME: This string syntax is nice and all but of course the quotes
* need to be stripped before we can make any use of the string value.
* There is a function in parser/scansup.c that does this but it uses
* palloc and there might be a little more magic needed to get it to
* work right. Now there are no string options, and if there were then
* the unquoted (`ID') tokens should still work. Of course this only
* affects the configuration file.
*/
STRING \'([^'\n]|\\.)*'
%%
\n ConfigFileLineno++; return GUC_EOL;
[ \t\r]+ /* eat whitespace */
#.*$ /* eat comment */
{ID} return GUC_ID;
{STRING} return GUC_STRING;
{INTEGER} return GUC_INTEGER;
{REAL} return GUC_REAL;
= return GUC_EQUALS;
. return GUC_ERROR;
%%
struct name_value_pair
{
char *name;
char *value;
struct name_value_pair *next;
};
/*
* Free a list of name/value pairs, including the names and the values
*/
static void
free_name_value_list(struct name_value_pair * list)
{
struct name_value_pair *item;
item = list;
while (item)
{
struct name_value_pair *save;
save = item->next;
free(item->name);
free(item->value);
free(item);
item = save;
}
}
/*
* Official function to read and process the configuration file. The
* parameter indicates in what context the file is being read
* (postmaster startup, backend startup, or SIGHUP). All options
* mentioned in the configuration file are set to new values. This
* function does not return if an error occurs. If an error occurs, no
* values will be changed.
*/
void
ProcessConfigFile(unsigned int context)
{
int token, parse_state;
char *opt_name, *opt_value;
char *filename;
struct stat stat_buf;
struct name_value_pair *item, *head, *tail;
int elevel;
FILE * fp;
Assert(context == PGC_POSTMASTER || context == PGC_BACKEND || context == PGC_SIGHUP);
Assert(DataDir);
elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR;
/*
* Open file
*/
filename = malloc(strlen(DataDir) + 16);
if (filename == NULL)
{
elog(elevel, "out of memory");
return;
}
sprintf(filename, "%s/configuration", DataDir);
fp = AllocateFile(filename, "r");
if (!fp)
{
free(filename);
/* File not found is fine */
if (errno != ENOENT)
elog(elevel, "could not read configuration: %s", strerror(errno));
return;
}
/*
* Check if the file is group or world writeable. If so, reject.
*/
if (fstat(fileno(fp), &stat_buf) == -1)
{
FreeFile(fp);
free(filename);
elog(elevel, "could not stat configuration file: %s", strerror(errno));
return;
}
if (stat_buf.st_mode & (S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH))
{
FreeFile(fp);
free(filename);
elog(elevel, "configuration file has wrong permissions");
return;
}
/*
* Parse
*/
yyin = fp;
parse_state = 0;
head = tail = NULL;
opt_name = opt_value = NULL;
while((token = yylex()))
switch(parse_state)
{
case 0: /* no previous input */
if (token == GUC_EOL) /* empty line */
continue;
if (token != GUC_ID)
goto parse_error;
opt_name = strdup(yytext);
if (opt_name == NULL)
goto out_of_memory;
parse_state = 1;
break;
case 1: /* found name */
/* ignore equals sign */
if (token == GUC_EQUALS)
token = yylex();
if (token != GUC_ID && token != GUC_STRING && token != GUC_INTEGER && token != GUC_REAL)
goto parse_error;
opt_value = strdup(yytext);
if (opt_value == NULL)
goto out_of_memory;
parse_state = 2;
break;
case 2: /* now we'd like an end of line */
if (token != GUC_EOL)
goto parse_error;
/* append to list */
item = malloc(sizeof *item);
if (item == NULL)
goto out_of_memory;
item->name = opt_name;
item->value = opt_value;
item->next = NULL;
if (!head)
tail = head = item;
else
{
tail->next = item;
tail = item;
}
parse_state = 0;
break;
}
FreeFile(fp);
free(filename);
/*
* Check if all options are valid
*/
for(item = head; item; item=item->next)
{
if (!set_config_option(item->name, item->value, context, false))
goto cleanup_exit;
}
/* If we got here all the options parsed okay. */
for(item = head; item; item=item->next)
set_config_option(item->name, item->value, context, true);
cleanup_exit:
free_name_value_list(head);
return;
parse_error:
FreeFile(fp);
free(filename);
free_name_value_list(head);
elog(elevel, "%s:%u: syntax error (ps:%d, t:%d)", filename,
ConfigFileLineno, parse_state, token);
return;
out_of_memory:
FreeFile(fp);
free(filename);
free_name_value_list(head);
elog(elevel, "out of memory");
return;
}
int
yywrap(void)
{
return 1;
}

View File

@ -0,0 +1,692 @@
/*--------------------------------------------------------------------
* guc.c
*
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.1 2000/05/31 00:28:34 petere Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*--------------------------------------------------------------------
*/
#include "postgres.h"
#include <errno.h>
#include <float.h>
#include <limits.h>
#include <unistd.h>
#include "utils/guc.h"
#include "access/transam.h"
#include "commands/async.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
#include "optimizer/paths.h"
#include "optimizer/planmain.h"
#include "parser/parse_expr.h"
#include "storage/fd.h"
#include "storage/lock.h"
#include "storage/proc.h"
#include "storage/spin.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/elog.h"
/* XXX should be in a header file */
extern bool Log_connections;
/*
* Debugging options
*/
bool Debug_print_query = false;
bool Debug_print_plan = false;
bool Debug_print_parse = false;
bool Debug_print_rewritten = false;
bool Debug_pretty_print = false;
bool Show_parser_stats = false;
bool Show_planner_stats = false;
bool Show_executor_stats = false;
bool Show_query_stats = false; /* this is sort of all three above together */
bool Show_btree_build_stats = false;
enum config_type
{
PGC_NONE = 0,
PGC_BOOL,
PGC_INT,
PGC_REAL,
PGC_STRING
};
struct config_generic
{
const char *name;
GucContext context;
void *variable;
};
struct config_bool
{
const char *name;
GucContext context;
bool *variable;
bool default_val;
};
struct config_int
{
const char *name;
GucContext context;
int *variable;
int default_val;
int min;
int max;
};
struct config_real
{
const char *name;
GucContext context;
double *variable;
double default_val;
double min;
double max;
};
/*
* String value options are allocated with strdup, not with the
* pstrdup/palloc mechanisms. That is because configuration settings
* are already in place before the memory subsystem is up. It would
* perhaps be an idea to change that sometime.
*/
struct config_string
{
const char *name;
GucContext context;
char *variable;
const char *default_val;
bool (*parse_hook)(const char *);
};
/******** option names follow ********/
static struct config_bool
ConfigureNamesBool[] =
{
{"enable_seqscan", PGC_USERSET, &enable_seqscan, true},
{"enable_indexscan", PGC_USERSET, &enable_indexscan, true},
{"enable_tidscan", PGC_USERSET, &enable_tidscan, true},
{"enable_sort", PGC_USERSET, &enable_sort, true},
{"enable_nestloop", PGC_USERSET, &enable_nestloop, true},
{"enable_mergejoin", PGC_USERSET, &enable_mergejoin, true},
{"enable_hashjoin", PGC_USERSET, &enable_hashjoin, true},
{"ksqo", PGC_USERSET, &_use_keyset_query_optimizer, false},
{"geqo", PGC_USERSET, &enable_geqo, true},
{"net_server", PGC_POSTMASTER, &NetServer, false},
{"fsync", PGC_POSTMASTER, &enableFsync, true},
{"log_connections", PGC_POSTMASTER, &Log_connections, false},
{"debug_print_query", PGC_SUSET, &Debug_print_query, false},
{"debug_print_parse", PGC_SUSET, &Debug_print_parse, false},
{"debug_print_rewritten", PGC_SUSET, &Debug_print_rewritten, false},
{"debug_print_plan", PGC_SUSET, &Debug_print_plan, false},
{"debug_pretty_print", PGC_SUSET, &Debug_pretty_print, false},
{"show_parser_stats", PGC_SUSET, &Show_parser_stats, false},
{"show_planner_stats", PGC_SUSET, &Show_planner_stats, false},
{"show_executor_stats", PGC_SUSET, &Show_executor_stats, false},
{"show_query_stats", PGC_SUSET, &Show_query_stats, false},
#ifdef BTREE_BUILD_STATS
{"show_btree_build_stats", PGC_SUSET, &Show_btree_build_stats, false},
#endif
{"trace_notify", PGC_SUSET, &Trace_notify, false},
#ifdef LOCK_DEBUG
{"trace_locks", PGC_SUSET, &Trace_locks, false},
{"trace_userlocks", PGC_SUSET, &Trace_userlocks, false},
{"trace_spinlocks", PGC_SUSET, &Trace_spinlocks, false},
{"debug_deadlocks", PGC_SUSET, &Debug_deadlocks, false},
#endif
{"hostlookup", PGC_POSTMASTER, &HostnameLookup, false},
{"showportnumber", PGC_POSTMASTER, &ShowPortNumber, false},
{NULL, 0, NULL, false}
};
static struct config_int
ConfigureNamesInt[] =
{
{"geqo_rels", PGC_USERSET, &geqo_rels,
DEFAULT_GEQO_RELS, 2, INT_MAX},
{"geqo_pool_size", PGC_USERSET, &Geqo_pool_size,
DEFAULT_GEQO_POOL_SIZE, 0, MAX_GEQO_POOL_SIZE},
{"geqo_effort", PGC_USERSET, &Geqo_effort,
1, 1, INT_MAX},
{"geqo_generations", PGC_USERSET, &Geqo_generations,
0, 0, INT_MAX},
{"geqo_random_seed", PGC_USERSET, &Geqo_random_seed,
-1, INT_MIN, INT_MAX},
{"deadlock_timeout", PGC_POSTMASTER, &DeadlockTimeout,
1000, 0, INT_MAX},
#ifdef ENABLE_SYSLOG
{"syslog", PGC_POSTMASTER, &Use_syslog,
0, 0, 2},
#endif
/*
* Note: There is some postprocessing done in PostmasterMain() to
* make sure the buffers are at least twice the number of
* backends, so the constraints here are partially unused.
*/
{"max_backends", PGC_POSTMASTER, &MaxBackends,
DEF_MAXBACKENDS, 1, MAXBACKENDS},
{"shmem_buffers", PGC_POSTMASTER, &NBuffers,
DEF_NBUFFERS, 16, INT_MAX},
{"port", PGC_POSTMASTER, &PostPortName,
DEF_PGPORT, 1, 65535},
/* XXX Is this really changeable at runtime? */
{"sort_mem", PGC_SUSET, &SortMem,
512, 1, INT_MAX},
{"debug_level", PGC_SUSET, &DebugLvl,
0, 0, 16},
#ifdef LOCK_DEBUG
{"trace_lock_oidmin", PGC_SUSET, &Trace_lock_oidmin,
BootstrapObjectIdData, 1, INT_MAX},
{"trace_lock_table", PGC_SUSET, &Trace_lock_table,
0, 0, INT_MAX},
#endif
{"max_expr_depth", PGC_USERSET, &max_expr_depth,
DEFAULT_MAX_EXPR_DEPTH, 10, INT_MAX},
{NULL, 0, NULL, 0, 0, 0}
};
static struct config_real
ConfigureNamesReal[] =
{
{"effective_cache_size", PGC_USERSET, &effective_cache_size,
DEFAULT_EFFECTIVE_CACHE_SIZE, 0, DBL_MAX},
{"random_page_cost", PGC_USERSET, &random_page_cost,
DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX},
{"cpu_tuple_cost", PGC_USERSET, &cpu_tuple_cost,
DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX},
{"cpu_index_tuple_cost", PGC_USERSET, &cpu_index_tuple_cost,
DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX},
{"cpu_operator_cost", PGC_USERSET, &cpu_operator_cost,
DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX},
{"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias,
DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS},
{NULL, 0, NULL, 0.0, 0.0, 0.0}
};
static struct config_string
ConfigureNamesString[] =
{
/* none so far */
{NULL, 0, NULL, NULL, NULL}
};
/******** end of options list ********/
/*
* Look up option NAME. If it exists, return it's data type, else
* PGC_NONE (zero). If record is not NULL, store the description of
* the option there.
*/
static enum config_type
find_option(const char * name, struct config_generic ** record)
{
int i;
Assert(name);
for (i = 0; ConfigureNamesBool[i].name; i++)
if (strcasecmp(ConfigureNamesBool[i].name, name)==0)
{
if (record)
*record = (struct config_generic *)&ConfigureNamesBool[i];
return PGC_BOOL;
}
for (i = 0; ConfigureNamesInt[i].name; i++)
if (strcasecmp(ConfigureNamesInt[i].name, name)==0)
{
if (record)
*record = (struct config_generic *)&ConfigureNamesInt[i];
return PGC_INT;
}
for (i = 0; ConfigureNamesReal[i].name; i++)
if (strcasecmp(ConfigureNamesReal[i].name, name)==0)
{
if (record)
*record = (struct config_generic *)&ConfigureNamesReal[i];
return PGC_REAL;
}
for (i = 0; ConfigureNamesString[i].name; i++)
if (strcasecmp(ConfigureNamesString[i].name, name)==0)
{
if (record)
*record = (struct config_generic *)&ConfigureNamesString[i];
return PGC_REAL;
}
return PGC_NONE;
}
/*
* Reset all options to their specified default values. Should only be
* called at program startup.
*/
void
ResetAllOptions(void)
{
int i;
for (i = 0; ConfigureNamesBool[i].name; i++)
*(ConfigureNamesBool[i].variable) = ConfigureNamesBool[i].default_val;
for (i = 0; ConfigureNamesInt[i].name; i++)
*(ConfigureNamesInt[i].variable) = ConfigureNamesInt[i].default_val;
for (i = 0; ConfigureNamesReal[i].name; i++)
*(ConfigureNamesReal[i].variable) = ConfigureNamesReal[i].default_val;
for (i = 0; ConfigureNamesString[i].name; i++)
{
char * str = NULL;
if (ConfigureNamesString[i].default_val)
{
str = strdup(ConfigureNamesString[i].default_val);
if (str == NULL)
elog(ERROR, "out of memory");
}
ConfigureNamesString[i].variable = str;
}
}
/*
* Try to interpret value as boolean value. Valid values are: true,
* false, yes, no, on, off, 1, 0. If the string parses okay, return
* true, else false. If result is not NULL, return the parsing result
* there.
*/
static bool
parse_bool(const char * value, bool * result)
{
size_t len = strlen(value);
if (strncasecmp(value, "true", len)==0)
{
if (result)
*result = true;
}
else if (strncasecmp(value, "false", len)==0)
{
if (result)
*result = false;
}
else if (strncasecmp(value, "yes", len)==0)
{
if (result)
*result = true;
}
else if (strncasecmp(value, "no", len)==0)
{
if (result)
*result = false;
}
else if (strcasecmp(value, "on")==0)
{
if (result)
*result = true;
}
else if (strcasecmp(value, "off")==0)
{
if (result)
*result = false;
}
else if (strcasecmp(value, "1")==0)
{
if (result)
*result = true;
}
else if (strcasecmp(value, "0")==0)
{
if (result)
*result = false;
}
else
return false;
return true;
}
/*
* Try to parse value as an integer. The accepted formats are the
* usual decimal, octal, or hexadecimal formats. If the string parses
* okay, return true, else false. If result is not NULL, return the
* value there.
*/
static bool
parse_int(const char * value, int * result)
{
long val;
char * endptr;
errno = 0;
val = strtol(value, &endptr, 0);
if (endptr == value || *endptr != '\0' || errno == ERANGE)
return false;
if (result)
*result = (int)val;
return true;
}
/*
* Try to parse value as a floating point constant in the usual
* format. If the value parsed okay return true, else false. If
* result is not NULL, return the semantic value there.
*/
static bool
parse_real(const char * value, double * result)
{
double val;
char * endptr;
errno = 0;
val = strtod(value, &endptr);
if (endptr == value || *endptr != '\0' || errno == ERANGE)
return false;
if (result)
*result = val;
return true;
}
/*
* Sets option `name' to given value. The value should be a string
* which is going to be parsed and converted to the appropriate data
* type. Parameter context should indicate in which context this
* function is being called so it can apply the access restrictions
* properly.
*
* If value is NULL, set the option to its default value. If the
* parameter DoIt is false then don't really set the option but do all
* the checks to see if it would work.
*
* If there is an error (non-existing option, invalid value) then an
* elog(ERROR) is thrown *unless* this is called as part of the
* configuration file re-read in the SIGHUP handler, in which case we
* simply write the error message via elog(DEBUG) and return false. In
* all other cases the function returns true. This is working around
* the deficiencies in the elog mechanism, so don't blame me.
*
* See also SetConfigOption for an external interface.
*/
bool
set_config_option(const char * name, const char * value, GucContext
context, bool DoIt)
{
struct config_generic * record;
enum config_type type;
int elevel;
elevel = (context == PGC_SIGHUP) ? DEBUG : ERROR;
type = find_option(name, &record);
if (type == PGC_NONE)
{
elog(elevel, "not a valid option name: %s", name);
return false;
}
if (record->context < context)
{
/* can't set option right now */
switch (context)
{
case PGC_USERSET:
elog(ERROR, "permission denied");
/*NORETURN*/
case PGC_SUSET:
elog(ERROR, "%s can only be set at startup", name);
/*NORETURN*/
case PGC_SIGHUP:
/* ignore the option */
return true;
case PGC_BACKEND:
/* ignore; is this the right thing to do? */
return true;
default:
elog(FATAL, "%s:%d: internal error", __FILE__, __LINE__);
/*NORETURN*/
}
}
switch(type)
{
case PGC_BOOL:
{
struct config_bool * conf = (struct config_bool *)record;
if (value)
{
bool boolval;
if (!parse_bool(value, &boolval))
{
elog(elevel, "expected boolean value for option %s", name);
return false;
}
if (DoIt)
*conf->variable = boolval;
}
else if (DoIt)
*conf->variable = conf->default_val;
break;
}
case PGC_INT:
{
struct config_int * conf = (struct config_int *)record;
if (value)
{
int intval;
if (!parse_int(value, &intval))
{
elog(elevel, "expected integer value for option %s", name);
return false;
}
if (intval < conf->min || intval > conf->max)
{
elog(elevel, "value out of permissible range %d .. %d", conf->min, conf->max);
return false;
}
if (DoIt)
*conf->variable = intval;
}
else if (DoIt)
*conf->variable = conf->default_val;
break;
}
case PGC_REAL:
{
struct config_real * conf = (struct config_real *)record;
if (value)
{
double dval;
if (!parse_real(value, &dval))
{
elog(elevel, "expected real number for option %s", name);
return false;
}
if (dval < conf->min || dval > conf->max)
{
elog(elevel, "value out of permissible range %g .. %g", conf->min, conf->max);
return false;
}
if (DoIt)
*conf->variable = dval;
}
else if (DoIt)
*conf->variable = conf->default_val;
break;
}
case PGC_STRING:
{
struct config_string * conf = (struct config_string *)record;
if (value)
{
if (conf->parse_hook && !(conf->parse_hook)(value))
{
elog(elevel, "value '%s' not accepted for option %s", value, name);
return false;
}
if (DoIt)
{
char * str;
str = strdup(value);
if (str == NULL)
{
elog(elevel, "out of memory");
return false;
}
free(conf->variable);
conf->variable = str;
}
}
else if (DoIt)
{
char * str;
str = strdup(conf->default_val);
if (str == NULL)
{
elog(elevel, "out of memory");
return false;
}
free(conf->variable);
conf->variable = str;
}
break;
}
default: ;
}
return true;
}
/*
* Set a config option to the given value. See also set_config_option,
* this is just the wrapper to be called from the outside.
*/
void
SetConfigOption(const char * name, const char * value, GucContext
context)
{
(void)set_config_option(name, value, context, true);
}
/*
* This is more or less the SHOW command. It returns a string with the
* value of the option `name'. If the option doesn't exist, throw an
* elog and don't return. issuper should be true if and only if the
* current user is a superuser. Normal users don't have read
* permission on all options.
*
* The string is *not* allocated for modification and is really only
* valid until the next call to configuration related functions.
*/
const char *
GetConfigOption(const char * name, bool issuper)
{
struct config_generic * record;
static char buffer[256];
enum config_type opttype;
opttype = find_option(name, &record);
if (opttype == PGC_NONE)
elog(ERROR, "not a valid option name: %s", name);
if (record->context < PGC_USERSET && !issuper)
elog(ERROR, "permission denied");
switch(opttype)
{
case PGC_BOOL:
return *((struct config_bool *)record)->variable ? "true" : "false";
case PGC_INT:
snprintf(buffer, 256, "%d", *((struct config_int *)record)->variable);
return buffer;
case PGC_REAL:
snprintf(buffer, 256, "%g", *((struct config_real *)record)->variable);
return buffer;
case PGC_STRING:
return ((struct config_string *)record)->variable;
default:
;
}
return NULL;
}

View File

@ -1,511 +0,0 @@
/*-------------------------------------------------------------------------
*
* trace.c
*
* Conditional trace and logging functions.
*
* Massimo Dal Zotto <dz@cs.unitn.it>
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#endif
#include "miscadmin.h"
#include "utils/trace.h"
#include <ctype.h>
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
/*
* We could support trace messages of indefinite length, as elog() does,
* but it's probably not worth the trouble. Instead limit trace message
* length to this.
*/
#define TRACEMSG_MAXLEN 4096
#ifdef USE_SYSLOG
/*
* Global option to control the use of syslog(3) for logging:
*
* 0 stdout/stderr only
* 1 stdout/stderr + syslog
* 2 syslog only
*/
#define UseSyslog pg_options[OPT_SYSLOG]
#define PG_LOG_FACILITY LOG_LOCAL0
#define PG_LOG_IDENT "postgres"
#else
#define UseSyslog 0
#endif
/*
* Trace option names, must match the constants in trace_opts[].
*/
static char *opt_names[] = {
"all", /* 0=trace some, 1=trace all, -1=trace
* none */
"verbose",
"query",
"plan",
"parse",
"rewritten",
"pretty_plan",
"pretty_parse",
"pretty_rewritten",
"parserstats",
"plannerstats",
"executorstats",
"shortlocks", /* currently unused but needed, see lock.c */
"locks",
"userlocks",
"spinlocks",
"notify",
"malloc",
"palloc",
"lock_debug_oidmin",
"lock_debug_relid",
"lock_read_priority", /* lock priority, see lock.c */
"deadlock_timeout", /* deadlock timeout, see proc.c */
"nofsync", /* turn fsync off */
"syslog", /* use syslog for error messages */
"hostlookup", /* enable hostname lookup in ps_status */
"showportnumber", /* show port number in ps_status */
/* NUM_PG_OPTIONS *//* must be the last item of enum */
};
/*
* Array of trace flags which can be set or reset independently.
*/
int pg_options[NUM_PG_OPTIONS] = {0};
/*
* Print a timestamp and a message to stdout if the trace flag
* indexed by the flag value is set.
*/
int
tprintf(int flag, const char *fmt,...)
{
va_list ap;
char line[TRACEMSG_MAXLEN + TIMESTAMP_SIZE + 1];
#ifdef USE_SYSLOG
int log_level;
#endif
if ((flag == TRACE_ALL) || (pg_options[TRACE_ALL] > 0))
{
/* unconditional trace or trace all option set */
}
else if (pg_options[TRACE_ALL] == 0)
{
if ((flag < 0) || (flag >= NUM_PG_OPTIONS) || (!pg_options[flag]))
return 0;
}
else if (pg_options[TRACE_ALL] < 0)
return 0;
#ifdef ELOG_TIMESTAMPS
strcpy(line, tprintf_timestamp());
#endif
va_start(ap, fmt);
vsnprintf(line + TIMESTAMP_SIZE, TRACEMSG_MAXLEN, fmt, ap);
va_end(ap);
#ifdef USE_SYSLOG
log_level = ((flag == TRACE_ALL) ? LOG_INFO : LOG_DEBUG);
write_syslog(log_level, line + TIMESTAMP_SIZE);
#endif
if (UseSyslog <= 1)
{
puts(line);
fflush(stdout);
}
return 1;
}
/*
* Print a timestamp and a message to stdout or to syslog.
*/
#ifdef NOT_USED
int
tprintf1(const char *fmt,...)
{
va_list ap;
char line[TRACEMSG_MAXLEN + TIMESTAMP_SIZE + 1];
#ifdef ELOG_TIMESTAMPS
strcpy(line, tprintf_timestamp());
#endif
va_start(ap, fmt);
vsnprintf(line + TIMESTAMP_SIZE, TRACEMSG_MAXLEN, fmt, ap);
va_end(ap);
#ifdef USE_SYSLOG
write_syslog(LOG_INFO, line + TIMESTAMP_SIZE);
#endif
if (UseSyslog <= 1)
{
puts(line);
fflush(stdout);
}
return 1;
}
#endif
/*
* Print a timestamp and a message to stderr.
*/
int
eprintf(const char *fmt,...)
{
va_list ap;
char line[TRACEMSG_MAXLEN + TIMESTAMP_SIZE + 1];
#ifdef ELOG_TIMESTAMPS
strcpy(line, tprintf_timestamp());
#endif
va_start(ap, fmt);
vsnprintf(line + TIMESTAMP_SIZE, TRACEMSG_MAXLEN, fmt, ap);
va_end(ap);
#ifdef USE_SYSLOG
write_syslog(LOG_ERR, line + TIMESTAMP_SIZE);
#endif
if (UseSyslog <= 1)
{
fputs(line, stderr);
fputc('\n', stderr);
fflush(stderr);
}
return 1;
}
#ifdef USE_SYSLOG
/*
* Write a message line to syslog if the syslog option is set.
*/
void
write_syslog(int level, char *line)
{
#ifndef PG_SYSLOG_LIMIT
#define PG_SYSLOG_LIMIT 128
#endif /* PG_SYSLOG_LIMIT */
static int openlog_done = 0;
static char buf[PG_SYSLOG_LIMIT+1];
static int logid = 0;
if (UseSyslog >= 1)
{
int len = strlen(line);
int buflen;
int seq = 0;
int l;
int i;
if (!openlog_done)
{
openlog_done = 1;
openlog(PG_LOG_IDENT, LOG_PID | LOG_NDELAY, PG_LOG_FACILITY);
}
/* divide into multiple syslog() calls if message is
* too long
*/
if (len > PG_SYSLOG_LIMIT)
{
logid++;
while (len > 0)
{
strncpy(buf, line, PG_SYSLOG_LIMIT);
buf[PG_SYSLOG_LIMIT] = '\0';
l = strlen(buf);
#ifdef MULTIBYTE
/* trim to multibyte letter boundary */
buflen = pg_mbcliplen(buf, l, l);
buf[buflen] = '\0';
l = strlen(buf);
#endif
/* already word boundary? */
if (isspace(line[l]) || line[l] == '\0')
{
buflen = l;
}
else
{
/* try to divide in word boundary */
i = l - 1;
while(i > 0 && !isspace(buf[i]))
{
i--;
}
if (i <= 0) /* couldn't divide word boundary */
{
buflen = l;
}
else
{
buflen = i;
buf[i] = '\0';
}
}
seq++;
/*
* Here we actually call syslog().
* For segmented messages, we add logid
* (incremented at each write_syslog call),
* and seq (incremented at each syslog call
* within a write_syslog call).
* This will prevent syslog to surpress
* "same" messages...
*/
syslog(level, "[%d-%d] %s", logid, seq, buf);
line += buflen;
len -= buflen;
}
}
else
{
syslog(level, "%s", line);
}
}
}
#endif
#ifdef ELOG_TIMESTAMPS
/*
* Return a timestamp string like "980119.17:25:59.902 [21974] "
*/
char *
tprintf_timestamp()
{
struct timeval tv;
struct timezone tz = {0, 0};
struct tm *time;
time_t tm;
static char timestamp[32],
pid[8];
gettimeofday(&tv, &tz);
tm = tv.tv_sec;
time = localtime(&tm);
sprintf(pid, "[%d]", MyProcPid);
sprintf(timestamp, "%02d%02d%02d.%02d:%02d:%02d.%03d %7s ",
time->tm_year % 100, time->tm_mon + 1, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec,
(int) (tv.tv_usec / 1000), pid);
return timestamp;
}
#endif
#ifdef NOT_USED
static int
option_flag(int flag)
{
if ((flag < 0) || (flag >= NUM_PG_OPTIONS))
return 0;
return pg_options[flag];
}
int
set_option_flag(int flag, int value)
{
if ((flag < 0) || (flag >= NUM_PG_OPTIONS))
return -1;
pg_options[flag] = value;
return value;
}
#endif
/*
* Parse an option string like "name,name+,name-,name=value".
* Single options are delimited by ',',space,tab,newline or cr.
*
* If 'secure' is false, the option string came from a remote client via
* connection "debug options" field --- do not obey any requests that
* might potentially be security loopholes.
*/
void
parse_options(char *str, bool secure)
{
char *s,
*name;
int i,
len,
val,
is_comment;
Assert((sizeof(opt_names) / sizeof(char *)) == NUM_PG_OPTIONS);
str = strdup(str);
for (s = str; *s;)
{
is_comment = 0;
name = s;
val = 1;
for (; *s; s++)
{
switch (*s)
{
case '#':
is_comment = 1;
break;
case '=':
*s++ = '\0';
val = strtol(s, &s, 10);
goto setval;
case '-':
*s++ = '\0';
val = 0;
goto setval;
case '+':
*s++ = '\0';
val = 1;
goto setval;
case ' ':
case ',':
case '\t':
case '\n':
case '\r':
*s = ',';
val = 1;
goto setval;
}
}
setval:
for (; *s; s++)
{
if (*s == ',')
{
*s++ = '\0';
break;
}
}
len = strlen(name);
if (len == 0)
continue;
for (i = 0; i < NUM_PG_OPTIONS; i++)
{
if (strncmp(name, opt_names[i], len) == 0)
{
pg_options[i] = val;
break;
}
}
if (!is_comment && (i >= NUM_PG_OPTIONS))
fprintf(stderr, "invalid option: %s\n", name);
}
free(str);
}
#define BUF_SIZE 4096
void
read_pg_options(SIGNAL_ARGS)
{
int fd;
int n;
int verbose;
char buffer[BUF_SIZE];
char c;
char *s,
*p;
if (!DataDir)
{
fprintf(stderr, "read_pg_options: DataDir not defined\n");
return;
}
snprintf(buffer, BUF_SIZE - 1, "%s/%s", DataDir, "pg_options");
#ifndef __CYGWIN32__
if ((fd = open(buffer, O_RDONLY)) < 0)
#else
if ((fd = open(buffer, O_RDONLY | O_BINARY)) < 0)
#endif
return;
if ((n = read(fd, buffer, BUF_SIZE - 1)) > 0)
{
/* collpse buffer in place removing comments and spaces */
for (s = buffer, p = buffer, c = '\0'; s < (buffer + n);)
{
switch (*s)
{
case '#':
while ((s < (buffer + n)) && (*s++ != '\n'));
break;
case ' ':
case '\t':
case '\n':
case '\r':
if (c != ',')
c = *p++ = ',';
s++;
break;
default:
c = *p++ = *s++;
break;
}
}
if (c == ',')
p--;
*p = '\0';
verbose = pg_options[TRACE_VERBOSE];
parse_options(buffer, true);
verbose |= pg_options[TRACE_VERBOSE];
if (verbose || postgres_signal_arg == SIGHUP)
tprintf(TRACE_ALL, "read_pg_options: %s", buffer);
}
close(fd);
}
void
show_options(void)
{
int i;
for (i = 0; i < NUM_PG_OPTIONS; i++)
elog(NOTICE, "%s=%d", opt_names[i], pg_options[i]);
}
/*
* Local variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/

View File

@ -26,7 +26,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.91 2000/04/25 08:29:02 petere Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.92 2000/05/31 00:28:35 petere Exp $
#
#-------------------------------------------------------------------------
@ -321,7 +321,6 @@ PG_HBA_SAMPLE="$PGLIB"/pg_hba.conf.sample
TEMPLATE_DESCR="$PGLIB"/local1_template1.description
GLOBAL_DESCR="$PGLIB"/global1.description
PG_GEQO_SAMPLE="$PGLIB"/pg_geqo.sample
PG_POSTMASTER_OPTS_DEFAULT_SAMPLE="$PGLIB"/postmaster.opts.default.sample
if [ "$show_setting" -eq 1 ]
@ -342,7 +341,6 @@ then
echo " PG_HBA_SAMPLE: $PG_HBA_SAMPLE"
echo " TEMPLATE_DESCR: $TEMPLATE_DESCR"
echo " GLOBAL_DESCR: $GLOBAL_DESCR"
echo " PG_GEQO_SAMPLE: $PG_GEQO_SAMPLE"
echo " PG_POSTMASTER_OPTS_DEFAULT_SAMPLE: $PG_POSTMASTER_OPTS_DEFAULT_SAMPLE"
echo
exit 0
@ -461,7 +459,6 @@ then
"$PGPATH"/pg_version "$PGDATA" || exit_nicely
cp "$PG_HBA_SAMPLE" "$PGDATA"/pg_hba.conf || exit_nicely
cp "$PG_GEQO_SAMPLE" "$PGDATA"/pg_geqo.sample || exit_nicely
cp "$PG_POSTMASTER_OPTS_DEFAULT_SAMPLE" "$PGDATA"/postmaster.opts.default || exit_nicely
echo "Adding template1 database to pg_database"
@ -482,7 +479,7 @@ fi
echo
PGSQL_OPT="-o /dev/null -O -F -Q -D$PGDATA"
PGSQL_OPT="-o /dev/null -O -F -D$PGDATA"
# Create a trigger so that direct updates to pg_shadow will be written
# to the flat password file pg_pwd

952
src/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -279,9 +279,14 @@ AC_MSG_CHECKING(setting DEF_PGPORT)
AC_ARG_WITH(
pgport,
[ --with-pgport=PORTNUM change default postmaster port ],
AC_DEFINE_UNQUOTED(DEF_PGPORT, "${withval}") AC_MSG_RESULT($with_pgport),
AC_DEFINE_UNQUOTED(DEF_PGPORT, "5432") AC_MSG_RESULT(5432)
[default_port="$withval"],
[default_port=5432]
)
dnl Need to do this twice because backend wants an integer and frontend a string
AC_DEFINE_UNQUOTED(DEF_PGPORT, ${default_port})
AC_DEFINE_UNQUOTED(DEF_PGPORT_STR, "${default_port}")
AC_MSG_RESULT(${default_port})
dnl DEF_MAXBACKENDS can be set by --with-maxbackends. Default value is 32.
AC_MSG_CHECKING(setting DEF_MAXBACKENDS)
@ -944,6 +949,13 @@ AC_TRY_LINK([#include <setjmp.h>],
[AC_DEFINE(HAVE_SIGSETJMP) AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
AC_ARG_ENABLE(syslog, [ --enable-syslog enable logging to syslog],
[case $enableval in y|ye|yes)
AC_CHECK_FUNC(syslog, [AC_DEFINE(ENABLE_SYSLOG)], [AC_MSG_ERROR([no syslog interface found])])
;;
esac]
)
dnl Check to see if we have a working 64-bit integer type.
dnl This breaks down into two steps:
dnl (1) figure out if the compiler has a 64-bit int type with working

View File

@ -6,13 +6,15 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: async.h,v 1.13 2000/01/26 05:58:00 momjian Exp $
* $Id: async.h,v 1.14 2000/05/31 00:28:37 petere Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef ASYNC_H
#define ASYNC_H
extern bool Trace_notify;
/* notify-related SQL statements */
extern void Async_Notify(char *relname);
extern void Async_Listen(char *relname, int pid);

View File

@ -2,15 +2,15 @@
* Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var'
* statements
*
* $Id: variable.h,v 1.9 2000/02/19 22:10:43 tgl Exp $
* $Id: variable.h,v 1.10 2000/05/31 00:28:37 petere Exp $
*
*/
#ifndef VARIABLE_H
#define VARIABLE_H 1
#define VARIABLE_H
extern bool SetPGVariable(const char *name, const char *value);
extern bool GetPGVariable(const char *name);
extern bool ResetPGVariable(const char *name);
extern void SetPGVariable(const char *name, const char *value);
extern void GetPGVariable(const char *name);
extern void ResetPGVariable(const char *name);
extern void set_default_datestyle(void);

View File

@ -8,12 +8,13 @@
* or in config.h afterwards. Of course, if you edit config.h, then your
* changes will be overwritten the next time you run configure.
*
* $Id: config.h.in,v 1.113 2000/05/12 13:58:25 scrappy Exp $
* $Id: config.h.in,v 1.114 2000/05/31 00:28:36 petere Exp $
*/
#ifndef CONFIG_H
#define CONFIG_H
/*
* Default runtime limit on number of backend server processes per postmaster;
* this is just the default setting for the postmaster's -N switch.
@ -61,14 +62,6 @@
*/
#define RELSEG_SIZE (0x40000000 / BLCKSZ)
/*
* As soon as the backend blocks on a lock, it waits this number of seconds
* before checking for a deadlock.
* We don't check for deadlocks just before sleeping because a deadlock is
* a rare event, and checking is an expensive operation.
*/
#define DEADLOCK_CHECK_TIMER 1
/*
* Maximum number of columns in an index and maximum number of arguments
* to a function. They must be the same value.
@ -113,16 +106,6 @@
*/
#define USER_LOCKS
/* Genetic Query Optimization (GEQO):
*
* The GEQO module in PostgreSQL is intended for the solution of the
* query optimization problem by means of a Genetic Algorithm (GA).
* It allows the handling of large JOIN queries through non-exhaustive
* search.
* For further information see README.GEQO <utesch@aut.tu-freiberg.de>.
*/
#define GEQO
/*
* Define this if you want psql to _always_ ask for a username and a password
* for password authentication.
@ -163,13 +146,7 @@
*/
/* #define ELOG_TIMESTAMPS */
/*
* USE_SYSLOG: use syslog for elog and error messages printed by tprintf
* and eprintf. This must be activated with the syslog flag in pg_options
* (syslog=0 for stdio, syslog=1 for stdio+syslog, syslog=2 for syslog).
* For information see backend/utils/misc/trace.c (Massimo Dal Zotto).
*/
/* #define USE_SYSLOG */
#undef ENABLE_SYSLOG
/* Debug #defines */
/* #define IPORTAL_DEBUG */
@ -183,6 +160,7 @@
/* #define NO_BUFFERISVALID */
/* #define NO_SECURITY */
/* #define OLD_REWRITE */
/* #define LOCK_DEBUG */
/*
* MAXPGPATH: standard size of a pathname buffer in Postgres (hence,
@ -225,7 +203,9 @@
* default. This can be overriden by command options, environment variables,
* and the postconfig hook. (now set by configure script)
*/
#undef DEF_PGPORT
#undef DEF_PGPORT
/* ... and once more as a string constant instead */
#undef DEF_PGPORT_STR
/* Define const as empty if your compiler doesn't grok const. */
#undef const

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: miscadmin.h,v 1.56 2000/05/29 19:16:55 tgl Exp $
* $Id: miscadmin.h,v 1.57 2000/05/31 00:28:36 petere Exp $
*
* NOTES
* some of the information in this file will be moved to
@ -27,7 +27,6 @@
#include "postgres.h"
#include "utils/trace.h"
/*****************************************************************************
* globals.h -- *
@ -102,12 +101,20 @@ extern char CTZName[];
extern char FloatFormat[];
extern char DateFormat[];
#define disableFsync pg_options[OPT_NOFSYNC]
extern bool enableFsync;
extern bool allowSystemTableMods;
extern int SortMem;
extern Oid LastOidProcessed; /* for query rewrite */
/* a few postmaster startup options are exported here so the
configuration file processor has access to them */
extern bool NetServer;
extern int MaxBackends;
extern int NBuffers;
extern int PostPortName;
/*****************************************************************************
* pdir.h -- *
* POSTGRES directory path definitions. *

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: cost.h,v 1.32 2000/04/12 17:16:42 momjian Exp $
* $Id: cost.h,v 1.33 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -38,10 +38,10 @@
/* parameter variables and flags */
extern double effective_cache_size;
extern Cost random_page_cost;
extern Cost cpu_tuple_cost;
extern Cost cpu_index_tuple_cost;
extern Cost cpu_operator_cost;
extern double random_page_cost;
extern double cpu_tuple_cost;
extern double cpu_index_tuple_cost;
extern double cpu_operator_cost;
extern Cost disable_cost;
extern bool enable_seqscan;
extern bool enable_indexscan;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo.h,v 1.18 2000/01/26 05:58:20 momjian Exp $
* $Id: geqo.h,v 1.19 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -41,32 +41,29 @@
*/
#define ERX
/* genetic algorithm parameters */
#define GEQO_FILE "pg_geqo" /* Name of the ga config file */
/*
* Configuration options
*/
extern int Geqo_pool_size;
#define DEFAULT_GEQO_POOL_SIZE 0 /* = default based on no. of relations. */
#define MIN_GEQO_POOL_SIZE 128
#define MAX_GEQO_POOL_SIZE 1024
#define MIN_POOL 128 /* minimum number of individuals */
#define MAX_POOL 1024 /* maximum number of individuals */
extern int Geqo_effort; /* 1 .. inf, only used to calculate generations default */
extern int Geqo_generations; /* 1 .. inf, or 0 to use default based on pool size */
#define LOW_EFFORT 1 /* optimization effort values */
#define MEDIUM_EFFORT 40 /* are multipliers for computed */
#define HIGH_EFFORT 80 /* number of generations */
extern double Geqo_selection_bias;
#define DEFAULT_GEQO_SELECTION_BIAS 2.0
#define MIN_GEQO_SELECTION_BIAS 1.5
#define MAX_GEQO_SELECTION_BIAS 2.0
#define SELECTION_BIAS 2.0 /* selective pressure within population */
/* should be 1.5 <= SELECTION_BIAS <= 2.0 */
extern int Geqo_random_seed; /* or negative to use current time */
/* parameter values set in geqo_params.c */
extern int PoolSize;
extern int Generations;
extern long RandomSeed;
extern double SelectionBias;
/* routines in geqo_main.c */
extern RelOptInfo *geqo(Query *root);
/* routines in geqo_params.c */
extern void geqo_params(int string_length);
/* routines in geqo_eval.c */
extern void geqo_eval_startup(void);
extern Cost geqo_eval(Query *root, Gene *tour, int num_gene);

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: paths.h,v 1.44 2000/04/12 17:16:42 momjian Exp $
* $Id: paths.h,v 1.45 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,7 +18,7 @@
#include "nodes/relation.h"
/* default GEQO threshold (default value for geqo_rels) */
#define GEQO_RELS 11
#define DEFAULT_GEQO_RELS 11
/*

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: planmain.h,v 1.39 2000/04/12 17:16:42 momjian Exp $
* $Id: planmain.h,v 1.40 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -55,6 +55,7 @@ extern void fix_opids(Node *node);
/*
* prep/prepkeyset.c
*/
extern bool _use_keyset_query_optimizer;
extern void transformKeySetQuery(Query *origNode);
#endif /* PLANMAIN_H */

View File

@ -7,13 +7,14 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: lock.h,v 1.37 2000/04/12 17:16:51 momjian Exp $
* $Id: lock.h,v 1.38 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef LOCK_H_
#define LOCK_H_
#include "postgres.h"
#include "storage/ipc.h"
#include "storage/itemptr.h"
#include "storage/shmem.h"
@ -26,6 +27,15 @@ typedef int LOCKMASK;
#define MAX_TABLE_SIZE 1000
#ifdef LOCK_DEBUG
extern int Trace_lock_oidmin;
extern bool Trace_locks;
extern bool Trace_userlocks;
extern int Trace_lock_table;
extern bool Debug_deadlocks;
#endif /* LOCK_DEBUG */
/* ----------------------
* The following defines are used to estimate how much shared
* memory the lock manager is going to require.
@ -259,10 +269,9 @@ extern int LockShmemSize(int maxBackends);
extern bool LockingDisabled(void);
extern bool DeadLockCheck(void *proc, LOCK *findlock);
#ifdef DEADLOCK_DEBUG
#ifdef LOCK_DEBUG
extern void DumpLocks(void);
extern void DumpAllLocks(void);
#endif
#endif /* LOCK_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: proc.h,v 1.30 2000/04/12 17:16:51 momjian Exp $
* $Id: proc.h,v 1.31 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -17,6 +17,9 @@
#include "access/xlog.h"
#include "storage/lock.h"
/* configurable option */
extern int DeadlockTimeout;
typedef struct
{
int sleeplock;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: spin.h,v 1.11 2000/01/26 05:58:33 momjian Exp $
* $Id: spin.h,v 1.12 2000/05/31 00:28:38 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -28,6 +28,10 @@
typedef int SPINLOCK;
#ifdef LOCK_DEBUG
extern bool Trace_spinlocks;
#endif
extern void CreateSpinlocks(IPCKey key);
extern void InitSpinLocks(void);
extern void SpinAcquire(SPINLOCK lockid);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: tcopprot.h,v 1.27 2000/04/12 17:16:53 momjian Exp $
* $Id: tcopprot.h,v 1.28 2000/05/31 00:28:39 petere Exp $
*
* OLD COMMENTS
* This file was created so that other c files could get the two
@ -28,6 +28,9 @@ extern bool Warn_restart_ready;
extern bool InError;
extern bool ExitAfterAbort;
extern bool HostnameLookup;
extern bool ShowPortNumber;
#ifndef BOOTSTRAP_INCLUDE
extern List *pg_parse_and_rewrite(char *query_string,
@ -50,5 +53,6 @@ extern int PostgresMain(int argc, char *argv[],
int real_argc, char *real_argv[]);
extern void ResetUsage(void);
extern void ShowUsage(void);
extern FILE * StatFp;
#endif /* TCOPPROT_H */

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: elog.h,v 1.16 2000/04/12 17:16:54 momjian Exp $
* $Id: elog.h,v 1.17 2000/05/31 00:28:40 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -23,6 +23,10 @@
#define LOG DEBUG
#define NOIND (-3) /* debug message, don't indent as far */
#ifdef ENABLE_SYSLOG
extern int Use_syslog;
#endif
#ifndef __GNUC__
extern void elog(int lev, const char *fmt,...);

47
src/include/utils/guc.h Normal file
View File

@ -0,0 +1,47 @@
/*
* guc.h
*
* External declarations pertaining to backend/utils/misc/guc.c and
* backend/utils/misc/guc-file.l
*
* $Header: /cvsroot/pgsql/src/include/utils/guc.h,v 1.1 2000/05/31 00:28:40 petere Exp $
*/
#ifndef GUC_H
#define GUC_H
#include "postgres.h"
/*
* This is sort of a permission list. Those contexts with a higher
* number can also be set via the lower numbered ways.
*/
typedef enum {
PGC_POSTMASTER = 1, /* static postmaster option */
PGC_BACKEND = 2, /* per backend startup option */
PGC_SIGHUP = 4, /* can change this option via SIGHUP */
PGC_SUSET = 8, /* can change this option via SET if superuser */
PGC_USERSET = 16, /* everyone can change this option via SET */
} GucContext;
void SetConfigOption(const char * name, const char * value, GucContext context);
const char * GetConfigOption(const char * name, bool issuper);
void ProcessConfigFile(GucContext context);
void ResetAllOptions(void);
bool set_config_option(const char * name, const char * value, GucContext context, bool DoIt);
extern bool Debug_print_query;
extern bool Debug_print_plan;
extern bool Debug_print_parse;
extern bool Debug_print_rewritten;
extern bool Debug_pretty_print;
extern bool Show_parser_stats;
extern bool Show_planner_stats;
extern bool Show_executor_stats;
extern bool Show_query_stats;
extern bool Show_btree_build_stats;
#endif /*GUC_H*/

View File

@ -1,91 +0,0 @@
/*-------------------------------------------------------------------------
*
* trace.h
*
* Conditional trace definitions.
*
* Massimo Dal Zotto <dz@cs.unitn.it>
*
*-------------------------------------------------------------------------
*/
#ifndef TRACE_H
#define TRACE_H
#include <string.h>
#include <time.h>
#ifdef ELOG_TIMESTAMPS
char *tprintf_timestamp(void);
#define TIMESTAMP_SIZE 28
#else
#define TIMESTAMP_SIZE 0
#endif
extern int tprintf(int flag, const char *fmt,...);
extern int eprintf(const char *fmt,...);
extern void write_syslog(int level, char *line);
extern void show_options(void);
extern void parse_options(char *str, bool secure);
extern void read_pg_options(SIGNAL_ARGS);
/*
* Trace options, used as index into pg_options.
* Must match the constants in pg_options[].
*/
enum pg_option_enum
{
TRACE_ALL, /* 0=trace some, 1=trace all, -1=trace
* none */
TRACE_VERBOSE,
TRACE_QUERY,
TRACE_PLAN,
TRACE_PARSE,
TRACE_REWRITTEN,
TRACE_PRETTY_PLAN, /* indented multiline versions of trees */
TRACE_PRETTY_PARSE,
TRACE_PRETTY_REWRITTEN,
TRACE_PARSERSTATS,
TRACE_PLANNERSTATS,
TRACE_EXECUTORSTATS,
TRACE_SHORTLOCKS, /* currently unused but needed, see lock.c */
TRACE_LOCKS,
TRACE_USERLOCKS,
TRACE_SPINLOCKS,
TRACE_NOTIFY,
TRACE_MALLOC,
TRACE_PALLOC,
TRACE_LOCKOIDMIN,
TRACE_LOCKRELATION,
OPT_LOCKREADPRIORITY, /* lock priority, see lock.c */
OPT_DEADLOCKTIMEOUT, /* deadlock timeout, see proc.c */
OPT_NOFSYNC, /* turn fsync off */
OPT_SYSLOG, /* use syslog for error messages */
OPT_HOSTLOOKUP, /* enable hostname lookup in ps_status */
OPT_SHOWPORTNUMBER, /* show port number in ps_status */
NUM_PG_OPTIONS /* must be the last item of enum */
};
extern int pg_options[NUM_PG_OPTIONS];
#ifdef __GNUC__
#define PRINTF(args...) tprintf1(args)
#define EPRINTF(args...) eprintf(args)
#define TPRINTF(flag, args...) tprintf(flag, args)
#else
#define PRINTF tprintf1
#define EPRINTF eprintf
#define TPRINTF tprintf
#endif
#endif /* TRACE_H */
/*
* Local variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.127 2000/05/21 21:19:53 tgl Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.128 2000/05/31 00:28:41 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -122,7 +122,7 @@ static const PQconninfoOption PQconninfoOptions[] = {
"Database-Host-IPv4-Address", "", 15}, /* Room for
* abc.def.ghi.jkl */
{"port", "PGPORT", DEF_PGPORT, NULL,
{"port", "PGPORT", DEF_PGPORT_STR, NULL,
"Database-Port", "", 6},
{"tty", "PGTTY", DefaultTty, NULL,
@ -416,7 +416,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
if ((pgport == NULL) || pgport[0] == '\0')
{
if ((tmp = getenv("PGPORT")) == NULL)
tmp = DEF_PGPORT;
tmp = DEF_PGPORT_STR;
conn->pgport = strdup(tmp);
}
else

View File

@ -45,6 +45,13 @@ rm -f bootstrap_tokens.h bootparse.c bootscanner.c
$MAKE bootstrap_tokens.h bootparse.c bootscanner.c
cd ../..
# Generate configuration file scanner
cd backend/utils/misc
rm -f guc-file.c lex.yy.c
$MAKE guc-file.c
cd ../../..
# Generate ecpg preprocessor's yacc and lex files
cd interfaces/ecpg/preproc