diff options
| author | Tom Lane | 2014-02-07 00:37:58 +0000 |
|---|---|---|
| committer | Tom Lane | 2014-02-07 00:38:06 +0000 |
| commit | 8de3e410faa06ab20ec1aa6d0abb0a2c040261ba (patch) | |
| tree | 167ce5bfe4dbfd97d4b6ed27683feeaf75c0c8b6 /src/test | |
| parent | 45e1b6c4c490a173208f98f4babc03b8fc69439e (diff) | |
In RelationClearRelation, postpone cache reload if !IsTransactionState().
We may process relcache flush requests during transaction startup or
shutdown. In general it's not terribly safe to do catalog access at those
times, so the code's habit of trying to immediately revalidate unflushable
relcache entries is risky. Although there are no field trouble reports
that are positively traceable to this, we have been able to demonstrate
failure of the assertions recently added in RelationIdGetRelation() and
SearchCatCache(). On the other hand, it seems safe to just postpone
revalidation of the cache entry until we're inside a valid transaction.
The one case where this is questionable is where we're exiting a
subtransaction and the outer transaction is holding the relcache entry open
--- but if we made any significant changes to the rel inside such a
subtransaction, we've got problems anyway. There are mechanisms in place
to prevent that (to wit, locks for cross-session cases and
CheckTableNotInUse() for intra-session cases), so let's trust to those
mechanisms to keep us out of trouble.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/transactions.out | 14 | ||||
| -rw-r--r-- | src/test/regress/sql/transactions.sql | 19 |
2 files changed, 33 insertions, 0 deletions
diff --git a/src/test/regress/expected/transactions.out b/src/test/regress/expected/transactions.out index 5c84ec50ca2..5d70863866f 100644 --- a/src/test/regress/expected/transactions.out +++ b/src/test/regress/expected/transactions.out @@ -552,6 +552,20 @@ ROLLBACK; DROP TABLE foo; DROP TABLE baz; DROP TABLE barbaz; +-- test case for problems with revalidating an open relation during abort +create function inverse(int) returns float8 as +$$ +begin + analyze revalidate_bug; + return 1::float8/$1; +exception + when division_by_zero then return 0; +end$$ language plpgsql volatile; +create table revalidate_bug (c float8 unique); +insert into revalidate_bug values (1); +insert into revalidate_bug values (inverse(0)); +drop table revalidate_bug; +drop function inverse(int); -- verify that cursors created during an aborted subtransaction are -- closed, but that we do not rollback the effect of any FETCHs -- performed in the aborted subtransaction diff --git a/src/test/regress/sql/transactions.sql b/src/test/regress/sql/transactions.sql index faf6a9bf938..9fac4a3f71f 100644 --- a/src/test/regress/sql/transactions.sql +++ b/src/test/regress/sql/transactions.sql @@ -333,6 +333,25 @@ DROP TABLE foo; DROP TABLE baz; DROP TABLE barbaz; + +-- test case for problems with revalidating an open relation during abort +create function inverse(int) returns float8 as +$$ +begin + analyze revalidate_bug; + return 1::float8/$1; +exception + when division_by_zero then return 0; +end$$ language plpgsql volatile; + +create table revalidate_bug (c float8 unique); +insert into revalidate_bug values (1); +insert into revalidate_bug values (inverse(0)); + +drop table revalidate_bug; +drop function inverse(int); + + -- verify that cursors created during an aborted subtransaction are -- closed, but that we do not rollback the effect of any FETCHs -- performed in the aborted subtransaction |
