Re: Add notification on BEGIN ATOMIC SQL functions using temp relations

From: Jim Jones <jim(dot)jones(at)uni-muenster(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Add notification on BEGIN ATOMIC SQL functions using temp relations
Date: 2025-10-13 15:16:33
Message-ID: 099b335a-62ca-45e6-ade9-800145a29963@uni-muenster.de
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Tom,

Thanks for the review and thorough feedback.

On 10/8/25 22:35, Tom Lane wrote:
> I think the right way to make this work is to look through the
> array of ObjectAddresses that ProcedureCreate builds to store
> into pg_depend, because that is by definition the authoritative
> info about what the function is dependent on. There's some
> refactoring pain to be endured to make that happen though.
> Most of the interesting-for-this-purpose dependencies are
> found by recordDependencyOnExpr, which summarily writes them
> out before we'd get a chance to look at them. I think what we
> want to do is refactor that so that we have a function along
> the lines of "add all the dependencies of this expression to
> a caller-supplied ObjectAddresses struct". Then merge the
> dependencies found by that function into the list of special
> dependencies that ProcedureCreate has hard-wired logic for, then
> de-duplicate that list, then (if not a temp function) scan the
> list for dependencies on temp objects, and finally (if no error)
> write it out to pg_depend using recordMultipleDependencies.
> This would provide more effective de-duplication of pg_depend
> entries than what ProcedureCreate is doing today, and it would
> give us full coverage not just partial.

PFA a first attempt to address your points.

0001 introduces collectDependenciesFromExpr(), which collects object
dependencies into a caller-supplied ObjectAddresses structure without
recording them immediately. recordDependencyOnExpr() now uses this
helper internally before performing the actual recording.

0002 builds on this infrastructure to collect dependencies before
applying temporary-object validation. It adopts a
"collect–then–filter–then–record" pattern for SQL function bodies in
ProcedureCreate(). After collecting, it calls filter_temp_objects() to
detect any references to temporary objects and raises an ERROR if found,
unless the function itself is being created in a temporary schema.

>
> I realize that you probably cribbed this logic from
> isQueryUsingTempRelation, but that is looking pretty sad too.
> As a concrete example of what I'm talking about:
>
> regression=# create temp table mytemp (f1 int);
> CREATE TABLE
> regression=# create view vfoo as select * from pg_class where oid = 'mytemp'::regclass;
> CREATE VIEW
> regression=# \c -
> You are now connected to database "regression" as user "postgres".
> regression=# \d vfoo
> Did not find any relation named "vfoo".

Here a few tests:

postgres=# CREATE TEMPORARY TABLE temp_table AS SELECT 1 AS val;
SELECT 1
postgres=# CREATE TEMPORARY VIEW temp_view AS SELECT 42 AS val;
CREATE VIEW

== temp table dependency ==
CREATE FUNCTION functest_temp_dep() RETURNS int LANGUAGE sql
BEGIN ATOMIC;
SELECT val FROM temp_table;
END;
ERROR: cannot use temporary object "temp_table" in SQL function with
BEGIN ATOMIC
DETAIL: SQL functions with BEGIN ATOMIC cannot depend on temporary objects.

== regclass cast ==

postgres=# CREATE FUNCTION functest_temp_dep() RETURNS int LANGUAGE sql
BEGIN ATOMIC;
SELECT * FROM pg_class WHERE oid = 'temp_table'::regclass;
END;
ERROR: cannot use temporary object "temp_table" in SQL function with
BEGIN ATOMIC
DETAIL: SQL functions with BEGIN ATOMIC cannot depend on temporary objects.

== subquery ==
postgres=# CREATE FUNCTION functest_temp_dep_subquery() RETURNS int
LANGUAGE sql
BEGIN ATOMIC;
SELECT (SELECT COUNT(*) FROM temp_table);
END;
ERROR: cannot use temporary object "temp_table" in SQL function with
BEGIN ATOMIC
DETAIL: SQL functions with BEGIN ATOMIC cannot depend on temporary objects.

== function created in pg_temp ==
-- this should work: the function is created in a temp schema
postgres=# CREATE FUNCTION pg_temp.functest_temp_dep() RETURNS int
LANGUAGE sql
BEGIN ATOMIC;
SELECT val FROM temp_table;
END;
CREATE FUNCTION

== temp view ==
postgres=# CREATE FUNCTION functest_temp_view() RETURNS int LANGUAGE sql
BEGIN ATOMIC;
SELECT val FROM temp_view;
END;
ERROR: cannot use temporary object "temp_view" in SQL function with
BEGIN ATOMIC
DETAIL: SQL functions with BEGIN ATOMIC cannot depend on temporary objects.

Thoughts?

Best regards, Jim

Attachment Content-Type Size
v4-0001-Refactor-dependency-recording-to-enable-dependenc.patch text/x-patch 5.8 KB
v4-0002-Prevent-SQL-functions-with-BEGIN-ATOMIC-from-depe.patch text/x-patch 24.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message jian he 2025-10-13 15:26:46 Re: add function argument name to substring and substr
Previous Message suyu.cmj 2025-10-13 15:03:02 Re: Question about InvalidatePossiblyObsoleteSlot()