blob: 4879dfb1b24719fe8bf8c718df9596defebb8396 [file] [log] [blame]
--
-- PLPGSQL
--
-- Testing various scenarios where plans will not be cached.
-- MPP-16204
--
-- ************************************************************
-- * Repro with drop table inside a function
-- * - Multiple executions should not raise an error
-- ************************************************************
--
drop table if exists cache_tab cascade;
drop function if exists cache_test();
create function cache_test() returns void as
$$
begin
drop table if exists cache_tab;
create table cache_tab (id int) distributed randomly;
insert into cache_tab values (1);
end;
$$ language plpgsql;
select cache_test();
-- following should not fail.
select cache_test();
drop table cache_tab;
drop function cache_test();
--
-- ************************************************************
-- * Repro with SELECT .. INTO inside a function
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab
(
c1 int,
c2 text
) partition by range(c1)
(default partition def,
partition part1 start (int '1') end (int '10'));
insert into cache_tab values(1, 2);
insert into cache_tab values(2, 3);
insert into cache_tab values(3, 4);
create function cache_test(id int) returns int as $$
declare
v_int int;
begin
select c1 from cache_tab where c2 = id INTO v_int;
return v_int;
end;
$$ language plpgsql;
select * from cache_test(1);
alter table cache_tab split default partition
start (11) inclusive
end (20) exclusive
into (partition part2, partition def);
-- following should not fail.
select * from cache_test(2);
drop table cache_tab cascade;
drop function cache_test(int);
--
-- ************************************************************
-- * Repro with drop table between executions
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab (
id int,
name varchar(50)
) distributed randomly;
insert into cache_tab values(1, 'abc');
insert into cache_tab values(2, 'def');
drop function if exists cache_test(var int);
create function cache_test(var int) returns varchar as $$
declare
v_name varchar(20) DEFAULT 'zzzz';
begin
select name from cache_tab into v_name where id = var;
return v_name;
end;
$$ language plpgsql;
select * from cache_test(1);
drop table if exists cache_tab;
create table cache_tab (
id int,
name varchar(50)
) distributed randomly;
-- following should not fail.
select * from cache_test(2);
drop table cache_tab;
drop function cache_test(int);
--
-- ************************************************************
-- * Repro with return cursor
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab (
c1 int,
c2 int,
c3 int
) distributed randomly;
insert into cache_tab values(1, 2, 100);
insert into cache_tab values(2, 3, 200);
insert into cache_tab values(3, 4, 300);
create function cache_test(refcursor) returns refcursor as $$
begin
open $1 for select * from cache_tab;
return $1;
end;
$$
language plpgsql;
begin;
select cache_test('refcursor');
fetch all in refcursor;
commit;
drop table if exists cache_tab;
create table cache_tab (
c1 int,
c2 int,
c3 int
) distributed randomly;
begin;
select cache_test('refcursor');
fetch all in refcursor;
commit;
drop table cache_tab;
drop function cache_test(refcursor);
--
-- ************************************************************
-- * Repro with fetch cursor
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab(
c1 int,
c2 int,
c3 int
) distributed randomly;
insert into cache_tab values(1, 2, 100);
insert into cache_tab values(1, 2, 100);
create function cache_test(var int) returns int as $$
declare
cur refcursor;
res int;
total_res int default 0;
begin
open cur for select c2 from cache_tab where c1 = var;
fetch cur into res;
while res is not null
loop
total_res := total_res + res;
fetch cur into res;
end loop;
return total_res;
end;
$$ language plpgsql;
select cache_test(1);
drop table if exists cache_tab;
create table cache_tab(
c1 int,
c2 int,
c3 int
) distributed randomly;
insert into cache_tab values(1, 2, 100);
-- following should not fail
select cache_test(1);
drop table cache_tab;
drop function cache_test(int);
--
-- ************************************************************
-- * Repro with function planned on segments
-- * - plan should be cached
-- ************************************************************
--
create table cache_tab
(
c1 int,
c2 text
) partition by range(c1)
(default partition def,
partition part1 start (int '1') end (int '10'));
insert into cache_tab values(1, 'foo1');
create function cache_test() returns int as $$
declare
v_temp varchar(10);
begin
select into v_temp hastriggers from pg_tables;
if v_temp is not null
then
return 1;
else
return 0;
end if;
end;
$$ language plpgsql;
select * from cache_tab where c1 = cache_test();
select * from cache_tab where c1 = cache_test();
drop table cache_tab;
drop function cache_test();
--
-- ************************************************************
-- * Block statement execution
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab
(
c1 int,
c2 int
) partition by range(c2)
(default partition def,
partition part1 start (int '1') end (int '10'));
insert into cache_tab values(0, 100);
insert into cache_tab values(1, 100);
insert into cache_tab values(2, 100);
create function cache_test(key int) returns int as $$
declare
v_int int;
v_res int default 0;
begin
loop
select c1 from cache_tab into v_int where c2 = key;
if found then
return v_res;
end if;
if v_int != 0 then
v_res := v_res + v_int;
end if;
end loop;
end;
$$ language plpgsql;
select cache_test(100);
alter table cache_tab split default partition
start (11) inclusive
end (20) exclusive
into (partition part2, partition def);
select cache_test(100);
drop table cache_tab cascade;
drop function cache_test(int);
--
-- ************************************************************
-- * Repro with PERFORM
-- * - Multiple executions should not raise an error
-- ************************************************************
--
create table cache_tab
(
c1 int,
c2 int
) partition by range(c2)
(default partition def,
partition part1 start (int '1') end (int '10'));
insert into cache_tab values(1, 100);
insert into cache_tab values(2, 100);
insert into cache_tab values(3, 100);
create function cache_test() returns void AS $$
begin
perform c1 from cache_tab;
end;
$$ language plpgsql;
select cache_test();
drop table if exists cache_tab;
create table cache_tab
(
c1 int,
c2 int
) partition by range(c2)
(default partition def,
partition part1 start (int '1') end (int '10'));
insert into cache_tab values(1, 100);
select cache_test();
drop table cache_tab;
drop function cache_test();
--
-- ************************************************************
-- * example with table functions
-- *
-- ************************************************************
--
create table cache_tab
(
a int,
b int
) distributed randomly;
insert into cache_tab values(1, 100);
insert into cache_tab values(2, 200);
drop function if exists get_cache_tab();
create function get_cache_tab() returns setof cache_tab as $$
select * from cache_tab where a = 1;
$$ language sql;
create function cache_test() returns setof integer as
$$
declare
r integer;
begin
for r IN select a from get_cache_tab()
loop
return next r;
end loop;
return;
end
$$ language plpgsql;
select cache_test();
drop function if exists get_cache_tab();
create function get_cache_tab() returns setof cache_tab as $$
select * from cache_tab where a = 2;
$$ language sql;
-- plan should not be cached, returns different results
select cache_test();
drop table cache_tab cascade;
drop function if exists get_cache_tab() ;
drop function if exists cache_test();
-- ************************************************************
-- * an example with CTAS
-- * multiple executions should not raise an error
-- ************************************************************
create table cache_tab(id int, data text);
insert into cache_tab values(1, 'abc');
insert into cache_tab values(2, 'abc');
insert into cache_tab values(3, 'abcd');
create or replace function cache_test() returns void as
$$
begin
drop table if exists cache_temp;
create table cache_temp as select * from cache_tab distributed randomly;
end
$$ language plpgsql;
select cache_test();
select * from cache_temp;
drop table cache_tab;
create table cache_tab(id int, data text);
insert into cache_tab values(1, 'abcde');
-- should not raise an error
select cache_test();
-- should return 1 row
select * from cache_temp;
drop table cache_tab cascade;
drop function cache_test();
drop table cache_temp;
--
-- ************************************************************
-- * recursive functions
-- ************************************************************
--
-- start_matchsubs
--
-- m|ERROR:\s+relation with OID \d+ does not exist|
-- s|ERROR:\s+relation with OID \d+ does not exist|ERROR: relation with OID DUMMY does not exist|
--
-- end_matchsubs
create table cache_tab(c1 int, c2 int) distributed randomly;
drop function if exists cache_test(count int);
create function cache_test(count int) returns int as $$
begin
if $1 <= 0 then
return $1;
else
insert into cache_tab values($1, $1);
end if;
return cache_test($1-1);
end;
$$ language plpgsql;
select cache_test(5);
drop table if exists cache_tab;
create table cache_tab(c1 int, c2 int) distributed randomly;
select cache_test(5);
drop function cache_test(count int);
--- another example with recursive functions
create function cache_test(count int) returns int as $$
begin
if $1 <= 0 then
return $1;
else
drop table if exists cache_tab;
create table cache_tab(c1 int, c2 int) distributed randomly;
insert into cache_tab values($1, $1);
end if;
return cache_test($1-1);
end;
$$ language plpgsql;
-- this will fail
select cache_test(5);
set gp_plpgsql_clear_cache_always = on;
-- this will pass
select cache_test(5);
drop table if exists cache_tab;
drop function cache_test(count int) cascade;
--
-- ************************************************************
-- * testing guc
-- ************************************************************
--
drop table if exists cache_tab cascade;
drop function if exists cache_test();
create function cache_test() returns void as
$$
begin
drop table if exists cache_tab;
create table cache_tab (id int) distributed randomly;
insert into cache_tab values (1);
end;
$$ language plpgsql;
BEGIN;
select cache_test();
-- this will fail
select cache_test();
COMMIT;
set gp_plpgsql_clear_cache_always = on;
select cache_test();
drop table cache_tab;
drop function cache_test();
--
-- ************************************************************
-- * testing guc
-- ************************************************************
--
drop table if exists cache_tab cascade;
drop function if exists cache_test();
set gp_plpgsql_clear_cache_always = off;
create function cache_test() returns void as
$$
declare count int;
begin
count := 3;
while count > 0
loop
drop table if exists cache_tab;
create table cache_tab (id int) distributed randomly;
insert into cache_tab values (1);
count := count - 1;
end loop;
end;
$$ language plpgsql;
-- this will fail
select cache_test();
set gp_plpgsql_clear_cache_always = on;
-- this will pass
select cache_test();
set gp_plpgsql_clear_cache_always = off;
drop function cache_test();
create function cache_test() returns void as
$$
declare count int;
begin
count := 3;
while count > 0
loop
set gp_plpgsql_clear_cache_always = on;
drop table if exists cache_tab;
create table cache_tab (id int) distributed randomly;
insert into cache_tab values (1);
count := count - 1;
end loop;
end;
$$ language plpgsql;
select cache_test();
drop table cache_tab;
drop function cache_test();