diff --git a/doc/src/sgml/ref/declare.sgml b/doc/src/sgml/ref/declare.sgml
index 269d2c101c4..744cda77726 100644
--- a/doc/src/sgml/ref/declare.sgml
+++ b/doc/src/sgml/ref/declare.sgml
@@ -1,5 +1,5 @@
@@ -175,10 +175,9 @@ DECLARE name [ BINARY ] [ INSENSITI
PostgreSQL reports an error if such a
command is used outside a transaction block.
Use
- ,
+ and
- and
-
+ (or )
to define a transaction block.
diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
index d32e6d364c8..701c2a19a48 100644
--- a/doc/src/sgml/ref/lock.sgml
+++ b/doc/src/sgml/ref/lock.sgml
@@ -1,5 +1,5 @@
@@ -160,12 +160,15 @@ where lockmode is one of:
- LOCK TABLE is useful only inside a transaction
- block (BEGIN>/COMMIT> pair), since the lock
- is dropped as soon as the transaction ends. A LOCK
- TABLE> command appearing outside any transaction block forms a
- self-contained transaction, so the lock will be dropped as soon as
- it is obtained.
+ LOCK TABLE> is useless outside a transaction block: the lock
+ would remain held only to the completion of the statement. Therefore
+ PostgreSQL reports an error if LOCK>
+ is used outside a transaction block.
+ Use
+ and
+
+ (or )
+ to define a transaction block.
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index b1a0fe28ca5..1218e7cb9b8 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.299 2008/10/10 13:48:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.300 2008/11/04 00:57:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -938,6 +938,11 @@ ProcessUtility(Node *parsetree,
break;
case T_LockStmt:
+ /*
+ * Since the lock would just get dropped immediately, LOCK TABLE
+ * outside a transaction block is presumed to be user error.
+ */
+ RequireTransactionChain(isTopLevel, "LOCK TABLE");
LockTableCommand((LockStmt *) parsetree);
break;
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 21f9fc26fd9..d1767e95ad4 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -45,7 +45,9 @@ INSERT INTO atest1 VALUES (1, 'one');
DELETE FROM atest1;
UPDATE atest1 SET a = 1 WHERE b = 'blech';
TRUNCATE atest1;
+BEGIN;
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
+COMMIT;
REVOKE ALL ON atest1 FROM PUBLIC;
SELECT * FROM atest1;
a | b
@@ -102,8 +104,10 @@ DELETE FROM atest2; -- fail
ERROR: permission denied for relation atest2
TRUNCATE atest2; -- fail
ERROR: permission denied for relation atest2
+BEGIN;
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
ERROR: permission denied for relation atest2
+COMMIT;
COPY atest2 FROM stdin; -- fail
ERROR: permission denied for relation atest2
GRANT ALL ON atest1 TO PUBLIC; -- fail
@@ -155,7 +159,9 @@ DELETE FROM atest2; -- fail
ERROR: permission denied for relation atest2
TRUNCATE atest2; -- fail
ERROR: permission denied for relation atest2
+BEGIN;
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
+COMMIT;
COPY atest2 FROM stdin; -- fail
ERROR: permission denied for relation atest2
-- checks in subquery, both fail
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 450d5d9d68d..63532f7e095 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -48,7 +48,9 @@ INSERT INTO atest1 VALUES (1, 'one');
DELETE FROM atest1;
UPDATE atest1 SET a = 1 WHERE b = 'blech';
TRUNCATE atest1;
+BEGIN;
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
+COMMIT;
REVOKE ALL ON atest1 FROM PUBLIC;
SELECT * FROM atest1;
@@ -80,7 +82,9 @@ SELECT * FROM atest1 FOR UPDATE; -- ok
SELECT * FROM atest2 FOR UPDATE; -- fail
DELETE FROM atest2; -- fail
TRUNCATE atest2; -- fail
+BEGIN;
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
+COMMIT;
COPY atest2 FROM stdin; -- fail
GRANT ALL ON atest1 TO PUBLIC; -- fail
@@ -105,7 +109,9 @@ SELECT * FROM atest1 FOR UPDATE; -- fail
SELECT * FROM atest2 FOR UPDATE; -- fail
DELETE FROM atest2; -- fail
TRUNCATE atest2; -- fail
+BEGIN;
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
+COMMIT;
COPY atest2 FROM stdin; -- fail
-- checks in subquery, both fail