Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 28b3a3d

Browse files
committed
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
1 parent 2145a76 commit 28b3a3d

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

doc/src/sgml/func.sgml

+5-3
Original file line numberDiff line numberDiff line change
@@ -6152,12 +6152,14 @@ SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
61526152

61536153
<listitem>
61546154
<para>
6155-
<literal>V</literal> effectively
6155+
<literal>V</literal> with <function>to_char</function>
61566156
multiplies the input values by
61576157
<literal>10^<replaceable>n</replaceable></literal>, where
61586158
<replaceable>n</replaceable> is the number of digits following
6159-
<literal>V</literal>.
6160-
<function>to_char</function> does not support the use of
6159+
<literal>V</literal>. <literal>V</literal> with
6160+
<function>to_number</function> divides in a similar manner.
6161+
<function>to_char</function> and <function>to_number</function>
6162+
do not support the use of
61616163
<literal>V</literal> combined with a decimal point
61626164
(e.g., <literal>99.9V99</literal> is not allowed).
61636165
</para>

src/backend/utils/adt/formatting.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -5055,7 +5055,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
50555055
VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION());
50565056

50575057
scale = Num.post;
5058-
precision = Max(0, Num.pre) + scale;
5058+
precision = Num.pre + Num.multi + scale;
50595059

50605060
if (shouldFree)
50615061
pfree(format);
@@ -5064,6 +5064,23 @@ numeric_to_number(PG_FUNCTION_ARGS)
50645064
CStringGetDatum(numstr),
50655065
ObjectIdGetDatum(InvalidOid),
50665066
Int32GetDatum(((precision << 16) | scale) + VARHDRSZ));
5067+
5068+
if (IS_MULTI(&Num))
5069+
{
5070+
Numeric x;
5071+
Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5072+
Int32GetDatum(10)));
5073+
Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5074+
Int32GetDatum(-Num.multi)));
5075+
5076+
x = DatumGetNumeric(DirectFunctionCall2(numeric_power,
5077+
NumericGetDatum(a),
5078+
NumericGetDatum(b)));
5079+
result = DirectFunctionCall2(numeric_mul,
5080+
result,
5081+
NumericGetDatum(x));
5082+
}
5083+
50675084
pfree(numstr);
50685085
return result;
50695086
}

0 commit comments

Comments
 (0)