Re: plpgsql function problem whith creating temp table - not correctly using search_path ? - Mailing list pgsql-general

From Pavel Stehule
Subject Re: plpgsql function problem whith creating temp table - not correctly using search_path ?
Date
Msg-id CAFj8pRAQ1GJGUZRb_u29SbnW_+VXSikvyEDK8kjkZhouztTAbw@mail.gmail.com
Whole thread Raw
In response to Re: plpgsql function problem whith creating temp table - not correctly using search_path ?  (benj.dev@laposte.net)
List pgsql-general


út 11. 1. 2022 v 16:51 odesílatel <benj.dev@laposte.net> napsal:
‌Hi, Thank you for pointing this part of the documentation.
It's actually works with EXECUTE 'INSERT INTO my_table VALUES((random() * 100)::INT);'; INSTEAD OF INSERT INTO my_table VALUES((random() * 100)::INT);
And it's possible to suppose that the test_search_path_v2 worked before because of the 
PERFORM set_config('search_path', '"$user", public', true); 
I imagine that the changement of search_path have on side effect to invalidate the cached plans here and force to recompute the query plan.
I imagine that the probleme appears in  test_search_path_v1 after second call maybe because  the cache is kept by following rules such as a certain number of executions

In this example, use EXECUTE only in INSERT INTO my_table is sufficient to remove the problem.
subsequent SELECT works (without the EXECUTE).
Does doing an EXECUTE on a table have the side effect of invalidating caches using that table name or is it just a "chance" here and for added security I should use EXECUTE everywhere?

EXECUTE uses one shot plan - this plan is not cached. It has not any impact on others' plans.

Regards

Pavel



Thanks
 
De : "David G. Johnston"
A : "benj.dev@laposte.net" ,"pgsql-general@postgresql.org"
Envoyé: mardi 11 Janvier 2022 15:18
Objet : Re: plpgsql function problem whith creating temp table - not correctly using search_path ?
 
On Tuesday, January 11, 2022, <benj.dev@laposte.net> wrote:

SHOW search_path -- => "$user", public;
DROP TABLE IF EXISTS my_table;
-- Executing each row on differents transactions but in the same session
/*Session A - Transaction 1*/ SELECT * FROM test_search_path_v1(true);  -- => OK takes table from pg_temp (no existing table in public)
/*Session A - Transaction 2*/ SELECT * FROM test_search_path_v1(false); -- => OK takes table from public
/*Session A - Transaction 3*/ SELECT * FROM test_search_path_v1(true);  -- => OK takes table from pg_temp (and the existing from public)
/*Session A - Transaction 4*/ SELECT * FROM test_search_path_v1(false); -- => OK takes table from public
/*Session A - Transaction 5*/ SELECT * FROM test_search_path_v1(true);  -- => NOK => it takes public and not pg_temp
 
Per [1], you are violating:
 
“Because PL/pgSQL saves prepared statements and sometimes execution plans in this way, SQL commands that appear directly in a PL/pgSQL function must refer to the same tables and columns on every execution; that is, you cannot use a parameter as the name of a table or column in an SQL command.”
 
While that wording is odd, it is not even possible to use variables in place of table and column names, what you are doing here is effectively the same.  I cannot explain the precise observed behavior, and maybe there is a bug here, but on its face what you are doing is simply invalid in face of how the session relation cache works.
 
 
David J.
 

pgsql-general by date:

Previous
From: benj.dev@laposte.net
Date:
Subject: Re: plpgsql function problem whith creating temp table - not correctly using search_path ?
Next
From: Dominique Devienne
Date:
Subject: Template for schema? (as opposed to databases)