aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/misc/guc-file.l90
-rw-r--r--src/backend/utils/misc/guc.c7
2 files changed, 85 insertions, 12 deletions
diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index e6e11090abd..bb9207a777a 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -45,6 +45,8 @@ static unsigned int ConfigFileLineno;
static const char *GUC_flex_fatal_errmsg;
static sigjmp_buf *GUC_flex_fatal_jmp;
+static void FreeConfigVariable(ConfigVariable *item);
+
/* flex fails to supply a prototype for yylex, so provide one */
int GUC_yylex(void);
@@ -151,14 +153,66 @@ ProcessConfigFile(GucContext context)
* file is in the data directory, we can't read it until the DataDir has
* been set.
*/
- if (DataDir &&
- !ParseConfigFile(PG_AUTOCONF_FILENAME, NULL, false, 0, elevel,
- &head, &tail))
+ if (DataDir)
{
- /* Syntax error(s) detected in the file, so bail out */
- error = true;
- ErrorConfFile = PG_AUTOCONF_FILENAME;
- goto cleanup_list;
+ if (!ParseConfigFile(PG_AUTOCONF_FILENAME, NULL, false, 0, elevel,
+ &head, &tail))
+ {
+ /* Syntax error(s) detected in the file, so bail out */
+ error = true;
+ ErrorConfFile = PG_AUTOCONF_FILENAME;
+ goto cleanup_list;
+ }
+ }
+ else
+ {
+ ConfigVariable *prev = NULL;
+
+ /*
+ * Pick up only the data_directory if DataDir is not set, which
+ * means that the configuration file is read for the first time and
+ * PG_AUTOCONF_FILENAME file cannot be read yet. In this case,
+ * we shouldn't pick any settings except the data_directory
+ * from postgresql.conf because they might be overwritten
+ * with the settings in PG_AUTOCONF_FILENAME file which will be
+ * read later. OTOH, since it's ensured that data_directory doesn't
+ * exist in PG_AUTOCONF_FILENAME file, it will never be overwritten
+ * later.
+ */
+ for (item = head; item;)
+ {
+ ConfigVariable *ptr = item;
+
+ item = item->next;
+ if (strcmp(ptr->name, "data_directory") != 0)
+ {
+ if (prev == NULL)
+ head = ptr->next;
+ else
+ {
+ prev->next = ptr->next;
+ /*
+ * On removing last item in list, we need to update tail
+ * to ensure that list will be maintianed.
+ */
+ if (prev->next == NULL)
+ tail = prev;
+ }
+ FreeConfigVariable(ptr);
+ }
+ else
+ prev = ptr;
+ }
+
+ /*
+ * Quick exit if data_directory is not present in list.
+ *
+ * Don't remember when we last successfully loaded the config file in
+ * this case because that time will be set soon by subsequent load of
+ * the config file.
+ */
+ if (head == NULL)
+ return;
}
/*
@@ -677,7 +731,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
*tail_p = prev_item;
}
- pfree(cur_item);
+ FreeConfigVariable(cur_item);
break;
}
}
@@ -858,6 +912,21 @@ cleanup:
}
/*
+ * Free a ConfigVariable
+ */
+static void
+FreeConfigVariable(ConfigVariable *item)
+{
+ if (item != NULL)
+ {
+ pfree(item->name);
+ pfree(item->value);
+ pfree(item->filename);
+ pfree(item);
+ }
+}
+
+/*
* Free a list of ConfigVariables, including the names and the values
*/
void
@@ -870,10 +939,7 @@ FreeConfigVariables(ConfigVariable *list)
{
ConfigVariable *next = item->next;
- pfree(item->name);
- pfree(item->value);
- pfree(item->filename);
- pfree(item);
+ FreeConfigVariable(item);
item = next;
}
}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9aa1bc4702a..60e4354f6bc 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4339,6 +4339,13 @@ SelectConfigFiles(const char *userDoption, const char *progname)
return false;
}
+ /*
+ * Read the configuration file for the first time. This time only
+ * data_directory parameter is picked up to determine the data directory
+ * so that we can read PG_AUTOCONF_FILENAME file next time. Then don't
+ * forget to read the configuration file again later to pick up all the
+ * parameters.
+ */
ProcessConfigFile(PGC_POSTMASTER);
/*