@ -755,13 +755,13 @@ const char *const config_type_names[] =
* For each supported conversion from one unit to another , we have an entry
* For each supported conversion from one unit to another , we have an entry
* in the table .
* in the table .
*
*
* To keep things simple , and to avoid intermediate - value overflows ,
* To keep things simple , and to avoid possible roundoff error ,
* conversions are never chained . There needs to be a direct conversion
* conversions are never chained . There needs to be a direct conversion
* between all units ( of the same type ) .
* between all units ( of the same type ) .
*
*
* The conversions from each base unit must be kept in order from greatest
* The conversions for each base unit must be kept in order from greatest to
* to smallest unit ; convert_from_base_unit ( ) relies on that . ( The order of
* smallest human - friendly unit ; convert_xxx_from_base_unit ( ) rely on that .
* the base units does not matter . )
* ( The order of the base - unit group s does not matter . )
*/
*/
# define MAX_UNIT_LEN 3 /* length of longest recognized unit string */
# define MAX_UNIT_LEN 3 /* length of longest recognized unit string */
@ -770,9 +770,7 @@ typedef struct
char unit [ MAX_UNIT_LEN + 1 ] ; /* unit, as a string, like "kB" or
char unit [ MAX_UNIT_LEN + 1 ] ; /* unit, as a string, like "kB" or
* " min " */
* " min " */
int base_unit ; /* GUC_UNIT_XXX */
int base_unit ; /* GUC_UNIT_XXX */
int64 multiplier ; /* If positive, multiply the value with this
double multiplier ; /* Factor for converting unit -> base_unit */
* for unit - > base_unit conversion . If
* negative , divide ( with the absolute value ) */
} unit_conversion ;
} unit_conversion ;
/* Ensure that the constants in the tables don't overflow or underflow */
/* Ensure that the constants in the tables don't overflow or underflow */
@ -787,45 +785,40 @@ static const char *memory_units_hint = gettext_noop("Valid units for this parame
static const unit_conversion memory_unit_conversion_table [ ] =
static const unit_conversion memory_unit_conversion_table [ ] =
{
{
/*
{ " TB " , GUC_UNIT_BYTE , 1024.0 * 1024.0 * 1024.0 * 1024.0 } ,
* TB - > bytes conversion always overflows 32 - bit integer , so this always
{ " GB " , GUC_UNIT_BYTE , 1024.0 * 1024.0 * 1024.0 } ,
* produces an error . Include it nevertheless for completeness , and so
{ " MB " , GUC_UNIT_BYTE , 1024.0 * 1024.0 } ,
* that you get an " out of range " error , rather than " invalid unit " .
{ " kB " , GUC_UNIT_BYTE , 1024.0 } ,
*/
{ " B " , GUC_UNIT_BYTE , 1.0 } ,
{ " TB " , GUC_UNIT_BYTE , INT64CONST ( 1024 ) * 1024 * 1024 * 1024 } ,
{ " GB " , GUC_UNIT_BYTE , 1024 * 1024 * 1024 } ,
{ " TB " , GUC_UNIT_KB , 1024.0 * 1024.0 * 1024.0 } ,
{ " MB " , GUC_UNIT_BYTE , 1024 * 1024 } ,
{ " GB " , GUC_UNIT_KB , 1024.0 * 1024.0 } ,
{ " kB " , GUC_UNIT_BYTE , 1024 } ,
{ " MB " , GUC_UNIT_KB , 1024.0 } ,
{ " B " , GUC_UNIT_BYTE , 1 } ,
{ " kB " , GUC_UNIT_KB , 1.0 } ,
{ " B " , GUC_UNIT_KB , 1.0 / 1024.0 } ,
{ " TB " , GUC_UNIT_KB , 1024 * 1024 * 1024 } ,
{ " GB " , GUC_UNIT_KB , 1024 * 1024 } ,
{ " TB " , GUC_UNIT_MB , 1024.0 * 1024.0 } ,
{ " MB " , GUC_UNIT_KB , 1024 } ,
{ " GB " , GUC_UNIT_MB , 1024.0 } ,
{ " kB " , GUC_UNIT_KB , 1 } ,
{ " MB " , GUC_UNIT_MB , 1.0 } ,
{ " B " , GUC_UNIT_KB , - 1024 } ,
{ " kB " , GUC_UNIT_MB , 1.0 / 1024.0 } ,
{ " B " , GUC_UNIT_MB , 1.0 / ( 1024.0 * 1024.0 ) } ,
{ " TB " , GUC_UNIT_MB , 1024 * 1024 } ,
{ " GB " , GUC_UNIT_MB , 1024 } ,
{ " TB " , GUC_UNIT_BLOCKS , ( 1024.0 * 1024.0 * 1024.0 ) / ( BLCKSZ / 1024 ) } ,
{ " MB " , GUC_UNIT_MB , 1 } ,
{ " GB " , GUC_UNIT_BLOCKS , ( 1024.0 * 1024.0 ) / ( BLCKSZ / 1024 ) } ,
{ " kB " , GUC_UNIT_MB , - 1024 } ,
{ " MB " , GUC_UNIT_BLOCKS , 1024.0 / ( BLCKSZ / 1024 ) } ,
{ " B " , GUC_UNIT_MB , - ( 1024 * 1024 ) } ,
{ " kB " , GUC_UNIT_BLOCKS , 1.0 / ( BLCKSZ / 1024 ) } ,
{ " B " , GUC_UNIT_BLOCKS , 1.0 / BLCKSZ } ,
{ " TB " , GUC_UNIT_BLOCKS , ( 1024 * 1024 * 1024 ) / ( BLCKSZ / 1024 ) } ,
{ " GB " , GUC_UNIT_BLOCKS , ( 1024 * 1024 ) / ( BLCKSZ / 1024 ) } ,
{ " TB " , GUC_UNIT_XBLOCKS , ( 1024.0 * 1024.0 * 1024.0 ) / ( XLOG_BLCKSZ / 1024 ) } ,
{ " MB " , GUC_UNIT_BLOCKS , 1024 / ( BLCKSZ / 1024 ) } ,
{ " GB " , GUC_UNIT_XBLOCKS , ( 1024.0 * 1024.0 ) / ( XLOG_BLCKSZ / 1024 ) } ,
{ " kB " , GUC_UNIT_BLOCKS , - ( BLCKSZ / 1024 ) } ,
{ " MB " , GUC_UNIT_XBLOCKS , 1024.0 / ( XLOG_BLCKSZ / 1024 ) } ,
{ " B " , GUC_UNIT_BLOCKS , - BLCKSZ } ,
{ " kB " , GUC_UNIT_XBLOCKS , 1.0 / ( XLOG_BLCKSZ / 1024 ) } ,
{ " B " , GUC_UNIT_XBLOCKS , 1.0 / XLOG_BLCKSZ } ,
{ " 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 ) } ,
{ " B " , GUC_UNIT_XBLOCKS , - XLOG_BLCKSZ } ,
{ " " } /* end of table marker */
{ " " } /* 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 char * time_units_hint = gettext_noop ( " Valid units for this parameter are \" us \" , \" ms \" , \" s \" , \" min \" , \" h \" , and \" d \" . " ) ;
static const unit_conversion time_unit_conversion_table [ ] =
static const unit_conversion time_unit_conversion_table [ ] =
{
{
@ -834,18 +827,21 @@ static const unit_conversion time_unit_conversion_table[] =
{ " min " , GUC_UNIT_MS , 1000 * 60 } ,
{ " min " , GUC_UNIT_MS , 1000 * 60 } ,
{ " s " , GUC_UNIT_MS , 1000 } ,
{ " s " , GUC_UNIT_MS , 1000 } ,
{ " ms " , GUC_UNIT_MS , 1 } ,
{ " ms " , GUC_UNIT_MS , 1 } ,
{ " us " , GUC_UNIT_MS , 1.0 / 1000 } ,
{ " d " , GUC_UNIT_S , 60 * 60 * 24 } ,
{ " d " , GUC_UNIT_S , 60 * 60 * 24 } ,
{ " h " , GUC_UNIT_S , 60 * 60 } ,
{ " h " , GUC_UNIT_S , 60 * 60 } ,
{ " min " , GUC_UNIT_S , 60 } ,
{ " min " , GUC_UNIT_S , 60 } ,
{ " s " , GUC_UNIT_S , 1 } ,
{ " s " , GUC_UNIT_S , 1 } ,
{ " ms " , GUC_UNIT_S , - 1000 } ,
{ " ms " , GUC_UNIT_S , 1.0 / 1000 } ,
{ " us " , GUC_UNIT_S , 1.0 / ( 1000 * 1000 ) } ,
{ " d " , GUC_UNIT_MIN , 60 * 24 } ,
{ " d " , GUC_UNIT_MIN , 60 * 24 } ,
{ " h " , GUC_UNIT_MIN , 60 } ,
{ " h " , GUC_UNIT_MIN , 60 } ,
{ " min " , GUC_UNIT_MIN , 1 } ,
{ " min " , GUC_UNIT_MIN , 1 } ,
{ " s " , GUC_UNIT_MIN , - 60 } ,
{ " s " , GUC_UNIT_MIN , 1.0 / 60 } ,
{ " ms " , GUC_UNIT_MIN , - 1000 * 60 } ,
{ " ms " , GUC_UNIT_MIN , 1.0 / ( 1000 * 60 ) } ,
{ " us " , GUC_UNIT_MIN , 1.0 / ( 1000 * 1000 * 60 ) } ,
{ " " } /* end of table marker */
{ " " } /* end of table marker */
} ;
} ;
@ -2273,28 +2269,6 @@ static struct config_int ConfigureNamesInt[] =
NULL , NULL , NULL
NULL , NULL , NULL
} ,
} ,
{
{ " vacuum_cost_delay " , PGC_USERSET , RESOURCES_VACUUM_DELAY ,
gettext_noop ( " Vacuum cost delay in milliseconds. " ) ,
NULL ,
GUC_UNIT_MS
} ,
& VacuumCostDelay ,
0 , 0 , 100 ,
NULL , NULL , NULL
} ,
{
{ " autovacuum_vacuum_cost_delay " , PGC_SIGHUP , AUTOVACUUM ,
gettext_noop ( " Vacuum cost delay in milliseconds, for autovacuum. " ) ,
NULL ,
GUC_UNIT_MS
} ,
& autovacuum_vac_cost_delay ,
20 , - 1 , 100 ,
NULL , NULL , NULL
} ,
{
{
{ " autovacuum_vacuum_cost_limit " , PGC_SIGHUP , AUTOVACUUM ,
{ " autovacuum_vacuum_cost_limit " , PGC_SIGHUP , AUTOVACUUM ,
gettext_noop ( " Vacuum cost amount available before napping, for autovacuum. " ) ,
gettext_noop ( " Vacuum cost amount available before napping, for autovacuum. " ) ,
@ -3320,6 +3294,28 @@ static struct config_real ConfigureNamesReal[] =
check_random_seed , assign_random_seed , show_random_seed
check_random_seed , assign_random_seed , show_random_seed
} ,
} ,
{
{ " vacuum_cost_delay " , PGC_USERSET , RESOURCES_VACUUM_DELAY ,
gettext_noop ( " Vacuum cost delay in milliseconds. " ) ,
NULL ,
GUC_UNIT_MS
} ,
& VacuumCostDelay ,
0 , 0 , 100 ,
NULL , NULL , NULL
} ,
{
{ " autovacuum_vacuum_cost_delay " , PGC_SIGHUP , AUTOVACUUM ,
gettext_noop ( " Vacuum cost delay in milliseconds, for autovacuum. " ) ,
NULL ,
GUC_UNIT_MS
} ,
& autovacuum_vac_cost_delay ,
20 , - 1 , 100 ,
NULL , NULL , NULL
} ,
{
{
{ " autovacuum_vacuum_scale_factor " , PGC_SIGHUP , AUTOVACUUM ,
{ " autovacuum_vacuum_scale_factor " , PGC_SIGHUP , AUTOVACUUM ,
gettext_noop ( " Number of tuple updates or deletes prior to vacuum as a fraction of reltuples. " ) ,
gettext_noop ( " Number of tuple updates or deletes prior to vacuum as a fraction of reltuples. " ) ,
@ -5960,17 +5956,35 @@ ReportGUCOption(struct config_generic *record)
/*
/*
* Convert a value from one of the human - friendly units ( " kB " , " min " etc . )
* 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 the given base unit . ' value ' and ' unit ' are the input value and unit
* to convert from . The converted value is stored in * base_value .
* to convert from ( there can be trailing spaces in the unit string ) .
* The converted value is stored in * base_value .
* It ' s caller ' s responsibility to round off the converted value as necessary
* and check for out - of - range .
*
*
* Returns true on success , false if the input unit is not recognized .
* Returns true on success , false if the input unit is not recognized .
*/
*/
static bool
static bool
convert_to_base_unit ( int64 value , const char * unit ,
convert_to_base_unit ( double value , const char * unit ,
int base_unit , int64 * base_value )
int base_unit , double * base_value )
{
{
char unitstr [ MAX_UNIT_LEN + 1 ] ;
int unitlen ;
const unit_conversion * table ;
const unit_conversion * table ;
int i ;
int i ;
/* extract unit string to compare to table entries */
unitlen = 0 ;
while ( * unit ! = ' \0 ' & & ! isspace ( ( unsigned char ) * unit ) & &
unitlen < MAX_UNIT_LEN )
unitstr [ unitlen + + ] = * ( unit + + ) ;
unitstr [ unitlen ] = ' \0 ' ;
/* allow whitespace after unit */
while ( isspace ( ( unsigned char ) * unit ) )
unit + + ;
if ( * unit ! = ' \0 ' )
return false ; /* unit too long, or garbage after it */
/* now search the appropriate table */
if ( base_unit & GUC_UNIT_MEMORY )
if ( base_unit & GUC_UNIT_MEMORY )
table = memory_unit_conversion_table ;
table = memory_unit_conversion_table ;
else
else
@ -5979,12 +5993,9 @@ convert_to_base_unit(int64 value, const char *unit,
for ( i = 0 ; * table [ i ] . unit ; i + + )
for ( i = 0 ; * table [ i ] . unit ; i + + )
{
{
if ( base_unit = = table [ i ] . base_unit & &
if ( base_unit = = table [ i ] . base_unit & &
strcmp ( unit , table [ i ] . unit ) = = 0 )
strcmp ( unitstr , table [ i ] . unit ) = = 0 )
{
{
if ( table [ i ] . multiplier < 0 )
* base_value = value * table [ i ] . multiplier ;
* base_value = value / ( - table [ i ] . multiplier ) ;
else
* base_value = value * table [ i ] . multiplier ;
return true ;
return true ;
}
}
}
}
@ -5992,14 +6003,15 @@ convert_to_base_unit(int64 value, const char *unit,
}
}
/*
/*
* Convert a value in some base unit to a human - friendly unit . The output
* Convert an integer value in some base unit to a human - friendly unit .
* 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
* The output unit is chosen so that it ' s the greatest unit that can represent
* converted to 1 MB , but 1025 is represented as 1025 kB .
* 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
static void
convert_from_base_unit ( int64 base_value , int base_unit ,
convert_int_ from_base_unit ( int64 base_value , int base_unit ,
int64 * value , const char * * unit )
int64 * value , const char * * unit )
{
{
const unit_conversion * table ;
const unit_conversion * table ;
int i ;
int i ;
@ -6016,22 +6028,62 @@ convert_from_base_unit(int64 base_value, int base_unit,
if ( base_unit = = table [ i ] . base_unit )
if ( base_unit = = table [ i ] . base_unit )
{
{
/*
/*
* Accept the first conversion that divides the value evenly . We
* Accept the first conversion that divides the value evenly . We
* assume that the conversions for each base unit are ordered from
* assume that the conversions for each base unit are ordered from
* greatest unit to the smallest !
* greatest unit to the smallest !
*/
*/
if ( table [ i ] . multiplier < 0 )
if ( table [ i ] . multiplier < = 1.0 | |
base_value % ( int64 ) table [ i ] . multiplier = = 0 )
{
{
* value = base_value * ( - table [ i ] . multiplier ) ;
* value = ( int64 ) rint ( base_value / table [ i ] . multiplier ) ;
* unit = table [ i ] . unit ;
* unit = table [ i ] . unit ;
break ;
break ;
}
}
else if ( base_value % table [ i ] . multiplier = = 0 )
}
{
}
* value = base_value / table [ i ] . multiplier ;
* unit = table [ i ] . unit ;
Assert ( * unit ! = NULL ) ;
}
/*
* Convert a floating - point value in some base unit to a human - friendly unit .
*
* Same as above , except we have to do the math a bit differently , and
* there ' s a possibility that we don ' t find any exact divisor .
*/
static void
convert_real_from_base_unit ( double base_value , int base_unit ,
double * 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 ; or
* if there is none , use the smallest ( last ) target unit .
*
* What we actually care about here is whether snprintf with " %g "
* will print the value as an integer , so the obvious test of
* " *value == rint(*value) " is too strict ; roundoff error might
* make us choose an unreasonably small unit . As a compromise ,
* accept a divisor that is within 1e-8 of producing an integer .
*/
* value = base_value / table [ i ] . multiplier ;
* unit = table [ i ] . unit ;
if ( * value > 0 & &
fabs ( ( rint ( * value ) / * value ) - 1.0 ) < = 1e-8 )
break ;
break ;
}
}
}
}
}
@ -6095,7 +6147,7 @@ get_config_unit_name(int flags)
* If the string parses okay , return true , else false .
* If the string parses okay , return true , else false .
* If okay and result is not NULL , return the value in * result .
* If okay and result is not NULL , return the value in * result .
* If not okay and hintmsg is not NULL , * hintmsg is set to a suitable
* If not okay and hintmsg is not NULL , * hintmsg is set to a suitable
* HINT message , or NULL if no hint provided .
* HINT message , or NULL if no hint provided .
*/
*/
bool
bool
parse_int ( const char * value , int * result , int flags , const char * * hintmsg )
parse_int ( const char * value , int * result , int flags , const char * * hintmsg )
@ -6130,26 +6182,14 @@ 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 ] ;
double cval ;
int unitlen ;
bool converted = false ;
if ( ( flags & GUC_UNIT ) = = 0 )
if ( ( flags & GUC_UNIT ) = = 0 )
return false ; /* this setting does not accept a unit */
return false ; /* this setting does not accept a unit */
unitlen = 0 ;
if ( ! convert_to_base_unit ( ( double ) val ,
while ( * endptr ! = ' \0 ' & & ! isspace ( ( unsigned char ) * endptr ) & &
endptr , ( flags & GUC_UNIT ) ,
unitlen < MAX_UNIT_LEN )
& cval ) )
unit [ unitlen + + ] = * ( endptr + + ) ;
unit [ unitlen ] = ' \0 ' ;
/* allow whitespace after unit */
while ( isspace ( ( unsigned char ) * endptr ) )
endptr + + ;
if ( * endptr = = ' \0 ' )
converted = convert_to_base_unit ( val , unit , ( flags & GUC_UNIT ) ,
& val ) ;
if ( ! converted )
{
{
/* invalid unit, or garbage after the unit; set hint and fail. */
/* invalid unit, or garbage after the unit; set hint and fail. */
if ( hintmsg )
if ( hintmsg )
@ -6162,13 +6202,15 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
return false ;
return false ;
}
}
/* Check for overflow due to units conversion */
/* Round to int, then check for overflow due to units conversion */
if ( val ! = ( int64 ) ( ( int32 ) val ) )
cval = rint ( cval ) ;
if ( cval > INT_MAX | | cval < INT_MIN )
{
{
if ( hintmsg )
if ( hintmsg )
* hintmsg = gettext_noop ( " Value exceeds integer range. " ) ;
* hintmsg = gettext_noop ( " Value exceeds integer range. " ) ;
return false ;
return false ;
}
}
val = ( int64 ) cval ;
}
}
if ( result )
if ( result )
@ -6180,32 +6222,59 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
/*
/*
* Try to parse value as a floating point number in the usual format .
* Try to parse value as a floating point number in the usual format .
*
* If the string parses okay , return true , else false .
* If the string parses okay , return true , else false .
* If okay and result is not NULL , return the value in * result .
* If okay and result is not NULL , return the value in * result .
* If not okay and hintmsg is not NULL , * hintmsg is set to a suitable
* HINT message , or NULL if no hint provided .
*/
*/
bool
bool
parse_real ( const char * value , double * result )
parse_real ( const char * value , double * result , int flags , const char * * hintmsg )
{
{
double val ;
double val ;
char * endptr ;
char * endptr ;
/* To suppress compiler warnings, always set output params */
if ( result )
if ( result )
* result = 0 ; /* suppress compiler warning */
* result = 0 ;
if ( hintmsg )
* hintmsg = NULL ;
errno = 0 ;
errno = 0 ;
val = strtod ( value , & endptr ) ;
val = strtod ( value , & endptr ) ;
if ( endptr = = value | | errno = = ERANGE )
if ( endptr = = value | | errno = = ERANGE )
return false ;
return false ; /* no HINT for these cases */
/* reject NaN (infinities will fail range checks later) */
/* reject NaN (infinities will fail range checks later) */
if ( isnan ( val ) )
if ( isnan ( val ) )
return false ;
return false ; /* treat same as syntax error; no HINT */
/* allow whitespace after number */
/* allow whitespace between number and unit */
while ( isspace ( ( unsigned char ) * endptr ) )
while ( isspace ( ( unsigned char ) * endptr ) )
endptr + + ;
endptr + + ;
/* Handle possible unit */
if ( * endptr ! = ' \0 ' )
if ( * endptr ! = ' \0 ' )
return false ;
{
if ( ( flags & GUC_UNIT ) = = 0 )
return false ; /* this setting does not accept a unit */
if ( ! convert_to_base_unit ( val ,
endptr , ( flags & GUC_UNIT ) ,
& val ) )
{
/* 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 ;
}
}
if ( result )
if ( result )
* result = val ;
* result = val ;
@ -6393,13 +6462,16 @@ parse_and_validate_value(struct config_generic *record,
case PGC_REAL :
case PGC_REAL :
{
{
struct config_real * conf = ( struct config_real * ) record ;
struct config_real * conf = ( struct config_real * ) record ;
const char * hintmsg ;
if ( ! parse_real ( value , & newval - > realval ) )
if ( ! parse_real ( value , & newval - > realval ,
conf - > gen . flags , & hintmsg ) )
{
{
ereport ( elevel ,
ereport ( elevel ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " parameter \" %s \" requires a numeric value " ,
errmsg ( " invalid value for parameter \" %s \" : \" %s \" " ,
name ) ) ) ;
name , value ) ,
hintmsg ? errhint ( " %s " , _ ( hintmsg ) ) : 0 ) ) ;
return false ;
return false ;
}
}
@ -9278,10 +9350,9 @@ _ShowOption(struct config_generic *record, bool use_units)
const char * unit ;
const char * unit ;
if ( use_units & & result > 0 & & ( record - > flags & GUC_UNIT ) )
if ( use_units & & result > 0 & & ( record - > flags & GUC_UNIT ) )
{
convert_int_from_base_unit ( result ,
convert_from_base_unit ( result , record - > flags & GUC_UNIT ,
record - > flags & GUC_UNIT ,
& result , & unit ) ;
& result , & unit ) ;
}
else
else
unit = " " ;
unit = " " ;
@ -9300,8 +9371,18 @@ _ShowOption(struct config_generic *record, bool use_units)
val = conf - > show_hook ( ) ;
val = conf - > show_hook ( ) ;
else
else
{
{
snprintf ( buffer , sizeof ( buffer ) , " %g " ,
double result = * conf - > variable ;
* conf - > variable ) ;
const char * unit ;
if ( use_units & & result > 0 & & ( record - > flags & GUC_UNIT ) )
convert_real_from_base_unit ( result ,
record - > flags & GUC_UNIT ,
& result , & unit ) ;
else
unit = " " ;
snprintf ( buffer , sizeof ( buffer ) , " %g%s " ,
result , unit ) ;
val = buffer ;
val = buffer ;
}
}
}
}