forked from huawei/openGauss-server
add: AlterSystemSet
This commit is contained in:
parent
5eaa986a1e
commit
36ef69d49a
|
|
@ -87,6 +87,7 @@
|
|||
|
||||
static void CopyMemInfoFields(const OpMemInfo* from, OpMemInfo* newnode);
|
||||
static ReplicaIdentityStmt* _copyReplicaIdentityStmt(const ReplicaIdentityStmt* from);
|
||||
static AlterSystemStmt* _copyAlterSystemStmt(const AlterSystemStmt * from);
|
||||
|
||||
static void CopyCursorFields(const Cursor_Data* from, Cursor_Data* newnode);
|
||||
/* ****************************************************************
|
||||
|
|
@ -6401,6 +6402,9 @@ void* copyObject(const void* from)
|
|||
case T_ReplicaIdentityStmt:
|
||||
retval = _copyReplicaIdentityStmt((ReplicaIdentityStmt*)from);
|
||||
break;
|
||||
case T_AlterSystemStmt:
|
||||
retval = _copyAlterSystemStmt((AlterSystemStmt*)from);
|
||||
break;
|
||||
case T_CreateSeqStmt:
|
||||
retval = _copyCreateSeqStmt((CreateSeqStmt*)from);
|
||||
break;
|
||||
|
|
@ -6827,6 +6831,13 @@ static ReplicaIdentityStmt* _copyReplicaIdentityStmt(const ReplicaIdentityStmt*
|
|||
return newnode;
|
||||
}
|
||||
|
||||
static AlterSystemStmt* _copyAlterSystemStmt(const AlterSystemStmt * from)
|
||||
{
|
||||
AlterSystemStmt* newnode = makeNode(AlterSystemStmt);
|
||||
COPY_NODE_FIELD(setstmt);
|
||||
return newnode;
|
||||
}
|
||||
|
||||
/*
|
||||
* CopyCursorFields -
|
||||
* copy Cursor_Data structure from "from" node to "newnode"
|
||||
|
|
|
|||
|
|
@ -1567,6 +1567,12 @@ static bool _equalReplicaIdentityStmt(const ReplicaIdentityStmt* a, const Replic
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool _equalAlterSystemStmt(const AlterSystemStmt * a, const AlterSystemStmt * b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(setstmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _equalCreateSeqStmt(const CreateSeqStmt* a, const CreateSeqStmt* b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(sequence);
|
||||
|
|
@ -3130,6 +3136,9 @@ bool equal(const void* a, const void* b)
|
|||
case T_ReplicaIdentityStmt:
|
||||
retval = _equalReplicaIdentityStmt((ReplicaIdentityStmt*)a, (ReplicaIdentityStmt*)b);
|
||||
break;
|
||||
case T_AlterSystemStmt:
|
||||
retval = _equalAlterSystemStmt((AlterSystemStmt*)a, (AlterSystemStmt*)b);
|
||||
break;
|
||||
case T_AlterSeqStmt:
|
||||
retval = _equalAlterSeqStmt((AlterSeqStmt*)a, (AlterSeqStmt*)b);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ static void processCASbits(int cas_bits, int location, const char *constrType,
|
|||
bool *deferrable, bool *initdeferred, bool *not_valid,
|
||||
bool *no_inherit, core_yyscan_t yyscanner);
|
||||
static Expr *makeNodeDecodeCondtion(Expr* firstCond,Expr* secondCond);
|
||||
static void is_kill_session(List *actionlist);
|
||||
static List *make_action_func(List *arguments);
|
||||
static List *get_func_args(char *sid);
|
||||
static char *pg_strsep(char **stringp, const char *delim);
|
||||
|
|
@ -451,7 +450,7 @@ static void ParseUpdateMultiSet(List *set_target_list, SelectStmt *stmt, core_yy
|
|||
|
||||
%type <mergewhen> merge_insert merge_update
|
||||
|
||||
%type <vsetstmt> set_rest set_rest_more SetResetClause FunctionSetResetClause
|
||||
%type <vsetstmt> generic_set set_rest set_rest_more SetResetClause FunctionSetResetClause
|
||||
|
||||
%type <node> TableElement TypedTableElement ConstraintElem TableFuncElement
|
||||
ForeignTableElement
|
||||
|
|
@ -637,7 +636,7 @@ static void ParseUpdateMultiSet(List *set_target_list, SelectStmt *stmt, core_yy
|
|||
/* PGXC_BEGIN */
|
||||
DICTIONARY DIRECT DIRECTORY DISABLE_P DISCARD DISTINCT DISTRIBUTE DISTRIBUTION DO DOCUMENT_P DOMAIN_P DOUBLE_P
|
||||
/* PGXC_END */
|
||||
DROP DUPLICATE
|
||||
DROP DUPLICATE DISCONNECT
|
||||
|
||||
EACH ELASTIC ELSE ENABLE_P ENCODING ENCRYPTED END_P ENFORCED ENUM_P ERRORS ESCAPE EOL ESCAPING EVERY EXCEPT EXCHANGE
|
||||
EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN
|
||||
|
|
@ -657,7 +656,7 @@ static void ParseUpdateMultiSet(List *set_target_list, SelectStmt *stmt, core_yy
|
|||
|
||||
JOIN
|
||||
|
||||
KEY
|
||||
KEY KILL
|
||||
|
||||
LABEL LANGUAGE LARGE_P LAST_P LC_COLLATE_P LC_CTYPE_P LEADING LEAKPROOF
|
||||
LEAST LESS LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP
|
||||
|
|
@ -1507,17 +1506,19 @@ AlterSessionStmt:
|
|||
/* "alter system" */
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Alter SYSTEM (kill a session)
|
||||
* Alter SYSTEM
|
||||
* (1. kill a session by "select pg_terminate_backend(pid)", so it only needs a SelectStmt node.)
|
||||
* (2. disconnect a session. unsupported currently.)
|
||||
* (3. set system parameter to, this is used to change configuration parameters persistently.)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
AlterSystemStmt:
|
||||
ALTER SYSTEM_P name_list SESSION Sconst altersys_option
|
||||
ALTER SYSTEM_P KILL SESSION Sconst altersys_option
|
||||
{
|
||||
SelectStmt *n = NULL;
|
||||
List *pid = NULL;
|
||||
|
||||
is_kill_session($3);
|
||||
pid = get_func_args($5);
|
||||
|
||||
n = makeNode(SelectStmt);
|
||||
|
|
@ -1531,7 +1532,22 @@ AlterSystemStmt:
|
|||
n->windowClause = NIL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
|
||||
| ALTER SYSTEM_P DISCONNECT SESSION Sconst altersys_option
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("unsupported action \"DISCONNECT\" for statement \" alter system \"")));
|
||||
}
|
||||
|
||||
| ALTER SYSTEM_P SET generic_set
|
||||
{
|
||||
AlterSystemStmt *n = makeNode(AlterSystemStmt);
|
||||
n->setstmt = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
altersys_option:
|
||||
IMMEDIATE {/* empty */}
|
||||
| {/* empty */}
|
||||
|
|
@ -1666,7 +1682,7 @@ set_rest:
|
|||
| set_rest_more
|
||||
;
|
||||
|
||||
set_rest_more: /* Generic SET syntaxes: */
|
||||
generic_set:
|
||||
var_name TO var_list
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
|
|
@ -1751,6 +1767,13 @@ set_rest_more: /* Generic SET syntaxes: */
|
|||
n->name = "current_schema";
|
||||
$$ = n;
|
||||
}
|
||||
;
|
||||
|
||||
set_rest_more: /* Generic SET syntaxes: */
|
||||
generic_set
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| var_name FROM CURRENT_P
|
||||
{
|
||||
VariableSetStmt *n = makeNode(VariableSetStmt);
|
||||
|
|
@ -11398,7 +11421,6 @@ DropdbStmt: DROP DATABASE database_name
|
|||
}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Manipulate a domain
|
||||
|
|
@ -17671,6 +17693,7 @@ unreserved_keyword:
|
|||
| DIRECTORY
|
||||
| DISABLE_P
|
||||
| DISCARD
|
||||
| DISCONNECT
|
||||
/* PGXC_BEGIN */
|
||||
| DISTRIBUTE
|
||||
| DISTRIBUTION
|
||||
|
|
@ -17742,6 +17765,7 @@ unreserved_keyword:
|
|||
| ISNULL
|
||||
| ISOLATION
|
||||
| KEY
|
||||
| KILL
|
||||
| LABEL
|
||||
| LANGUAGE
|
||||
| LARGE_P
|
||||
|
|
@ -18858,45 +18882,6 @@ makeNodeDecodeCondtion(Expr* firstCond,Expr* secondCond)
|
|||
return (Expr*)c;
|
||||
}
|
||||
|
||||
// check weather is an action of "kill session"
|
||||
// unsupported action "disconnect"
|
||||
static void
|
||||
is_kill_session(List *actionlist)
|
||||
{
|
||||
char *actionopt = NULL;
|
||||
ListCell *lc = NULL;
|
||||
|
||||
if (1 != actionlist->length)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("undefined or invalid action for statement \" alter system \"")));
|
||||
return;
|
||||
}
|
||||
|
||||
lc = list_head(actionlist);
|
||||
actionopt = ((Value *)(lfirst(lc)))->val.str;
|
||||
|
||||
if (!pg_strcasecmp(actionopt, "KILL"))
|
||||
return;
|
||||
else if (!pg_strcasecmp(actionopt, "DISCONNECT"))
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("unsupported action \"%s\" for statement \" alter system \"",
|
||||
actionopt)));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("undefined action \"%s\" for statement \" alter system \"",
|
||||
actionopt)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// make function infomation to kill the session
|
||||
// make "ResTarget" for invoking function "pg_terminate_backend",
|
||||
// only the first cell of arguments is effective, it is treated as pid
|
||||
|
|
|
|||
|
|
@ -483,6 +483,8 @@ static const char* show_unix_socket_permissions(void);
|
|||
static const char* show_log_file_mode(void);
|
||||
static char* config_enum_get_options(
|
||||
struct config_enum* record, const char* prefix, const char* suffix, const char* separator);
|
||||
static bool validate_conf_option(struct config_generic * record, const char *name, const char *value,
|
||||
GucSource source, int elevel, bool freemem, void *newval, void **newextra);
|
||||
|
||||
/* Database Security: Support password complexity */
|
||||
static bool check_int_parameter(int* newval, void** extra, GucSource source);
|
||||
|
|
@ -11885,6 +11887,7 @@ static void show_guc_config_option(const char* name, DestReceiver* dest);
|
|||
static void show_all_guc_config(DestReceiver* dest);
|
||||
static char* _show_option(struct config_generic* record, bool use_units);
|
||||
static bool validate_option_array_item(const char* name, const char* value, bool skip_if_no_permissions);
|
||||
static void replace_config_value(char** optlines, char* name, char* value, config_type vartype);
|
||||
|
||||
/*
|
||||
* Some infrastructure for checking malloc/strdup/realloc calls
|
||||
|
|
@ -14324,6 +14327,202 @@ static char* config_enum_get_options(
|
|||
return retstr.data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates configuration parameter and value, by calling check hook functions
|
||||
* depending on record's vartype. It validates if the parameter
|
||||
* value given is in range of expected predefined value for that parameter.
|
||||
*
|
||||
* freemem - true indicates memory for newval and newextra will be
|
||||
* freed in this function, false indicates it will be freed
|
||||
* by caller.
|
||||
* Return value:
|
||||
* true : the value is valid
|
||||
* false: the name or value is invalid
|
||||
*/
|
||||
bool validate_conf_option(struct config_generic * record, const char *name, const char *value, GucSource source,
|
||||
int elevel, bool freemem, void *newvalue, void **newextra)
|
||||
{
|
||||
Assert(value != NULL);
|
||||
|
||||
/*
|
||||
* Validate the value for the passed record, to ensure it is in expected range.
|
||||
*/
|
||||
switch (record->vartype)
|
||||
{
|
||||
case PGC_BOOL:
|
||||
{
|
||||
struct config_bool *conf = (struct config_bool *) record;
|
||||
bool tmpnewval;
|
||||
bool* newval = (newvalue == NULL ? &tmpnewval : (bool*)newvalue);
|
||||
|
||||
if (!parse_bool(value, newval)) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("parameter \"%s\" requires a Boolean value", name)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!call_bool_check_hook(conf, newval, newextra, source, elevel))
|
||||
return false;
|
||||
|
||||
if (*newextra && freemem)
|
||||
pfree(*newextra);
|
||||
}
|
||||
break;
|
||||
case PGC_INT:
|
||||
{
|
||||
struct config_int *conf = (struct config_int *) record;
|
||||
int tmpnewval;
|
||||
int* newval = (newvalue == NULL ? &tmpnewval : (int*)newvalue);
|
||||
const char *hintmsg = NULL;
|
||||
|
||||
if (!parse_int(value, newval, conf->gen.flags, &hintmsg)) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid value for parameter \"%s\": \"%s\"",
|
||||
name, value), hintmsg ? errhint("%s", _(hintmsg)) : 0));
|
||||
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;
|
||||
}
|
||||
|
||||
if (!call_int_check_hook(conf, newval, newextra, source, elevel))
|
||||
return false;
|
||||
|
||||
if (*newextra && freemem)
|
||||
pfree(*newextra);
|
||||
}
|
||||
break;
|
||||
case PGC_INT64:
|
||||
{
|
||||
struct config_int64* conf = (struct config_int64*)record;
|
||||
int64 tmpnewval;
|
||||
int64* newval = (newvalue == NULL ? &tmpnewval : (int64*)newvalue);
|
||||
const char* hintmsg = NULL;
|
||||
|
||||
if (!parse_int64(value, newval, &hintmsg)) {
|
||||
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("%ld is outside the valid range for parameter \"%s\" (%ld .. %ld)",
|
||||
*newval, name, conf->min, conf->max)));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!call_int64_check_hook(conf, newval, newextra, source, elevel))
|
||||
return false;
|
||||
|
||||
if (*newextra && freemem)
|
||||
pfree(newextra);
|
||||
}
|
||||
break;
|
||||
case PGC_REAL:
|
||||
{
|
||||
struct config_real *conf = (struct config_real *) record;
|
||||
double tmpnewval;
|
||||
double* newval = (newvalue == NULL ? &tmpnewval : (double*)newvalue);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!call_real_check_hook(conf, newval, newextra, source, elevel))
|
||||
return false;
|
||||
|
||||
if (*newextra && freemem)
|
||||
pfree(*newextra);
|
||||
}
|
||||
break;
|
||||
case PGC_STRING:
|
||||
{
|
||||
struct config_string *conf = (struct config_string *) record;
|
||||
char* tmpnewval = NULL;
|
||||
char** newval = newvalue == NULL ? &tmpnewval : (char**)newvalue;
|
||||
|
||||
/* The value passed by the caller could be transient, so we always strdup it. */
|
||||
*newval = guc_strdup(elevel, value);
|
||||
if (*newval == NULL)
|
||||
return false;
|
||||
|
||||
/* The only built-in "parsing" check we have is to apply truncation if GUC_IS_NAME. */
|
||||
if (conf->gen.flags & GUC_IS_NAME)
|
||||
truncate_identifier(*newval, strlen(*newval), true);
|
||||
|
||||
if (!call_string_check_hook(conf, newval, newextra, source, elevel)) {
|
||||
pfree(*newval);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Free the malloc'd data if any */
|
||||
if (freemem) {
|
||||
if (*newval != NULL)
|
||||
pfree(*newval);
|
||||
if (*newextra != NULL)
|
||||
pfree(*newextra);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PGC_ENUM:
|
||||
{
|
||||
struct config_enum *conf = (struct config_enum *) record;
|
||||
int tmpnewval;
|
||||
int* newval = (newvalue == NULL ? &tmpnewval : (int*)newvalue);
|
||||
|
||||
if (!config_enum_lookup_by_name(conf, value, newval)) {
|
||||
char* hintmsg;
|
||||
|
||||
hintmsg = config_enum_get_options(conf, "Available values: ", ".", ", ");
|
||||
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid value for parameter \"%s\": \"%s\"", name, value),
|
||||
hintmsg ? errhint("%s", _(hintmsg)) : 0));
|
||||
|
||||
if (hintmsg != NULL)
|
||||
pfree(hintmsg);
|
||||
return false;
|
||||
}
|
||||
if (!call_enum_check_hook(conf, newval, newextra, source, LOG))
|
||||
return false;
|
||||
|
||||
if (*newextra && freemem)
|
||||
pfree(*newextra);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_ATTRIBUTE),
|
||||
errmsg("unknow guc variable type: %d", record->vartype)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetThreadLocalGUC(knl_session_context* session)
|
||||
{
|
||||
default_statistics_target = session->attr.attr_sql.default_statistics_target;
|
||||
|
|
@ -14590,14 +14789,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
void* newextra = NULL;
|
||||
|
||||
if (value != NULL) {
|
||||
if (!parse_bool(value, &newval)) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("parameter \"%s\" requires a Boolean value", name)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!call_bool_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -14681,27 +14873,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
void* newextra = NULL;
|
||||
|
||||
if (value != NULL) {
|
||||
const char* hintmsg = NULL;
|
||||
|
||||
if (!parse_int(value, &newval, conf->gen.flags, &hintmsg)) {
|
||||
ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid value for parameter \"%s\": \"%s\"", name, value),
|
||||
hintmsg ? errhint("%s", _(hintmsg)) : 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
if (!call_int_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -14780,26 +14952,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
void* newextra = NULL;
|
||||
|
||||
if (value != NULL) {
|
||||
const char* hintmsg = NULL;
|
||||
if (!parse_int64(value, &newval, &hintmsg)) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("parameter \"%s\" requires a numeric value", name)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (newval < conf->min || newval > conf->max) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("%ld is outside the valid range for parameter \"%s\" (%ld .. %ld)",
|
||||
newval,
|
||||
name,
|
||||
conf->min,
|
||||
conf->max)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!call_int64_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -14872,25 +15025,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
void* newextra = NULL;
|
||||
|
||||
if (value != NULL) {
|
||||
if (!parse_real(value, &newval)) {
|
||||
ereport(elevel,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("parameter \"%s\" requires a numeric value", name)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
if (!call_real_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -14978,14 +15113,6 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
}
|
||||
|
||||
if (value != NULL) {
|
||||
/*
|
||||
* The value passed by the caller could be transient, so
|
||||
* we always strdup it.
|
||||
*/
|
||||
newval = guc_strdup(elevel, value);
|
||||
if (newval == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// when \parallel in gsql is on, we use "set search_path to pg_temp_XXX"
|
||||
// to tell new started parallel postgres which temp namespace should use.
|
||||
|
|
@ -15016,16 +15143,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The only built-in "parsing" check we have is to apply
|
||||
* truncation if GUC_IS_NAME.
|
||||
*/
|
||||
if (conf->gen.flags & GUC_IS_NAME) {
|
||||
truncate_identifier(newval, strlen(newval), true);
|
||||
}
|
||||
|
||||
if (!call_string_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
pfree(newval);
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -15119,20 +15237,7 @@ int set_config_option(const char* name, const char* value, GucContext context, G
|
|||
void* newextra = NULL;
|
||||
|
||||
if (value != NULL) {
|
||||
if (!config_enum_lookup_by_name(conf, value, &newval)) {
|
||||
char* hintmsg = NULL;
|
||||
hintmsg = config_enum_get_options(conf, "Available values: ", ".", ", ");
|
||||
ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid value for parameter \"%s\": \"%s\"", name, value),
|
||||
hintmsg ? errhint("%s", _(hintmsg)) : 0));
|
||||
|
||||
if (hintmsg != NULL) {
|
||||
pfree(hintmsg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!call_enum_check_hook(conf, &newval, &newextra, source, elevel)) {
|
||||
if (!validate_conf_option(record, name, value, source, elevel, false, &newval, &newextra)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (source == PGC_S_DEFAULT) {
|
||||
|
|
@ -15500,6 +15605,228 @@ static char* flatten_set_variable_args(const char* name, List* args)
|
|||
return buf.data;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function takes list of all configuration parameters in
|
||||
* postgresql.conf and parameter to be updated as input arguments and
|
||||
* replace the updated configuration parameter value in a list. If the
|
||||
* parameter to be updated is new then it is appended to the list of
|
||||
* parameters.
|
||||
*/
|
||||
static void replace_config_value(char** optlines, char* name, char* value, config_type vartype)
|
||||
{
|
||||
Assert(optlines != NULL);
|
||||
|
||||
int index = 0;
|
||||
int optvalue_off = 0;
|
||||
int optvalue_len = 0;
|
||||
char* newline = (char*)pg_malloc(MAX_PARAM_LEN);
|
||||
int rc = 0;
|
||||
|
||||
switch (vartype) {
|
||||
case PGC_BOOL:
|
||||
case PGC_INT:
|
||||
case PGC_INT64:
|
||||
case PGC_REAL:
|
||||
case PGC_ENUM:
|
||||
rc = snprintf_s(newline, MAX_PARAM_LEN, MAX_PARAM_LEN - 1, "%s = %s\n", name, value);
|
||||
break;
|
||||
case PGC_STRING:
|
||||
rc = snprintf_s(newline, MAX_PARAM_LEN, MAX_PARAM_LEN - 1, "%s = '%s'\n", name, value);
|
||||
break;
|
||||
}
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
|
||||
index = find_guc_option(optlines, name, NULL, NULL, &optvalue_off, &optvalue_len);
|
||||
|
||||
/* add or replace */
|
||||
if (index == INVALID_LINES_IDX) {
|
||||
/* find the first NULL point reserved. */
|
||||
for (index = 0; optlines[index] != NULL; index++);
|
||||
|
||||
} else {
|
||||
/* copy comment to newline and pfree old line */
|
||||
rc = strncpy_s(newline + rc - 1, MAX_PARAM_LEN - rc,
|
||||
optlines[index] + optvalue_off + optvalue_len, MAX_PARAM_LEN - rc - 1);
|
||||
securec_check(rc, "\0", "\0");
|
||||
pfree(optlines[index]);
|
||||
}
|
||||
|
||||
optlines[index] = newline;
|
||||
}
|
||||
|
||||
/*
|
||||
* Persist the configuration parameter value.
|
||||
*
|
||||
* This function takes all previous configuration parameters
|
||||
* set by ALTER SYSTEM command and the currently set ones
|
||||
* and write them all to the automatic configuration file.
|
||||
*
|
||||
* The configuration parameters are written to a temporary
|
||||
* file then renamed to the final name. The template for the
|
||||
* temporary file is postgresql.auto.conf.temp.
|
||||
*
|
||||
* An LWLock is used to serialize writing to the same file.
|
||||
*
|
||||
* In case of an error, we leave the original automatic
|
||||
* configuration file (postgresql.auto.conf) intact.
|
||||
*/
|
||||
void AlterSystemSetConfigFile(AlterSystemStmt * altersysstmt)
|
||||
{
|
||||
#define GUCCONF_FILE "postgresql.conf"
|
||||
#define GUCCONF_FILE_BAK "postgresql.conf.bak"
|
||||
#define GUCCONF_FILE_BAK_BAK "postgresql.conf.bak_bak"
|
||||
#define GUCCONF_FILE_LOCK "postgresql.conf.lock"
|
||||
|
||||
char *name = NULL;
|
||||
char *value = NULL;
|
||||
struct config_generic *record = NULL;
|
||||
char ConfFileName[MAXPGPATH];
|
||||
char ConfTmpFileName[MAXPGPATH];
|
||||
char ConfTmpBakFileName[MAXPGPATH];
|
||||
char ConfLockFileName[MAXPGPATH];
|
||||
struct stat st;
|
||||
void *newextra = NULL;
|
||||
ConfFileLock filelock = {NULL, 0};
|
||||
errno_t rc;
|
||||
ErrCode ret;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to execute ALTER SYSTEM SET command"))));
|
||||
|
||||
/*
|
||||
* Validate the name and arguments [value1, value2 ... ].
|
||||
*/
|
||||
name = altersysstmt->setstmt->name;
|
||||
switch (altersysstmt->setstmt->kind) {
|
||||
case VAR_SET_VALUE:
|
||||
value = ExtractSetVariableArgs(altersysstmt->setstmt);
|
||||
break;
|
||||
|
||||
case VAR_SET_DEFAULT:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OPERATE_NOT_SUPPORTED),
|
||||
(errmsg("ALTER SYSTEM SET does not support 'set to default'."))));
|
||||
value = NULL;
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized ALTER SYSTEM SET stmt type: %d",
|
||||
altersysstmt->setstmt->kind);
|
||||
break;
|
||||
}
|
||||
|
||||
record = find_option(name, false, LOG);
|
||||
if (record == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("unrecognized configuration parameter \"%s\"", name)));
|
||||
|
||||
if ((record->context != PGC_POSTMASTER && record->context != PGC_SIGHUP && record->context != PGC_BACKEND) ||
|
||||
record->flags & GUC_DISALLOW_IN_FILE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
|
||||
errmsg("unsupport parameter: %s\n"
|
||||
"ALTER SYSTEM SET only support POSTMASTER-level, SIGHUP-level and BACKEND-level guc variable,\n"
|
||||
"and it must be allowed to set in postgresql.conf.", name)));
|
||||
|
||||
if (!validate_conf_option(record, name, value, PGC_S_FILE, ERROR, true, NULL, &newextra))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid value for parameter \"%s\": \"%s\"", name, value)));
|
||||
|
||||
|
||||
rc = snprintf_s(ConfFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%s", t_thrd.proc_cxt.DataDir, GUCCONF_FILE);
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
rc = snprintf_s(ConfTmpFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%s", t_thrd.proc_cxt.DataDir, GUCCONF_FILE_BAK);
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
rc = snprintf_s(ConfLockFileName, MAXPGPATH, MAXPGPATH - 1, "%s/%s", t_thrd.proc_cxt.DataDir, GUCCONF_FILE_LOCK);
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
rc = snprintf_s(ConfTmpBakFileName, MAXPGPATH, MAXPGPATH - 1,
|
||||
"%s/%s", t_thrd.proc_cxt.DataDir, GUCCONF_FILE_BAK_BAK);
|
||||
securec_check_ss(rc, "\0", "\0");
|
||||
|
||||
/*
|
||||
* one backend is allowed to operate on postgresql.conf.bak file, to
|
||||
* ensure that we need to update the contents of the file with
|
||||
* AutoFileLock. To ensure crash safety, first the contents are written to
|
||||
* temporary file and then rename it to postgresql.auto.conf. In case
|
||||
* there exists a temp file from previous crash, that can be reused.
|
||||
*/
|
||||
char** opt_lines = NULL;
|
||||
if (stat(ConfFileName, &st) == 0 && get_file_lock(ConfLockFileName, &filelock) == CODE_OK) {
|
||||
opt_lines = read_guc_file(ConfFileName);
|
||||
} else {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FILE_READ_FAILED),
|
||||
errmsg("File does not exits or it is being used.Can not open file: %s.", ConfFileName)));
|
||||
}
|
||||
|
||||
/*
|
||||
* replace with new value if the configuration parameter already
|
||||
* exists OR add it as a new cofiguration parameter in the file.
|
||||
*/
|
||||
replace_config_value(opt_lines, name, value, record->vartype);
|
||||
ret = write_guc_file(ConfTmpFileName, opt_lines);
|
||||
release_opt_lines(opt_lines);
|
||||
if (ret != CODE_OK) {
|
||||
release_file_lock(&filelock);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FILE_WRITE_FAILED),
|
||||
errmsg("write %s failed: %s.", ConfTmpFileName, gs_strerror(ret))));
|
||||
}
|
||||
|
||||
/* we should leave postgresql.conf.bak like gs_guc */
|
||||
opt_lines = read_guc_file(ConfTmpFileName);
|
||||
ret = write_guc_file(ConfTmpBakFileName, opt_lines);
|
||||
release_opt_lines(opt_lines);
|
||||
opt_lines = NULL;
|
||||
if (ret != CODE_OK) {
|
||||
release_file_lock(&filelock);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FILE_WRITE_FAILED),
|
||||
errmsg("write %s failed: %s.", ConfTmpBakFileName, gs_strerror(ret))));
|
||||
}
|
||||
|
||||
/*
|
||||
* As the rename is atomic operation, if any problem occurs after this
|
||||
* at max it can loose the parameters set by last ALTER SYSTEM SET
|
||||
* command.
|
||||
*/
|
||||
if (rename(ConfTmpBakFileName, ConfFileName) < 0) {
|
||||
release_file_lock(&filelock);
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not rename file \"%s\" to \"%s\"", ConfTmpFileName, ConfFileName)));
|
||||
}
|
||||
|
||||
release_file_lock(&filelock);
|
||||
|
||||
/*
|
||||
* send signal to postmaster to reload postgresql.conf, POSTMASTER-level variable
|
||||
* takes effect only after restarting the database, but we still need to send the
|
||||
* signal so that we can send the postgresql.conf to standby node.
|
||||
*/
|
||||
if (gs_signal_send(PostmasterPid, SIGHUP)) {
|
||||
ereport(WARNING, (errmsg("Failed to send signal to postmaster to reload guc config file.")));
|
||||
return;
|
||||
}
|
||||
|
||||
/* print notice message */
|
||||
switch (record->context) {
|
||||
case PGC_POSTMASTER:
|
||||
ereport(NOTICE,
|
||||
(errmsg("please restart the database for the POSTMASTER level parameter to take effect.")));
|
||||
break;
|
||||
case PGC_BACKEND:
|
||||
ereport(NOTICE,
|
||||
(errmsg("please reconnect the database for the BACKEND level parameter to take effect.")));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SET command
|
||||
*/
|
||||
|
|
@ -20066,7 +20393,7 @@ char** read_guc_file(const char* path)
|
|||
}
|
||||
|
||||
/* set up the result and the line buffer */
|
||||
result = (char**)pg_malloc((nlines + 1) * sizeof(char*));
|
||||
result = (char**)pg_malloc((nlines + 2) * sizeof(char*)); // Reserve one extra for alter system set.
|
||||
buffer = (char*)pg_malloc(maxlength + 1);
|
||||
|
||||
/* now reprocess the file and store the lines */
|
||||
|
|
@ -20078,7 +20405,7 @@ char** read_guc_file(const char* path)
|
|||
}
|
||||
(void)fclose(infile);
|
||||
pfree(buffer);
|
||||
result[nlines] = NULL;
|
||||
result[nlines] = result[nlines + 1] = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1313,6 +1313,10 @@ static void pgaudit_ProcessUtility(Node* parsetree, const char* queryString, Par
|
|||
VariableSetStmt* variablesetstmt = (VariableSetStmt*)(parsetree);
|
||||
pgaudit_process_set_parameter(variablesetstmt->name, queryString);
|
||||
} break;
|
||||
case T_AlterSystemStmt: {
|
||||
AlterSystemStmt* altersystemstmt = (AlterSystemStmt*)(parsetree);
|
||||
pgaudit_process_set_parameter(altersystemstmt->setstmt->name, queryString);
|
||||
} break;
|
||||
case T_CreateDataSourceStmt: {
|
||||
CreateDataSourceStmt* createdatasourcestmt = (CreateDataSourceStmt*)(parsetree);
|
||||
pgaudit_ddl_datasource(createdatasourcestmt->srcname, queryString);
|
||||
|
|
|
|||
|
|
@ -4787,6 +4787,11 @@ void standard_ProcessUtility(Node* parse_tree, const char* query_string, ParamLi
|
|||
ExecCreateTableAs((CreateTableAsStmt*)parse_tree, query_string, params, completion_tag);
|
||||
break;
|
||||
|
||||
case T_AlterSystemStmt:
|
||||
PreventTransactionChain(is_top_level, "ALTER SYSTEM SET");
|
||||
AlterSystemSetConfigFile((AlterSystemStmt*)parse_tree);
|
||||
break;
|
||||
|
||||
case T_VariableSetStmt:
|
||||
ExecSetVariableStmt((VariableSetStmt*)parse_tree);
|
||||
#ifdef PGXC
|
||||
|
|
@ -7175,6 +7180,10 @@ const char* CreateCommandTag(Node* parse_tree)
|
|||
tag = "CREATE TABLE AS";
|
||||
break;
|
||||
|
||||
case T_AlterSystemStmt:
|
||||
tag = "ALTER SYSTEM SET";
|
||||
break;
|
||||
|
||||
case T_VariableSetStmt:
|
||||
switch (((VariableSetStmt*)parse_tree)->kind) {
|
||||
case VAR_SET_VALUE:
|
||||
|
|
@ -8020,6 +8029,10 @@ LogStmtLevel GetCommandLogLevel(Node* parse_tree)
|
|||
lev = LOGSTMT_DDL;
|
||||
break;
|
||||
|
||||
case T_AlterSystemStmt:
|
||||
lev = LOGSTMT_DDL;
|
||||
break;
|
||||
|
||||
case T_VariableSetStmt:
|
||||
lev = LOGSTMT_ALL;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -452,6 +452,7 @@ typedef enum NodeTag {
|
|||
T_DropDirectoryStmt,
|
||||
T_CreateRlsPolicyStmt,
|
||||
T_AlterRlsPolicyStmt,
|
||||
T_AlterSystemStmt,
|
||||
|
||||
/*
|
||||
* TAGS FOR PARSE TREE NODES (parsenodes.h)
|
||||
|
|
|
|||
|
|
@ -2901,6 +2901,15 @@ typedef struct DropdbStmt {
|
|||
bool missing_ok; /* skip error if db is missing? */
|
||||
} DropdbStmt;
|
||||
|
||||
/* ----------------------
|
||||
* Alter System Statement
|
||||
* ----------------------
|
||||
*/
|
||||
typedef struct AlterSystemStmt {
|
||||
NodeTag type;
|
||||
VariableSetStmt *setstmt; /* SET subcommand */
|
||||
} AlterSystemStmt;
|
||||
|
||||
/* ----------------------
|
||||
* Cluster Statement (support pbrown's cluster index implementation)
|
||||
* ----------------------
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ PG_KEYWORD("direct", DIRECT, UNRESERVED_KEYWORD)
|
|||
PG_KEYWORD("directory", DIRECTORY, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("disconnect", DISCONNECT, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD)
|
||||
#ifdef PGXC
|
||||
PG_KEYWORD("distribute", DISTRIBUTE, UNRESERVED_KEYWORD)
|
||||
|
|
@ -269,6 +270,7 @@ PG_KEYWORD("isnull", ISNULL, UNRESERVED_KEYWORD)
|
|||
PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD)
|
||||
PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("kill", KILL, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD)
|
||||
PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD)
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ extern bool parse_int64(const char* value, int64* result, const char** hintmsg);
|
|||
extern bool parse_real(const char* value, double* result);
|
||||
extern int set_config_option(const char* name, const char* value, GucContext context, GucSource source,
|
||||
GucAction action, bool changeVal, int elevel, bool isReload = false);
|
||||
extern void AlterSystemSetConfigFile(AlterSystemStmt * setstmt);
|
||||
extern char* GetConfigOptionByName(const char* name, const char** varname);
|
||||
extern void GetConfigOptionByNum(int varnum, const char** values, bool* noshow);
|
||||
extern int GetNumConfigOptions(void);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,406 @@
|
|||
----------------------------------------------------------
|
||||
-- The common user should not have the permission.
|
||||
---------------------------------------------------------
|
||||
DROP ROLE IF EXISTS alter_system_testuser;
|
||||
NOTICE: role "alter_system_testuser" does not exist, skipping
|
||||
CREATE USER alter_system_testuser PASSWORD 'test@1233';
|
||||
SET SESSION AUTHORIZATION alter_system_testuser PASSWORD 'test@1233';
|
||||
show use_workload_manager;
|
||||
use_workload_manager
|
||||
----------------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET use_workload_manager to off;
|
||||
ERROR: must be superuser to execute ALTER SYSTEM SET command
|
||||
show io_limits;
|
||||
io_limits
|
||||
-----------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET io_limits to 100;
|
||||
ERROR: must be superuser to execute ALTER SYSTEM SET command
|
||||
select pg_sleep(1); -- wait to reload postgres.conf file
|
||||
pg_sleep
|
||||
----------
|
||||
|
||||
(1 row)
|
||||
|
||||
show use_workload_manager;
|
||||
use_workload_manager
|
||||
----------------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
show io_limits;
|
||||
io_limits
|
||||
-----------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
\c
|
||||
DROP user alter_system_testuser;
|
||||
-------------------------------------------------------
|
||||
-- clear pg_query_audit for the last test
|
||||
-------------------------------------------------------
|
||||
show audit_enabled;
|
||||
audit_enabled
|
||||
---------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
show audit_set_parameter;
|
||||
audit_set_parameter
|
||||
---------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
show audit_user_violation;
|
||||
audit_user_violation
|
||||
----------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT pg_delete_audit('2000-01-01 ','9999-01-01');
|
||||
pg_delete_audit
|
||||
-----------------
|
||||
|
||||
(1 row)
|
||||
|
||||
--------------------------------------------------------
|
||||
-- for POSTMASTER GUC
|
||||
--------------------------------------------------------
|
||||
SHOW enable_thread_pool;
|
||||
enable_thread_pool
|
||||
--------------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET enable_thread_pool to off;
|
||||
NOTICE: please restart the database for the POSTMASTER level parameter to take effect.
|
||||
ALTER SYSTEM SET enable_thread_pool to on;
|
||||
NOTICE: please restart the database for the POSTMASTER level parameter to take effect.
|
||||
------------------------------------------------------
|
||||
-- for SIGHUP GUC
|
||||
------------------------------------------------------
|
||||
-- change
|
||||
SHOW password_lock_time;
|
||||
password_lock_time
|
||||
--------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET password_lock_time to 1.1;
|
||||
SHOW autovacuum;
|
||||
autovacuum
|
||||
------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autovacuum to off;
|
||||
SHOW log_destination;
|
||||
log_destination
|
||||
-----------------
|
||||
stderr
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET log_destination to 'stderr,csvlog';
|
||||
SHOW autovacuum_mode;
|
||||
autovacuum_mode
|
||||
-----------------
|
||||
mix
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autovacuum_mode to 'analyze';
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
100000
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
pg_sleep
|
||||
----------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- check result and change back.
|
||||
SHOW password_lock_time;
|
||||
password_lock_time
|
||||
--------------------
|
||||
1.1
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET password_lock_time to 1;
|
||||
SHOW autovacuum;
|
||||
autovacuum
|
||||
------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autovacuum to on;
|
||||
SHOW log_destination;
|
||||
log_destination
|
||||
-----------------
|
||||
stderr,csvlog
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET log_destination to 'stderr';
|
||||
SHOW autovacuum_mode;
|
||||
autovacuum_mode
|
||||
-----------------
|
||||
analyze
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autovacuum_mode to mix;
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
1000
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
pg_sleep
|
||||
----------
|
||||
|
||||
(1 row)
|
||||
|
||||
SHOW password_lock_time;
|
||||
password_lock_time
|
||||
--------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SHOW autovacuum;
|
||||
autovacuum
|
||||
------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
SHOW log_destination;
|
||||
log_destination
|
||||
-----------------
|
||||
stderr
|
||||
(1 row)
|
||||
|
||||
SHOW autovacuum_mode;
|
||||
autovacuum_mode
|
||||
-----------------
|
||||
mix
|
||||
(1 row)
|
||||
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
100000
|
||||
(1 row)
|
||||
|
||||
-- some err case
|
||||
ALTER SYSTEM SET password_lock_time to true;
|
||||
ERROR: parameter "password_lock_time" requires a numeric value
|
||||
ALTER SYSTEM SET autovacuum to 'lalala';
|
||||
ERROR: parameter "autovacuum" requires a Boolean value
|
||||
ALTER SYSTEM SET log_destination to 'abcdefg';
|
||||
ERROR: invalid value for parameter "log_destination": "abcdefg"
|
||||
DETAIL: Unrecognized key word: "abcdefg".
|
||||
ALTER SYSTEM SET autovacuum_mode to 123;
|
||||
ERROR: invalid value for parameter "autovacuum_mode": "123"
|
||||
HINT: Available values: analyze, vacuum, mix, none.
|
||||
ALTER SYSTEM SET autovacuum_mode to lalala;
|
||||
ERROR: invalid value for parameter "autovacuum_mode": "lalala"
|
||||
HINT: Available values: analyze, vacuum, mix, none.
|
||||
ALTER SYSTEM SET parctl_min_cost TO -100;
|
||||
ERROR: -100 is outside the valid range for parameter "parctl_min_cost" (-1 .. 2147483647)
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1.1;
|
||||
ERROR: invalid value for parameter "parctl_min_cost": "1.1"
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
pg_sleep
|
||||
----------
|
||||
|
||||
(1 row)
|
||||
|
||||
SHOW password_lock_time;
|
||||
password_lock_time
|
||||
--------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SHOW autovacuum;
|
||||
autovacuum
|
||||
------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
SHOW log_destination;
|
||||
log_destination
|
||||
-----------------
|
||||
stderr
|
||||
(1 row)
|
||||
|
||||
SHOW autovacuum_mode;
|
||||
autovacuum_mode
|
||||
-----------------
|
||||
mix
|
||||
(1 row)
|
||||
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
100000
|
||||
(1 row)
|
||||
|
||||
------------------------------------------------------
|
||||
-- FOR BACKEND GUC
|
||||
------------------------------------------------------
|
||||
show ignore_system_indexes;
|
||||
ignore_system_indexes
|
||||
-----------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET ignore_system_indexes TO on;
|
||||
NOTICE: please reconnect the database for the BACKEND level parameter to take effect.
|
||||
show ignore_system_indexes;
|
||||
ignore_system_indexes
|
||||
-----------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET ignore_system_indexes TO off;
|
||||
NOTICE: please reconnect the database for the BACKEND level parameter to take effect.
|
||||
show ignore_system_indexes;
|
||||
ignore_system_indexes
|
||||
-----------------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
----------------------------------------------------
|
||||
-- for USERSET GUC
|
||||
----------------------------------------------------
|
||||
show io_limits;
|
||||
io_limits
|
||||
-----------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET io_limits to 100;
|
||||
ERROR: unsupport parameter: io_limits
|
||||
ALTER SYSTEM SET only support POSTMASTER-level, SIGHUP-level and BACKEND-level guc variable,
|
||||
and it must be allowed to set in postgresql.conf.
|
||||
show io_limits;
|
||||
io_limits
|
||||
-----------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET io_limits to 0;
|
||||
ERROR: unsupport parameter: io_limits
|
||||
ALTER SYSTEM SET only support POSTMASTER-level, SIGHUP-level and BACKEND-level guc variable,
|
||||
and it must be allowed to set in postgresql.conf.
|
||||
show io_limits;
|
||||
io_limits
|
||||
-----------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
-----------------------------------------------------
|
||||
-- for SUSET GUC
|
||||
----------------------------------------------------
|
||||
show autoanalyze;
|
||||
autoanalyze
|
||||
-------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autoanalyze to on;
|
||||
ERROR: unsupport parameter: autoanalyze
|
||||
ALTER SYSTEM SET only support POSTMASTER-level, SIGHUP-level and BACKEND-level guc variable,
|
||||
and it must be allowed to set in postgresql.conf.
|
||||
show autoanalyze;
|
||||
autoanalyze
|
||||
-------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autoanalyze to off;
|
||||
ERROR: unsupport parameter: autoanalyze
|
||||
ALTER SYSTEM SET only support POSTMASTER-level, SIGHUP-level and BACKEND-level guc variable,
|
||||
and it must be allowed to set in postgresql.conf.
|
||||
show autoanalyze;
|
||||
autoanalyze
|
||||
-------------
|
||||
off
|
||||
(1 row)
|
||||
|
||||
-----------------------------------------------------
|
||||
-- UNSUPPORT SET TO DEFAULT
|
||||
-----------------------------------------------------
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
100000
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
ALTER SYSTEM SET parctl_min_cost TO default;
|
||||
ERROR: ALTER SYSTEM SET does not support 'set to default'.
|
||||
select pg_sleep(1);
|
||||
pg_sleep
|
||||
----------
|
||||
|
||||
(1 row)
|
||||
|
||||
SHOW parctl_min_cost;
|
||||
parctl_min_cost
|
||||
-----------------
|
||||
1000
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
-------------------------------------------------------
|
||||
-- can not in a transaction
|
||||
-------------------------------------------------------
|
||||
BEGIN;
|
||||
SHOW autovacuum;
|
||||
autovacuum
|
||||
------------
|
||||
on
|
||||
(1 row)
|
||||
|
||||
ALTER SYSTEM SET autovacuum to off;
|
||||
ERROR: ALTER SYSTEM SET cannot run inside a transaction block
|
||||
SHOW autovacuum;
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
ALTER SYSTEM SET autovacuum to on;
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
SHOW autovacuum;
|
||||
ERROR: current transaction is aborted, commands ignored until end of transaction block
|
||||
END;
|
||||
-------------------------------------------------------
|
||||
-- shoule be audited.
|
||||
------------------------------------------------------
|
||||
SELECT type,result,userid,database,client_conninfo,object_name,detail_info FROM pg_query_audit('2000-01-01 08:00:00','9999-01-01 08:00:00');
|
||||
type | result | userid | database | client_conninfo | object_name | detail_info
|
||||
----------------+--------+--------+------------+-----------------+-----------------------+------------------------------------------------------
|
||||
internal_event | ok | 10 | regression | gsql@[local] | null | SELECT pg_delete_audit('2000-01-01 ','9999-01-01');
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | enable_thread_pool | ALTER SYSTEM SET enable_thread_pool to off;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | enable_thread_pool | ALTER SYSTEM SET enable_thread_pool to on;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | password_lock_time | ALTER SYSTEM SET password_lock_time to 1.1;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | autovacuum | ALTER SYSTEM SET autovacuum to off;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | log_destination | ALTER SYSTEM SET log_destination to 'stderr,csvlog';
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | autovacuum_mode | ALTER SYSTEM SET autovacuum_mode to 'analyze';
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | parctl_min_cost | ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | password_lock_time | ALTER SYSTEM SET password_lock_time to 1;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | autovacuum | ALTER SYSTEM SET autovacuum to on;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | log_destination | ALTER SYSTEM SET log_destination to 'stderr';
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | autovacuum_mode | ALTER SYSTEM SET autovacuum_mode to mix;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | parctl_min_cost | ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | ignore_system_indexes | ALTER SYSTEM SET ignore_system_indexes TO on;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | ignore_system_indexes | ALTER SYSTEM SET ignore_system_indexes TO off;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | parctl_min_cost | ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
set_parameter | ok | 10 | regression | gsql@[local] | parctl_min_cost | ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
(17 rows)
|
||||
|
||||
|
|
@ -25,6 +25,7 @@ test: create_view1 create_view2 create_view3 create_view4 create_view5 int8
|
|||
test: select
|
||||
test: misc
|
||||
test: stats
|
||||
test: alter_system_set
|
||||
|
||||
#dispatch from 13
|
||||
test: function
|
||||
|
|
|
|||
|
|
@ -21,4 +21,5 @@ test: create_view1 create_view2 create_view3 create_view4 create_view5 int8
|
|||
#dupliacated select int8
|
||||
test: select
|
||||
test: misc
|
||||
test: stats
|
||||
test: stats
|
||||
test: alter_system_set
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
----------------------------------------------------------
|
||||
-- The common user should not have the permission.
|
||||
---------------------------------------------------------
|
||||
|
||||
DROP ROLE IF EXISTS alter_system_testuser;
|
||||
CREATE USER alter_system_testuser PASSWORD 'test@1233';
|
||||
|
||||
SET SESSION AUTHORIZATION alter_system_testuser PASSWORD 'test@1233';
|
||||
show use_workload_manager;
|
||||
ALTER SYSTEM SET use_workload_manager to off;
|
||||
show io_limits;
|
||||
ALTER SYSTEM SET io_limits to 100;
|
||||
select pg_sleep(1); -- wait to reload postgres.conf file
|
||||
show use_workload_manager;
|
||||
show io_limits;
|
||||
|
||||
\c
|
||||
DROP user alter_system_testuser;
|
||||
|
||||
-------------------------------------------------------
|
||||
-- clear pg_query_audit for the last test
|
||||
-------------------------------------------------------
|
||||
show audit_enabled;
|
||||
show audit_set_parameter;
|
||||
show audit_user_violation;
|
||||
SELECT pg_delete_audit('2000-01-01 ','9999-01-01');
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
-- for POSTMASTER GUC
|
||||
--------------------------------------------------------
|
||||
SHOW enable_thread_pool;
|
||||
ALTER SYSTEM SET enable_thread_pool to off;
|
||||
ALTER SYSTEM SET enable_thread_pool to on;
|
||||
|
||||
------------------------------------------------------
|
||||
-- for SIGHUP GUC
|
||||
------------------------------------------------------
|
||||
-- change
|
||||
SHOW password_lock_time;
|
||||
ALTER SYSTEM SET password_lock_time to 1.1;
|
||||
SHOW autovacuum;
|
||||
ALTER SYSTEM SET autovacuum to off;
|
||||
SHOW log_destination;
|
||||
ALTER SYSTEM SET log_destination to 'stderr,csvlog';
|
||||
SHOW autovacuum_mode;
|
||||
ALTER SYSTEM SET autovacuum_mode to 'analyze';
|
||||
SHOW parctl_min_cost;
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
|
||||
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
|
||||
|
||||
-- check result and change back.
|
||||
SHOW password_lock_time;
|
||||
ALTER SYSTEM SET password_lock_time to 1;
|
||||
SHOW autovacuum;
|
||||
ALTER SYSTEM SET autovacuum to on;
|
||||
SHOW log_destination;
|
||||
ALTER SYSTEM SET log_destination to 'stderr';
|
||||
SHOW autovacuum_mode;
|
||||
ALTER SYSTEM SET autovacuum_mode to mix;
|
||||
SHOW parctl_min_cost;
|
||||
ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
|
||||
SHOW password_lock_time;
|
||||
SHOW autovacuum;
|
||||
SHOW log_destination;
|
||||
SHOW autovacuum_mode;
|
||||
SHOW parctl_min_cost;
|
||||
|
||||
|
||||
|
||||
-- some err case
|
||||
ALTER SYSTEM SET password_lock_time to true;
|
||||
ALTER SYSTEM SET autovacuum to 'lalala';
|
||||
ALTER SYSTEM SET log_destination to 'abcdefg';
|
||||
ALTER SYSTEM SET autovacuum_mode to 123;
|
||||
ALTER SYSTEM SET autovacuum_mode to lalala;
|
||||
ALTER SYSTEM SET parctl_min_cost TO -100;
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1.1;
|
||||
|
||||
select pg_sleep(2); -- wait to reload postgres.conf file
|
||||
|
||||
SHOW password_lock_time;
|
||||
SHOW autovacuum;
|
||||
SHOW log_destination;
|
||||
SHOW autovacuum_mode;
|
||||
SHOW parctl_min_cost;
|
||||
|
||||
------------------------------------------------------
|
||||
-- FOR BACKEND GUC
|
||||
------------------------------------------------------
|
||||
show ignore_system_indexes;
|
||||
ALTER SYSTEM SET ignore_system_indexes TO on;
|
||||
show ignore_system_indexes;
|
||||
ALTER SYSTEM SET ignore_system_indexes TO off;
|
||||
show ignore_system_indexes;
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- for USERSET GUC
|
||||
----------------------------------------------------
|
||||
show io_limits;
|
||||
ALTER SYSTEM SET io_limits to 100;
|
||||
show io_limits;
|
||||
ALTER SYSTEM SET io_limits to 0;
|
||||
show io_limits;
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- for SUSET GUC
|
||||
----------------------------------------------------
|
||||
show autoanalyze;
|
||||
ALTER SYSTEM SET autoanalyze to on;
|
||||
show autoanalyze;
|
||||
ALTER SYSTEM SET autoanalyze to off;
|
||||
show autoanalyze;
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- UNSUPPORT SET TO DEFAULT
|
||||
-----------------------------------------------------
|
||||
SHOW parctl_min_cost;
|
||||
ALTER SYSTEM SET parctl_min_cost TO 1000;
|
||||
ALTER SYSTEM SET parctl_min_cost TO default;
|
||||
select pg_sleep(1);
|
||||
SHOW parctl_min_cost;
|
||||
ALTER SYSTEM SET parctl_min_cost TO 100000;
|
||||
|
||||
-------------------------------------------------------
|
||||
-- can not in a transaction
|
||||
-------------------------------------------------------
|
||||
BEGIN;
|
||||
SHOW autovacuum;
|
||||
ALTER SYSTEM SET autovacuum to off;
|
||||
SHOW autovacuum;
|
||||
ALTER SYSTEM SET autovacuum to on;
|
||||
SHOW autovacuum;
|
||||
END;
|
||||
|
||||
-------------------------------------------------------
|
||||
-- shoule be audited.
|
||||
------------------------------------------------------
|
||||
SELECT type,result,userid,database,client_conninfo,object_name,detail_info FROM pg_query_audit('2000-01-01 08:00:00','9999-01-01 08:00:00');
|
||||
|
||||
Loading…
Reference in New Issue