Add test for MAINTAIN permission with pg_restore_extended_stats()

Like its cousin functions for the restore of relation and attribute
stats, pg_restore_extended_stats() needs to be run by a user that is the
database owner or has MAINTAIN privileges on the table whose stats are
restored.  This commit adds a regression test ensuring that MAINTAIN is
required when calling the function.  This test also checks that a
ShareUpdateExclusive lock is taken on the table whose stats are
restored.

This has been split from the commit that has introduced
pg_restore_extended_stats(), for clarity.

Author: Corey Huinker <corey.huinker@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/CADkLM=dpz3KFnqP-dgJ-zvRvtjsa8UZv8wDAQdqho=qN3kX0Zg@mail.gmail.com
pull/270/head
Michael Paquier 1 week ago
parent 114e84c532
commit d9abd9e105
  1. 42
      src/test/regress/expected/stats_import.out
  2. 32
      src/test/regress/sql/stats_import.sql

@ -1685,6 +1685,48 @@ WARNING: could not restore extended statistics object "stats_import"."test_stat
f
(1 row)
-- Check that MAINTAIN is required when restoring statistics.
CREATE ROLE regress_test_extstat_restore;
GRANT ALL ON SCHEMA stats_import TO regress_test_extstat_restore;
SET ROLE regress_test_extstat_restore;
-- No data to restore; this fails on a permission failure.
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',
'relname', 'test_clone',
'statistics_schemaname', 'stats_import',
'statistics_name', 'test_stat_clone',
'inherited', false);
ERROR: permission denied for table test_clone
RESET ROLE;
GRANT MAINTAIN ON stats_import.test_clone TO regress_test_extstat_restore;
SET ROLE regress_test_extstat_restore;
-- This works, check the lock on the relation while on it.
BEGIN;
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',
'relname', 'test_clone',
'statistics_schemaname', 'stats_import',
'statistics_name', 'test_stat_clone',
'inherited', false,
'n_distinct', '[{"attributes" : [2,3], "ndistinct" : 4}]'::pg_ndistinct);
pg_restore_extended_stats
---------------------------
t
(1 row)
SELECT mode FROM pg_locks WHERE locktype = 'relation' AND
relation = 'stats_import.test_clone'::regclass AND
pid = pg_backend_pid();
mode
--------------------------
ShareUpdateExclusiveLock
(1 row)
COMMIT;
RESET ROLE;
REVOKE MAINTAIN ON stats_import.test_clone FROM regress_test_extstat_restore;
REVOKE ALL ON SCHEMA stats_import FROM regress_test_extstat_restore;
DROP ROLE regress_test_extstat_restore;
-- ndistinct value doesn't match object definition
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',

@ -1210,6 +1210,38 @@ SELECT pg_catalog.pg_restore_extended_stats(
'statistics_name', 'test_stat_clone',
'inherited', false);
-- Check that MAINTAIN is required when restoring statistics.
CREATE ROLE regress_test_extstat_restore;
GRANT ALL ON SCHEMA stats_import TO regress_test_extstat_restore;
SET ROLE regress_test_extstat_restore;
-- No data to restore; this fails on a permission failure.
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',
'relname', 'test_clone',
'statistics_schemaname', 'stats_import',
'statistics_name', 'test_stat_clone',
'inherited', false);
RESET ROLE;
GRANT MAINTAIN ON stats_import.test_clone TO regress_test_extstat_restore;
SET ROLE regress_test_extstat_restore;
-- This works, check the lock on the relation while on it.
BEGIN;
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',
'relname', 'test_clone',
'statistics_schemaname', 'stats_import',
'statistics_name', 'test_stat_clone',
'inherited', false,
'n_distinct', '[{"attributes" : [2,3], "ndistinct" : 4}]'::pg_ndistinct);
SELECT mode FROM pg_locks WHERE locktype = 'relation' AND
relation = 'stats_import.test_clone'::regclass AND
pid = pg_backend_pid();
COMMIT;
RESET ROLE;
REVOKE MAINTAIN ON stats_import.test_clone FROM regress_test_extstat_restore;
REVOKE ALL ON SCHEMA stats_import FROM regress_test_extstat_restore;
DROP ROLE regress_test_extstat_restore;
-- ndistinct value doesn't match object definition
SELECT pg_catalog.pg_restore_extended_stats(
'schemaname', 'stats_import',

Loading…
Cancel
Save