4
4
*
5
5
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
6
6
*
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 $
8
8
*/
9
9
10
10
%{
@@ -116,6 +116,9 @@ ProcessConfigFile(GucContext context)
116
116
{
117
117
intelevel;
118
118
struct name_value_pair *item, *head, *tail;
119
+ inti;
120
+ bool *in_conffile = NULL;
121
+ const char *var;
119
122
120
123
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
121
124
@@ -140,19 +143,158 @@ ProcessConfigFile(GucContext context)
140
143
/* Check if all options are valid */
141
144
for (item = head; item; item = item->next)
142
145
{
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
+
143
156
if (!set_config_option(item->name, item->value, context,
144
157
PGC_S_FILE, false, false))
145
158
goto cleanup_list;
146
159
}
147
160
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
+
149
181
for (item = head; item; item = item->next)
150
182
{
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)
151
278
set_config_option (item->name, item->value, context,
152
279
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 );
154
295
155
296
cleanup_list:
297
+ free (in_conffile);
156
298
free_name_value_list (head);
157
299
}
158
300
@@ -312,14 +454,14 @@ ParseConfigFile(const char *config_file, const char *calling_file,
312
454
{
313
455
pfree (opt_name);
314
456
pfree (opt_value);
315
- /* we assume error message was logged already */
457
+
458
+ /* We assume the error message was logged already. */
316
459
OK =false ;
317
460
goto cleanup_exit;
318
461
}
319
- pfree (opt_name);
320
- pfree (opt_value);
321
462
}
322
- else
463
+
464
+ if (pg_strcasecmp (opt_name," include" ) !=0 )
323
465
{
324
466
/* append to list */
325
467
struct name_value_pair *item;