44 *
55 * Copyright (c) 2000-2007, PostgreSQL Global Development Group
66 *
7- * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.49 2007/03/13 14:32:25 petere Exp $
7+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.50 2007/04/21 20:02:40 petere Exp $
88 */
99
1010%{
@@ -116,6 +116,9 @@ ProcessConfigFile(GucContext context)
116116{
117117intelevel;
118118struct name_value_pair *item, *head, *tail;
119+ inti;
120+ bool *in_conffile = NULL;
121+ const char *var;
119122
120123Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
121124
@@ -140,19 +143,158 @@ ProcessConfigFile(GucContext context)
140143/* Check if all options are valid */
141144for (item = head; item; item = item->next)
142145{
146+ char *sep = strchr(item->name, GUC_QUALIFIER_SEPARATOR);
147+ if (sep && !is_custom_class(item->name, sep - item->name))
148+ {
149+ ereport(elevel,
150+ (errcode(ERRCODE_UNDEFINED_OBJECT),
151+ errmsg("unrecognized configuration parameter\" %s\" ",
152+ item->name)));
153+ goto cleanup_list;
154+ }
155+
143156if (!set_config_option(item->name, item->value, context,
144157 PGC_S_FILE, false, false))
145158goto cleanup_list;
146159}
147160
148- /* If we got here all the options checked out okay, so apply them. */
161+
162+ /*
163+ * Mark all variables as not showing up in the config file. The
164+ * allocation has to take place after ParseConfigFile() since this
165+ * function can change num_guc_variables due to custom variables.
166+ * It would be easier to add a new field or status bit to struct
167+ * conf_generic, but that way we would expose internal information
168+ * that is just needed here in the following few lines. The price
169+ * to pay for this separation are a few more loops over the set of
170+ * configuration options, but those are expected to be rather few
171+ * and we only have to pay the cost at SIGHUP. We initialize
172+ * in_conffile only here because set_config_option() makes
173+ * guc_variables grow with custom variables.
174+ */
175+ in_conffile = guc_malloc(elevel, num_guc_variables * sizeof(bool));
176+ if (!in_conffile)
177+ goto cleanup_list;
178+ for (i = 0; i < num_guc_variables; i++)
179+ in_conffile[i] = false;
180+
149181for (item = head; item; item = item->next)
150182{
183+ /*
184+ * After set_config_option() the variable name item->name is
185+ * known to exist.
186+ */
187+ Assert(guc_get_index(item->name) >= 0);
188+ in_conffile[guc_get_index(item->name)] = true;
189+ }
190+
191+ for (i = 0; i < num_guc_variables; i++)
192+ {
193+ struct config_generic *gconf = guc_variables[i];
194+ if (!in_conffile[i] && gconf->source == PGC_S_FILE)
195+ {
196+ if (gconf->context < PGC_SIGHUP)
197+ ereport(elevel,
198+ (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
199+ errmsg("parameter\" %s\" cannot be changed after server start; configuration file change ignored",
200+ gconf->name)));
201+ else
202+ {
203+ /* prepare */
204+ GucStack *stack;
205+ if (gconf->reset_source == PGC_S_FILE)
206+ gconf->reset_source = PGC_S_DEFAULT;
207+ for (stack = gconf->stack; stack; stack = stack->prev)
208+ if (stack->source == PGC_S_FILE)
209+ stack->source = PGC_S_DEFAULT;
210+ /* apply the default */
211+ set_config_option(gconf->name, NULL, context,
212+ PGC_S_DEFAULT, false, true);
213+ }
214+ }
215+ else if (!in_conffile[i] && gconf->reset_source == PGC_S_FILE)
216+ {
217+ /*------
218+ * Change the reset_val to default_val. Here' s an
219+ * example: In the configuration file we have
220+ *
221+ * seq_page_cost =3.00
222+ *
223+ * Now we execute in a session
224+ *
225+ * SET seq_page_cost TO4.00 ;
226+ *
227+ * Then we removethis option from the configuration file
228+ *and send SIGHUP. Now when you execute
229+ *
230+ * RESET seq_page_cost;
231+ *
232+ * it should fall back to1.00 (thedefault valuefor
233+ * seq_page_cost)and not to3.00 (which is the current
234+ * reset_val).
235+ */
236+
237+ switch (gconf->vartype)
238+ {
239+ case PGC_BOOL:
240+ {
241+ struct config_bool *conf;
242+ conf = (struct config_bool *) gconf;
243+ conf->reset_val = conf->boot_val ;
244+ break ;
245+ }
246+ case PGC_INT:
247+ {
248+ struct config_int *conf;
249+ conf = (struct config_int *) gconf;
250+ conf->reset_val = conf->boot_val ;
251+ break ;
252+ }
253+ case PGC_REAL:
254+ {
255+ struct config_real *conf;
256+ conf = (struct config_real *) gconf;
257+ conf->reset_val = conf->boot_val ;
258+ break ;
259+ }
260+ case PGC_STRING:
261+ {
262+ struct config_string *conf;
263+ conf = (struct config_string *) gconf;
264+ /*
265+ * We can cast away the const here because we
266+ * won't free the address. It is protected by
267+ * set_string_field() and string_field_used().
268+ */
269+ conf->reset_val = (char *) conf->boot_val ;
270+ break ;
271+ }
272+ }
273+ }
274+ }
275+
276+ /* If we got here all the options checked out okay, so apply them. */
277+ for (item = head; item; item = item->next)
151278set_config_option (item->name, item->value, context,
152279 PGC_S_FILE,false ,true );
153- }
280+
281+ /*
282+ * Reset variables to the value of environment variables
283+ * (PGC_S_ENV_VAR overrules PGC_S_FILE). PGPORT is ignored,
284+ * because it cannot be changed without restart.
285+ */
286+ var = getenv(" PGDATESTYLE" );
287+ if (var !=NULL )
288+ set_config_option (" datestyle" , var, context,
289+ PGC_S_ENV_VAR,false ,true );
290+
291+ var = getenv(" PGCLIENTENCODING" );
292+ if (var !=NULL )
293+ set_config_option (" client_encoding" , var, context,
294+ PGC_S_ENV_VAR,false ,true );
154295
155296 cleanup_list:
297+ free (in_conffile);
156298free_name_value_list (head);
157299}
158300
@@ -312,14 +454,14 @@ ParseConfigFile(const char *config_file, const char *calling_file,
312454{
313455pfree (opt_name);
314456pfree (opt_value);
315- /* we assume error message was logged already */
457+
458+ /* We assume the error message was logged already. */
316459OK =false ;
317460goto cleanup_exit;
318461}
319- pfree (opt_name);
320- pfree (opt_value);
321462}
322- else
463+
464+ if (pg_strcasecmp (opt_name," include" ) !=0 )
323465{
324466/* append to list */
325467struct name_value_pair *item;