Skip to content

Commit f52db96

Browse files
committed
Disallow CREATE STATISTICS on system catalogs
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 7b504eb, 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
1 parent 046c8fa commit f52db96

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

src/backend/commands/statscmds.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "postgres.h"
1616

1717
#include "access/relscan.h"
18+
#include "catalog/catalog.h"
1819
#include "catalog/dependency.h"
1920
#include "catalog/indexing.h"
2021
#include "catalog/namespace.h"
@@ -124,6 +125,13 @@ CreateStatistics(CreateStatsStmt *stmt)
124125
if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
125126
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind),
126127
RelationGetRelationName(rel));
128+
129+
/* Creating statistics on system catalogs is not allowed */
130+
if (!allowSystemTableMods && IsSystemRelation(rel))
131+
ereport(ERROR,
132+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
133+
errmsg("permission denied: \"%s\" is a system catalog",
134+
RelationGetRelationName(rel))));
127135
}
128136

129137
Assert(rel);

src/test/regress/expected/stats_ext.out

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SET max_parallel_workers = 0;
66
SET max_parallel_workers_per_gather = 0;
77
SET work_mem = '128kB';
88
-- Verify failures
9+
CREATE TABLE ext_stats_test (x int, y int, z int);
910
CREATE STATISTICS tst;
1011
ERROR: syntax error at or near ";"
1112
LINE 1: CREATE STATISTICS tst;
@@ -20,16 +21,17 @@ LINE 1: CREATE STATISTICS tst FROM sometab;
2021
^
2122
CREATE STATISTICS tst ON a, b FROM nonexistant;
2223
ERROR: relation "nonexistant" does not exist
23-
CREATE STATISTICS tst ON a, b FROM pg_class;
24+
CREATE STATISTICS tst ON a, b FROM ext_stats_test;
2425
ERROR: column "a" does not exist
25-
CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class;
26+
CREATE STATISTICS tst ON x, x, y FROM ext_stats_test;
2627
ERROR: duplicate column name in statistics definition
27-
CREATE STATISTICS tst ON relnatts + relpages FROM pg_class;
28+
CREATE STATISTICS tst ON x + y FROM ext_stats_test;
2829
ERROR: only simple column references are allowed in CREATE STATISTICS
29-
CREATE STATISTICS tst ON (relpages, reltuples) FROM pg_class;
30+
CREATE STATISTICS tst ON (x, y) FROM ext_stats_test;
3031
ERROR: only simple column references are allowed in CREATE STATISTICS
31-
CREATE STATISTICS tst (unrecognized) ON relname, relnatts FROM pg_class;
32+
CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test;
3233
ERROR: unrecognized statistics kind "unrecognized"
34+
DROP TABLE ext_stats_test;
3335
-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
3436
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
3537
CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;

src/test/regress/sql/stats_ext.sql

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ SET max_parallel_workers_per_gather = 0;
88
SET work_mem = '128kB';
99

1010
-- Verify failures
11+
CREATE TABLE ext_stats_test (x int, y int, z int);
1112
CREATE STATISTICS tst;
1213
CREATE STATISTICS tst ON a, b;
1314
CREATE STATISTICS tst FROM sometab;
1415
CREATE STATISTICS tst ON a, b FROM nonexistant;
15-
CREATE STATISTICS tst ON a, b FROM pg_class;
16-
CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class;
17-
CREATE STATISTICS tst ON relnatts + relpages FROM pg_class;
18-
CREATE STATISTICS tst ON (relpages, reltuples) FROM pg_class;
19-
CREATE STATISTICS tst (unrecognized) ON relname, relnatts FROM pg_class;
16+
CREATE STATISTICS tst ON a, b FROM ext_stats_test;
17+
CREATE STATISTICS tst ON x, x, y FROM ext_stats_test;
18+
CREATE STATISTICS tst ON x + y FROM ext_stats_test;
19+
CREATE STATISTICS tst ON (x, y) FROM ext_stats_test;
20+
CREATE STATISTICS tst (unrecognized) ON x, y FROM ext_stats_test;
21+
DROP TABLE ext_stats_test;
2022

2123
-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
2224
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);

0 commit comments

Comments
 (0)