Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
fb55af22
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
fb55af22
编写于
8月 12, 2006
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Back out patch to reorganize guc processing. Was causing regression
failures.
上级
2d2eec6e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
249 addition
and
414 deletion
+249
-414
src/backend/utils/misc/guc-file.l
src/backend/utils/misc/guc-file.l
+19
-55
src/backend/utils/misc/guc.c
src/backend/utils/misc/guc.c
+229
-355
src/include/utils/guc.h
src/include/utils/guc.h
+1
-4
未找到文件。
src/backend/utils/misc/guc-file.l
浏览文件 @
fb55af22
...
...
@@ -4,7 +4,7 @@
*
* Copyright (c) 2000-2006, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.4
1 2006/08/12 04:11:50
momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.4
2 2006/08/12 04:12:41
momjian Exp $
*/
%{
...
...
@@ -50,8 +50,7 @@ int GUC_yylex(void);
static bool ParseConfigFile(const char *config_file, const char *calling_file,
int depth, GucContext context, int elevel,
struct name_value_pair **head_p,
struct name_value_pair **tail_p,
int *varcount);
struct name_value_pair **tail_p);
static void free_name_value_list(struct name_value_pair * list);
static char *GUC_scanstr(const char *s);
...
...
@@ -115,10 +114,8 @@ STRING \'([^'\\\n]|\\.|\'\')*\'
void
ProcessConfigFile(GucContext context)
{
int elevel
, i
;
int elevel;
struct name_value_pair *item, *head, *tail;
bool *apply_list = NULL;
int varcount = 0;
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
...
...
@@ -137,56 +134,25 @@ ProcessConfigFile(GucContext context)
if (!ParseConfigFile(ConfigFileName, NULL,
0, context, elevel,
&head, &tail
, &varcount
))
&head, &tail))
goto cleanup_list;
/* Can we allocate memory here, what about leaving here prematurely? */
apply_list = (bool *) palloc(sizeof(bool) * varcount);
/* Check if all options are valid */
for (item = head
, i = 0; item; item = item->next, i++
)
for (item = head
; item; item = item->next
)
{
bool isEqual, isContextOk;
if (!verify_config_option(item->name, item->value, context,
PGC_S_FILE, &isEqual, &isContextOk))
{
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("configuration file is invalid")));
if (!set_config_option(item->name, item->value, context,
PGC_S_FILE, false, false))
goto cleanup_list;
}
if( isContextOk == false )
{
apply_list[i] = false;
if( context == PGC_SIGHUP )
{
if ( isEqual == false )
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
item->name)));
}
else
/* if it is boot phase, context must be valid for all
* configuration item. */
goto cleanup_list;
}
else
apply_list[i] = true;
}
/* If we got here all the options checked out okay, so apply them. */
for (item = head
, i = 0; item; item = item->next, i++
)
if (apply_list[i])
set_config_option(item->name, item->value, context,
PGC_S_FILE, false, true);
for (item = head
; item; item = item->next
)
{
set_config_option(item->name, item->value, context,
PGC_S_FILE, false, true);
}
cleanup_list:
if (apply_list)
pfree(apply_list);
cleanup_list:
free_name_value_list(head);
}
...
...
@@ -223,14 +189,13 @@ static bool
ParseConfigFile(const char *config_file, const char *calling_file,
int depth, GucContext context, int elevel,
struct name_value_pair **head_p,
struct name_value_pair **tail_p,
int *varcount)
struct name_value_pair **tail_p)
{
bool
OK = true;
char
abs_path[MAXPGPATH];
FILE
*fp;
bool OK = true;
char abs_path[MAXPGPATH];
FILE *fp;
YY_BUFFER_STATE lex_buffer;
int
token;
int token;
/*
* Reject too-deep include nesting depth. This is just a safety check
...
...
@@ -324,7 +289,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
if (!ParseConfigFile(opt_value, config_file,
depth + 1, context, elevel,
head_p, tail_p
, varcount
))
head_p, tail_p))
{
pfree(opt_name);
pfree(opt_value);
...
...
@@ -368,7 +333,6 @@ ParseConfigFile(const char *config_file, const char *calling_file,
else
(*tail_p)->next = item;
*tail_p = item;
(*varcount)++;
}
/* break out of loop if read EOF, else loop for next line */
...
...
src/backend/utils/misc/guc.c
浏览文件 @
fb55af22
...
...
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.33
6 2006/08/12 04:11:50
momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.33
7 2006/08/12 04:12:41
momjian Exp $
*
*--------------------------------------------------------------------
*/
...
...
@@ -3690,258 +3690,96 @@ call_string_assign_hook(GucStringAssignHook assign_hook,
return
result
;
}
/*
* Try to parse value. Determine what is type and call related
* parsing function or if newval is equal to NULL, reset value
* to default or bootval. If the value parsed okay return true,
* else false.
* Sets option `name' to given value. The value should be a string
* which is going to be parsed and converted to the appropriate data
* type. The context and source parameters indicate in which context this
* function is being called so it can apply the access restrictions
* properly.
*
* If value is NULL, set the option to its default value. If the
* parameter changeVal is false then don't really set the option but do all
* the checks to see if it would work.
*
* If there is an error (non-existing option, invalid value) then an
* ereport(ERROR) is thrown *unless* this is called in a context where we
* don't want to ereport (currently, startup or SIGHUP config file reread).
* In that case we write a suitable error message via ereport(DEBUG) and
* return false. This is working around the deficiencies in the ereport
* mechanism, so don't blame me. In all other cases, the function
* returns true, including cases where the input is valid but we chose
* not to apply it because of context or source-priority considerations.
*
* See also SetConfigOption for an external interface.
*/
static
bool
parse_value
(
int
elevel
,
const
struct
config_generic
*
record
,
const
char
*
value
,
GucSource
*
source
,
bool
changeVal
,
union
config_var_value
*
retv
al
)
bool
set_config_option
(
const
char
*
name
,
const
char
*
value
,
GucContext
context
,
GucSource
source
,
bool
isLocal
,
bool
changeV
al
)
{
struct
config_generic
*
record
;
int
elevel
;
bool
makeDefault
;
Assert
(
!
(
changeVal
&&
retval
==
NULL
)
);
/*
* Evaluate value and set variable.
*/
switch
(
record
->
vartype
)
if
(
context
==
PGC_SIGHUP
||
source
==
PGC_S_DEFAULT
)
{
case
PGC_BOOL
:
{
struct
config_bool
*
conf
=
(
struct
config_bool
*
)
record
;
bool
newval
;
if
(
value
)
{
if
(
!
parse_bool
(
value
,
&
newval
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires a Boolean value"
,
record
->
name
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
*
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
*
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %d"
,
record
->
name
,
(
int
)
newval
)));
return
false
;
}
if
(
retval
!=
NULL
)
retval
->
boolval
=
newval
;
break
;
}
case
PGC_INT
:
{
struct
config_int
*
conf
=
(
struct
config_int
*
)
record
;
int
newval
;
if
(
value
)
{
if
(
!
parse_int
(
value
,
&
newval
,
conf
->
gen
.
flags
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires an integer value"
,
record
->
name
)));
return
false
;
}
if
(
newval
<
conf
->
min
||
newval
>
conf
->
max
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"%d is outside the valid range for parameter
\"
%s
\"
(%d .. %d)"
,
newval
,
record
->
name
,
conf
->
min
,
conf
->
max
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
*
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
*
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %d"
,
record
->
name
,
newval
)));
return
false
;
}
if
(
retval
!=
NULL
)
retval
->
intval
=
newval
;
break
;
}
case
PGC_REAL
:
{
struct
config_real
*
conf
=
(
struct
config_real
*
)
record
;
double
newval
;
if
(
value
)
{
if
(
!
parse_real
(
value
,
&
newval
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires a numeric value"
,
record
->
name
)));
return
false
;
}
if
(
newval
<
conf
->
min
||
newval
>
conf
->
max
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"%g is outside the valid range for parameter
\"
%s
\"
(%g .. %g)"
,
newval
,
record
->
name
,
conf
->
min
,
conf
->
max
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
*
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
*
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %g"
,
record
->
name
,
newval
)));
return
false
;
}
if
(
retval
!=
NULL
)
retval
->
realval
=
newval
;
break
;
}
case
PGC_STRING
:
{
struct
config_string
*
conf
=
(
struct
config_string
*
)
record
;
char
*
newval
;
if
(
value
)
{
newval
=
guc_strdup
(
elevel
,
value
);
if
(
newval
==
NULL
)
return
false
;
/*
* The only sort of "parsing" check we need to do is
* apply truncation if GUC_IS_NAME.
*/
if
(
conf
->
gen
.
flags
&
GUC_IS_NAME
)
truncate_identifier
(
newval
,
strlen
(
newval
),
true
);
}
else
if
(
conf
->
reset_val
)
{
/*
* We could possibly avoid strdup here, but easier to make
* this case work the same as the normal assignment case.
*/
newval
=
guc_strdup
(
elevel
,
conf
->
reset_val
);
if
(
newval
==
NULL
)
return
false
;
*
source
=
conf
->
gen
.
reset_source
;
}
else
{
/* Nothing to reset to, as yet; so do nothing */
break
;
}
if
(
conf
->
assign_hook
)
{
const
char
*
hookresult
;
/*
* If the hook ereports, we have to make sure we free
* newval, else it will be a permanent memory leak.
*/
hookresult
=
call_string_assign_hook
(
conf
->
assign_hook
,
newval
,
changeVal
,
*
source
);
if
(
hookresult
==
NULL
)
{
free
(
newval
);
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
:
\"
%s
\"
"
,
record
->
name
,
value
?
value
:
""
)));
return
false
;
}
else
if
(
hookresult
!=
newval
)
{
free
(
newval
);
/*
* Having to cast away const here is annoying, but the
* alternative is to declare assign_hooks as returning
* char*, which would mean they'd have to cast away
* const, or as both taking and returning char*, which
* doesn't seem attractive either --- we don't want
* them to scribble on the passed str.
*/
newval
=
(
char
*
)
hookresult
;
}
}
/*
* To avoid cluttering the log, only the postmaster bleats loudly
* about problems with the config file.
*/
elevel
=
IsUnderPostmaster
?
DEBUG2
:
LOG
;
}
else
if
(
source
==
PGC_S_DATABASE
||
source
==
PGC_S_USER
)
elevel
=
INFO
;
else
elevel
=
ERROR
;
if
(
!
changeVal
)
free
(
newval
);
if
(
retval
!=
NULL
)
retval
->
stringval
=
newval
;
break
;
}
record
=
find_option
(
name
,
elevel
);
if
(
record
==
NULL
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_UNDEFINED_OBJECT
),
errmsg
(
"unrecognized configuration parameter
\"
%s
\"
"
,
name
)));
return
false
;
}
return
true
;
}
/*
* Check if the option can be set at this time. See guc.h for the precise
* rules.
*/
static
bool
checkContext
(
int
elevel
,
struct
config_generic
*
record
,
GucContext
context
)
{
/*
* Check if the option can be set at this time. See guc.h for the precise
* rules. Note that we don't want to throw errors if we're in the SIGHUP
* context. In that case we just ignore the attempt and return true.
*/
switch
(
record
->
context
)
{
case
PGC_INTERNAL
:
if
(
context
==
PGC_SIGHUP
)
return
true
;
if
(
context
!=
PGC_INTERNAL
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_CANT_CHANGE_RUNTIME_PARAM
),
errmsg
(
"parameter
\"
%s
\"
cannot be changed"
,
record
->
name
)));
name
)));
return
false
;
}
break
;
case
PGC_POSTMASTER
:
if
(
context
==
PGC_SIGHUP
)
return
false
;
{
if
(
changeVal
&&
!
is_newvalue_equal
(
record
,
value
))
ereport
(
elevel
,
(
errcode
(
ERRCODE_CANT_CHANGE_RUNTIME_PARAM
),
errmsg
(
"parameter
\"
%s
\"
cannot be changed after server start; configuration file change ignored"
,
name
)));
return
true
;
}
if
(
context
!=
PGC_POSTMASTER
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_CANT_CHANGE_RUNTIME_PARAM
),
errmsg
(
"parameter
\"
%s
\"
cannot be changed after server start"
,
record
->
name
)));
name
)));
return
false
;
}
break
;
...
...
@@ -3951,7 +3789,7 @@ checkContext(int elevel, struct config_generic *record, GucContext context)
ereport
(
elevel
,
(
errcode
(
ERRCODE_CANT_CHANGE_RUNTIME_PARAM
),
errmsg
(
"parameter
\"
%s
\"
cannot be changed now"
,
record
->
name
)));
name
)));
return
false
;
}
...
...
@@ -3974,16 +3812,14 @@ checkContext(int elevel, struct config_generic *record, GucContext context)
* backend start.
*/
if
(
IsUnderPostmaster
)
{
return
false
;
}
return
true
;
}
else
if
(
context
!=
PGC_BACKEND
&&
context
!=
PGC_POSTMASTER
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_CANT_CHANGE_RUNTIME_PARAM
),
errmsg
(
"parameter
\"
%s
\"
cannot be set after connection start"
,
record
->
name
)));
name
)));
return
false
;
}
break
;
...
...
@@ -3993,7 +3829,7 @@ checkContext(int elevel, struct config_generic *record, GucContext context)
ereport
(
elevel
,
(
errcode
(
ERRCODE_INSUFFICIENT_PRIVILEGE
),
errmsg
(
"permission denied to set parameter
\"
%s
\"
"
,
record
->
name
)));
name
)));
return
false
;
}
break
;
...
...
@@ -4001,115 +3837,6 @@ checkContext(int elevel, struct config_generic *record, GucContext context)
/* always okay */
break
;
}
return
true
;
}
/*
* Get error level for different sources and context.
*/
static
int
get_elevel
(
GucContext
context
,
GucSource
source
)
{
int
elevel
;
if
(
context
==
PGC_SIGHUP
||
source
==
PGC_S_DEFAULT
)
{
/*
* To avoid cluttering the log, only the postmaster bleats loudly
* about problems with the config file.
*/
elevel
=
IsUnderPostmaster
?
DEBUG2
:
LOG
;
}
else
if
(
source
==
PGC_S_DATABASE
||
source
==
PGC_S_USER
)
elevel
=
INFO
;
else
elevel
=
ERROR
;
return
elevel
;
}
/*
* Verify if option exists and value is valid.
* It is primary used for validation of items in configuration file.
*/
bool
verify_config_option
(
const
char
*
name
,
const
char
*
value
,
GucContext
context
,
GucSource
source
,
bool
*
isNewEqual
,
bool
*
isContextOK
)
{
union
config_var_value
newval
;
int
elevel
;
struct
config_generic
*
record
;
elevel
=
get_elevel
(
context
,
source
);
record
=
find_option
(
name
,
elevel
);
if
(
record
==
NULL
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_UNDEFINED_OBJECT
),
errmsg
(
"unrecognized configuration parameter
\"
%s
\"
"
,
name
)));
return
false
;
}
if
(
parse_value
(
elevel
,
record
,
value
,
&
source
,
false
,
&
newval
)
)
{
if
(
isNewEqual
!=
NULL
)
*
isNewEqual
=
is_newvalue_equal
(
record
,
value
);
if
(
isContextOK
!=
NULL
)
*
isContextOK
=
checkContext
(
elevel
,
record
,
context
);
}
else
return
false
;
return
true
;
}
/*
* Sets option `name' to given value. The value should be a string
* which is going to be parsed and converted to the appropriate data
* type. The context and source parameters indicate in which context this
* function is being called so it can apply the access restrictions
* properly.
*
* If value is NULL, set the option to its default value. If the
* parameter changeVal is false then don't really set the option but do all
* the checks to see if it would work.
*
* If there is an error (non-existing option, invalid value) then an
* ereport(ERROR) is thrown *unless* this is called in a context where we
* don't want to ereport (currently, startup or SIGHUP config file reread).
* In that case we write a suitable error message via ereport(DEBUG) and
* return false. This is working around the deficiencies in the ereport
* mechanism, so don't blame me. In all other cases, the function
* returns true, including cases where the input is valid but we chose
* not to apply it because of context or source-priority considerations.
*
* See also SetConfigOption for an external interface.
*/
bool
set_config_option
(
const
char
*
name
,
const
char
*
value
,
GucContext
context
,
GucSource
source
,
bool
isLocal
,
bool
changeVal
)
{
struct
config_generic
*
record
;
int
elevel
;
bool
makeDefault
;
elevel
=
get_elevel
(
context
,
source
);
record
=
find_option
(
name
,
elevel
);
if
(
record
==
NULL
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_UNDEFINED_OBJECT
),
errmsg
(
"unrecognized configuration parameter
\"
%s
\"
"
,
name
)));
return
false
;
}
/* Check if change is allowed in the running context. */
if
(
!
checkContext
(
elevel
,
record
,
context
)
)
return
false
;
/*
* Should we set reset/stacked values? (If so, the behavior is not
...
...
@@ -4144,9 +3871,33 @@ set_config_option(const char *name, const char *value,
{
struct
config_bool
*
conf
=
(
struct
config_bool
*
)
record
;
bool
newval
;
if
(
!
parse_value
(
elevel
,
record
,
value
,
&
source
,
changeVal
,
(
union
config_var_value
*
)
&
newval
)
)
return
false
;
if
(
value
)
{
if
(
!
parse_bool
(
value
,
&
newval
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires a Boolean value"
,
name
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %d"
,
name
,
(
int
)
newval
)));
return
false
;
}
if
(
changeVal
||
makeDefault
)
{
...
...
@@ -4197,8 +3948,40 @@ set_config_option(const char *name, const char *value,
struct
config_int
*
conf
=
(
struct
config_int
*
)
record
;
int
newval
;
if
(
!
parse_value
(
elevel
,
record
,
value
,
&
source
,
changeVal
,
(
union
config_var_value
*
)
&
newval
)
)
return
false
;
if
(
value
)
{
if
(
!
parse_int
(
value
,
&
newval
,
conf
->
gen
.
flags
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires an integer value"
,
name
)));
return
false
;
}
if
(
newval
<
conf
->
min
||
newval
>
conf
->
max
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"%d is outside the valid range for parameter
\"
%s
\"
(%d .. %d)"
,
newval
,
name
,
conf
->
min
,
conf
->
max
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %d"
,
name
,
newval
)));
return
false
;
}
if
(
changeVal
||
makeDefault
)
{
...
...
@@ -4249,8 +4032,40 @@ set_config_option(const char *name, const char *value,
struct
config_real
*
conf
=
(
struct
config_real
*
)
record
;
double
newval
;
if
(
!
parse_value
(
elevel
,
record
,
value
,
&
source
,
changeVal
,
(
union
config_var_value
*
)
&
newval
)
)
return
false
;
if
(
value
)
{
if
(
!
parse_real
(
value
,
&
newval
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"parameter
\"
%s
\"
requires a numeric value"
,
name
)));
return
false
;
}
if
(
newval
<
conf
->
min
||
newval
>
conf
->
max
)
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"%g is outside the valid range for parameter
\"
%s
\"
(%g .. %g)"
,
newval
,
name
,
conf
->
min
,
conf
->
max
)));
return
false
;
}
}
else
{
newval
=
conf
->
reset_val
;
source
=
conf
->
gen
.
reset_source
;
}
if
(
conf
->
assign_hook
)
if
(
!
(
*
conf
->
assign_hook
)
(
newval
,
changeVal
,
source
))
{
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
: %g"
,
name
,
newval
)));
return
false
;
}
if
(
changeVal
||
makeDefault
)
{
...
...
@@ -4301,8 +4116,71 @@ set_config_option(const char *name, const char *value,
struct
config_string
*
conf
=
(
struct
config_string
*
)
record
;
char
*
newval
;
if
(
!
parse_value
(
elevel
,
record
,
value
,
&
source
,
changeVal
,
(
union
config_var_value
*
)
&
newval
)
)
return
false
;
if
(
value
)
{
newval
=
guc_strdup
(
elevel
,
value
);
if
(
newval
==
NULL
)
return
false
;
/*
* The only sort of "parsing" check we need to do is
* apply truncation if GUC_IS_NAME.
*/
if
(
conf
->
gen
.
flags
&
GUC_IS_NAME
)
truncate_identifier
(
newval
,
strlen
(
newval
),
true
);
}
else
if
(
conf
->
reset_val
)
{
/*
* We could possibly avoid strdup here, but easier to make
* this case work the same as the normal assignment case.
*/
newval
=
guc_strdup
(
elevel
,
conf
->
reset_val
);
if
(
newval
==
NULL
)
return
false
;
source
=
conf
->
gen
.
reset_source
;
}
else
{
/* Nothing to reset to, as yet; so do nothing */
break
;
}
if
(
conf
->
assign_hook
)
{
const
char
*
hookresult
;
/*
* If the hook ereports, we have to make sure we free
* newval, else it will be a permanent memory leak.
*/
hookresult
=
call_string_assign_hook
(
conf
->
assign_hook
,
newval
,
changeVal
,
source
);
if
(
hookresult
==
NULL
)
{
free
(
newval
);
ereport
(
elevel
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid value for parameter
\"
%s
\"
:
\"
%s
\"
"
,
name
,
value
?
value
:
""
)));
return
false
;
}
else
if
(
hookresult
!=
newval
)
{
free
(
newval
);
/*
* Having to cast away const here is annoying, but the
* alternative is to declare assign_hooks as returning
* char*, which would mean they'd have to cast away
* const, or as both taking and returning char*, which
* doesn't seem attractive either --- we don't want
* them to scribble on the passed str.
*/
newval
=
(
char
*
)
hookresult
;
}
}
if
(
changeVal
||
makeDefault
)
{
...
...
@@ -4350,8 +4228,7 @@ set_config_option(const char *name, const char *value,
}
}
else
if
(
newval
!=
NULL
)
free
(
newval
);
free
(
newval
);
break
;
}
}
...
...
@@ -5437,9 +5314,6 @@ _ShowOption(struct config_generic * record, bool use_units)
static
bool
is_newvalue_equal
(
struct
config_generic
*
record
,
const
char
*
newvalue
)
{
if
(
!
newvalue
)
return
false
;
switch
(
record
->
vartype
)
{
case
PGC_BOOL
:
...
...
src/include/utils/guc.h
浏览文件 @
fb55af22
...
...
@@ -7,7 +7,7 @@
* Copyright (c) 2000-2006, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.7
2 2006/08/11 20:08:28
momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.7
3 2006/08/12 04:12:41
momjian Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
...
...
@@ -193,9 +193,6 @@ extern void ParseLongOption(const char *string, char **name, char **value);
extern
bool
set_config_option
(
const
char
*
name
,
const
char
*
value
,
GucContext
context
,
GucSource
source
,
bool
isLocal
,
bool
changeVal
);
extern
bool
verify_config_option
(
const
char
*
name
,
const
char
*
value
,
GucContext
context
,
GucSource
source
,
bool
*
isNewEqual
,
bool
*
isContextOK
);
extern
char
*
GetConfigOptionByName
(
const
char
*
name
,
const
char
**
varname
);
extern
void
GetConfigOptionByNum
(
int
varnum
,
const
char
**
values
,
bool
*
noshow
);
extern
int
GetNumConfigOptions
(
void
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录