Project: YugabyteDB (App Definition and Development / Database)
File: globality-of-metadata-and-privacy-of-use-of-temp-objects.md

title: Demonstrate the globality of metadata, and the privacy of use, of temporary objects [YSQL] headerTitle: Demonstrate the globality of metadata, and the privacy of use, of temporary objects linkTitle: Globality of metadata and privacy of use of temp objects description: Demonstrates that all sessions can see the metadata for temporary objects created by all other sessionsbut that only the session that created a temporary object can use it. [YSQL] menu: v2.18: identifier: globality-of-metadata-and-privacy-of-use-of-temp-objects parent: creating-and-using-temporary-schema-objects weight: 300 type: docs These tests will show that temporary object metadata is visible across different sessions but that you can use a temporary object only in the session that created it. Create and save this SQL script as "prepare-qry.sql". ```plpgsql prepare qry as with c(name, ismytemp, schema, owner) as ( select c.relname, c.relnamespace = pgmytemp_schema(), n.nspname, r.rolname from pg_class as c inner join pg_namespace as n on c.relnamespace = n.oid inner join pg_roles as r on c.relowner = r.oid where relkind = 'r') select name, ismytemp::text, schema from c where owner = current_role order by (replace(schema::text, 'pgtemp', ''))::int; ``` And create and save this SQL script as "t.sql". ```plpgsql -- For example, connect as the role "d0$u0" to the database "d0". \c d0 d0$u0 create table pg_temp.t(k int, v int) on commit delete rows; \ir prepare-qry.sql start transaction; insert into pg_temp.t(k, v) values(1, 42); select * from pg_temp.t; execute qry; ``` Start a new session as an ordinary role that has all privileges on the current database. Call this "Session 0". Make sure that there are no other sessions using this database. Then do this: ```plpgsql -- For example, connect as the role "d0$u0" to the database "d0". \c d0 d0$u0 \i prepare-qry.sql execute qry; ``` At this stage, it will produce no rows. Then, in a new terminal window, start a new session as the same test user connecting to the same database. Call this "Session 1". Execute the script: ```plpgsql \i t.sql ``` Repeat this for a reasonable number of newly started sessions. Three is enough. But the more you start, the more convincing the demo will be of the rule for the behavior. When you've started as many sessions as you intend to, repeat execute qry in each session. With "Session 0" through "Session 3", you'll see (something like) this in "Session 0": ```output name | ismytemp | schema ++-- t | false | pgtemp3 t | false | pgtemp4 t | false | pgtemp5 ``` The actual numbers appended to pgtemp\ are unpredictable. Notice that pgmytempschema() returned false_ for each of the three temporary schemas. The results show that each session that executed this: ```plpgsql create table pg_temp.t ``` using a schema-qualified identifier for the temporary table that starts with the alias pgtemp, has created a differently-named temporary schema. This, of course, must be the case because a schema-object is uniquely identified by its name and the name of the schema where it livesand the table always has the same name,

You'll then see this in "Session 2"_: ```output name | ismytemp | schema ++-- t | true | pgtemp3 t | false | pgtemp4 t | false | pgtemp5 ``` Notice that that pgmytempschema() returned true for pgtemp3 andfalse for the other two temporary schemas. The same pattern continues: pgtemp4 is the temporary schema for "Session 2"; and pgtemp5 is the temporary schema for "Session 3"_. Now exit each of "Session 3", "Session 2", and "Session 1", in turn, and after exiting each repeat execute qry in "Session 0". You'll see that when each session exits, its temporary schema vanishes. First, create a new version of "prepare-qry.sql" thus: ```plpgsql prepare qry as with c(name, kind, ismytemp, schema, owner) as ( select c.relname, 'table', c.relnamespace = pgmytemp_schema(), n.nspname, r.rolname from pg_class as c inner join pg_namespace as n on c.relnamespace = n.oid inner join pg_roles as r on c.relowner = r.oid where relkind = 'r' union all select p.proname, 'function', p.pronamespace = pgmytemp_schema(), n.nspname, r.rolname from pg_proc as p inner join pg_namespace as n on p.pronamespace = n.oid inner join pg_roles as r on p.proowner = r.oid where prokind = 'f') select name, kind, ismytemp::text, schema from c where owner = current_role order by name desc; ``` Now exit and re-start "Session 0" as, so far, the only session and create and populate a temporary table and create a temporary function to display its contents. ```plpgsql \c d0 d0$u0 create table pg_temp.t(k int); insert into pg_temp.t(k) values (17), (42), (57); create function pg_temp.f(i out int) returns setof int language sql set searchpath = pgcatalog, pg_temp as $body$ select k from pg_temp.t order by k; $body$; select i from pg_temp.f(); ``` This is the result: ```output i 17 42 57 ``` Now, still in the same session, do this: ```plpgsql \ir prepare-qry.sql execute qry; ``` This is the result: ```output name | kind | ismytemp | schema +-++-- t | table | true | pgtemp2 f | function | true | pgtemp2 ``` To prepare for the second part of the test, demonstrate that it is possible to identify the actual temporary schema that the current session uses rather than do this with the pgtemp_ alias: ```plpgsql select k from pgtemp2.t order by k; ``` and ```plpgsql select i from pgtemp2.f(); ``` Now start a second session and do this: ```plpgsql \c d0 d0$u0 \ir prepare-qry.sql execute qry; ``` Just as the tests in the section led to expect, you'll see this: ```output name | kind | ismytemp | schema +-++-- t | table | false | pgtemp2 f | function | false | pgtemp2 ``` In other words, you see the same facts about the same temporary schema-objects with the difference that the temporary schema where they live does not belong to the current session. Now try to use the temporary schema-objects using the same explicit identifiers that worked in the session to which the pgtemp2 belongs: ```plpgsql select k from pgtemp2.t order by k; ``` and ```plpgsql select i from pgtemp2.f(); ``` Each of these attempts fails with the same error: ```output permission denied for schema pgtemp2 ``` Arguably, the error could have been better worded. After all, the owner of pgtemp2 is the role that implicitly created it. And this same role has authorized both sessions. Nevertheless, the meaning is clear: only the session that created a temporary schema-object can use it.