diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index d1e628fefcab1ff77931b1e291e7258bcba5d3b6..0cc329691dde66b2d26ab72aa55e8d91ec06c6fb 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -89,6 +89,18 @@ include 'filename' Inclusions can be nested. </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> <indexterm> <primary>SIGHUP</primary> diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index a094c7a2d2d8f651c37a464826fa2d34351543c6..5fe5d14544cd68f9716447fbf188ed42e1fd960f 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 8e3057a0140093f37c3fc28854e14d34b6c6bfca..52109e533c9ef7dfbcd4c74b27c053614d44e32e 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,