blob: 8cdd104635a21251ee97295de82b81bbf93948c3 [file] [log] [blame]
-- MPP-24237
-- Security definer function causes temp table not to be dropped due to pg_toast access privileges
CREATE or replace FUNCTION sec_definer_create_test() RETURNS void AS $$
BEGIN
RAISE NOTICE 'Creating table';
execute 'create temporary table wmt_toast_issue_temp (name varchar, address varchar) distributed randomly';
RAISE NOTICE 'Table created';
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
create role sec_definer_role with login ;
grant execute on function sec_definer_create_test() to sec_definer_role;
set role sec_definer_role;
select sec_definer_create_test() ;
-- Remember the name of the temp namespace and temp toast namespace
CREATE TABLE temp_nspnames as
select nsp.nspname as nspname, toastnsp.nspname as toastnspname from pg_class c
inner join pg_namespace nsp on c.relnamespace = nsp.oid
inner join pg_class toastc on toastc.oid = c.reltoastrelid
inner join pg_namespace toastnsp on toastc.relnamespace = toastnsp.oid
where c.oid = 'wmt_toast_issue_temp'::regclass;
-- there should be exactly one temp table with that name.
select count(*) from temp_nspnames;
-- Disconnect and reconnect.
\c regression
-- It can take a while for the old backend to finish cleaning up the
-- temp tables.
select pg_sleep(2);
-- Check that the temp namespaces were dropped altogether.
select nsp.nspname, temp_nspnames.* FROM pg_namespace nsp, temp_nspnames
where nsp.nspname = temp_nspnames.nspname OR nsp.nspname = temp_nspnames.toastnspname;
-- Check that the temporary table was dropped at disconnect. (It really should be
-- gone if the whole namespace is gone, but doesn't hurt to check.)
select * from pg_tables where tablename = 'wmt_toast_issue_temp';
-- Clean up
reset role;
drop table temp_nspnames;
drop function public.sec_definer_create_test();
drop role sec_definer_role;
-- Check if myTempNamespace is correct in N-Gang query.
create table tn_a(id int) distributed by (id);
create temp table tn_a_tmp(a int) distributed replicated;
insert into tn_a values (1), (2);
insert into tn_a_tmp values(1);
create or replace function fun(sql text, a oid) returns bigint AS 'return plpy.execute(sql).nrows() + a' language plpython3u stable;
create table tn_a_new as with c as (select fun('select * from tn_a_tmp', s.id) from tn_a s) select 1 from c;
drop table tn_a;
drop table tn_a_tmp;
drop table tn_a_new;
-- Check if old gang can accept new temp schema, after temp schema changed on coordinator
\c
create table tn_b_a(id int) distributed by (id);
create table tn_b_b(id int, a_id int) distributed by (id);
insert into tn_b_a values (1), (2);
insert into tn_b_b values (3, 1), (4, 2);
select a.id, b.id from tn_b_a a, tn_b_b b where a.id = b.a_id order by 1, 2;
create temp table tn_b_temp(a int) distributed replicated;
insert into tn_b_temp values(1);
create table tn_b_new as with c as (select fun('select * from tn_b_temp', s.id) from tn_b_b s) select 1 from c;
drop table tn_b_a;
drop table tn_b_b;
drop table tn_b_temp;
drop table tn_b_new;
drop function fun(sql text, a oid);
-- Chek if error out inside UDF, myTempNamespace will roll back
\c
create or replace function errored_udf() returns int[] as 'BEGIN RAISE EXCEPTION ''AAA''; END' language plpgsql;
create table n as select from generate_series(1, 10);
select count(*) from n n1, n n2; -- boot reader gang
create temp table nn as select errored_udf() from n;
create temp table nnn as select * from generate_series(1, 10); -- check if reader do the rollback. should OK
select count(*) from nnn n1, nnn n2; -- check if reader can read temp table. should OK
drop table n;
drop function errored_udf();