PoC_int_guc_representation.patch
text/x-patch
Filename: PoC_int_guc_representation.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/misc/guc.c | 46 | 7 |
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index d374f5372c..3ca2d6dec4 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -6011,7 +6011,7 @@ convert_to_base_unit(double value, const char *unit,
*/
static void
convert_int_from_base_unit(int64 base_value, int base_unit,
- int64 *value, const char **unit)
+ double *value, const char **unit, int *digits)
{
const unit_conversion *table;
int i;
@@ -6027,6 +6027,9 @@ convert_int_from_base_unit(int64 base_value, int base_unit,
{
if (base_unit == table[i].base_unit)
{
+ const double frac_digits = 2;
+ double rval;
+
/*
* Accept the first conversion that divides the value evenly. We
* assume that the conversions for each base unit are ordered from
@@ -6035,7 +6038,42 @@ convert_int_from_base_unit(int64 base_value, int base_unit,
if (table[i].multiplier <= 1.0 ||
base_value % (int64) table[i].multiplier == 0)
{
- *value = (int64) rint(base_value / table[i].multiplier);
+ *digits = 0;
+ *value = rint(base_value / table[i].multiplier);
+ *unit = table[i].unit;
+ break;
+ }
+
+ /*
+ * If base_value is exactly represented by a number with at most
+ * two fraction digits, we prefer it than lower units.
+ */
+ rval = (double)base_value / table[i].multiplier;
+ rval = rint(rval * pow(10, frac_digits)) *
+ pow(10, -frac_digits);
+
+ /*
+ * Acceptable range for rval is quite arbitrary.
+ */
+ if ((rval >= 1.0 ||
+ (table[i + 1].unit &&
+ table[i].multiplier / table[i + 1].multiplier < 1000) &&
+ (int64)rint(rval * table[i].multiplier) == base_value)
+ {
+ int frac;
+
+ /* count required fraction digits */
+ for (frac = 1 ; frac < frac_digits ; frac++)
+ {
+ if (rval * 10.0 - floor(rval * 10.0) < 0.1)
+ {
+ *digits = frac;
+ break;
+ }
+ }
+ if (frac == frac_digits)
+ *digits = frac_digits;
+ *value = rval;
*unit = table[i].unit;
break;
}
@@ -9359,18 +9397,19 @@ _ShowOption(struct config_generic *record, bool use_units)
* Use int64 arithmetic to avoid overflows in units
* conversion.
*/
- int64 result = *conf->variable;
+ double result = *conf->variable;
const char *unit;
+ int digits = 0;
if (use_units && result > 0 && (record->flags & GUC_UNIT))
- convert_int_from_base_unit(result,
+ convert_int_from_base_unit(*conf->variable,
record->flags & GUC_UNIT,
- &result, &unit);
+ &result, &unit, &digits);
else
unit = "";
- snprintf(buffer, sizeof(buffer), INT64_FORMAT "%s",
- result, unit);
+ snprintf(buffer, sizeof(buffer), "%.*f %s",
+ digits, result, unit);
val = buffer;
}
}