Commit 6d09b210 authored by Andrew Dunstan's avatar Andrew Dunstan

include_if_exists facility for config file.

This works the same as include, except that an error is not thrown
if the file is missing. Instead the fact that it's missing is
logged.

Greg Smith, reviewed by Euler Taveira de Oliveira.
parent 1da5c119
...@@ -89,6 +89,18 @@ include 'filename' ...@@ -89,6 +89,18 @@ include 'filename'
Inclusions can be nested. Inclusions can be nested.
</para> </para>
<para>
<indexterm>
<primary><literal>include_if_exists</></primary>
<secondary>in configuration file</secondary>
</indexterm>
Use the same approach as the <literal>include</> directive, continuing
normally if the file does not exist. A regular <literal>include</>
will stop with an error if the referenced file is missing, while
<literal>include_if_exists</> does not. A warning about the missing
file will be logged.
</para>
<para> <para>
<indexterm> <indexterm>
<primary>SIGHUP</primary> <primary>SIGHUP</primary>
......
...@@ -129,7 +129,7 @@ ProcessConfigFile(GucContext context) ...@@ -129,7 +129,7 @@ ProcessConfigFile(GucContext context)
/* Parse the file into a list of option names and values */ /* Parse the file into a list of option names and values */
head = tail = NULL; head = tail = NULL;
if (!ParseConfigFile(ConfigFileName, NULL, 0, elevel, &head, &tail)) if (!ParseConfigFile(ConfigFileName, NULL, true, 0, elevel, &head, &tail))
{ {
/* Syntax error(s) detected in the file, so bail out */ /* Syntax error(s) detected in the file, so bail out */
error = true; error = true;
...@@ -363,7 +363,7 @@ ProcessConfigFile(GucContext context) ...@@ -363,7 +363,7 @@ ProcessConfigFile(GucContext context)
* and absolute-ifying the path name if necessary. * and absolute-ifying the path name if necessary.
*/ */
bool bool
ParseConfigFile(const char *config_file, const char *calling_file, ParseConfigFile(const char *config_file, const char *calling_file, bool strict,
int depth, int elevel, int depth, int elevel,
ConfigVariable **head_p, ConfigVariable **head_p,
ConfigVariable **tail_p) ConfigVariable **tail_p)
...@@ -414,11 +414,19 @@ ParseConfigFile(const char *config_file, const char *calling_file, ...@@ -414,11 +414,19 @@ ParseConfigFile(const char *config_file, const char *calling_file,
fp = AllocateFile(config_file, "r"); fp = AllocateFile(config_file, "r");
if (!fp) if (!fp)
{ {
ereport(elevel, if (strict)
(errcode_for_file_access(), {
errmsg("could not open configuration file \"%s\": %m", ereport(elevel,
(errcode_for_file_access(),
errmsg("could not open configuration file \"%s\": %m",
config_file)));
return false;
}
ereport(LOG,
(errmsg("skipping missing configuration file \"%s\"",
config_file))); config_file)));
return false; return OK;
} }
OK = ParseConfigFp(fp, config_file, depth, elevel, head_p, tail_p); OK = ParseConfigFp(fp, config_file, depth, elevel, head_p, tail_p);
...@@ -512,7 +520,24 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ...@@ -512,7 +520,24 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
} }
/* OK, process the option name and value */ /* OK, process the option name and value */
if (guc_name_compare(opt_name, "include") == 0) if (guc_name_compare(opt_name, "include_if_exists") == 0)
{
/*
* An include_if_exists directive isn't a variable and should be
* processed immediately.
*/
unsigned int save_ConfigFileLineno = ConfigFileLineno;
if (!ParseConfigFile(opt_value, config_file, false,
depth + 1, elevel,
head_p, tail_p))
OK = false;
yy_switch_to_buffer(lex_buffer);
ConfigFileLineno = save_ConfigFileLineno;
pfree(opt_name);
pfree(opt_value);
}
else if (guc_name_compare(opt_name, "include") == 0)
{ {
/* /*
* An include directive isn't a variable and should be processed * An include directive isn't a variable and should be processed
...@@ -520,7 +545,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ...@@ -520,7 +545,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
*/ */
unsigned int save_ConfigFileLineno = ConfigFileLineno; unsigned int save_ConfigFileLineno = ConfigFileLineno;
if (!ParseConfigFile(opt_value, config_file, if (!ParseConfigFile(opt_value, config_file, true,
depth + 1, elevel, depth + 1, elevel,
head_p, tail_p)) head_p, tail_p))
OK = false; OK = false;
......
...@@ -111,7 +111,7 @@ typedef struct ConfigVariable ...@@ -111,7 +111,7 @@ typedef struct ConfigVariable
} ConfigVariable; } ConfigVariable;
extern bool ParseConfigFile(const char *config_file, const char *calling_file, extern bool ParseConfigFile(const char *config_file, const char *calling_file,
int depth, int elevel, bool strict, int depth, int elevel,
ConfigVariable **head_p, ConfigVariable **tail_p); ConfigVariable **head_p, ConfigVariable **tail_p);
extern bool ParseConfigFp(FILE *fp, const char *config_file, extern bool ParseConfigFp(FILE *fp, const char *config_file,
int depth, int elevel, int depth, int elevel,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment