diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/executor/spi.c | 18 | ||||
-rw-r--r-- | src/test/regress/expected/plancache.out | 40 | ||||
-rw-r--r-- | src/test/regress/sql/plancache.sql | 19 |
3 files changed, 68 insertions, 9 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 3d72fa20a55..a5601ecdfca 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.184 2007/11/15 21:14:35 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.185 2007/11/30 18:38:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1375,14 +1375,6 @@ _SPI_prepare_plan(const char *src, SPIPlanPtr plan) int cursor_options = plan->cursor_options; /* - * Increment CommandCounter to see changes made by now. We must do this - * to be sure of seeing any schema changes made by a just-preceding SPI - * command. (But we don't bother advancing the snapshot, since the - * planner generally operates under SnapshotNow rules anyway.) - */ - CommandCounterIncrement(); - - /* * Setup error traceback support for ereport() */ spierrcontext.callback = _SPI_error_callback; @@ -1662,6 +1654,14 @@ _SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, if (cplan) ReleaseCachedPlan(cplan, true); cplan = NULL; + + /* + * If not read-only mode, advance the command counter after the + * last command. This ensures that its effects are visible, in + * case it was DDL that would affect the next CachedPlanSource. + */ + if (!read_only) + CommandCounterIncrement(); } fail: diff --git a/src/test/regress/expected/plancache.out b/src/test/regress/expected/plancache.out index d7d7be92529..7ee11921c25 100644 --- a/src/test/regress/expected/plancache.out +++ b/src/test/regress/expected/plancache.out @@ -202,6 +202,7 @@ 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'); @@ -219,3 +220,42 @@ execute p2; 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 3 at SQL statement +NOTICE: 1 +NOTICE: 2 +NOTICE: 3 + cachebug +---------- + +(1 row) + +select cachebug(); +NOTICE: drop cascades to rule _RETURN on view vv +CONTEXT: SQL statement "drop table if exists temptable cascade" +PL/pgSQL function "cachebug" line 3 at SQL statement +NOTICE: drop cascades to view vv +CONTEXT: SQL statement "drop table if exists temptable cascade" +PL/pgSQL function "cachebug" line 3 at SQL statement +NOTICE: 1 +NOTICE: 2 +NOTICE: 3 + cachebug +---------- + +(1 row) + diff --git a/src/test/regress/sql/plancache.sql b/src/test/regress/sql/plancache.sql index fc57279d985..26848168f06 100644 --- a/src/test/regress/sql/plancache.sql +++ b/src/test/regress/sql/plancache.sql @@ -124,6 +124,8 @@ execute p1; drop schema s1 cascade; drop schema s2 cascade; +reset search_path; + -- Check that invalidation deals with regclass constants create temp sequence seq; @@ -137,3 +139,20 @@ drop sequence seq; create temp sequence seq; execute p2; + +-- 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(); +select cachebug(); |