!519 The double type in the GUC parameter supports the unit.

Merge pull request !519 from Cross-罗/test_branch
This commit is contained in:
opengauss-bot
2020-12-18 15:37:23 +08:00
committed by Gitee
8 changed files with 446 additions and 193 deletions

View File

@ -341,7 +341,7 @@ partition_max_cache_size|int|4096,1073741823|kB|NULL|
partition_mem_batch|int|1,65535|NULL|NULL|
password_effect_time|real|0,999|NULL|NULL|
password_encryption_type|int|0,2|NULL|NULL|
password_lock_time|real|0,365|NULL|password_lock_time and failed_login_attempts must have positive for lock and unlock functions to work as.|
password_lock_time|real|0,365|d|password_lock_time and failed_login_attempts must have positive for lock and unlock functions to work as.|
password_max_length|int|6,999|NULL|NULL|
password_min_digital|int|0,999|NULL|NULL|
password_min_length|int|6,999|NULL|NULL|

View File

@ -75,7 +75,7 @@ UNIT_LETTER [a-zA-Z]
INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*
EXPONENT [Ee]{SIGN}?{DIGIT}+
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?{UNIT_LETTER}*
LETTER [A-Za-z_\200-\377]
LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]

View File

@ -1231,20 +1231,20 @@ static void init_configure_names_bool()
NULL,
NULL
},
{
{
"enable_hypo_index",
PGC_USERSET,
QUERY_TUNING_METHOD,
gettext_noop("Enable hypothetical index for explain."),
NULL
},
&u_sess->attr.attr_sql.enable_hypo_index,
false,
NULL,
NULL,
NULL
},
{
{
"enable_hypo_index",
PGC_USERSET,
QUERY_TUNING_METHOD,
gettext_noop("Enable hypothetical index for explain."),
NULL
},
&u_sess->attr.attr_sql.enable_hypo_index,
false,
NULL,
NULL,
NULL
},
#ifdef ENABLE_MULTIPLE_NODES
{
{
@ -1689,16 +1689,16 @@ static void init_configure_names_bool()
},
{
{
"enable_parallel_hash",
PGC_USERSET,
"enable_parallel_hash",
PGC_USERSET,
QUERY_TUNING_METHOD,
gettext_noop("Enables the planner's user of parallel hash plans."),
NULL
},
&u_sess->attr.attr_sql.enable_parallel_hash,
true,
NULL,
NULL,
NULL,
NULL,
NULL
},
{
@ -4730,8 +4730,8 @@ static void init_configure_names_int()
},
{
{
"vacuum_gtt_defer_check_age",
PGC_USERSET,
"vacuum_gtt_defer_check_age",
PGC_USERSET,
CLIENT_CONN_STATEMENT,
gettext_noop("The defer check age of GTT, used to check expired data after vacuum."),
NULL
@ -9858,7 +9858,8 @@ static void init_configure_names_real()
PGC_SIGHUP,
CONN_AUTH_SECURITY,
gettext_noop("password lock time"),
NULL
NULL,
GUC_UNIT_DAY
},
&u_sess->attr.attr_security.Password_lock_time,
1.0,
@ -12646,7 +12647,7 @@ static void init_single_node_unsupport_guc()
u_sess->attr.attr_storage.gds_debug_mod = false;
u_sess->attr.attr_sql.enable_slot_log = false;
u_sess->attr.attr_storage.enable_twophase_commit = false;
/* for Int Guc Variables */
u_sess->attr.attr_resource.max_active_statements = -1;
u_sess->attr.attr_resource.dynamic_memory_quota = 80;
@ -14337,160 +14338,9 @@ bool parse_int(const char* value, int* result, int flags, const char** hintmsg)
* but seems necessary to avoid intermediate-value overflows.
*/
if (flags & GUC_UNIT_MEMORY) {
/* Set hint for use if no match or trailing garbage */
if (hintmsg != NULL) {
*hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");
}
#if BLCKSZ < 1024 || BLCKSZ > (1024 * 1024)
#error BLCKSZ must be between 1KB and 1MB
#endif
#if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024 * 1024)
#error XLOG_BLCKSZ must be between 1KB and 1MB
#endif
if (strncmp(endptr, "kB", 2) == 0) {
endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_BLOCKS:
val /= (BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val /= (XLOG_BLCKSZ / 1024);
break;
default:
break;
}
} else if (strncmp(endptr, "MB", 2) == 0) {
endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_KB:
val *= KB_PER_MB;
break;
case GUC_UNIT_BLOCKS:
val *= KB_PER_MB / (BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val *= KB_PER_MB / (XLOG_BLCKSZ / 1024);
break;
default:
break;
}
} else if (strncmp(endptr, "GB", 2) == 0) {
endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_KB:
val *= KB_PER_GB;
break;
case GUC_UNIT_BLOCKS:
val *= KB_PER_GB / (BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val *= KB_PER_GB / (XLOG_BLCKSZ / 1024);
break;
default:
break;
}
}
val = (int64)memory_unit_convert(&endptr, val, flags, hintmsg);
} else if (flags & GUC_UNIT_TIME) {
/* Set hint for use if no match or trailing garbage */
if (hintmsg != NULL) {
*hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
}
if (strncmp(endptr, "ms", 2) == 0) {
endptr += 2;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_S:
val /= MS_PER_S;
break;
case GUC_UNIT_MIN:
val /= MS_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= MS_PER_H;
break;
default:
break;
}
} else if (strncmp(endptr, "s", 1) == 0) {
endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_S;
break;
case GUC_UNIT_MIN:
val /= S_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= S_PER_H;
break;
default:
break;
}
} else if (strncmp(endptr, "min", 3) == 0) {
endptr += 3;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_MIN;
break;
case GUC_UNIT_S:
val *= S_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= MIN_PER_H;
break;
default:
break;
}
} else if (strncmp(endptr, "h", 1) == 0) {
endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_H;
break;
case GUC_UNIT_S:
val *= S_PER_H;
break;
case GUC_UNIT_MIN:
val *= MIN_PER_H;
break;
default:
break;
}
} else if (strncmp(endptr, "d", 1) == 0) {
endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_D;
break;
case GUC_UNIT_S:
val *= S_PER_D;
break;
case GUC_UNIT_MIN:
val *= MIN_PER_D;
break;
case GUC_UNIT_HOUR:
val *= H_PER_D;
default:
break;
}
}
val = (int64)time_unit_convert(&endptr, val, flags, hintmsg);
}
/* allow whitespace after unit */
@ -14519,6 +14369,7 @@ bool parse_int(const char* value, int* result, int flags, const char** hintmsg)
return true;
}
/*
* Try to parse value as an 64-bit integer. The accepted format is
* decimal number.
@ -14573,7 +14424,7 @@ bool parse_int64(const char* value, int64* result, const char** hintmsg)
* If the string parses okay, return true, else false.
* If okay and result is not NULL, return the value in *result.
*/
bool parse_real(const char* value, double* result)
bool parse_real(const char* value, double* result, int flags, const char** hintmsg)
{
double val;
char* endptr = NULL;
@ -14600,7 +14451,25 @@ bool parse_real(const char* value, double* result)
}
if (*endptr != '\0') {
return false;
/*
* Note: the multiple-switch coding technique here is a bit tedious,
* but seems necessary to avoid intermediate-value overflows.
*/
if (flags & GUC_UNIT_MEMORY) {
val = memory_unit_convert(&endptr, val, flags, hintmsg);
} else if (flags & GUC_UNIT_TIME) {
val = time_unit_convert(&endptr, val, flags, hintmsg);
}
/* allow whitespace after unit */
while (isspace((unsigned char)*endptr)) {
endptr++;
}
if (*endptr != '\0') {
return false; /* appropriate hint, if any, already set */
}
}
if (result != NULL) {
@ -14610,6 +14479,187 @@ bool parse_real(const char* value, double* result)
return true;
}
/*
* The reference is used because auto-increment of formal parameters does not change the value of the actual parameter.
* As a result, an error is reported.
*/
double memory_unit_convert(char** endptr, double value, int flags, const char** hintmsg)
{
double val = value;
/* Set hint for use if no match or trailing garbage */
if (hintmsg != NULL) {
*hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", and \"GB\".");
}
#if BLCKSZ < 1024 || BLCKSZ > (1024 * 1024)
#error BLCKSZ must be between 1KB and 1MB
#endif
#if XLOG_BLCKSZ < 1024 || XLOG_BLCKSZ > (1024 * 1024)
#error XLOG_BLCKSZ must be between 1KB and 1MB
#endif
if (strncmp(*endptr, "kB", 2) == 0) {
*endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_BLOCKS:
val /= (double)(BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val /= (double)(XLOG_BLCKSZ / 1024);
break;
default:
break;
}
} else if (strncmp(*endptr, "MB", 2) == 0) {
*endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_KB:
val *= KB_PER_MB;
break;
case GUC_UNIT_BLOCKS:
val *= KB_PER_MB / ((double)BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val *= KB_PER_MB / ((double)XLOG_BLCKSZ / 1024);
break;
default:
break;
}
} else if (strncmp(*endptr, "GB", 2) == 0) {
*endptr += 2;
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_KB:
val *= KB_PER_GB;
break;
case GUC_UNIT_BLOCKS:
val *= KB_PER_GB / ((double)BLCKSZ / 1024);
break;
case GUC_UNIT_XBLOCKS:
val *= KB_PER_GB / ((double)XLOG_BLCKSZ / 1024);
break;
default:
break;
}
}
return val;
}
double time_unit_convert(char** endptr, double value, int flags, const char** hintmsg)
{
double val = value;
/* Set hint for use if no match or trailing garbage */
if (hintmsg != NULL) {
*hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
}
if (strncmp(*endptr, "ms", 2) == 0) {
*endptr += 2;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_S:
val /= MS_PER_S;
break;
case GUC_UNIT_MIN:
val /= MS_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= MS_PER_H;
break;
case GUC_UNIT_DAY:
val /= MS_PER_D;
break;
default:
break;
}
} else if (strncmp(*endptr, "s", 1) == 0) {
*endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_S;
break;
case GUC_UNIT_MIN:
val /= S_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= S_PER_H;
break;
case GUC_UNIT_DAY:
val /= S_PER_D;
break;
default:
break;
}
} else if (strncmp(*endptr, "min", 3) == 0) {
*endptr += 3;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_MIN;
break;
case GUC_UNIT_S:
val *= S_PER_MIN;
break;
case GUC_UNIT_HOUR:
val /= MIN_PER_H;
break;
case GUC_UNIT_DAY:
val /= MIN_PER_D;
break;
default:
break;
}
} else if (strncmp(*endptr, "h", 1) == 0) {
*endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_H;
break;
case GUC_UNIT_S:
val *= S_PER_H;
break;
case GUC_UNIT_MIN:
val *= MIN_PER_H;
break;
case GUC_UNIT_DAY:
val /= H_PER_D;
break;
default:
break;
}
} else if (strncmp(*endptr, "d", 1) == 0) {
*endptr += 1;
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_MS:
val *= MS_PER_D;
break;
case GUC_UNIT_S:
val *= S_PER_D;
break;
case GUC_UNIT_MIN:
val *= MIN_PER_D;
break;
case GUC_UNIT_HOUR:
val *= H_PER_D;
default:
break;
}
}
return val;
}
/*
* @Description: Get guc string value according to val.
* @in record: Enum configure struct.
@ -14888,8 +14938,9 @@ bool validate_conf_option(struct config_generic * record, const char *name, cons
struct config_real *conf = (struct config_real *) record;
double tmpnewval;
double* newval = (newvalue == NULL ? &tmpnewval : (double*)newvalue);
const char *hintmsg = NULL;
if (!parse_real(value, newval)) {
if (!parse_real(value, newval, conf->gen.flags, &hintmsg)) {
ereport(elevel,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("parameter \"%s\" requires a numeric value", name)));
@ -17142,7 +17193,7 @@ void GetConfigOptionByNum(int varnum, const char** values, bool* noshow)
values[1] = _show_option(conf, false);
/* unit */
if (conf->vartype == PGC_INT) {
if (conf->vartype == PGC_INT || conf->vartype == PGC_REAL) {
char buf[8];
switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)) {
@ -17178,6 +17229,10 @@ void GetConfigOptionByNum(int varnum, const char** values, bool* noshow)
values[2] = "hour";
break;
case GUC_UNIT_DAY:
values[2] = "d";
break;
default:
values[2] = "";
break;
@ -17549,15 +17604,15 @@ static char* _show_option(struct config_generic* record, bool use_units)
*/
int64 result = *conf->variable;
const char* unit = NULL;
int flags = record->flags;
if (use_units && result > 0 && (record->flags & GUC_UNIT_MEMORY)) {
switch (record->flags & GUC_UNIT_MEMORY) {
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_BLOCKS:
result *= BLCKSZ / 1024;
result *= (double)BLCKSZ / 1024;
break;
case GUC_UNIT_XBLOCKS:
result *= XLOG_BLCKSZ / 1024;
result *= (double)XLOG_BLCKSZ / 1024;
break;
default:
break;
@ -17573,17 +17628,19 @@ static char* _show_option(struct config_generic* record, bool use_units)
unit = "kB";
}
} else if (use_units && result > 0 && (record->flags & GUC_UNIT_TIME)) {
switch (record->flags & GUC_UNIT_TIME) {
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_S:
result *= MS_PER_S;
break;
case GUC_UNIT_MIN:
result *= MS_PER_MIN;
break;
case GUC_UNIT_HOUR:
result *= MS_PER_H;
break;
case GUC_UNIT_DAY:
result *= MS_PER_D;
break;
default:
break;
}
@ -17631,7 +17688,69 @@ static char* _show_option(struct config_generic* record, bool use_units)
if (conf->show_hook) {
val = (*conf->show_hook)();
} else {
rc = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "%g", *conf->variable);
double result = *conf->variable;
const char* unit = NULL;
int flags = record->flags;
if (use_units && result > 0 && (record->flags & GUC_UNIT_MEMORY)) {
switch (flags & GUC_UNIT_MEMORY) {
case GUC_UNIT_BLOCKS:
result *= (double)BLCKSZ / 1024;
break;
case GUC_UNIT_XBLOCKS:
result *= (double)XLOG_BLCKSZ / 1024;
break;
default:
break;
}
if (result / KB_PER_GB >= 1.0) {
result /= KB_PER_GB;
unit = "GB";
} else if (result / KB_PER_MB >= 1.0) {
result /= KB_PER_MB;
unit = "MB";
} else {
unit = "kB";
}
} else if (use_units && result > 0 && (record->flags & GUC_UNIT_TIME)) {
switch (flags & GUC_UNIT_TIME) {
case GUC_UNIT_S:
result *= MS_PER_S;
break;
case GUC_UNIT_MIN:
result *= MS_PER_MIN;
break;
case GUC_UNIT_HOUR:
result *= MS_PER_H;
break;
case GUC_UNIT_DAY:
result *= MS_PER_D;
break;
default:
break;
}
if (result / MS_PER_D >= 1.0) {
result /= MS_PER_D;
unit = "d";
} else if (result / MS_PER_H >= 1.0) {
result /= MS_PER_H;
unit = "h";
} else if (result / MS_PER_MIN >= 1.0) {
result /= MS_PER_MIN;
unit = "min";
} else if (result / MS_PER_S >= 1.0) {
result /= MS_PER_S;
unit = "s";
} else {
unit = "ms";
}
} else {
unit = "";
}
rc = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "%g%s", result, unit);
securec_check_ss(rc, "\0", "\0");
val = buffer;
}

