From 3908473c809d5c24940faebfabdad673f4302178 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 8 Nov 2000 22:10:03 +0000 Subject: Make DROP TABLE rollback-able: postpone physical file delete until commit. (WAL logging for this is not done yet, however.) Clean up a number of really crufty things that are no longer needed now that DROP behaves nicely. Make temp table mapper do the right things when drop or rename affecting a temp table is rolled back. Also, remove "relation modified while in use" error check, in favor of locking tables at first reference and holding that lock throughout the statement. --- src/backend/parser/parse_clause.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'src/backend/parser/parse_clause.c') diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 38dc3ea0976..60521d13475 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.70 2000/10/07 00:58:17 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.71 2000/11/08 22:09:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -87,6 +87,34 @@ makeRangeTable(ParseState *pstate, List *frmList) } } +/* + * lockTargetTable + * Find the target relation of INSERT/UPDATE/DELETE and acquire write + * lock on it. This must be done before building the range table, + * in case the target is also mentioned as a source relation --- we + * want to be sure to grab the write lock before any read lock. + * + * The ParseState's link to the target relcache entry is also set here. + */ +void +lockTargetTable(ParseState *pstate, char *relname) +{ + /* Close old target; this could only happen for multi-action rules */ + if (pstate->p_target_relation != NULL) + heap_close(pstate->p_target_relation, NoLock); + pstate->p_target_relation = NULL; + pstate->p_target_rangetblentry = NULL; /* setTargetTable will set this */ + + /* + * Open target rel and grab suitable lock (which we will hold till + * end of transaction). + * + * analyze.c will eventually do the corresponding heap_close(), + * but *not* release the lock. + */ + pstate->p_target_relation = heap_openr(relname, RowExclusiveLock); +} + /* * setTargetTable * Add the target relation of INSERT/UPDATE/DELETE to the range table, @@ -133,13 +161,10 @@ setTargetTable(ParseState *pstate, char *relname, bool inh, bool inJoinSet) if (inJoinSet) addRTEtoJoinList(pstate, rte); - /* This could only happen for multi-action rules */ - if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation, AccessShareLock); + /* lockTargetTable should have been called earlier */ + Assert(pstate->p_target_relation != NULL); pstate->p_target_rangetblentry = rte; - pstate->p_target_relation = heap_open(rte->relid, AccessShareLock); - /* will close relation later, see analyze.c */ } -- cgit v1.2.3