44 *
55 * Copyright (c) 2000-2006, PostgreSQL Global Development Group
66 *
7- * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.42 2006/08/12 04:12:41 momjian Exp $
7+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.43 2006/08/13 01:30:17 momjian Exp $
88 */
99
1010%{
@@ -50,7 +50,8 @@ int GUC_yylex(void);
5050static bool ParseConfigFile (const char *config_file,const char *calling_file,
5151int depth, GucContext context,int elevel,
5252struct name_value_pair **head_p,
53- struct name_value_pair **tail_p);
53+ struct name_value_pair **tail_p,
54+ int *varcount);
5455static void free_name_value_list (struct name_value_pair * list);
5556static char *GUC_scanstr (const char *s);
5657
@@ -114,8 +115,10 @@ STRING \'([^'\\\n]|\\.|\'\')*\'
114115void
115116ProcessConfigFile(GucContext context)
116117{
117- intelevel;
118+ intelevel, i ;
118119struct name_value_pair *item, *head, *tail;
120+ bool *apply_list = NULL;
121+ intvarcount = 0;
119122
120123Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
121124
@@ -134,25 +137,56 @@ ProcessConfigFile(GucContext context)
134137
135138if (!ParseConfigFile(ConfigFileName, NULL,
136139 0, context, elevel,
137- &head, &tail))
140+ &head, &tail, &varcount ))
138141goto cleanup_list;
139142
143+ /* Can we allocate memory here, what about leaving here prematurely? */
144+ apply_list = (bool *) palloc(sizeof(bool) * varcount);
145+
140146/* Check if all options are valid */
141- for (item = head; item; item = item->next)
147+ for (item = head, i = 0 ; item; item = item->next, i++ )
142148{
143- if (!set_config_option(item->name, item->value, context,
144- PGC_S_FILE, false, false))
149+ bool isEqual, isContextOk;
150+
151+ if (!verify_config_option(item->name, item->value, context,
152+ PGC_S_FILE, &isEqual, &isContextOk))
153+ {
154+ ereport(elevel,
155+ (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
156+ errmsg("configuration file is invalid")));
145157goto cleanup_list;
158+ }
159+
160+ if (isContextOk == false)
161+ {
162+ apply_list[i] = false;
163+ if (context == PGC_SIGHUP)
164+ {
165+ if (isEqual == false)
166+ ereport(elevel,
167+ (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
168+ errmsg("parameter\" %s\" cannot be changed after server start; configuration file change ignored",
169+ item->name)));
170+ }
171+ else
172+ /* if it is boot phase, context must be valid for all
173+ * configuration item. */
174+ goto cleanup_list;
175+ }
176+ else
177+ apply_list[i] = true;
146178}
147179
148180/* If we got here all the options checked out okay, so apply them. */
149- for (item = head; item; item = item->next)
150- {
151- set_config_option(item->name, item->value, context,
152- PGC_S_FILE, false, true);
153- }
181+ for (item = head, i = 0 ; item; item = item->next, i++ )
182+ if (apply_list[i])
183+ set_config_option(item->name, item->value, context,
184+ PGC_S_FILE, false, true);
185+
154186
155- cleanup_list:
187+ cleanup_list:
188+ if (apply_list)
189+ pfree(apply_list);
156190free_name_value_list(head);
157191}
158192
@@ -189,13 +223,14 @@ static bool
189223ParseConfigFile (const char *config_file,const char *calling_file,
190224int depth, GucContext context,int elevel,
191225struct name_value_pair **head_p,
192- struct name_value_pair **tail_p)
226+ struct name_value_pair **tail_p,
227+ int *varcount)
193228{
194- bool OK =true ;
195- char abs_path[MAXPGPATH];
196- FILE *fp;
229+ bool OK =true ;
230+ char abs_path[MAXPGPATH];
231+ FILE *fp;
197232YY_BUFFER_STATE lex_buffer;
198- int token;
233+ int token;
199234
200235/*
201236 * Reject too-deep include nesting depth. This is just a safety check
@@ -289,7 +324,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
289324
290325if (!ParseConfigFile (opt_value, config_file,
291326 depth +1 , context, elevel,
292- head_p, tail_p))
327+ head_p, tail_p, varcount ))
293328{
294329pfree (opt_name);
295330pfree (opt_value);
@@ -333,6 +368,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
333368else
334369(*tail_p)->next = item;
335370*tail_p = item;
371+ (*varcount)++;
336372}
337373
338374/* break out of loop if read EOF, else loop for next line */