]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Disallow CREATE STATISTICS on system catalogs
authorTomas Vondra <tomas.vondra@postgresql.org>
Fri, 15 Jan 2021 22:24:19 +0000 (23:24 +0100)
committerTomas Vondra <tomas.vondra@postgresql.org>
Fri, 15 Jan 2021 22:33:16 +0000 (23:33 +0100)
Add a check that CREATE STATISTICS does not add extended statistics on
system catalogs, similarly to indexes etc.  It can be overriden using
the allow_system_table_mods GUC.

This bug exists since 7b504eb282c, adding the extended statistics, so
backpatch all the way back to PostgreSQL 10.

Author: Tomas Vondra
Reported-by: Dean Rasheed
Backpatch-through: 10
Discussion: https://postgr.es/m/CAEZATCXAPrrOKwEsyZKQ4uzzJQWBCt6QAvOcgqRGdWwT1zb%2BrQ%40mail.gmail.com

src/backend/commands/statscmds.c
src/test/regress/expected/stats_ext.out
src/test/regress/sql/stats_ext.sql

index 34d11c2a9802675ae8df6bfabe0a51e80e813f38..5678d31d0b6dca4020d010ab1d060feb5c17332f 100644 (file)
@@ -132,6 +132,13 @@ CreateStatistics(CreateStatsStmt *stmt)
                if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
                        aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind),
                                                   RelationGetRelationName(rel));
+
+               /* Creating statistics on system catalogs is not allowed */
+               if (!allowSystemTableMods && IsSystemRelation(rel))
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                        errmsg("permission denied: \"%s\" is a system catalog",
+                                                       RelationGetRelationName(rel))));
        }
 
        Assert(rel);
index cd4b60314cc99373aee162ca53e80bd0e99a16ef..f2a1863c7b180368fbc52320e604afa28d0f7f57 100644 (file)
@@ -23,6 +23,7 @@ begin
 end;
 $$;
 -- Verify failures
+CREATE TABLE ext_stats_test (x int, y int, z int);
 CREATE STATISTICS tst;
 ERROR:  syntax error at or near ";"
 LINE 1: CREATE STATISTICS tst;
@@ -37,16 +38,17 @@ LINE 1: CREATE STATISTICS tst FROM sometab;
                               ^
 CREATE STATISTICS tst ON a, b FROM nonexistent;
 ERROR:  relation "nonexistent" does not exist
-CREATE STATISTICS tst ON a, b FROM pg_class;
+CREATE STATISTICS tst ON a, b FROM ext_stats_test;
 ERROR:  column "a" does not exist
-CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class;
+CREATE STATISTICS tst ON x, x, y FROM ext_stats_test;
 ERROR:  duplicate column name in statistics definition
-CREATE STATISTICS tst ON relnatts + relpages FROM pg_class;
+CREATE STATISTICS tst ON x + y FROM ext_stats_test;
 ERROR:  only simple column references are allowed in CREATE STATISTICS
-CREATE STATISTICS tst ON (relpages, reltuples) FROM pg_class;
+CREATE STATISTICS tst ON (x, y) FROM ext_stats_test;
 ERROR:  only simple column references are allowed in CREATE STATISTICS
-CREATE STATISTICS tst (unrecognized) ON relname, relnatts FROM pg_class;
+CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test;
 ERROR:  unrecognized statistics kind "unrecognized"
+DROP TABLE ext_stats_test;
 -- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
 CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
 CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;
index 992959cb6a36d626cbe573cdcad38c7e80d8b16c..85dcf8be0999c6f159284e5c8aaef3e4ce9802eb 100644 (file)
@@ -26,15 +26,17 @@ end;
 $$;
 
 -- Verify failures
+CREATE TABLE ext_stats_test (x int, y int, z int);
 CREATE STATISTICS tst;
 CREATE STATISTICS tst ON a, b;
 CREATE STATISTICS tst FROM sometab;
 CREATE STATISTICS tst ON a, b FROM nonexistent;
-CREATE STATISTICS tst ON a, b FROM pg_class;
-CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class;
-CREATE STATISTICS tst ON relnatts + relpages FROM pg_class;
-CREATE STATISTICS tst ON (relpages, reltuples) FROM pg_class;
-CREATE STATISTICS tst (unrecognized) ON relname, relnatts FROM pg_class;
+CREATE STATISTICS tst ON a, b FROM ext_stats_test;
+CREATE STATISTICS tst ON x, x, y FROM ext_stats_test;
+CREATE STATISTICS tst ON x + y FROM ext_stats_test;
+CREATE STATISTICS tst ON (x, y) FROM ext_stats_test;
+CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test;
+DROP TABLE ext_stats_test;
 
 -- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
 CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);