mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Refactor unit conversions code in guc.c.
Replace the if-switch-case constructs with two conversion tables, containing all the supported conversions between human-readable unit strings and the base units used in GUC variables. This makes the code easier to read, and makes adding new units simpler.
This commit is contained in:
parent
bc208a5a2f
commit
1b63026473
@ -97,20 +97,6 @@
|
|||||||
#define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
|
#define CONFIG_EXEC_PARAMS_NEW "global/config_exec_params.new"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define KB_PER_MB (1024)
|
|
||||||
#define KB_PER_GB (1024*1024)
|
|
||||||
#define KB_PER_TB (1024*1024*1024)
|
|
||||||
|
|
||||||
#define MS_PER_S 1000
|
|
||||||
#define S_PER_MIN 60
|
|
||||||
#define MS_PER_MIN (1000 * 60)
|
|
||||||
#define MIN_PER_H 60
|
|
||||||
#define S_PER_H (60 * 60)
|
|
||||||
#define MS_PER_H (1000 * 60 * 60)
|
|
||||||
#define MIN_PER_D (60 * 24)
|
|
||||||
#define S_PER_D (60 * 60 * 24)
|
|
||||||
#define MS_PER_D (1000 * 60 * 60 * 24)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Precision with which REAL type guc values are to be printed for GUC
|
* Precision with which REAL type guc values are to be printed for GUC
|
||||||
* serialization.
|
* serialization.
|
||||||
@ -666,6 +652,88 @@ const char *const config_type_names[] =
|
|||||||
/* PGC_ENUM */ "enum"
|
/* PGC_ENUM */ "enum"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit conversion tables.
|
||||||
|
*
|
||||||
|
* There are two tables, one for memory units, and another for time units.
|
||||||
|
* For each supported conversion from one unit to another, we have an entry
|
||||||
|
* in the table.
|
||||||
|
*
|
||||||
|
* To keep things simple, and to avoid intermediate-value overflows,
|
||||||
|
* conversions are never chained. There needs to be a direct conversion
|
||||||
|
* between all units (of the same type).
|
||||||
|
*
|
||||||
|
* The conversions from each base unit must be kept in order from greatest
|
||||||
|
* to smallest unit; convert_from_base_unit() relies on that. (The order of
|
||||||
|
* the base units does not matter.)
|
||||||
|
*/
|
||||||
|
#define MAX_UNIT_LEN 3 /* length of longest recognized unit string */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char unit[MAX_UNIT_LEN + 1]; /* unit, as a string, like "kB" or "min" */
|
||||||
|
int base_unit; /* GUC_UNIT_XXX */
|
||||||
|
int multiplier; /* If positive, multiply the value with this for
|
||||||
|
* unit -> base_unit conversion. If negative,
|
||||||
|
* divide (with the absolute value) */
|
||||||
|
} unit_conversion;
|
||||||
|
|
||||||
|
/* Ensure that the constants in the tables don't overflow or underflow */
|
||||||
|
#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
|
||||||
|
|
||||||
|
static const char *memory_units_hint =
|
||||||
|
gettext_noop("Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\".");
|
||||||
|
|
||||||
|
static const unit_conversion memory_unit_conversion_table[] =
|
||||||
|
{
|
||||||
|
{ "TB", GUC_UNIT_KB, 1024*1024*1024 },
|
||||||
|
{ "GB", GUC_UNIT_KB, 1024*1024 },
|
||||||
|
{ "MB", GUC_UNIT_KB, 1024 },
|
||||||
|
{ "kB", GUC_UNIT_KB, 1 },
|
||||||
|
|
||||||
|
{ "TB", GUC_UNIT_BLOCKS, (1024*1024*1024) / (BLCKSZ / 1024) },
|
||||||
|
{ "GB", GUC_UNIT_BLOCKS, (1024*1024) / (BLCKSZ / 1024) },
|
||||||
|
{ "MB", GUC_UNIT_BLOCKS, 1024 / (BLCKSZ / 1024) },
|
||||||
|
{ "kB", GUC_UNIT_BLOCKS, -(BLCKSZ / 1024) },
|
||||||
|
|
||||||
|
{ "TB", GUC_UNIT_XBLOCKS, (1024*1024*1024) / (XLOG_BLCKSZ / 1024) },
|
||||||
|
{ "GB", GUC_UNIT_XBLOCKS, (1024*1024) / (XLOG_BLCKSZ / 1024) },
|
||||||
|
{ "MB", GUC_UNIT_XBLOCKS, 1024 / (XLOG_BLCKSZ / 1024) },
|
||||||
|
{ "kB", GUC_UNIT_XBLOCKS, -(XLOG_BLCKSZ / 1024) },
|
||||||
|
|
||||||
|
{ "" } /* end of table marker */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *time_units_hint =
|
||||||
|
gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");
|
||||||
|
|
||||||
|
static const unit_conversion time_unit_conversion_table[] =
|
||||||
|
{
|
||||||
|
{ "d", GUC_UNIT_MS, 1000 * 60 * 60 * 24 },
|
||||||
|
{ "h", GUC_UNIT_MS, 1000 * 60 * 60 },
|
||||||
|
{ "min", GUC_UNIT_MS, 1000 * 60},
|
||||||
|
{ "s", GUC_UNIT_MS, 1000 },
|
||||||
|
{ "ms", GUC_UNIT_MS, 1 },
|
||||||
|
|
||||||
|
{ "d", GUC_UNIT_S, 60 * 60 * 24 },
|
||||||
|
{ "h", GUC_UNIT_S, 60 * 60 },
|
||||||
|
{ "min", GUC_UNIT_S, 60 },
|
||||||
|
{ "s", GUC_UNIT_S, 1 },
|
||||||
|
{ "ms", GUC_UNIT_S, -1000 },
|
||||||
|
|
||||||
|
{ "d", GUC_UNIT_MIN, 60 * 24 },
|
||||||
|
{ "h", GUC_UNIT_MIN, 60 },
|
||||||
|
{ "min", GUC_UNIT_MIN, 1 },
|
||||||
|
{ "s", GUC_UNIT_MIN, -60 },
|
||||||
|
{ "ms", GUC_UNIT_MIN, -1000 * 60 },
|
||||||
|
|
||||||
|
{ "" } /* end of table marker */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Contents of GUC tables
|
* Contents of GUC tables
|
||||||
@ -5029,6 +5097,88 @@ ReportGUCOption(struct config_generic * record)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a value from one of the human-friendly units ("kB", "min" etc.)
|
||||||
|
* to the given base unit. 'value' and 'unit' are the input value and unit
|
||||||
|
* to convert from. The converted value is stored in *base_value.
|
||||||
|
*
|
||||||
|
* Returns true on success, false if the input unit is not recognized.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
convert_to_base_unit(int64 value, const char *unit,
|
||||||
|
int base_unit, int64 *base_value)
|
||||||
|
{
|
||||||
|
const unit_conversion *table;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (base_unit & GUC_UNIT_MEMORY)
|
||||||
|
table = memory_unit_conversion_table;
|
||||||
|
else
|
||||||
|
table = time_unit_conversion_table;
|
||||||
|
|
||||||
|
for (i = 0; *table[i].unit; i++)
|
||||||
|
{
|
||||||
|
if (base_unit == table[i].base_unit &&
|
||||||
|
strcmp(unit, table[i].unit) == 0)
|
||||||
|
{
|
||||||
|
if (table[i].multiplier < 0)
|
||||||
|
*base_value = value / (-table[i].multiplier);
|
||||||
|
else
|
||||||
|
*base_value = value * table[i].multiplier;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a value in some base unit to a human-friendly unit. The output
|
||||||
|
* unit is chosen so that it's the greatest unit that can represent the value
|
||||||
|
* without loss. For example, if the base unit is GUC_UNIT_KB, 1024 is
|
||||||
|
* converted to 1 MB, but 1025 is represented as 1025 kB.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
convert_from_base_unit(int64 base_value, int base_unit,
|
||||||
|
int64 *value, const char **unit)
|
||||||
|
{
|
||||||
|
const unit_conversion *table;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*unit = NULL;
|
||||||
|
|
||||||
|
if (base_unit & GUC_UNIT_MEMORY)
|
||||||
|
table = memory_unit_conversion_table;
|
||||||
|
else
|
||||||
|
table = time_unit_conversion_table;
|
||||||
|
|
||||||
|
for (i = 0; *table[i].unit; i++)
|
||||||
|
{
|
||||||
|
if (base_unit == table[i].base_unit)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Accept the first conversion that divides the value evenly.
|
||||||
|
* We assume that the conversions for each base unit are ordered
|
||||||
|
* from greatest unit to the smallest!
|
||||||
|
*/
|
||||||
|
if (table[i].multiplier < 0)
|
||||||
|
{
|
||||||
|
*value = base_value * (-table[i].multiplier);
|
||||||
|
*unit = table[i].unit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (base_value % table[i].multiplier == 0)
|
||||||
|
{
|
||||||
|
*value = base_value / table[i].multiplier;
|
||||||
|
*unit = table[i].unit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(*unit != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to parse value as an integer. The accepted formats are the
|
* Try to parse value as an integer. The accepted formats are the
|
||||||
* usual decimal, octal, or hexadecimal formats, optionally followed by
|
* usual decimal, octal, or hexadecimal formats, optionally followed by
|
||||||
@ -5072,170 +5222,37 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
|
|||||||
/* Handle possible unit */
|
/* Handle possible unit */
|
||||||
if (*endptr != '\0')
|
if (*endptr != '\0')
|
||||||
{
|
{
|
||||||
/*
|
char unit[MAX_UNIT_LEN + 1];
|
||||||
* Note: the multiple-switch coding technique here is a bit tedious,
|
int unitlen;
|
||||||
* but seems necessary to avoid intermediate-value overflows.
|
bool converted = false;
|
||||||
*/
|
|
||||||
if (flags & GUC_UNIT_MEMORY)
|
|
||||||
{
|
|
||||||
/* Set hint for use if no match or trailing garbage */
|
|
||||||
if (hintmsg)
|
|
||||||
*hintmsg = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\".");
|
|
||||||
|
|
||||||
#if BLCKSZ < 1024 || BLCKSZ > (1024*1024)
|
if ((flags & GUC_UNIT) == 0)
|
||||||
#error BLCKSZ must be between 1KB and 1MB
|
return false; /* this setting does not accept a unit */
|
||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strncmp(endptr, "TB", 2) == 0)
|
|
||||||
{
|
|
||||||
endptr += 2;
|
|
||||||
switch (flags & GUC_UNIT_MEMORY)
|
|
||||||
{
|
|
||||||
case GUC_UNIT_KB:
|
|
||||||
val *= KB_PER_TB;
|
|
||||||
break;
|
|
||||||
case GUC_UNIT_BLOCKS:
|
|
||||||
val *= KB_PER_TB / (BLCKSZ / 1024);
|
|
||||||
break;
|
|
||||||
case GUC_UNIT_XBLOCKS:
|
|
||||||
val *= KB_PER_TB / (XLOG_BLCKSZ / 1024);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (flags & GUC_UNIT_TIME)
|
|
||||||
{
|
|
||||||
/* Set hint for use if no match or trailing garbage */
|
|
||||||
if (hintmsg)
|
|
||||||
*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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
unitlen = 0;
|
||||||
|
while (*endptr != '\0' && !isspace((unsigned char) *endptr) &&
|
||||||
|
unitlen < MAX_UNIT_LEN)
|
||||||
|
unit[unitlen++] = *(endptr++);
|
||||||
|
unit[unitlen] = '\0';
|
||||||
/* allow whitespace after unit */
|
/* allow whitespace after unit */
|
||||||
while (isspace((unsigned char) *endptr))
|
while (isspace((unsigned char) *endptr))
|
||||||
endptr++;
|
endptr++;
|
||||||
|
|
||||||
if (*endptr != '\0')
|
if (*endptr == '\0')
|
||||||
return false; /* appropriate hint, if any, already set */
|
converted = convert_to_base_unit(val, unit, (flags & GUC_UNIT),
|
||||||
|
&val);
|
||||||
|
if (!converted)
|
||||||
|
{
|
||||||
|
/* invalid unit, or garbage after the unit; set hint and fail. */
|
||||||
|
if (hintmsg)
|
||||||
|
{
|
||||||
|
if (flags & GUC_UNIT_MEMORY)
|
||||||
|
*hintmsg = memory_units_hint;
|
||||||
|
else
|
||||||
|
*hintmsg = time_units_hint;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for overflow due to units conversion */
|
/* Check for overflow due to units conversion */
|
||||||
if (val != (int64) ((int32) val))
|
if (val != (int64) ((int32) val))
|
||||||
@ -8108,76 +8125,10 @@ _ShowOption(struct config_generic * record, bool use_units)
|
|||||||
int64 result = *conf->variable;
|
int64 result = *conf->variable;
|
||||||
const char *unit;
|
const char *unit;
|
||||||
|
|
||||||
if (use_units && result > 0 &&
|
if (use_units && result > 0 && (record->flags & GUC_UNIT))
|
||||||
(record->flags & GUC_UNIT_MEMORY))
|
|
||||||
{
|
{
|
||||||
switch (record->flags & GUC_UNIT_MEMORY)
|
convert_from_base_unit(result, record->flags & GUC_UNIT,
|
||||||
{
|
&result, &unit);
|
||||||
case GUC_UNIT_BLOCKS:
|
|
||||||
result *= BLCKSZ / 1024;
|
|
||||||
break;
|
|
||||||
case GUC_UNIT_XBLOCKS:
|
|
||||||
result *= XLOG_BLCKSZ / 1024;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result % KB_PER_TB == 0)
|
|
||||||
{
|
|
||||||
result /= KB_PER_TB;
|
|
||||||
unit = "TB";
|
|
||||||
}
|
|
||||||
else if (result % KB_PER_GB == 0)
|
|
||||||
{
|
|
||||||
result /= KB_PER_GB;
|
|
||||||
unit = "GB";
|
|
||||||
}
|
|
||||||
else if (result % KB_PER_MB == 0)
|
|
||||||
{
|
|
||||||
result /= KB_PER_MB;
|
|
||||||
unit = "MB";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unit = "kB";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (use_units && result > 0 &&
|
|
||||||
(record->flags & GUC_UNIT_TIME))
|
|
||||||
{
|
|
||||||
switch (record->flags & GUC_UNIT_TIME)
|
|
||||||
{
|
|
||||||
case GUC_UNIT_S:
|
|
||||||
result *= MS_PER_S;
|
|
||||||
break;
|
|
||||||
case GUC_UNIT_MIN:
|
|
||||||
result *= MS_PER_MIN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result % MS_PER_D == 0)
|
|
||||||
{
|
|
||||||
result /= MS_PER_D;
|
|
||||||
unit = "d";
|
|
||||||
}
|
|
||||||
else if (result % MS_PER_H == 0)
|
|
||||||
{
|
|
||||||
result /= MS_PER_H;
|
|
||||||
unit = "h";
|
|
||||||
}
|
|
||||||
else if (result % MS_PER_MIN == 0)
|
|
||||||
{
|
|
||||||
result /= MS_PER_MIN;
|
|
||||||
unit = "min";
|
|
||||||
}
|
|
||||||
else if (result % MS_PER_S == 0)
|
|
||||||
{
|
|
||||||
result /= MS_PER_S;
|
|
||||||
unit = "s";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unit = "ms";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
unit = "";
|
unit = "";
|
||||||
|
@ -212,6 +212,8 @@ typedef enum
|
|||||||
#define GUC_UNIT_MIN 0x4000 /* value is in minutes */
|
#define GUC_UNIT_MIN 0x4000 /* value is in minutes */
|
||||||
#define GUC_UNIT_TIME 0x7000 /* mask for MS, S, MIN */
|
#define GUC_UNIT_TIME 0x7000 /* mask for MS, S, MIN */
|
||||||
|
|
||||||
|
#define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME)
|
||||||
|
|
||||||
#define GUC_NOT_WHILE_SEC_REST 0x8000 /* can't set if security restricted */
|
#define GUC_NOT_WHILE_SEC_REST 0x8000 /* can't set if security restricted */
|
||||||
#define GUC_DISALLOW_IN_AUTO_FILE 0x00010000 /* can't set in
|
#define GUC_DISALLOW_IN_AUTO_FILE 0x00010000 /* can't set in
|
||||||
* PG_AUTOCONF_FILENAME */
|
* PG_AUTOCONF_FILENAME */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user