diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index b946eab3039..7f40177129c 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation LOCK - lock a table + lock a named relation (table, etc) @@ -34,7 +34,9 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] Description - LOCK TABLE obtains a table-level lock, waiting + LOCK TABLE obtains a table-level lock on a + relation (table, partitioned table, foreign table, view, + materialized view, index, composite type, sequence), waiting if necessary for any conflicting locks to be released. If NOWAIT is specified, LOCK TABLE does not wait to acquire the desired lock: if it @@ -110,17 +112,18 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] name - The name (optionally schema-qualified) of an existing table to - lock. If ONLY is specified before the table name, only that - table is locked. If ONLY is not specified, the table and all - its descendant tables (if any) are locked. Optionally, * + The name (optionally schema-qualified) of an existing relation to + lock. If ONLY is specified before a table name, only that + table is locked. If ONLY is not specified, the table and all + its descendant tables (if any) are locked. Optionally, * can be specified after the table name to explicitly indicate that - descendant tables are included. + descendant tables are included. When locking a view, all relations appearing + in the view definition are locked, regardless of ONLY. - The command LOCK TABLE a, b; is equivalent to - LOCK TABLE a; LOCK TABLE b;. The tables are locked + The command LOCK TABLE a, b; is equivalent to + LOCK TABLE a; LOCK TABLE b;. The relations are locked one-by-one in the order specified in the LOCK TABLE command. diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index bb7d9e8239e..d48a15984f3 100644 --- a/src/backend/commands/lockcmds.c +++ b/src/backend/commands/lockcmds.c @@ -88,13 +88,6 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid, return; /* woops, concurrently dropped; no permissions * check */ - /* Currently, we only allow plain tables to be locked */ - if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table", - rv->relname))); - /* * Make note if a temporary relation has been accessed in this * transaction. diff --git a/src/test/regress/expected/lock.out b/src/test/regress/expected/lock.out index fd273445030..fec1c379833 100644 --- a/src/test/regress/expected/lock.out +++ b/src/test/regress/expected/lock.out @@ -5,7 +5,10 @@ CREATE SCHEMA lock_schema1; SET search_path = lock_schema1; CREATE TABLE lock_tbl1 (a BIGINT); -CREATE VIEW lock_view1 AS SELECT 1; +CREATE VIEW lock_view1 AS SELECT 1 AS a; +CREATE MATERIALIZED VIEW lock_mv1 AS SELECT * FROM lock_view1; +CREATE INDEX lock_mvi1 ON lock_mv1 (a); +CREATE SEQUENCE lock_seq; CREATE ROLE regress_rol_lock1; ALTER ROLE regress_rol_lock1 SET search_path = lock_schema1; GRANT USAGE ON SCHEMA lock_schema1 TO regress_rol_lock1; @@ -30,8 +33,7 @@ LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT; LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT; LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT; LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE NOWAIT; -LOCK TABLE lock_view1 IN EXCLUSIVE MODE; -- Will fail; can't lock a non-table -ERROR: "lock_view1" is not a table +LOCK TABLE lock_view1 IN EXCLUSIVE MODE; ROLLBACK; -- Verify that we can lock a table with inheritance children. CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1); @@ -51,13 +53,21 @@ BEGIN; LOCK TABLE ONLY lock_tbl1; ROLLBACK; RESET ROLE; +-- Lock other relations +BEGIN TRANSACTION; +LOCK TABLE lock_mv1; +LOCK TABLE lock_mvi1; +LOCK TABLE lock_seq; +ROLLBACK; -- -- Clean up -- +DROP MATERIALIZED VIEW lock_mv1; DROP VIEW lock_view1; DROP TABLE lock_tbl3; DROP TABLE lock_tbl2; DROP TABLE lock_tbl1; +DROP SEQUENCE lock_seq; DROP SCHEMA lock_schema1 CASCADE; DROP ROLE regress_rol_lock1; -- atomic ops tests diff --git a/src/test/regress/sql/lock.sql b/src/test/regress/sql/lock.sql index 567e8bccf1b..81af5d08fc8 100644 --- a/src/test/regress/sql/lock.sql +++ b/src/test/regress/sql/lock.sql @@ -6,7 +6,10 @@ CREATE SCHEMA lock_schema1; SET search_path = lock_schema1; CREATE TABLE lock_tbl1 (a BIGINT); -CREATE VIEW lock_view1 AS SELECT 1; +CREATE VIEW lock_view1 AS SELECT 1 AS a; +CREATE MATERIALIZED VIEW lock_mv1 AS SELECT * FROM lock_view1; +CREATE INDEX lock_mvi1 ON lock_mv1 (a); +CREATE SEQUENCE lock_seq; CREATE ROLE regress_rol_lock1; ALTER ROLE regress_rol_lock1 SET search_path = lock_schema1; GRANT USAGE ON SCHEMA lock_schema1 TO regress_rol_lock1; @@ -33,7 +36,7 @@ LOCK TABLE lock_tbl1 IN SHARE MODE NOWAIT; LOCK TABLE lock_tbl1 IN SHARE ROW EXCLUSIVE MODE NOWAIT; LOCK TABLE lock_tbl1 IN EXCLUSIVE MODE NOWAIT; LOCK TABLE lock_tbl1 IN ACCESS EXCLUSIVE MODE NOWAIT; -LOCK TABLE lock_view1 IN EXCLUSIVE MODE; -- Will fail; can't lock a non-table +LOCK TABLE lock_view1 IN EXCLUSIVE MODE; ROLLBACK; -- Verify that we can lock a table with inheritance children. @@ -55,13 +58,23 @@ LOCK TABLE ONLY lock_tbl1; ROLLBACK; RESET ROLE; +-- Lock other relations +BEGIN TRANSACTION; +LOCK TABLE lock_mv1; +LOCK TABLE lock_mvi1; +LOCK TABLE lock_seq; +ROLLBACK; + + -- -- Clean up -- +DROP MATERIALIZED VIEW lock_mv1; DROP VIEW lock_view1; DROP TABLE lock_tbl3; DROP TABLE lock_tbl2; DROP TABLE lock_tbl1; +DROP SEQUENCE lock_seq; DROP SCHEMA lock_schema1 CASCADE; DROP ROLE regress_rol_lock1;