1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-20 05:03:10 +03:00

Add prokind column, replacing proisagg and proiswindow

The new column distinguishes normal functions, procedures, aggregates,
and window functions.  This replaces the existing columns proisagg and
proiswindow, and replaces the convention that procedures are indicated
by prorettype == 0.  Also change prorettype to be VOIDOID for procedures.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
This commit is contained in:
Peter Eisentraut
2018-03-02 08:57:38 -05:00
parent 1733460f02
commit fd1a421fe6
40 changed files with 3246 additions and 3174 deletions

View File

@ -83,21 +83,21 @@ ERROR: must be owner of function alt_agg3
ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- failed (name conflict)
ERROR: function alt_agg2(integer) already exists in schema "alt_nsp2"
RESET SESSION AUTHORIZATION;
SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
SELECT n.nspname, proname, prorettype::regtype, prokind, a.rolname
FROM pg_proc p, pg_namespace n, pg_authid a
WHERE p.pronamespace = n.oid AND p.proowner = a.oid
AND n.nspname IN ('alt_nsp1', 'alt_nsp2')
ORDER BY nspname, proname;
nspname | proname | prorettype | proisagg | rolname
----------+-----------+------------+----------+---------------------
alt_nsp1 | alt_agg2 | integer | t | regress_alter_user2
alt_nsp1 | alt_agg3 | integer | t | regress_alter_user1
alt_nsp1 | alt_agg4 | integer | t | regress_alter_user2
alt_nsp1 | alt_func2 | integer | f | regress_alter_user2
alt_nsp1 | alt_func3 | integer | f | regress_alter_user1
alt_nsp1 | alt_func4 | integer | f | regress_alter_user2
alt_nsp2 | alt_agg2 | integer | t | regress_alter_user3
alt_nsp2 | alt_func2 | integer | f | regress_alter_user3
nspname | proname | prorettype | prokind | rolname
----------+-----------+------------+---------+---------------------
alt_nsp1 | alt_agg2 | integer | a | regress_alter_user2
alt_nsp1 | alt_agg3 | integer | a | regress_alter_user1
alt_nsp1 | alt_agg4 | integer | a | regress_alter_user2
alt_nsp1 | alt_func2 | integer | f | regress_alter_user2
alt_nsp1 | alt_func3 | integer | f | regress_alter_user1
alt_nsp1 | alt_func4 | integer | f | regress_alter_user2
alt_nsp2 | alt_agg2 | integer | a | regress_alter_user3
alt_nsp2 | alt_func2 | integer | f | regress_alter_user3
(8 rows)
--

View File

@ -271,6 +271,15 @@ ERROR: could not find a function named "functest_b_1"
DROP FUNCTION functest_b_2; -- error, ambiguous
ERROR: function name "functest_b_2" is not unique
HINT: Specify the argument list to select the function unambiguously.
-- CREATE OR REPLACE tests
CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL AS 'SELECT $1';
CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS 'SELECT $1';
ERROR: cannot change routine kind
DETAIL: "functest1" is a function.
CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE SQL AS 'SELECT $1';
ERROR: cannot change routine kind
DETAIL: "functest1" is a function.
DROP FUNCTION functest1(a int);
-- Cleanups
DROP SCHEMA temp_func_test CASCADE;
NOTICE: drop cascades to 16 other objects

View File

