mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 09:01:17 +02:00
Code and docs review for numeric-factorial patch.
This commit is contained in:
parent
ea4b9f14f3
commit
145d9fa46c
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_operator.sgml,v 1.23 2003/11/29 19:51:38 pgsql Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_operator.sgml,v 1.24 2003/12/02 00:26:59 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -108,9 +108,9 @@ DROP OPERATOR ~ (none, bit);
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
Remove the right unary factorial operator <literal>x!</literal>
|
Remove the right unary factorial operator <literal>x!</literal>
|
||||||
for type <type>integer</type>:
|
for type <type>bigint</type>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
DROP OPERATOR ! (integer, none);
|
DROP OPERATOR ! (bigint, none);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.40 2003/12/01 21:53:15 momjian Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/typeconv.sgml,v 1.41 2003/12/02 00:26:59 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter Id="typeconv">
|
<chapter Id="typeconv">
|
||||||
@ -412,7 +412,7 @@ type to resolve the unknown literals to.
|
|||||||
</example>
|
</example>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
<title>Absolute-Value and Factorial Operator Type Resolution</title>
|
<title>Absolute-Value and Negation Operator Type Resolution</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <productname>PostgreSQL</productname> operator catalog has several
|
The <productname>PostgreSQL</productname> operator catalog has several
|
||||||
@ -437,6 +437,30 @@ SELECT @ '-4.5e500' AS "abs";
|
|||||||
ERROR: "-4.5e500" is out of range for type double precision
|
ERROR: "-4.5e500" is out of range for type double precision
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
On the other hand, the prefix operator <literal>~</> (bitwise negation)
|
||||||
|
is defined only for integer data types, not for <type>float8</type>. So, if we
|
||||||
|
try a similar case with <literal>~</>, we get:
|
||||||
|
<screen>
|
||||||
|
SELECT ~ '20' AS "negation";
|
||||||
|
|
||||||
|
ERROR: operator is not unique: ~ "unknown"
|
||||||
|
HINT: Could not choose a best candidate operator. You may need to add explicit
|
||||||
|
type casts.
|
||||||
|
</screen>
|
||||||
|
This happens because the system can't decide which of the several
|
||||||
|
possible <literal>~</> operators should be preferred. We can help
|
||||||
|
it out with an explicit cast:
|
||||||
|
<screen>
|
||||||
|
SELECT ~ CAST('20' AS int8) AS "negation";
|
||||||
|
|
||||||
|
negation
|
||||||
|
----------
|
||||||
|
-21
|
||||||
|
(1 row)
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
|
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.69 2003/12/01 21:52:37 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.70 2003/12/02 00:26:59 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1290,49 +1290,39 @@ numeric_larger(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* numeric_fac()
|
* numeric_fac()
|
||||||
* Computer factorial
|
*
|
||||||
|
* Compute factorial
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
numeric_fac(PG_FUNCTION_ARGS)
|
numeric_fac(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
|
||||||
int64 num = PG_GETARG_INT64(0);
|
int64 num = PG_GETARG_INT64(0);
|
||||||
NumericVar count;
|
|
||||||
NumericVar fact;
|
|
||||||
NumericVar zerovar;
|
|
||||||
NumericVar result;
|
|
||||||
Numeric res;
|
Numeric res;
|
||||||
|
NumericVar fact;
|
||||||
|
NumericVar result;
|
||||||
|
|
||||||
if(num < 1) {
|
if (num <= 1)
|
||||||
|
{
|
||||||
res = make_result(&const_one);
|
res = make_result(&const_one);
|
||||||
PG_RETURN_NUMERIC(res);
|
PG_RETURN_NUMERIC(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init_var(&fact);
|
init_var(&fact);
|
||||||
init_var(&count);
|
|
||||||
init_var(&result);
|
init_var(&result);
|
||||||
init_var(&zerovar);
|
|
||||||
zero_var(&zerovar);
|
|
||||||
|
|
||||||
int8_to_numericvar((int64)num, &result);
|
int8_to_numericvar(num, &result);
|
||||||
set_var_from_var(&const_one, &count);
|
|
||||||
|
|
||||||
for(num = num - 1; num > 0; num--) {
|
for (num = num - 1; num > 1; num--)
|
||||||
set_var_from_var(&result,&count);
|
{
|
||||||
|
int8_to_numericvar(num, &fact);
|
||||||
|
|
||||||
int8_to_numericvar((int64)num,&fact);
|
mul_var(&result, &fact, &result, 0);
|
||||||
|
|
||||||
mul_var(&count, &fact, &result, count.dscale + fact.dscale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = make_result(&count);
|
res = make_result(&result);
|
||||||
|
|
||||||
free_var(&count);
|
|
||||||
free_var(&fact);
|
free_var(&fact);
|
||||||
free_var(&result);
|
free_var(&result);
|
||||||
free_var(&zerovar);
|
|
||||||
|
|
||||||
PG_RETURN_NUMERIC(res);
|
PG_RETURN_NUMERIC(res);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user