> Tatsuo Ishii wrote:
> >>I agree with Tom here. I have used the Oracle NOWAIT feature in the
> >>past and think it is a great feature IMHO. But when you need to use it,
> >>you want it to apply very specifically to a single statement. Using a
> >>sledge hammer when you need a tweezers isn't the right way to go.
> >
> >
> > Once I have written patches for 7.3 to implement this feature for LOCK
> > statement. For example:
> >
> > test=# LOCK TABLE sales NO WAIT;
> > ERROR: Cannot aquire relation lock
> >
> > If there's enough interest, I will modify and submit it for 7.5.
> > --
> > Tatsuo Ishii
> >
> > ---------------------------(end of broadcast)---------------------------
> > TIP 8: explain analyze is your friend
>
>
> That would be great.
> Many people are asking for that.
> Maybe I have time to implement that for SELECT FOR UPDATE.
Here it is(against 7.3.3).
--
Tatsuo Ishii
*** ./src/backend/access/heap/heapam.c.orig 2003-07-04 09:12:10.000000000 +0900
--- ./src/backend/access/heap/heapam.c 2003-07-12 13:52:43.000000000 +0900
***************
*** 479,484 ****
--- 479,517 ----
return r;
}
+ Relation
+ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool no_wait)
+ {
+ Relation r;
+
+ Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+
+ /*
+ * increment access statistics
+ */
+ IncrHeapAccessStat(local_open);
+ IncrHeapAccessStat(global_open);
+
+ /* The relcache does all the real work... */
+ r = RelationIdGetRelation(relationId);
+
+ if (!RelationIsValid(r))
+ elog(ERROR, "Relation %u does not exist", relationId);
+
+ if (lockmode != NoLock)
+ {
+ if (no_wait)
+ {
+ if (!ConditionalLockRelation(r, lockmode))
+ elog(ERROR, "Cannot aquire relation lock");
+ }
+ else
+ LockRelation(r, lockmode);
+ }
+
+ return r;
+ }
+
/* ----------------
* relation_openrv - open any relation specified by a RangeVar
*
*** ./src/backend/commands/lockcmds.c.orig 2003-07-04 09:21:30.000000000 +0900
--- ./src/backend/commands/lockcmds.c 2003-07-12 13:53:30.000000000 +0900
***************
*** 58,64 ****
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_rel_name(reloid));
! rel = relation_open(reloid, lockstmt->mode);
/* Currently, we only allow plain tables to be locked */
if (rel->rd_rel->relkind != RELKIND_RELATION)
--- 58,64 ----
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_rel_name(reloid));
! rel = conditional_relation_open(reloid, lockstmt->mode,
lockstmt->no_wait);
/* Currently, we only allow plain tables to be locked */
if (rel->rd_rel->relkind != RELKIND_RELATION)
*** ./src/backend/parser/gram.y.orig 2003-07-12 12:45:30.000000000 +0900
--- ./src/backend/parser/gram.y 2003-07-12 13:37:27.000000000 +0900
***************
*** 161,166 ****
--- 161,167 ----
%type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace
+ %type <boolean> opt_no_wait
%type <list> user_list
***************
*** 392,397 ****
--- 393,400 ----
VACUUM VALID VALIDATOR VALUES VARCHAR VARYING
VERBOSE VERSION VIEW VOLATILE
+ WAIT
+
WHEN WHERE WITH WITHOUT WORK WRITE
YEAR_P
***************
*** 4050,4061 ****
}
;
! LockStmt: LOCK_P opt_table qualified_name_list opt_lock
{
LockStmt *n = makeNode(LockStmt);
n->relations = $3;
n->mode = $4;
$$ = (Node *)n;
}
;
--- 4053,4065 ----
}
;
! LockStmt: LOCK_P opt_table qualified_name_list opt_lock opt_no_wait
{
LockStmt *n = makeNode(LockStmt);
n->relations = $3;
n->mode = $4;
+ n->no_wait = $5;
$$ = (Node *)n;
}
;
***************
*** 4074,4079 ****
--- 4078,4087 ----
| ACCESS EXCLUSIVE { $$ =
AccessExclusiveLock; }
;
+ opt_no_wait: NO WAIT { $$ = TRUE; }
+ | /*EMPTY*/ { $$ =
FALSE; }
+ ;
+
/*****************************************************************************
*
*** ./src/backend/parser/keywords.c.orig 2003-07-12 13:39:23.000000000 +0900
--- ./src/backend/parser/keywords.c 2003-07-12 13:39:47.000000000 +0900
***************
*** 318,323 ****
--- 318,324 ----
{"version", VERSION},
{"view", VIEW},
{"volatile", VOLATILE},
+ {"wait", WAIT},
{"when", WHEN},
{"where", WHERE},
{"with", WITH},
*** ./src/include/nodes/parsenodes.h.orig 2003-07-12 12:48:48.000000000 +0900
--- ./src/include/nodes/parsenodes.h 2003-07-12 13:44:04.000000000 +0900
***************
*** 1593,1598 ****
--- 1593,1599 ----
NodeTag type;
List *relations; /* relations to lock */
int mode; /* lock mode */
+ bool no_wait; /* no wait mode */
} LockStmt;
/* ----------------------
*** src/include/access/heapam.h.orig 2003-07-19 14:08:22.000000000 +0900
--- src/include/access/heapam.h 2003-07-19 14:08:48.000000000 +0900
***************
*** 136,141 ****
--- 136,142 ----
/* heapam.c */
extern Relation relation_open(Oid relationId, LOCKMODE lockmode);
+ extern Relation conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool
no_wait);
extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode);
extern Relation relation_openr(const char *sysRelationName, LOCKMODE lockmode);
extern void relation_close(Relation relation, LOCKMODE lockmode);
---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings