Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/backend/commands/statscmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ compare_int16(const void *a, const void *b)
* CREATE STATISTICS
*/
ObjectAddress
CreateStatistics(CreateStatsStmt *stmt)
CreateStatistics(CreateStatsStmt *stmt, bool check_rights)
{
int16 attnums[STATS_MAX_DIMENSIONS];
int nattnums = 0;
Expand Down Expand Up @@ -179,6 +179,20 @@ CreateStatistics(CreateStatsStmt *stmt)
}
namestrcpy(&stxname, namestr);

/*
* Check we have creation rights in target namespace. Skip check if
* caller doesn't want it.
*/
if (check_rights)
{
AclResult aclresult;

aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_SCHEMA,
get_namespace_name(namespaceId));
}

/*
* Deal with the possibility that the statistics object already exists.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/backend/commands/tablecmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -10599,7 +10599,7 @@ ATExecAddStatistics(AlteredTableInfo *tab, Relation rel,
Assert(stmt->transformed);

HOLD_DISPATCH();
address = CreateStatistics(stmt);
address = CreateStatistics(stmt, !is_rebuild);
RESUME_DISPATCH();

return address;
Expand Down
2 changes: 1 addition & 1 deletion src/backend/tcop/utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -2517,7 +2517,7 @@ ProcessUtilitySlow(ParseState *pstate,
/* Run parse analysis ... */
stmt = transformStatsStmt(relid, stmt, queryString);

address = CreateStatistics(stmt);
address = CreateStatistics(stmt, true);
}
break;

Expand Down
2 changes: 1 addition & 1 deletion src/include/commands/defrem.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ extern void RemoveOperatorById(Oid operOid);
extern ObjectAddress AlterOperator(AlterOperatorStmt *stmt);

/* commands/statscmds.c */
extern ObjectAddress CreateStatistics(CreateStatsStmt *stmt);
extern ObjectAddress CreateStatistics(CreateStatsStmt *stmt, bool check_rights);
extern ObjectAddress AlterStatistics(AlterStatsStmt *stmt);
extern void RemoveStatisticsById(Oid statsOid);
extern Oid StatisticsGetRelation(Oid statId, bool missing_ok);
Expand Down
19 changes: 19 additions & 0 deletions src/test/regress/expected/stats_ext.out
Original file line number Diff line number Diff line change
Expand Up @@ -3277,6 +3277,23 @@ SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x
s_expr | {1}
(2 rows)

-- CREATE STATISTICS checks for CREATE on the schema
RESET SESSION AUTHORIZATION;
CREATE SCHEMA sts_sch1 CREATE TABLE sts_sch1.tbl (a INT, b INT);
GRANT USAGE ON SCHEMA sts_sch1 TO regress_stats_user1;
ALTER TABLE sts_sch1.tbl OWNER TO regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
CREATE STATISTICS sts_sch1.fail ON a, b FROM sts_sch1.tbl;
ERROR: permission denied for schema sts_sch1
RESET SESSION AUTHORIZATION;
GRANT CREATE ON SCHEMA sts_sch1 TO regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
CREATE STATISTICS sts_sch1.pass ON a, b FROM sts_sch1.tbl;
-- re-creating statistics via ALTER TABLE bypasses checks for CREATE on schema
RESET SESSION AUTHORIZATION;
REVOKE CREATE ON SCHEMA sts_sch1 FROM regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
ALTER TABLE sts_sch1.tbl ALTER COLUMN a TYPE SMALLINT;
-- Tidy up
DROP OPERATOR <<< (int, int);
DROP FUNCTION op_leak(int, int);
Expand All @@ -3286,6 +3303,8 @@ DROP SCHEMA tststats CASCADE;
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table tststats.priv_test_tbl
drop cascades to view tststats.priv_test_view
DROP SCHEMA sts_sch1 CASCADE;
NOTICE: drop cascades to table sts_sch1.tbl
DROP USER regress_stats_user1;
-- test analyze with extended statistics
CREATE TABLE tbl_issue1293 (col1 int, col2 int);
Expand Down
19 changes: 19 additions & 0 deletions src/test/regress/sql/stats_ext.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1675,12 +1675,31 @@ SELECT statistics_name, most_common_vals FROM pg_stats_ext x
SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x
WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*);

-- CREATE STATISTICS checks for CREATE on the schema
RESET SESSION AUTHORIZATION;
CREATE SCHEMA sts_sch1 CREATE TABLE sts_sch1.tbl (a INT, b INT);
GRANT USAGE ON SCHEMA sts_sch1 TO regress_stats_user1;
ALTER TABLE sts_sch1.tbl OWNER TO regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
CREATE STATISTICS sts_sch1.fail ON a, b FROM sts_sch1.tbl;
RESET SESSION AUTHORIZATION;
GRANT CREATE ON SCHEMA sts_sch1 TO regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
CREATE STATISTICS sts_sch1.pass ON a, b FROM sts_sch1.tbl;

-- re-creating statistics via ALTER TABLE bypasses checks for CREATE on schema
RESET SESSION AUTHORIZATION;
REVOKE CREATE ON SCHEMA sts_sch1 FROM regress_stats_user1;
SET SESSION AUTHORIZATION regress_stats_user1;
ALTER TABLE sts_sch1.tbl ALTER COLUMN a TYPE SMALLINT;

-- Tidy up
DROP OPERATOR <<< (int, int);
DROP FUNCTION op_leak(int, int);
RESET SESSION AUTHORIZATION;
DROP TABLE stats_ext_tbl;
DROP SCHEMA tststats CASCADE;
DROP SCHEMA sts_sch1 CASCADE;
DROP USER regress_stats_user1;

-- test analyze with extended statistics
Expand Down
Loading