On Wed, Jul 6, 2022 at 11:50 AM Bryn Llewellyn <b...@yugabyte.com> wrote:

>
> It succeeded. And the \d metacommand showed me that I now have a table
> pg_temp_3.x. Using a different database, it ends up in "pg_temp_1. What's
> going on here? Is "pg_temp" a kind of generic nickname for ANY "pg_temp_N"?
>
> I hate to realize that I'm failing to understand a fundamental principle.
>
> It rather looks like the name-res to pg_catalog and (some) pg_temp is
> hard-coded and doesn't rely on the reigning search_path. Or, to put it
> another way, these two schemas are inevitably at the end of the search_path
> no matter what you set explicitly, and never mind that "show search_path"
> doesn't show them unless you also put them on the path (again) explicitly.
>

You either didn't read or failed or retain knowledge of the words in the
documentation that are the canonical reference for search_path and explain
exactly this.  I suggest you (re-)read them.

https://www.postgresql.org/docs/current/runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT
(under search_path)

And elsewhere I'm sure it is written that since temporary objects are
session-local it was decided that a useful implementation detail for that
would be for each session to have its own temporary schema, hence the
appended integer to distinguish them (referencing pg_temp works, the system
resolves the session specific schema name for you).


>
> I can't make sense of this wording from "Writing SECURITY
> DEFINER Functions Safely":
>
> « A secure arrangement can be obtained by forcing the temporary schema to
> be searched last. To do this, write pg_temp as the last entry
> in search_path. »
>
> If I do this:
>
> *set search_path = 'pg_catalog, pg_temp';*
> *show search_path;*
>

> Then I see what I set—in that order. But if I set the search_path to empty
> (and don't see pg_catalog or pg_temp with "show") PG behaves as if they're
> still there.
>

Those same docs also explain why search_path shows what it does (it is the
literally saved value) and to find out how the system actually resolved it
at runtime to come up with a final search_path you need to use a different
thing (via a function).



> Not only as my f() and p() above show. But even, say, "select count(*)
> from pg_class". Moreover, this is allowed too:
>
>
>
> *set search_path = 'pg_temp, pg_catalog, pg_temp';show search_path;*
> Now I see exactly what I set.
>

If you meant that to be a literal thing you've only identified one very
oddly named schema...otherwise yes I get your point.



> It seems strange that this is allowed. How does the implementation handle
> this when a to-be-resolved name exists nowhere? Does it just crank on,
> repeatedly searching where it already failed, right up to the bitter end?
>

Probably...or maybe it ignores the second reference and it is treated the
same as 'pg_temp, pg_catalog'

>
> Here's another test whose outcome surprises me and seems to be at odds
> with what you're saying and what the "Writing SECURITY DEFINER Functions
> Safely" section says:
>
>
>
>
>
>
> *select count(*) from pg_class; -- 399create temporary table pg_class(k
> int);select count(*) from pg_class; -- 0set search_path = 'pg_catalog,
> pg_temp';select count(*) from pg_class; -- STILL 0*
> Why does the final "select" show that the temp table's name has still
> captured the one in pg_catalog even though it's ahead in the path.
>

Remember that session scoped relation cache we went on about a little while
back...I think that by creating the object you got a cache invalidation but
simply changing the search_path does not cause a cache invalidation.


> The "Writing SECURITY DEFINER Functions Safely" section explicitly
> recommends that a subprogram includes a "set search_path" specification.
> But, as I read it, you're saying that this advice is wrong (at least when a
> function will be invoked in more than a bare "select" because it prevents
> inlining.
>
> How should I resolve these two conflicting pieces of advice?
>

There is no "conflict" - you basically get to choose safety or
performance.  Though since performance isn't guaranteed nor always a need I
would say choose safety unless you've confirmed that you need performance.

David J.

Reply via email to