Remove factorial operators, leaving only the factorial() function.
authorTom Lane <[email protected]>
Thu, 17 Sep 2020 20:17:27 +0000 (16:17 -0400)
committerTom Lane <[email protected]>
Thu, 17 Sep 2020 20:17:27 +0000 (16:17 -0400)
The "!" operator is our only built-in postfix operator.  Remove it,
on the way to removal of grammar support for postfix operators.

There is also a "!!" prefix operator, but since it's been marked
deprecated for most of its existence, we might as well remove it too.

Also zap the SQL alias function numeric_fac(), which seems to have
equally little reason to live.

Mark Dilger, based on work by myself and Robert Haas;
review by John Naylor

Discussion: https://postgr.es/m/38ca86db-42ab-9b48-2902-337a0d6b8311@2ndquadrant.com

contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/sql/postgres_fdw.sql
doc/src/sgml/func.sgml
src/include/catalog/catversion.h
src/include/catalog/pg_operator.dat
src/include/catalog/pg_proc.dat
src/test/regress/expected/create_operator.out
src/test/regress/expected/numeric.out
src/test/regress/sql/create_operator.sql
src/test/regress/sql/numeric.sql

index 84bc0ee381715a730732ba6df72a39c994817466..10e23d02ed56d0b05c3612582b3b8c38c4d080af 100644 (file)
@@ -653,14 +653,6 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1;          -- Op
    Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = (- "C 1")))
 (3 rows)
 
-EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!;           -- OpExpr(r)
-                                                QUERY PLAN                                                
-----------------------------------------------------------------------------------------------------------
- Foreign Scan on public.ft1 t1
-   Output: c1, c2, c3, c4, c5, c6, c7, c8
-   Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = ("C 1" !)))
-(3 rows)
-
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr
                                                                  QUERY PLAN                                                                 
 --------------------------------------------------------------------------------------------------------------------------------------------
index d452d063430ad866e73e9309cbaf81db8ed4693e..78156d10b4860b95ef0a40cac7f5106d5ec34a42 100644 (file)
@@ -307,7 +307,6 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL;        -- Nu
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL;    -- NullTest
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1;          -- OpExpr(l)
-EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!;           -- OpExpr(r)
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr
 EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef
index e2e618791ee01d80da31cfb77a21fb60d167080f..d6283a35d84f189c4702e77b44acb4a18bb9fb4d 100644 (file)
@@ -1048,36 +1048,6 @@ repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue>
        </para></entry>
       </row>
 
-      <row>
-       <entry role="func_table_entry"><para role="func_signature">
-        <type>bigint</type> <literal>!</literal>
-        <returnvalue>numeric</returnvalue>
-       </para>
-       <para>
-        Factorial
-        (deprecated, use <link linkend="function-factorial"><function>factorial()</function></link> instead)
-       </para>
-       <para>
-        <literal>5 !</literal>
-        <returnvalue>120</returnvalue>
-       </para></entry>
-      </row>
-
-      <row>
-       <entry role="func_table_entry"><para role="func_signature">
-        <literal>!!</literal> <type>bigint</type>
-        <returnvalue>numeric</returnvalue>
-       </para>
-       <para>
-        Factorial as a prefix operator
-        (deprecated, use <link linkend="function-factorial"><function>factorial()</function></link> instead)
-       </para>
-       <para>
-        <literal>!! 5</literal>
-        <returnvalue>120</returnvalue>
-       </para></entry>
-      </row>
-
       <row>
        <entry role="func_table_entry"><para role="func_signature">
         <literal>@</literal> <replaceable>numeric_type</replaceable>
index 06ddb1f16b43083403d645c7d0b2d8ac4dbf52e4..358935997087b32173c1455394ecd71dd052903b 100644 (file)
@@ -53,7 +53,6 @@
  */
 
 /*                         yyyymmddN */
-/* FIXME: bump this before pushing! */
-#define CATALOG_VERSION_NO 202009031
+#define CATALOG_VERSION_NO 202009171
 
 #endif
