1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

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
This commit is contained in:
Bruce Momjian
2015-10-05 21:03:38 -04:00
parent 2145a76604
commit 28b3a3d41a
2 changed files with 23 additions and 4 deletions

View File

@ -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>

View File

@ -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)
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;
} }