summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorCédric Villemain2011-05-13 20:55:39 +0000
committerCédric Villemain2011-05-13 20:55:39 +0000
commite0c3b474d5436c7874aef36988f2646bdb890249 (patch)
tree49c41d2b8abbd9bae4096643d840859f3a02a08c /src/backend/utils
parent40cefa392974c73ec20deb3c15fb5111ed7fad17 (diff)
parent9bb6d9795253bb521f81c626fea49a704a369ca9 (diff)
Merge branch 'master' into analyze_cacheanalyze_cache
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/datetime.c31
-rw-r--r--src/backend/utils/init/postinit.c2
-rw-r--r--src/backend/utils/misc/guc-file.l41
-rw-r--r--src/backend/utils/misc/guc.c33
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample6
-rw-r--r--src/backend/utils/mmgr/aset.c25
6 files changed, 83 insertions, 55 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index db0a6487ac..0a12a9b2e1 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -3569,24 +3569,27 @@ DateTimeParseError(int dterr, const char *str, const char *datatype)
static const datetkn *
datebsearch(const char *key, const datetkn *base, int nel)
{
- const datetkn *last = base + nel - 1,
- *position;
- int result;
-
- while (last >= base)
+ if (nel > 0)
{
- position = base + ((last - base) >> 1);
- result = key[0] - position->token[0];
- if (result == 0)
+ const datetkn *last = base + nel - 1,
+ *position;
+ int result;
+
+ while (last >= base)
{
- result = strncmp(key, position->token, TOKMAXLEN);
+ position = base + ((last - base) >> 1);
+ result = key[0] - position->token[0];
if (result == 0)
- return position;
+ {
+ result = strncmp(key, position->token, TOKMAXLEN);
+ if (result == 0)
+ return position;
+ }
+ if (result < 0)
+ last = position - 1;
+ else
+ base = position + 1;
}
- if (result < 0)
- last = position - 1;
- else
- base = position + 1;
}
return NULL;
}
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 1f6fba5f75..3ac3254afb 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -324,7 +324,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
PGC_INTERNAL, PGC_S_OVERRIDE);
/* If we have no other source of client_encoding, use server encoding */
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
- PGC_BACKEND, PGC_S_DEFAULT);
+ PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
/* assign locale variables */
collate = NameStr(dbform->datcollate);
diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index 10ef12eb24..78907b939d 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -14,6 +14,7 @@
#include <ctype.h>
#include <unistd.h>
+#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/guc.h"
@@ -109,7 +110,6 @@ ProcessConfigFile(GucContext context)
*tail;
char *cvc = NULL;
struct config_string *cvc_struct;
- const char *envvar;
int i;
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
@@ -265,7 +265,7 @@ ProcessConfigFile(GucContext context)
stack->source = PGC_S_DEFAULT;
}
- /* Now we can re-apply the wired-in default */
+ /* Now we can re-apply the wired-in default (i.e., the boot_val) */
set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT,
GUC_ACTION_SET, true);
if (context == PGC_SIGHUP)
@@ -275,25 +275,28 @@ ProcessConfigFile(GucContext context)
}
/*
- * Restore any variables determined by environment variables. This
- * is a no-op except in the case where one of these had been in the
- * config file and is now removed. PGC_S_ENV_VAR will override the
- * wired-in default we just applied, but cannot override any other source.
+ * Restore any variables determined by environment variables or
+ * dynamically-computed defaults. This is a no-op except in the case
+ * where one of these had been in the config file and is now removed.
*
- * Keep this list in sync with InitializeGUCOptions()!
- * PGPORT can be ignored, because it cannot be changed without restart.
- * We assume rlimit hasn't changed, either.
+ * In particular, we *must not* do this during the postmaster's
+ * initial loading of the file, since the timezone functions in
+ * particular should be run only after initialization is complete.
+ *
+ * XXX this is an unmaintainable crock, because we have to know how
+ * to set (or at least what to call to set) every variable that could
+ * potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
+ * However, there's no time to redesign it for 9.1.
*/
- envvar = getenv("PGDATESTYLE");
- if (envvar != NULL)
- set_config_option("datestyle", envvar, PGC_POSTMASTER,
- PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
- envvar = getenv("PGCLIENTENCODING");
- if (envvar != NULL)
- set_config_option("client_encoding", envvar, PGC_POSTMASTER,
- PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
+ if (context == PGC_SIGHUP)
+ {
+ InitializeGUCOptionsFromEnvironment();
+ pg_timezone_initialize();
+ pg_timezone_abbrev_initialize();
+ /* this selects SQL_ASCII in processes not connected to a database */
+ SetConfigOption("client_encoding", GetDatabaseEncodingName(),
+ PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
+ }
/* If we got here all the options checked out okay, so apply them. */
for (item = head; item; item = item->next)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 738e2152ba..92391eda2f 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -502,6 +502,7 @@ const char *const GucContext_Names[] =
const char *const GucSource_Names[] =
{
/* PGC_S_DEFAULT */ "default",
+ /* PGC_S_DYNAMIC_DEFAULT */ "default",
/* PGC_S_ENV_VAR */ "environment variable",
/* PGC_S_FILE */ "configuration file",
/* PGC_S_ARGV */ "command line",
@@ -3269,6 +3270,7 @@ static int GUCNestLevel = 0; /* 1 when in main transaction */
static int guc_var_compare(const void *a, const void *b);
static int guc_name_compare(const char *namea, const char *nameb);
+static void InitializeGUCOptionsFromEnvironment(void);
static void InitializeOneGUCOption(struct config_generic * gconf);
static void push_old_value(struct config_generic * gconf, GucAction action);
static void ReportGUCOption(struct config_generic * record);
@@ -3812,8 +3814,6 @@ void
InitializeGUCOptions(void)
{
int i;
- char *env;
- long stack_rlimit;
/*
* Before log_line_prefix could possibly receive a nonempty setting, make
@@ -3852,9 +3852,25 @@ InitializeGUCOptions(void)
/*
* For historical reasons, some GUC parameters can receive defaults from
- * environment variables. Process those settings. NB: if you add or
- * remove anything here, see also ProcessConfigFile().
+ * environment variables. Process those settings.
*/
+ InitializeGUCOptionsFromEnvironment();
+}
+
+/*
+ * Assign any GUC values that can come from the server's environment.
+ *
+ * This is called from InitializeGUCOptions, and also from ProcessConfigFile
+ * to deal with the possibility that a setting has been removed from
+ * postgresql.conf and should now get a value from the environment.
+ * (The latter is a kludge that should probably go away someday; if so,
+ * fold this back into InitializeGUCOptions.)
+ */
+static void
+InitializeGUCOptionsFromEnvironment(void)
+{
+ char *env;
+ long stack_rlimit;
env = getenv("PGPORT");
if (env != NULL)
@@ -6334,6 +6350,7 @@ define_custom_variable(struct config_generic * variable)
switch (pHolder->gen.source)
{
case PGC_S_DEFAULT:
+ case PGC_S_DYNAMIC_DEFAULT:
case PGC_S_ENV_VAR:
case PGC_S_FILE:
case PGC_S_ARGV:
@@ -8420,15 +8437,13 @@ assign_timezone_abbreviations(const char *newval, void *extra)
*
* This is called after initial loading of postgresql.conf. If no
* timezone_abbreviations setting was found therein, select default.
+ * If a non-default value is already installed, nothing will happen.
*/
void
pg_timezone_abbrev_initialize(void)
{
- if (timezone_abbreviations_string == NULL)
- {
- SetConfigOption("timezone_abbreviations", "Default",
- PGC_POSTMASTER, PGC_S_DEFAULT);
- }
+ SetConfigOption("timezone_abbreviations", "Default",
+ PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
}
static const char *
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index b8a1582eaa..655dad42c7 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -390,8 +390,7 @@
#log_temp_files = -1 # log temporary files equal or larger
# than the specified size in kilobytes;
# -1 disables, 0 logs all temp files
-#log_timezone = unknown # actually, defaults to TZ environment
- # setting
+#log_timezone = '(defaults to server environment setting)'
#------------------------------------------------------------------------------
@@ -471,8 +470,7 @@
#datestyle = 'iso, mdy'
#intervalstyle = 'postgres'
-#timezone = unknown # actually, defaults to TZ environment
- # setting
+#timezone = '(defaults to server environment setting)'
#timezone_abbreviations = 'Default' # Select the set of available time zone
# abbreviations. Currently, there are
# Default
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index e95dcb6b7c..140b0c74d9 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -89,7 +89,9 @@
*
* With the current parameters, request sizes up to 8K are treated as chunks,
* larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS
- * to adjust the boundary point.
+ * to adjust the boundary point. (But in contexts with small maxBlockSize,
+ * we may set the allocChunkLimit to less than 8K, so as to avoid space
+ * wastage.)
*--------------------
*/
@@ -97,6 +99,8 @@
#define ALLOCSET_NUM_FREELISTS 11
#define ALLOC_CHUNK_LIMIT (1 << (ALLOCSET_NUM_FREELISTS-1+ALLOC_MINBITS))
/* Size of largest chunk that we use a fixed size for */
+#define ALLOC_CHUNK_FRACTION 4
+/* We allow chunks to be at most 1/4 of maxBlockSize (less overhead) */
/*--------------------
* The first block allocated for an allocset has size initBlockSize.
@@ -380,15 +384,20 @@ AllocSetContextCreate(MemoryContext parent,
/*
* Compute the allocation chunk size limit for this context. It can't be
* more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
- * If maxBlockSize is small then requests exceeding the maxBlockSize
- * should be treated as large chunks, too. We have to have
- * allocChunkLimit a power of two, because the requested and
- * actually-allocated sizes of any chunk must be on the same side of the
- * limit, else we get confused about whether the chunk is "big".
+ * If maxBlockSize is small then requests exceeding the maxBlockSize, or
+ * even a significant fraction of it, should be treated as large chunks
+ * too. For the typical case of maxBlockSize a power of 2, the chunk size
+ * limit will be at most 1/8th maxBlockSize, so that given a stream of
+ * requests that are all the maximum chunk size we will waste at most
+ * 1/8th of the allocated space.
+ *
+ * We have to have allocChunkLimit a power of two, because the requested
+ * and actually-allocated sizes of any chunk must be on the same side of
+ * the limit, else we get confused about whether the chunk is "big".
*/
context->allocChunkLimit = ALLOC_CHUNK_LIMIT;
- while (context->allocChunkLimit >
- (Size) (maxBlockSize - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ))
+ while ((Size) (context->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
+ (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
context->allocChunkLimit >>= 1;
/*