index 4f8b9865effc4cc6f1407f656699c6916f4f9bfd..7cc812adda638d8e9c26ee5364b7ebcb006dbfc1 100644 (file)
   oprname => '>=', oprleft => 'xid8', oprright => 'xid8', oprresult => 'bool',
   oprcom => '<=(xid8,xid8)', oprnegate => '<(xid8,xid8)', oprcode => 'xid8ge',
   oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' },
-{ oid => '388', descr => 'deprecated, use factorial() instead',
-  oprname => '!', oprkind => 'r', oprleft => 'int8', oprright => '0',
-  oprresult => 'numeric', oprcode => 'numeric_fac' },
-{ oid => '389', descr => 'deprecated, use factorial() instead',
-  oprname => '!!', oprkind => 'l', oprleft => '0', oprright => 'int8',
-  oprresult => 'numeric', oprcode => 'numeric_fac' },
 { oid => '385', descr => 'equal',
   oprname => '=', oprcanhash => 't', oprleft => 'cid', oprright => 'cid',
   oprresult => 'bool', oprcom => '=(cid,cid)', oprcode => 'cideq',
index 96d7efd4270cf70a68f88be504b59c1e1206ff65..1ae4288146622a897a81605c6e223e9e46b7ab2f 100644 (file)
 { oid => '110', descr => 'I/O',
   proname => 'unknownout', prorettype => 'cstring', proargtypes => 'unknown',
   prosrc => 'unknownout' },
-{ oid => '111',
-  descr => 'implementation of deprecated ! and !! factorial operators',
-  proname => 'numeric_fac', prorettype => 'numeric', proargtypes => 'int8',
-  prosrc => 'numeric_fac' },
 
 { oid => '115',
   proname => 'box_above_eq', prorettype => 'bool', proargtypes => 'box box',
index 54e8b791595dc10408c064cad1abdb87271b044d..9e4d4e93fb79e464ecae4df90f43cfdaf2fd40ea 100644 (file)
@@ -16,15 +16,15 @@ CREATE OPERATOR <% (
 );
 CREATE OPERATOR @#@ (
    rightarg = int8,        -- left unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 CREATE OPERATOR #@# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 CREATE OPERATOR #%# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 -- Test operator created above
 SELECT point '(1,2)' <% widget '(0,0,3)' AS t,
@@ -40,7 +40,7 @@ ERROR:  operator does not exist: integer ######
 -- => is disallowed now
 CREATE OPERATOR => (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 ERROR:  syntax error at or near "=>"
 LINE 1: CREATE OPERATOR => (
@@ -50,7 +50,7 @@ LINE 1: CREATE OPERATOR => (
 -- this is legal because ! is not allowed in sql ops
 CREATE OPERATOR !=- (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 SELECT 2 !=-;
  ?column? 
@@ -128,7 +128,7 @@ REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1;
 SET ROLE regress_rol_op1;
 CREATE OPERATOR schema_op1.#*# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 ERROR:  permission denied for schema schema_op1
 ROLLBACK;
@@ -136,7 +136,7 @@ ROLLBACK;
 BEGIN TRANSACTION;
 CREATE OPERATOR #*# (
    leftarg = SETOF int8,
-   procedure = numeric_fac
+   procedure = factorial
 );
 ERROR:  SETOF type not allowed for operator argument
 ROLLBACK;
@@ -144,7 +144,7 @@ ROLLBACK;
 BEGIN TRANSACTION;
 CREATE OPERATOR #*# (
    rightarg = SETOF int8,
-   procedure = numeric_fac
+   procedure = factorial
 );
 ERROR:  SETOF type not allowed for operator argument
 ROLLBACK;
@@ -168,13 +168,13 @@ ROLLBACK;
 -- Should fail. Invalid attribute
 CREATE OPERATOR #@%# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac,
+   procedure = factorial,
    invalid_att = int8
 );
 WARNING:  operator attribute "invalid_att" not recognized
 -- Should fail. At least leftarg or rightarg should be mandatorily specified
 CREATE OPERATOR #@%# (
-   procedure = numeric_fac
+   procedure = factorial
 );
 ERROR:  at least one of leftarg or rightarg must be specified
 -- Should fail. Procedure should be mandatorily specified
index 86940ec683861f014745cb94932861f1e4e7e489..823f3fbccf517ca5b2332b5e2ea068c07f410430 100644 (file)
@@ -2972,16 +2972,10 @@ ERROR:  value overflows numeric format
 --
 -- Tests for factorial
 --
-SELECT 4!;
- ?column? 
-----------
-       24
-(1 row)
-
-SELECT !!3;
- ?column? 
-----------
-        6
+SELECT factorial(4);
+ factorial 
+-----------
+        24
 (1 row)
 
 SELECT factorial(15);
@@ -2990,16 +2984,14 @@ SELECT factorial(15);
  1307674368000
 (1 row)
 
-SELECT 100000!;
+SELECT factorial(100000);
 ERROR:  value overflows numeric format
-SELECT 0!;
- ?column? 
-----------
-        1
+SELECT factorial(0);
+ factorial 
+-----------
+         1
 (1 row)
 
-SELECT -4!;
-ERROR:  factorial of a negative number is undefined
 SELECT factorial(-4);
 ERROR:  factorial of a negative number is undefined
 --
index 8b6fd0bb43d62764ce1add88e239b324d1ae1383..c32da8c066a77d8cc2212aeafcfca1c7712b0d6a 100644 (file)
@@ -19,17 +19,17 @@ CREATE OPERATOR <% (
 
 CREATE OPERATOR @#@ (
    rightarg = int8,        -- left unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 
 CREATE OPERATOR #@# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 
 CREATE OPERATOR #%# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 
 -- Test operator created above
@@ -42,7 +42,7 @@ COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
 -- => is disallowed now
 CREATE OPERATOR => (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 
 -- lexing of <=, >=, <>, != has a number of edge cases
@@ -51,7 +51,7 @@ CREATE OPERATOR => (
 -- this is legal because ! is not allowed in sql ops
 CREATE OPERATOR !=- (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 SELECT 2 !=-;
 -- make sure lexer returns != as <> even in edge cases
@@ -85,7 +85,7 @@ REVOKE USAGE ON SCHEMA schema_op1 FROM regress_rol_op1;
 SET ROLE regress_rol_op1;
 CREATE OPERATOR schema_op1.#*# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac
+   procedure = factorial
 );
 ROLLBACK;
 
@@ -94,7 +94,7 @@ ROLLBACK;
 BEGIN TRANSACTION;
 CREATE OPERATOR #*# (
    leftarg = SETOF int8,
-   procedure = numeric_fac
+   procedure = factorial
 );
 ROLLBACK;
 
@@ -103,7 +103,7 @@ ROLLBACK;
 BEGIN TRANSACTION;
 CREATE OPERATOR #*# (
    rightarg = SETOF int8,
-   procedure = numeric_fac
+   procedure = factorial
 );
 ROLLBACK;
 
@@ -129,13 +129,13 @@ ROLLBACK;
 -- Should fail. Invalid attribute
 CREATE OPERATOR #@%# (
    leftarg = int8,     -- right unary
-   procedure = numeric_fac,
+   procedure = factorial,
    invalid_att = int8
 );
 
 -- Should fail. At least leftarg or rightarg should be mandatorily specified
 CREATE OPERATOR #@%# (
-   procedure = numeric_fac
+   procedure = factorial
 );
 
 -- Should fail. Procedure should be mandatorily specified
index febb096af23bed5cebf709878649671d8c3ed164..5eac895e86e17000a3a2d20887c6c966709937b7 100644 (file)
@@ -1300,12 +1300,10 @@ SELECT lcm(9999 * (10::numeric)^131068 + (10::numeric^131068 - 1), 2); -- overfl
 --
 -- Tests for factorial
 --
-SELECT 4!;
-SELECT !!3;
+SELECT factorial(4);
 SELECT factorial(15);
-SELECT 100000!;
-SELECT 0!;
-SELECT -4!;
+SELECT factorial(100000);
+SELECT factorial(0);
 SELECT factorial(-4);
 
 --