summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorAlvaro Herrera2014-10-07 20:23:34 +0000
committerAlvaro Herrera2014-10-07 20:23:34 +0000
commitdf630b0dd5ea2de52972d456f5978a012436115e (patch)
treebe0007351a856caa48230155f5c5bcfe5a31f86d /src/include
parentc421efd21330f2e5bed253b4a53d7ea5e084edf6 (diff)
Implement SKIP LOCKED for row-level locks
This clause changes the behavior of SELECT locking clauses in the presence of locked rows: instead of causing a process to block waiting for the locks held by other processes (or raise an error, with NOWAIT), SKIP LOCKED makes the new reader skip over such rows. While this is not appropriate behavior for general purposes, there are some cases in which it is useful, such as queue-like tables. Catalog version bumped because this patch changes the representation of stored rules. Reviewed by Craig Ringer (based on a previous attempt at an implementation by Simon Riggs, who also provided input on the syntax used in the current patch), David Rowley, and Álvaro Herrera. Author: Thomas Munro
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/heapam.h3
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/executor/executor.h4
-rw-r--r--src/include/nodes/execnodes.h2
-rw-r--r--src/include/nodes/parsenodes.h5
-rw-r--r--src/include/nodes/plannodes.h3
-rw-r--r--src/include/parser/analyze.h3
-rw-r--r--src/include/parser/kwlist.h2
-rw-r--r--src/include/utils/lockwaitpolicy.h31
-rw-r--r--src/include/utils/snapshot.h3
10 files changed, 49 insertions, 9 deletions
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 493839f60e9..7f7166d832e 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -19,6 +19,7 @@
#include "nodes/primnodes.h"
#include "storage/bufpage.h"
#include "storage/lock.h"
+#include "utils/lockwaitpolicy.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
@@ -144,7 +145,7 @@ extern HTSU_Result heap_update(Relation relation, ItemPointer otid,
CommandId cid, Snapshot crosscheck, bool wait,
HeapUpdateFailureData *hufd, LockTupleMode *lockmode);
extern HTSU_Result heap_lock_tuple(Relation relation, HeapTuple tuple,
- CommandId cid, LockTupleMode mode, bool nowait,
+ CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy,
bool follow_update,
Buffer *buffer, HeapUpdateFailureData *hufd);
extern void heap_inplace_update(Relation relation, HeapTuple tuple);
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index a3464a5df90..69ef30a3596 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201409293
+#define CATALOG_VERSION_NO 201410071
#endif
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 02661350d94..d167b496fce 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -16,6 +16,7 @@
#include "executor/execdesc.h"
#include "nodes/parsenodes.h"
+#include "utils/lockwaitpolicy.h"
/*
@@ -199,7 +200,8 @@ extern TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate,
Relation relation, Index rti, int lockmode,
ItemPointer tid, TransactionId priorXmax);
extern HeapTuple EvalPlanQualFetch(EState *estate, Relation relation,
- int lockmode, bool noWait, ItemPointer tid, TransactionId priorXmax);
+ int lockmode, LockWaitPolicy wait_policy, ItemPointer tid,
+ TransactionId priorXmax);
extern void EvalPlanQualInit(EPQState *epqstate, EState *estate,
Plan *subplan, List *auxrowmarks, int epqParam);
extern void EvalPlanQualSetPlan(EPQState *epqstate,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index b271f213f59..39d2c10bdfe 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -429,7 +429,7 @@ typedef struct ExecRowMark
Index prti; /* parent range table index, if child */
Index rowmarkId; /* unique identifier for resjunk columns */
RowMarkType markType; /* see enum in nodes/plannodes.h */
- bool noWait; /* NOWAIT option */
+ LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */
ItemPointerData curCtid; /* ctid of currently locked tuple, if any */
} ExecRowMark;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index f3aa69e4a1b..cef95446984 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -23,6 +23,7 @@
#include "nodes/bitmapset.h"
#include "nodes/primnodes.h"
#include "nodes/value.h"
+#include "utils/lockwaitpolicy.h"
/* Possible sources of a Query */
typedef enum QuerySource
@@ -631,7 +632,7 @@ typedef struct LockingClause
NodeTag type;
List *lockedRels; /* FOR [KEY] UPDATE/SHARE relations */
LockClauseStrength strength;
- bool noWait; /* NOWAIT option */
+ LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */
} LockingClause;
/*
@@ -976,7 +977,7 @@ typedef struct RowMarkClause
NodeTag type;
Index rti; /* range table index of target relation */
LockClauseStrength strength;
- bool noWait; /* NOWAIT option */
+ LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED */
bool pushedDown; /* pushed down from higher query level? */
} RowMarkClause;
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 18394946f86..fb02390da51 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -17,6 +17,7 @@
#include "access/sdir.h"
#include "nodes/bitmapset.h"
#include "nodes/primnodes.h"
+#include "utils/lockwaitpolicy.h"
/* ----------------------------------------------------------------
@@ -834,7 +835,7 @@ typedef struct PlanRowMark
Index prti; /* range table index of parent relation */
Index rowmarkId; /* unique identifier for resjunk columns */
RowMarkType markType; /* see enum above */
- bool noWait; /* NOWAIT option */
+ LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED options */
bool isParent; /* true if this is a "dummy" parent entry */
} PlanRowMark;
diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h
index 370a445b7fc..f5da6bfecef 100644
--- a/src/include/parser/analyze.h
+++ b/src/include/parser/analyze.h
@@ -39,6 +39,7 @@ extern bool analyze_requires_snapshot(Node *parseTree);
extern char *LCS_asString(LockClauseStrength strength);
extern void CheckSelectLocking(Query *qry, LockClauseStrength strength);
extern void applyLockingClause(Query *qry, Index rtindex,
- LockClauseStrength strength, bool noWait, bool pushedDown);
+ LockClauseStrength strength,
+ LockWaitPolicy waitPolicy, bool pushedDown);
#endif /* ANALYZE_H */
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index 3c8c1b9e252..e14dc9a1395 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -230,6 +230,7 @@ PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD)
PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD)
PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD)
PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD)
+PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD)
PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD)
PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD)
PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD)
@@ -345,6 +346,7 @@ PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD)
PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD)
PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD)
PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD)
+PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD)
PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD)
PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD)
PG_KEYWORD("some", SOME, RESERVED_KEYWORD)
diff --git a/src/include/utils/lockwaitpolicy.h b/src/include/utils/lockwaitpolicy.h
new file mode 100644
index 00000000000..7ec9c26717d
--- /dev/null
+++ b/src/include/utils/lockwaitpolicy.h
@@ -0,0 +1,31 @@
+/*-------------------------------------------------------------------------
+ * lockwaitpolicy.h
+ * Header file for LockWaitPolicy enum.
+ *
+ * Copyright (c) 2014, PostgreSQL Global Development Group
+ *
+ * src/include/utils/lockwaitpolicy.h
+ *-------------------------------------------------------------------------
+ */
+#ifndef LOCKWAITPOLICY_H
+#define LOCKWAITPOLICY_H
+
+/*
+ * This enum controls how to deal with rows being locked by FOR UPDATE/SHARE
+ * clauses (i.e., NOWAIT and SKIP LOCKED clauses). The ordering here is
+ * important, because the highest numerical value takes precedence when a
+ * RTE is specified multiple ways. See applyLockingClause.
+ */
+typedef enum
+{
+ /* Wait for the lock to become available (default behavior) */
+ LockWaitBlock,
+
+ /* Skip rows that can't be locked (SKIP LOCKED) */
+ LockWaitSkip,
+
+ /* Raise an error if a row cannot be locked (NOWAIT) */
+ LockWaitError
+} LockWaitPolicy;
+
+#endif /* LOCKWAITPOLICY_H */
diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h
index d8e8b351ed2..53e474fbb29 100644
--- a/src/include/utils/snapshot.h
+++ b/src/include/utils/snapshot.h
@@ -104,7 +104,8 @@ typedef enum
HeapTupleInvisible,
HeapTupleSelfUpdated,
HeapTupleUpdated,
- HeapTupleBeingUpdated
+ HeapTupleBeingUpdated,
+ HeapTupleWouldBlock /* can be returned by heap_tuple_lock */
} HTSU_Result;
#endif /* SNAPSHOT_H */