mirror of
https://github.com/postgres/postgres.git
synced 2025-05-11 05:41:32 +03:00
Disallow LOCK TABLE outside a transaction block (or function), since this case
almost certainly represents user error. Per a gripe from Sebastian Böhm and subsequent discussion.
This commit is contained in:
parent
99e0996284
commit
31b15fe8dc
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/declare.sgml,v 1.42 2007/10/24 23:27:07 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/declare.sgml,v 1.43 2008/11/04 00:57:19 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -175,10 +175,9 @@ DECLARE <replaceable class="parameter">name</replaceable> [ BINARY ] [ INSENSITI
|
|||||||
<productname>PostgreSQL</productname> reports an error if such a
|
<productname>PostgreSQL</productname> reports an error if such a
|
||||||
command is used outside a transaction block.
|
command is used outside a transaction block.
|
||||||
Use
|
Use
|
||||||
<xref linkend="sql-begin" endterm="sql-begin-title">,
|
<xref linkend="sql-begin" endterm="sql-begin-title"> and
|
||||||
<xref linkend="sql-commit" endterm="sql-commit-title">
|
<xref linkend="sql-commit" endterm="sql-commit-title">
|
||||||
and
|
(or <xref linkend="sql-rollback" endterm="sql-rollback-title">)
|
||||||
<xref linkend="sql-rollback" endterm="sql-rollback-title">
|
|
||||||
to define a transaction block.
|
to define a transaction block.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.49 2008/09/08 00:47:40 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/lock.sgml,v 1.50 2008/11/04 00:57:19 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -160,12 +160,15 @@ where <replaceable class="PARAMETER">lockmode</replaceable> is one of:
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>LOCK TABLE</command> is useful only inside a transaction
|
<command>LOCK TABLE</> is useless outside a transaction block: the lock
|
||||||
block (<command>BEGIN</>/<command>COMMIT</> pair), since the lock
|
would remain held only to the completion of the statement. Therefore
|
||||||
is dropped as soon as the transaction ends. A <command>LOCK
|
<productname>PostgreSQL</productname> reports an error if <command>LOCK</>
|
||||||
TABLE</> command appearing outside any transaction block forms a
|
is used outside a transaction block.
|
||||||
self-contained transaction, so the lock will be dropped as soon as
|
Use
|
||||||
it is obtained.
|
<xref linkend="sql-begin" endterm="sql-begin-title"> and
|
||||||
|
<xref linkend="sql-commit" endterm="sql-commit-title">
|
||||||
|
(or <xref linkend="sql-rollback" endterm="sql-rollback-title">)
|
||||||
|
to define a transaction block.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
break;
|
||||||
|
|
||||||
case T_LockStmt:
|
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);
|
LockTableCommand((LockStmt *) parsetree);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -45,7 +45,9 @@ INSERT INTO atest1 VALUES (1, 'one');
|
|||||||
DELETE FROM atest1;
|
DELETE FROM atest1;
|
||||||
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
||||||
TRUNCATE atest1;
|
TRUNCATE atest1;
|
||||||
|
BEGIN;
|
||||||
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
||||||
|
COMMIT;
|
||||||
REVOKE ALL ON atest1 FROM PUBLIC;
|
REVOKE ALL ON atest1 FROM PUBLIC;
|
||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
a | b
|
a | b
|
||||||
@ -102,8 +104,10 @@ DELETE FROM atest2; -- fail
|
|||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
TRUNCATE atest2; -- fail
|
TRUNCATE atest2; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
BEGIN;
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
COMMIT;
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
@ -155,7 +159,9 @@ DELETE FROM atest2; -- fail
|
|||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
TRUNCATE atest2; -- fail
|
TRUNCATE atest2; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
|
BEGIN;
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
||||||
|
COMMIT;
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: permission denied for relation atest2
|
ERROR: permission denied for relation atest2
|
||||||
-- checks in subquery, both fail
|
-- checks in subquery, both fail
|
||||||
|
@ -48,7 +48,9 @@ INSERT INTO atest1 VALUES (1, 'one');
|
|||||||
DELETE FROM atest1;
|
DELETE FROM atest1;
|
||||||
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
UPDATE atest1 SET a = 1 WHERE b = 'blech';
|
||||||
TRUNCATE atest1;
|
TRUNCATE atest1;
|
||||||
|
BEGIN;
|
||||||
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
REVOKE ALL ON atest1 FROM PUBLIC;
|
REVOKE ALL ON atest1 FROM PUBLIC;
|
||||||
SELECT * FROM atest1;
|
SELECT * FROM atest1;
|
||||||
@ -80,7 +82,9 @@ SELECT * FROM atest1 FOR UPDATE; -- ok
|
|||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
TRUNCATE atest2; -- fail
|
TRUNCATE atest2; -- fail
|
||||||
|
BEGIN;
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
||||||
|
COMMIT;
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
|
|
||||||
@ -105,7 +109,9 @@ SELECT * FROM atest1 FOR UPDATE; -- fail
|
|||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
TRUNCATE atest2; -- fail
|
TRUNCATE atest2; -- fail
|
||||||
|
BEGIN;
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
||||||
|
COMMIT;
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
|
|
||||||
-- checks in subquery, both fail
|
-- checks in subquery, both fail
|
||||||
|
Loading…
x
Reference in New Issue
Block a user