@ -74,6 +74,7 @@ WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
0::oid = ANY (p1.proargtypes) OR
procost <= 0 OR
CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR
prokind NOT IN ('f', 'a', 'w', 'p') OR
provolatile NOT IN ('i', 's', 'v') OR
proparallel NOT IN ('s', 'r', 'u');
oid | proname
@ -88,10 +89,10 @@ WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
-----+---------
(0 rows)
-- proiswindow shouldn't be set together with proisagg or proretset
-- proretset should only be set for normal functions
SELECT p1.oid, p1.proname
FROM pg_proc AS p1
WHERE proiswindow AND (proisagg OR proretset);
WHERE proretset AND prokind != 'f';
oid | proname
-----+---------
(0 rows)
@ -154,9 +155,9 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid < p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
(p1.proisagg = false OR p2.proisagg = false) AND
(p1.prokind != 'a' OR p2.prokind != 'a') AND
(p1.prolang != p2.prolang OR
p1.proisagg != p2.proisagg OR
p1.prokind != p2.prokind OR
p1.prosecdef != p2.prosecdef OR
p1.proleakproof != p2.proleakproof OR
p1.proisstrict != p2.proisstrict OR
@ -182,7 +183,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.prorettype < p2.prorettype)
@ -198,7 +199,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.proargtypes[0] < p2.proargtypes[0])
@ -216,7 +217,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.proargtypes[1] < p2.proargtypes[1])
@ -233,7 +234,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[2] < p2.proargtypes[2])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -246,7 +247,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[3] < p2.proargtypes[3])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -259,7 +260,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[4] < p2.proargtypes[4])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -271,7 +272,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[5] < p2.proargtypes[5])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -283,7 +284,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[6] < p2.proargtypes[6])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -295,7 +296,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[7] < p2.proargtypes[7])
ORDER BY 1, 2;
proargtypes | proargtypes
@ -1292,15 +1293,15 @@ WHERE aggfnoid = 0 OR aggtransfn = 0 OR
SELECT a.aggfnoid::oid, p.proname
FROM pg_aggregate as a, pg_proc as p
WHERE a.aggfnoid = p.oid AND
(NOT p.proisagg OR p.proretset OR p.pronargs < a.aggnumdirectargs);
(p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs);
aggfnoid | proname
----------+---------
(0 rows)
-- Make sure there are no proisagg pg_proc entries without matches.
-- Make sure there are no prokind = PROKIND_AGGREGATE pg_proc entries without matches.
SELECT oid, proname
FROM pg_proc as p
WHERE p.proisagg AND
WHERE p.prokind = 'a' AND
NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
oid | proname
-----+---------
@ -1639,7 +1640,7 @@ ORDER BY 1, 2;
SELECT p1.oid::regprocedure, p2.oid::regprocedure
FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND
p1.proisagg AND p2.proisagg AND
p1.prokind = 'a' AND p2.prokind = 'a' AND
array_dims(p1.proargtypes) != array_dims(p2.proargtypes)
ORDER BY 1;
oid | oid
@ -1650,7 +1651,7 @@ ORDER BY 1;
-- For the same reason, built-in aggregates with default arguments are no good.
SELECT oid, proname
FROM pg_proc AS p
WHERE proisagg AND proargdefaults IS NOT NULL;
WHERE prokind = 'a' AND proargdefaults IS NOT NULL;
oid | proname
-----+---------
(0 rows)
@ -1660,7 +1661,7 @@ WHERE proisagg AND proargdefaults IS NOT NULL;
-- that is not subject to the misplaced ORDER BY issue).
SELECT p.oid, proname
FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid
WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n';
oid | proname
-----+---------
(0 rows)

View File

@ -1521,9 +1521,11 @@ UNION ALL
SELECT l.objoid,
l.classoid,
l.objsubid,
CASE
WHEN (pro.proisagg = true) THEN 'aggregate'::text
WHEN (pro.proisagg = false) THEN 'function'::text
CASE pro.prokind
WHEN 'a'::"char" THEN 'aggregate'::text
WHEN 'f'::"char" THEN 'function'::text
WHEN 'p'::"char" THEN 'procedure'::text
WHEN 'w'::"char" THEN 'window'::text
ELSE NULL::text
END AS objtype,
pro.pronamespace AS objnamespace,

View File

@ -81,7 +81,7 @@ ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2; -- failed (name conflict)
RESET SESSION AUTHORIZATION;
SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
SELECT n.nspname, proname, prorettype::regtype, prokind, a.rolname
FROM pg_proc p, pg_namespace n, pg_authid a
WHERE p.pronamespace = n.oid AND p.proowner = a.oid
AND n.nspname IN ('alt_nsp1', 'alt_nsp2')

View File

@ -175,6 +175,14 @@ DROP FUNCTION functest_b_1; -- error, not found
DROP FUNCTION functest_b_2; -- error, ambiguous
-- CREATE OR REPLACE tests
CREATE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL AS 'SELECT $1';
CREATE OR REPLACE FUNCTION functest1(a int) RETURNS int LANGUAGE SQL WINDOW AS 'SELECT $1';
CREATE OR REPLACE PROCEDURE functest1(a int) LANGUAGE SQL AS 'SELECT $1';
DROP FUNCTION functest1(a int);
-- Cleanups
DROP SCHEMA temp_func_test CASCADE;
DROP USER regress_unpriv_user;

View File

