diff options
author | Bruce Momjian | 2015-10-06 01:03:38 +0000 |
---|---|---|
committer | Bruce Momjian | 2015-10-06 01:03:38 +0000 |
commit | 28b3a3d41a8b72841a3f5067217f639a7d337c0e (patch) | |
tree | 58a938a35f46a2c443ef98c409125cb44e97d200 | |
parent | 2145a766044b4de32ab154a074ade0bf78d021df (diff) |
to_number(): allow 'V' to divide by 10^(the number of digits)
to_char('V') already multiplied in a similar manner.
Report by Jeremy Lowery
-rw-r--r-- | doc/src/sgml/func.sgml | 8 | ||||
-rw-r--r-- | src/backend/utils/adt/formatting.c | 19 |
2 files changed, 23 insertions, 4 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 897ed64779..f8d9e46093 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -6152,12 +6152,14 @@ SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); <listitem> <para> - <literal>V</literal> effectively + <literal>V</literal> with <function>to_char</function> multiplies the input values by <literal>10^<replaceable>n</replaceable></literal>, where <replaceable>n</replaceable> is the number of digits following - <literal>V</literal>. - <function>to_char</function> does not support the use of + <literal>V</literal>. <literal>V</literal> with + <function>to_number</function> divides in a similar manner. + <function>to_char</function> and <function>to_number</function> + do not support the use of <literal>V</literal> combined with a decimal point (e.g., <literal>99.9V99</literal> is not allowed). </para> diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 5b09de32ef..0a203f8899 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -5055,7 +5055,7 @@ numeric_to_number(PG_FUNCTION_ARGS) VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION()); scale = Num.post; - precision = Max(0, Num.pre) + scale; + precision = Num.pre + Num.multi + scale; if (shouldFree) pfree(format); @@ -5064,6 +5064,23 @@ numeric_to_number(PG_FUNCTION_ARGS) CStringGetDatum(numstr), ObjectIdGetDatum(InvalidOid), Int32GetDatum(((precision << 16) | scale) + VARHDRSZ)); + + if (IS_MULTI(&Num)) + { + Numeric x; + Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric, + Int32GetDatum(10))); + Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric, + Int32GetDatum(-Num.multi))); + + x = DatumGetNumeric(DirectFunctionCall2(numeric_power, + NumericGetDatum(a), + NumericGetDatum(b))); + result = DirectFunctionCall2(numeric_mul, + result, + NumericGetDatum(x)); + } + pfree(numstr); return result; } |