diff --git a/doc/src/sgml/ref/drop_operator.sgml b/doc/src/sgml/ref/drop_operator.sgml index 4c14954c48238eef8550552e79729e77d12d7f28..5b17ebec1b5bd508718199a2ea6c5ca7d77afe2f 100644 --- a/doc/src/sgml/ref/drop_operator.sgml +++ b/doc/src/sgml/ref/drop_operator.sgml @@ -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 --> @@ -108,9 +108,9 @@ DROP OPERATOR ~ (none, bit); <para> Remove the right unary factorial operator <literal>x!</literal> - for type <type>integer</type>: + for type <type>bigint</type>: <programlisting> -DROP OPERATOR ! (integer, none); +DROP OPERATOR ! (bigint, none); </programlisting> </para> </refsect1> diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index bd68c242b3cdf7e777d9299d0134421570acc168..64a1a5c98574dc8b60e75c194d2eef718fc0659e 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -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"> @@ -412,7 +412,7 @@ type to resolve the unknown literals to. </example> <example> -<title>Absolute-Value and Factorial Operator Type Resolution</title> +<title>Absolute-Value and Negation Operator Type Resolution</title> <para> 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 </screen> </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> </sect1> diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 7f16ee37a247910126cb99ab0654080c8cda548b..e825b101a1656070629673f6edba6aace194ae9a 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -14,7 +14,7 @@ * Copyright (c) 1998-2003, PostgreSQL Global Development Group * * 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() - * Computer factorial + * + * Compute factorial */ - Datum numeric_fac(PG_FUNCTION_ARGS) { - int64 num = PG_GETARG_INT64(0); - NumericVar count; + Numeric res; NumericVar fact; - NumericVar zerovar; NumericVar result; - Numeric res; - if(num < 1) { + if (num <= 1) + { res = make_result(&const_one); PG_RETURN_NUMERIC(res); } - init_var(&fact); - init_var(&count); init_var(&result); - init_var(&zerovar); - zero_var(&zerovar); - - int8_to_numericvar((int64)num, &result); - set_var_from_var(&const_one, &count); - for(num = num - 1; num > 0; num--) { - set_var_from_var(&result,&count); + int8_to_numericvar(num, &result); - int8_to_numericvar((int64)num,&fact); + for (num = num - 1; num > 1; num--) + { + int8_to_numericvar(num, &fact); - mul_var(&count, &fact, &result, count.dscale + fact.dscale); + mul_var(&result, &fact, &result, 0); } - res = make_result(&count); + res = make_result(&result); - free_var(&count); free_var(&fact); free_var(&result); - free_var(&zerovar); PG_RETURN_NUMERIC(res); }