2 -- Tests to exercise the plan caching/invalidation mechanism
4 CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl;
5 -- create and use a cached plan
6 PREPARE prepstmt AS SELECT * FROM pcachetest;
9 ------------------+-------------------
11 123 | 4567890123456789
12 4567890123456789 | 123
13 4567890123456789 | 4567890123456789
14 4567890123456789 | -4567890123456789
17 -- and one with parameters
18 PREPARE prepstmt2(bigint) AS SELECT * FROM pcachetest WHERE q1 = $1;
19 EXECUTE prepstmt2(123);
21 -----+------------------
23 123 | 4567890123456789
26 -- invalidate the plans and see what happens
27 DROP TABLE pcachetest;
29 ERROR: relation "pcachetest" does not exist
30 EXECUTE prepstmt2(123);
31 ERROR: relation "pcachetest" does not exist
32 -- recreate the temp table (this demonstrates that the raw plan is
33 -- purely textual and doesn't depend on OIDs, for instance)
34 CREATE TEMP TABLE pcachetest AS SELECT * FROM int8_tbl ORDER BY 2;
37 ------------------+-------------------
38 4567890123456789 | -4567890123456789
39 4567890123456789 | 123
41 123 | 4567890123456789
42 4567890123456789 | 4567890123456789
45 EXECUTE prepstmt2(123);
47 -----+------------------
49 123 | 4567890123456789
52 -- prepared statements should prevent change in output tupdesc,
53 -- since clients probably aren't expecting that to change on the fly
54 ALTER TABLE pcachetest ADD COLUMN q3 bigint;
56 ERROR: cached plan must not change result type
57 EXECUTE prepstmt2(123);
58 ERROR: cached plan must not change result type
59 -- but we're nice guys and will let you undo your mistake
60 ALTER TABLE pcachetest DROP COLUMN q3;
63 ------------------+-------------------
64 4567890123456789 | -4567890123456789
65 4567890123456789 | 123
67 123 | 4567890123456789
68 4567890123456789 | 4567890123456789
71 EXECUTE prepstmt2(123);
73 -----+------------------
75 123 | 4567890123456789
78 -- Try it with a view, which isn't directly used in the resulting plan
79 -- but should trigger invalidation anyway
80 CREATE TEMP VIEW pcacheview AS
81 SELECT * FROM pcachetest;
82 PREPARE vprep AS SELECT * FROM pcacheview;
85 ------------------+-------------------
86 4567890123456789 | -4567890123456789
87 4567890123456789 | 123
89 123 | 4567890123456789
90 4567890123456789 | 4567890123456789
93 CREATE OR REPLACE TEMP VIEW pcacheview AS
94 SELECT q1, q2/2 AS q2 FROM pcachetest;
97 ------------------+-------------------
98 4567890123456789 | -2283945061728394
101 123 | 2283945061728394
102 4567890123456789 | 2283945061728394
105 -- Check basic SPI plan invalidation
106 create function cache_test(int) returns int as $$
109 create temp table t1(f1 int);
110 insert into t1 values($1);
111 insert into t1 values(11);
112 insert into t1 values(12);
113 insert into t1 values(13);
114 select sum(f1) into total from t1;
119 select cache_test(1);
125 select cache_test(2);
131 select cache_test(3);
137 -- Check invalidation of plpgsql "simple expression"
138 create temp view v1 as
140 create function cache_test_2() returns int as $$
143 end$$ language plpgsql;
144 select cache_test_2();
150 create or replace temp view v1 as
152 select cache_test_2();
158 create or replace temp view v1 as
159 select 2+2+4+(select max(unique1) from tenk1) as f1;
160 select cache_test_2();
166 --- Check that change of search_path is ignored by replans
168 create table abc (f1 int);
170 create table abc (f1 int);
171 insert into s1.abc values(123);
172 insert into s2.abc values(456);
173 set search_path = s1;
174 prepare p1 as select f1 from abc;
181 set search_path = s2;
194 alter table s1.abc add column f2 float8; -- force replan
201 drop schema s1 cascade;
202 NOTICE: drop cascades to table s1.abc
203 drop schema s2 cascade;
204 NOTICE: drop cascades to table abc
206 -- Check that invalidation deals with regclass constants
207 create temp sequence seq;
208 prepare p2 as select nextval('seq');
216 create temp sequence seq;
223 -- Check DDL via SPI, immediately followed by SPI plan re-use
224 -- (bug in original coding)
225 create function cachebug() returns void as $$
228 drop table if exists temptable cascade;
229 create temp table temptable as select * from generate_series(1,3) as f1;
230 create temp view vv as select * from temptable;
231 for r in select * from vv loop
234 end$$ language plpgsql;
236 NOTICE: table "temptable" does not exist, skipping
237 CONTEXT: SQL statement "drop table if exists temptable cascade"
238 PL/pgSQL function "cachebug" line 3 at SQL statement
248 NOTICE: drop cascades to view vv
249 CONTEXT: SQL statement "drop table if exists temptable cascade"
250 PL/pgSQL function "cachebug" line 3 at SQL statement