mirror of
https://github.com/postgres/postgres.git
synced 2025-12-19 17:02:53 +03:00
Issue a NOTICE if a created function depends on any temp objects.
We don't have an official concept of temporary functions. (You can make one explicitly in pg_temp, but then you have to explicitly schema-qualify it on every call.) However, until now we were quite laissez-faire about whether a non-temporary function could depend on a temporary object, such as a temp table or view. If one does, it will silently go away at end of session, due to the automatic DROP ... CASCADE on the session's temporary objects. People have complained that that's surprising; however, we can't really forbid it because other people (including our own regression tests) rely on being able to do it. Let's compromise by emitting a NOTICE at CREATE FUNCTION time. This is somewhat comparable to our ancient practice of emitting a NOTICE when forcing a view to become temp because it depends on temp tables. Along the way, refactor recordDependencyOnExpr() so that the dependencies of an expression can be combined with other dependencies, instead of being emitted separately and perhaps duplicatively. We should probably make the implementation of temp-by-default views use the same infrastructure used here, but that's for another patch. It's unclear whether there are any other object classes that deserve similar treatment. Author: Jim Jones <jim.jones@uni-muenster.de> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/19cf6ae1-04cd-422c-a760-d7e75fe6cba9@uni-muenster.de
This commit is contained in:
@@ -25,6 +25,8 @@ exec
|
||||
|
||||
(1 row)
|
||||
|
||||
s1: NOTICE: function "uses_a_temp_type" will be effectively temporary
|
||||
DETAIL: It depends on temporary type just_give_me_a_type.
|
||||
step s1_discard_temp:
|
||||
DISCARD TEMP;
|
||||
|
||||
@@ -82,6 +84,8 @@ exec
|
||||
|
||||
(1 row)
|
||||
|
||||
s1: NOTICE: function "uses_a_temp_type" will be effectively temporary
|
||||
DETAIL: It depends on temporary type just_give_me_a_type.
|
||||
step s1_exit:
|
||||
SELECT pg_terminate_backend(pg_backend_pid());
|
||||
|
||||
|
||||
@@ -455,6 +455,16 @@ DROP TABLE functest3 CASCADE;
|
||||
NOTICE: drop cascades to 2 other objects
|
||||
DETAIL: drop cascades to view functestv3
|
||||
drop cascades to function functest_s_14()
|
||||
-- Check reporting of temporary-object dependencies within SQL-standard body
|
||||
-- (tests elsewhere already cover dependencies on arg and result types)
|
||||
CREATE TEMP SEQUENCE mytempseq;
|
||||
CREATE FUNCTION functest_tempseq() RETURNS int
|
||||
RETURN nextval('mytempseq');
|
||||
NOTICE: function "functest_tempseq" will be effectively temporary
|
||||
DETAIL: It depends on temporary sequence mytempseq.
|
||||
-- This discards mytempseq and therefore functest_tempseq(). If it fails to,
|
||||
-- the function will appear in the information_schema tests below.
|
||||
DISCARD TEMP;
|
||||
-- information_schema tests
|
||||
CREATE FUNCTION functest_IS_1(a int, b int default 1, c text default 'foo')
|
||||
RETURNS int
|
||||
|
||||
@@ -2178,6 +2178,8 @@ alter table users drop column todrop;
|
||||
create or replace function get_first_user() returns users as
|
||||
$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$
|
||||
language sql stable;
|
||||
NOTICE: function "get_first_user" will be effectively temporary
|
||||
DETAIL: It depends on temporary type users.
|
||||
SELECT get_first_user();
|
||||
get_first_user
|
||||
-------------------
|
||||
@@ -2193,6 +2195,8 @@ SELECT * FROM get_first_user();
|
||||
create or replace function get_users() returns setof users as
|
||||
$$ SELECT * FROM users ORDER BY userid; $$
|
||||
language sql stable;
|
||||
NOTICE: function "get_users" will be effectively temporary
|
||||
DETAIL: It depends on temporary type users.
|
||||
SELECT get_users();
|
||||
get_users
|
||||
---------------------
|
||||
|
||||
@@ -306,6 +306,8 @@ SELECT * FROM foo;
|
||||
-- Check use of a whole-row variable for an inlined set-returning function
|
||||
CREATE FUNCTION foo_f() RETURNS SETOF foo AS
|
||||
$$ SELECT * FROM foo OFFSET 0 $$ LANGUAGE sql STABLE;
|
||||
NOTICE: function "foo_f" will be effectively temporary
|
||||
DETAIL: It depends on temporary type foo.
|
||||
UPDATE foo SET f2 = foo_f.f2 FROM foo_f() WHERE foo_f.f1 = foo.f1
|
||||
RETURNING foo_f;
|
||||
foo_f
|
||||
@@ -930,6 +932,8 @@ BEGIN ATOMIC
|
||||
(SELECT count(*) FROM foo WHERE foo = o),
|
||||
(SELECT count(*) FROM foo WHERE foo = n);
|
||||
END;
|
||||
NOTICE: function "foo_update" will be effectively temporary
|
||||
DETAIL: It depends on temporary table foo.
|
||||
\sf foo_update
|
||||
CREATE OR REPLACE FUNCTION public.foo_update()
|
||||
RETURNS void
|
||||
|
||||
@@ -907,6 +907,8 @@ create temp table compos (f1 int, f2 text);
|
||||
create function fcompos1(v compos) returns void as $$
|
||||
insert into compos values (v); -- fail
|
||||
$$ language sql;
|
||||
NOTICE: function "fcompos1" will be effectively temporary
|
||||
DETAIL: It depends on temporary type compos.
|
||||
ERROR: column "f1" is of type integer but expression is of type compos
|
||||
LINE 2: insert into compos values (v); -- fail
|
||||
^
|
||||
@@ -914,12 +916,18 @@ HINT: You will need to rewrite or cast the expression.
|
||||
create function fcompos1(v compos) returns void as $$
|
||||
insert into compos values (v.*);
|
||||
$$ language sql;
|
||||
NOTICE: function "fcompos1" will be effectively temporary
|
||||
DETAIL: It depends on temporary type compos.
|
||||
create function fcompos2(v compos) returns void as $$
|
||||
select fcompos1(v);
|
||||
$$ language sql;
|
||||
NOTICE: function "fcompos2" will be effectively temporary
|
||||
DETAIL: It depends on temporary type compos.
|
||||
create function fcompos3(v compos) returns void as $$
|
||||
select fcompos1(fcompos3.v.*);
|
||||
$$ language sql;
|
||||
NOTICE: function "fcompos3" will be effectively temporary
|
||||
DETAIL: It depends on temporary type compos.
|
||||
select fcompos1(row(1,'one'));
|
||||
fcompos1
|
||||
----------
|
||||
@@ -1012,6 +1020,8 @@ select last(f) from fullname f;
|
||||
|
||||
create function longname(fullname) returns text language sql
|
||||
as $$select $1.first || ' ' || $1.last$$;
|
||||
NOTICE: function "longname" will be effectively temporary
|
||||
DETAIL: It depends on temporary type fullname.
|
||||
select f.longname from fullname f;
|
||||
longname
|
||||
----------
|
||||
|
||||
@@ -241,6 +241,17 @@ SELECT functest_S_14();
|
||||
|
||||
DROP TABLE functest3 CASCADE;
|
||||
|
||||
-- Check reporting of temporary-object dependencies within SQL-standard body
|
||||
-- (tests elsewhere already cover dependencies on arg and result types)
|
||||
CREATE TEMP SEQUENCE mytempseq;
|
||||
|
||||
CREATE FUNCTION functest_tempseq() RETURNS int
|
||||
RETURN nextval('mytempseq');
|
||||
|
||||
-- This discards mytempseq and therefore functest_tempseq(). If it fails to,
|
||||
-- the function will appear in the information_schema tests below.
|
||||
DISCARD TEMP;
|
||||
|
||||
|
||||
-- information_schema tests
|
||||
|
||||
|
||||
Reference in New Issue
Block a user