View File

@ -184,6 +184,7 @@ typedef struct {
#define GUC_UNIT_S 0x2000 /* value is in seconds */
#define GUC_UNIT_MIN 0x4000 /* value is in minutes */
#define GUC_UNIT_HOUR 0x5000 /* value is in hour */
#define GUC_UNIT_DAY 0x6000 /* value is in day */
#define GUC_UNIT_TIME 0x7000 /* mask for MS, S, MIN */
#define GUC_NOT_WHILE_SEC_REST 0x8000 /* can't set if security restricted */
@ -242,7 +243,9 @@ extern void BeginReportingGUCOptions(void);
extern void ParseLongOption(const char* string, char** name, char** value);
extern bool parse_int(const char* value, int* result, int flags, const char** hintmsg);
extern bool parse_int64(const char* value, int64* result, const char** hintmsg);
extern bool parse_real(const char* value, double* result);
extern bool parse_real(const char* value, double* result, int flags = 0, const char** hintmsg = NULL);
double time_unit_convert(char** endptr, double value, int flags, const char** hintmsg);
double memory_unit_convert(char** endptr, double value, int flags, const char** hintmsg);
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);

View File

@ -88,7 +88,7 @@ NOTICE: please restart the database for the POSTMASTER level parameter to take
SHOW password_lock_time;
password_lock_time
--------------------
1
1d
(1 row)
ALTER SYSTEM SET password_lock_time to 1.1;
@ -137,7 +137,7 @@ select pg_sleep(2); -- wait to reload postgres.conf file
SHOW password_lock_time;
password_lock_time
--------------------
1.1
1.1d
(1 row)
ALTER SYSTEM SET password_lock_time to 1;
@ -185,7 +185,7 @@ select pg_sleep(2); -- wait to reload postgres.conf file
SHOW password_lock_time;
password_lock_time
--------------------
1
1d
(1 row)
SHOW autovacuum;
@ -243,7 +243,7 @@ select pg_sleep(2); -- wait to reload postgres.conf file
SHOW password_lock_time;
password_lock_time
--------------------
1
1d
(1 row)
SHOW autovacuum;

View File

@ -0,0 +1,97 @@
alter system set password_lock_time to '1s';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
1s
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '1.1s';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
1.1s
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '1min';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
1min
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '1h';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
1h
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '1d';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
1d
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '0.1h';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
6min
(1 row)
---------------------------------------------------------------------------
alter system set password_lock_time to '0.1d';
select pg_sleep(5);
pg_sleep
----------
(1 row)
show password_lock_time;
password_lock_time
--------------------
2.4h
(1 row)

View File

@ -86,3 +86,4 @@ test: synchronous_commit_test
test: alter_set_same_parameter
test: gs_guc_value_range
test: global_temporary_table_get_table_def
test: double_support_unit

View File

@ -0,0 +1,33 @@
alter system set password_lock_time to '1s';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '1.1s';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '1min';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '1h';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '1d';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '0.1h';
select pg_sleep(5);
show password_lock_time;
---------------------------------------------------------------------------
alter system set password_lock_time to '0.1d';
select pg_sleep(5);
show password_lock_time;