postgresql/src/test/regress/expected/plancache.out

259 lines
6.1 KiB
Plaintext

--
-- Tests to exercise the plan caching/invalidation mechanism
--
CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl;
-- create and use a cached plan
PREPARE prepstmt AS SELECT * FROM pcachetest;
EXECUTE prepstmt;
q1 | q2
------------------+-------------------
123 | 456
123 | 4567890123456789
4567890123456789 | 123
4567890123456789 | 4567890123456789
4567890123456789 | -4567890123456789
(5 rows)
-- and one with parameters
PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1;
EXECUTE prepstmt2(123);
q1 | q2
-----+------------------
123 | 456
123 | 4567890123456789
(2 rows)
-- invalidate the plans and see what happens
DROP TABLE pcachetest;
EXECUTE prepstmt;
ERROR: relation "pcachetest" does not exist
EXECUTE prepstmt2(123);
ERROR: relation "pcachetest" does not exist
-- recreate the temp table (this demonstrates that the raw plan is
-- purely textual and doesn't depend on OIDs, for instance)
CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2;
EXECUTE prepstmt;
q1 | q2
------------------+-------------------
4567890123456789 | -4567890123456789
4567890123456789 | 123
123 | 456
123 | 4567890123456789
4567890123456789 | 4567890123456789
(5 rows)
EXECUTE prepstmt2(123);
q1 | q2
-----+------------------
123 | 456
123 | 4567890123456789
(2 rows)
-- prepared statements should prevent change in output tupdesc,
-- since clients probably aren't expecting that to change on the fly
ALTER TABLE pcachetest ADD COLUMN q3 bigint;
EXECUTE prepstmt;
ERROR: cached plan must not change result type
EXECUTE prepstmt2(123);
ERROR: cached plan must not change result type
-- but we're nice guys and will let you undo your mistake
ALTER TABLE pcachetest DROP COLUMN q3;
EXECUTE prepstmt;
q1 | q2
------------------+-------------------
4567890123456789 | -4567890123456789
4567890123456789 | 123
123 | 456
123 | 4567890123456789
4567890123456789 | 4567890123456789
(5 rows)
EXECUTE prepstmt2(123);
q1 | q2
-----+------------------
123 | 456
123 | 4567890123456789
(2 rows)
-- Try it with a view, which isn't directly used in the resulting plan
-- but should trigger invalidation anyway
CREATE TEMP VIEW pcacheview AS
SELECT * FROM pcachetest;
PREPARE vprep AS SELECT * FROM pcacheview;
EXECUTE vprep;
q1 | q2
------------------+-------------------
4567890123456789 | -4567890123456789
4567890123456789 | 123
123 | 456
123 | 4567890123456789
4567890123456789 | 4567890123456789
(5 rows)
CREATE OR REPLACE TEMP VIEW pcacheview AS
SELECT q1, q2/2 AS q2 FROM pcachetest;
EXECUTE vprep;
q1 | q2
------------------+-------------------
4567890123456789 | -2283945061728394
4567890123456789 | 61
123 | 228
123 | 2283945061728394
4567890123456789 | 2283945061728394
(5 rows)
-- Check basic SPI plan invalidation
create function cache_test(int) returns int as $$
declare total int;
begin
create temp table t1(f1 int);
insert into t1 values($1);
insert into t1 values(11);
insert into t1 values(12);
insert into t1 values(13);
select sum(f1) into total from t1;
drop table t1;
return total;
end
$$ language plpgsql;
select cache_test(1);
cache_test
------------
37
(1 row)
select cache_test(2);
cache_test
------------
38
(1 row)
select cache_test(3);
cache_test
------------
39
(1 row)
-- Check invalidation of plpgsql "simple expression"
create temp view v1 as
select 2+2 as f1;
create function cache_test_2() returns int as $$
begin
return f1 from v1;
end$$ language plpgsql;
select cache_test_2();
cache_test_2
--------------
4
(1 row)
create or replace temp view v1 as
select 2+2+4 as f1;
select cache_test_2();
cache_test_2
--------------
8
(1 row)
create or replace temp view v1 as
select 2+2+4+(select max(unique1) from tenk1) as f1;
select cache_test_2();
cache_test_2
--------------
10007
(1 row)
--- Check that change of search_path is ignored by replans
create schema s1
create table abc (f1 int);
create schema s2
create table abc (f1 int);
insert into s1.abc values(123);
insert into s2.abc values(456);
set search_path = s1;
prepare p1 as select f1 from abc;
execute p1;
f1
-----
123
(1 row)
set search_path = s2;
select f1 from abc;
f1
-----
456
(1 row)
execute p1;
f1
-----
123
(1 row)
alter table s1.abc add column f2 float8; -- force replan
execute p1;
f1
-----
123
(1 row)
drop schema s1 cascade;
NOTICE: drop cascades to table s1.abc
drop schema s2 cascade;
NOTICE: drop cascades to table abc
reset search_path;
-- Check that invalidation deals with regclass constants
create temp sequence seq;
prepare p2 as select nextval('seq');
execute p2;
nextval
---------
1
(1 row)
drop sequence seq;
create temp sequence seq;
execute p2;
nextval
---------
1
(1 row)
-- Check DDL via SPI, immediately followed by SPI plan re-use
-- (bug in original coding)
create function cachebug() returns void as $$
declare r int;
begin
drop table if exists temptable cascade;
create temp table temptable as select * from generate_series(1,3) as f1;
create temp view vv as select * from temptable;
for r in select * from vv loop
raise notice '%', r;
end loop;
end$$ language plpgsql;
select cachebug();
NOTICE: table "temptable" does not exist, skipping
CONTEXT: SQL statement "drop table if exists temptable cascade"
PL/pgSQL function "cachebug" line 4 at SQL statement
NOTICE: 1
NOTICE: 2
NOTICE: 3
cachebug
----------
(1 row)
select cachebug();
NOTICE: drop cascades to view vv
CONTEXT: SQL statement "drop table if exists temptable cascade"
PL/pgSQL function "cachebug" line 4 at SQL statement
NOTICE: 1
NOTICE: 2
NOTICE: 3
cachebug
----------
(1 row)