mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-03 11:47:20 +02:00
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 7b504eb282
, 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
This commit is contained in:
parent
046c8facec
commit
f52db96944
@ -15,6 +15,7 @@
|
|||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/relscan.h"
|
#include "access/relscan.h"
|
||||||
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
@ -124,6 +125,13 @@ CreateStatistics(CreateStatsStmt *stmt)
|
|||||||
if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
|
if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner))
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind),
|
aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind),
|
||||||
RelationGetRelationName(rel));
|
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);
|
Assert(rel);
|
||||||
|
@ -6,6 +6,7 @@ SET max_parallel_workers = 0;
|
|||||||
SET max_parallel_workers_per_gather = 0;
|
SET max_parallel_workers_per_gather = 0;
|
||||||
SET work_mem = '128kB';
|
SET work_mem = '128kB';
|
||||||
-- Verify failures
|
-- Verify failures
|
||||||
|
CREATE TABLE ext_stats_test (x int, y int, z int);
|
||||||
CREATE STATISTICS tst;
|
CREATE STATISTICS tst;
|
||||||
ERROR: syntax error at or near ";"
|
ERROR: syntax error at or near ";"
|
||||||
LINE 1: CREATE STATISTICS tst;
|
LINE 1: CREATE STATISTICS tst;
|
||||||
@ -20,16 +21,17 @@ LINE 1: CREATE STATISTICS tst FROM sometab;
|
|||||||
^
|
^
|
||||||
CREATE STATISTICS tst ON a, b FROM nonexistant;
|
CREATE STATISTICS tst ON a, b FROM nonexistant;
|
||||||
ERROR: relation "nonexistant" does not exist
|
ERROR: relation "nonexistant" 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
|
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
|
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
|
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
|
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"
|
ERROR: unrecognized statistics kind "unrecognized"
|
||||||
|
DROP TABLE ext_stats_test;
|
||||||
-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
|
-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
|
||||||
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
|
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
|
||||||
CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;
|
CREATE STATISTICS IF NOT EXISTS ab1_a_b_stats ON a, b FROM ab1;
|
||||||
|
@ -8,15 +8,17 @@ SET max_parallel_workers_per_gather = 0;
|
|||||||
SET work_mem = '128kB';
|
SET work_mem = '128kB';
|
||||||
|
|
||||||
-- Verify failures
|
-- Verify failures
|
||||||
|
CREATE TABLE ext_stats_test (x int, y int, z int);
|
||||||
CREATE STATISTICS tst;
|
CREATE STATISTICS tst;
|
||||||
CREATE STATISTICS tst ON a, b;
|
CREATE STATISTICS tst ON a, b;
|
||||||
CREATE STATISTICS tst FROM sometab;
|
CREATE STATISTICS tst FROM sometab;
|
||||||
CREATE STATISTICS tst ON a, b FROM nonexistant;
|
CREATE STATISTICS tst ON a, b FROM nonexistant;
|
||||||
CREATE STATISTICS tst ON a, b FROM pg_class;
|
CREATE STATISTICS tst ON a, b FROM ext_stats_test;
|
||||||
CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class;
|
CREATE STATISTICS tst ON x, x, y FROM ext_stats_test;
|
||||||
CREATE STATISTICS tst ON relnatts + relpages FROM pg_class;
|
CREATE STATISTICS tst ON x + y FROM ext_stats_test;
|
||||||
CREATE STATISTICS tst ON (relpages, reltuples) FROM pg_class;
|
CREATE STATISTICS tst ON (x, y) FROM ext_stats_test;
|
||||||
CREATE STATISTICS tst (unrecognized) ON relname, relnatts FROM pg_class;
|
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
|
-- Ensure stats are dropped sanely, and test IF NOT EXISTS while at it
|
||||||
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
|
CREATE TABLE ab1 (a INTEGER, b INTEGER, c INTEGER);
|
||||||
|
Loading…
Reference in New Issue
Block a user