@ -82,6 +82,7 @@ WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
0::oid = ANY (p1.proargtypes) OR
procost <= 0 OR
CASE WHEN proretset THEN prorows <= 0 ELSE prorows != 0 END OR
prokind NOT IN ('f', 'a', 'w', 'p') OR
provolatile NOT IN ('i', 's', 'v') OR
proparallel NOT IN ('s', 'r', 'u');
@ -90,10 +91,10 @@ SELECT p1.oid, p1.proname
FROM pg_proc as p1
WHERE prosrc IS NULL OR prosrc = '' OR prosrc = '-';
-- proiswindow shouldn't be set together with proisagg or proretset
-- proretset should only be set for normal functions
SELECT p1.oid, p1.proname
FROM pg_proc AS p1
WHERE proiswindow AND (proisagg OR proretset);
WHERE proretset AND prokind != 'f';
-- currently, no built-in functions should be SECURITY DEFINER;
-- this might change in future, but there will probably never be many.
@ -140,9 +141,9 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid < p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
(p1.proisagg = false OR p2.proisagg = false) AND
(p1.prokind != 'a' OR p2.prokind != 'a') AND
(p1.prolang != p2.prolang OR
p1.proisagg != p2.proisagg OR
p1.prokind != p2.prokind OR
p1.prosecdef != p2.prosecdef OR
p1.proleakproof != p2.proleakproof OR
p1.proisstrict != p2.proisstrict OR
@ -166,7 +167,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.prorettype < p2.prorettype)
@ -177,7 +178,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.proargtypes[0] < p2.proargtypes[0])
@ -188,7 +189,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
p1.prosrc NOT LIKE E'range\\_constructor_' AND
p2.prosrc NOT LIKE E'range\\_constructor_' AND
(p1.proargtypes[1] < p2.proargtypes[1])
@ -199,7 +200,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[2] < p2.proargtypes[2])
ORDER BY 1, 2;
@ -208,7 +209,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[3] < p2.proargtypes[3])
ORDER BY 1, 2;
@ -217,7 +218,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[4] < p2.proargtypes[4])
ORDER BY 1, 2;
@ -226,7 +227,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[5] < p2.proargtypes[5])
ORDER BY 1, 2;
@ -235,7 +236,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[6] < p2.proargtypes[6])
ORDER BY 1, 2;
@ -244,7 +245,7 @@ FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid != p2.oid AND
p1.prosrc = p2.prosrc AND
p1.prolang = 12 AND p2.prolang = 12 AND
NOT p1.proisagg AND NOT p2.proisagg AND
p1.prokind != 'a' AND p2.prokind != 'a' AND
(p1.proargtypes[7] < p2.proargtypes[7])
ORDER BY 1, 2;
@ -804,13 +805,13 @@ WHERE aggfnoid = 0 OR aggtransfn = 0 OR
SELECT a.aggfnoid::oid, p.proname
FROM pg_aggregate as a, pg_proc as p
WHERE a.aggfnoid = p.oid AND
(NOT p.proisagg OR p.proretset OR p.pronargs < a.aggnumdirectargs);
(p.prokind != 'a' OR p.proretset OR p.pronargs < a.aggnumdirectargs);
-- Make sure there are no proisagg pg_proc entries without matches.
-- Make sure there are no prokind = PROKIND_AGGREGATE pg_proc entries without matches.
SELECT oid, proname
FROM pg_proc as p
WHERE p.proisagg AND
WHERE p.prokind = 'a' AND
NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
-- If there is no finalfn then the output type must be the transtype.
@ -1089,7 +1090,7 @@ ORDER BY 1, 2;
SELECT p1.oid::regprocedure, p2.oid::regprocedure
FROM pg_proc AS p1, pg_proc AS p2
WHERE p1.oid < p2.oid AND p1.proname = p2.proname AND
p1.proisagg AND p2.proisagg AND
p1.prokind = 'a' AND p2.prokind = 'a' AND
array_dims(p1.proargtypes) != array_dims(p2.proargtypes)
ORDER BY 1;
@ -1097,7 +1098,7 @@ ORDER BY 1;
SELECT oid, proname
FROM pg_proc AS p
WHERE proisagg AND proargdefaults IS NOT NULL;
WHERE prokind = 'a' AND proargdefaults IS NOT NULL;
-- For the same reason, we avoid creating built-in variadic aggregates, except
-- that variadic ordered-set aggregates are OK (since they have special syntax
@ -1105,7 +1106,7 @@ WHERE proisagg AND proargdefaults IS NOT NULL;
SELECT p.oid, proname
FROM pg_proc AS p JOIN pg_aggregate AS a ON a.aggfnoid = p.oid
WHERE proisagg AND provariadic != 0 AND a.aggkind = 'n';
WHERE prokind = 'a' AND provariadic != 0 AND a.aggkind = 'n';
-- **************** pg_opfamily ****************