diff --git a/doc/src/sgml/ref/drop_operator.sgml b/doc/src/sgml/ref/drop_operator.sgml
index 4c14954c48..5b17ebec1b 100644
--- a/doc/src/sgml/ref/drop_operator.sgml
+++ b/doc/src/sgml/ref/drop_operator.sgml
@@ -1,5 +1,5 @@
@@ -108,9 +108,9 @@ DROP OPERATOR ~ (none, bit);
Remove the right unary factorial operator x!
- for type integer:
+ for type bigint:
-DROP OPERATOR ! (integer, none);
+DROP OPERATOR ! (bigint, none);
diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml
index bd68c242b3..64a1a5c985 100644
--- a/doc/src/sgml/typeconv.sgml
+++ b/doc/src/sgml/typeconv.sgml
@@ -1,5 +1,5 @@
@@ -412,7 +412,7 @@ type to resolve the unknown literals to.
-Absolute-Value and Factorial Operator Type Resolution
+Absolute-Value and Negation Operator Type Resolution
The PostgreSQL operator catalog has several
@@ -437,6 +437,30 @@ SELECT @ '-4.5e500' AS "abs";
ERROR: "-4.5e500" is out of range for type double precision
+
+
+On the other hand, the prefix operator ~> (bitwise negation)
+is defined only for integer data types, not for float8. So, if we
+try a similar case with ~>, we get:
+
+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.
+
+This happens because the system can't decide which of the several
+possible ~> operators should be preferred. We can help
+it out with an explicit cast:
+
+SELECT ~ CAST('20' AS int8) AS "negation";
+
+ negation
+----------
+ -21
+(1 row)
+
+
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 7f16ee37a2..e825b101a1 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;
- NumericVar fact;
- NumericVar zerovar;
- NumericVar result;
Numeric res;
+ NumericVar fact;
+ NumericVar result;
- 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);
+ int8_to_numericvar(num, &result);
- for(num = num - 1; num > 0; num--) {
- set_var_from_var(&result,&count);
+ for (num = num - 1; num > 1; num--)
+ {
+ int8_to_numericvar(num, &fact);
- int8_to_numericvar((int64)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);
}