diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index d1e628fefca..0cc329691dd 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -89,6 +89,18 @@ include 'filename' Inclusions can be nested. + + + include_if_exists + in configuration file + + Use the same approach as the include directive, continuing + normally if the file does not exist. A regular include + will stop with an error if the referenced file is missing, while + include_if_exists does not. A warning about the missing + file will be logged. + + SIGHUP diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index a094c7a2d2d..5fe5d14544c 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -129,7 +129,7 @@ ProcessConfigFile(GucContext context) /* Parse the file into a list of option names and values */ 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 */ error = true; @@ -363,7 +363,7 @@ ProcessConfigFile(GucContext context) * and absolute-ifying the path name if necessary. */ 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, ConfigVariable **head_p, ConfigVariable **tail_p) @@ -414,11 +414,19 @@ ParseConfigFile(const char *config_file, const char *calling_file, fp = AllocateFile(config_file, "r"); if (!fp) { - ereport(elevel, - (errcode_for_file_access(), - errmsg("could not open configuration file \"%s\": %m", + if (strict) + { + 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))); - return false; + return OK; } 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, } /* 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 @@ -520,7 +545,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, */ unsigned int save_ConfigFileLineno = ConfigFileLineno; - if (!ParseConfigFile(opt_value, config_file, + if (!ParseConfigFile(opt_value, config_file, true, depth + 1, elevel, head_p, tail_p)) OK = false; diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 8e3057a0140..52109e533c9 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -111,7 +111,7 @@ typedef struct ConfigVariable } ConfigVariable; 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); extern bool ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,