Commit 28b3a3d4 authored by Bruce Momjian's avatar Bruce Momjian

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
parent 2145a766
...@@ -6152,12 +6152,14 @@ SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); ...@@ -6152,12 +6152,14 @@ SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
<listitem> <listitem>
<para> <para>
<literal>V</literal> effectively <literal>V</literal> with <function>to_char</function>
multiplies the input values by multiplies the input values by
<literal>10^<replaceable>n</replaceable></literal>, where <literal>10^<replaceable>n</replaceable></literal>, where
<replaceable>n</replaceable> is the number of digits following <replaceable>n</replaceable> is the number of digits following
<literal>V</literal>. <literal>V</literal>. <literal>V</literal> with
<function>to_char</function> does not support the use of <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 <literal>V</literal> combined with a decimal point
(e.g., <literal>99.9V99</literal> is not allowed). (e.g., <literal>99.9V99</literal> is not allowed).
</para> </para>
......
...@@ -5055,7 +5055,7 @@ numeric_to_number(PG_FUNCTION_ARGS) ...@@ -5055,7 +5055,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION()); VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION());
scale = Num.post; scale = Num.post;
precision = Max(0, Num.pre) + scale; precision = Num.pre + Num.multi + scale;
if (shouldFree) if (shouldFree)
pfree(format); pfree(format);
...@@ -5064,6 +5064,23 @@ numeric_to_number(PG_FUNCTION_ARGS) ...@@ -5064,6 +5064,23 @@ numeric_to_number(PG_FUNCTION_ARGS)
CStringGetDatum(numstr), CStringGetDatum(numstr),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(((precision << 16) | scale) + VARHDRSZ)); 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); pfree(numstr);
return result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment