From: Japin Li Date: Thu, 4 Aug 2022 22:46:17 +0800 Subject: [PATCH v1 1/1] Fix unrecognized node type about statistics on expressions Commit a4d75c86bf supported extended statistics on expressions, however it checks the column privilege pass a wrong pointer to pull_varattnos(). There has another bug when checking the attribute privilege, since the bitmap contains the offset by FirstLowInvalidHeapAttributeNumber. --- src/backend/statistics/extended_stats.c | 7 +++++-- src/test/regress/expected/stats_ext.out | 9 +++++++++ src/test/regress/sql/stats_ext.sql | 10 ++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index d2aa8d0ca3..a6a312d3de 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -1619,7 +1619,7 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, /* Don't have table privilege, must check individual columns */ if (*exprs != NIL) { - pull_varattnos((Node *) exprs, relid, &clause_attnums); + pull_varattnos((Node *) *exprs, relid, &clause_attnums); clause_attnums = bms_add_members(clause_attnums, *attnums); } else @@ -1639,7 +1639,10 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, while ((attnum = bms_next_member(clause_attnums, attnum)) >= 0) { - if (pg_attribute_aclcheck(rte->relid, attnum, userid, + /* bit #s are offset by FirstLowInvalidHeapAttributeNumber */ + AttrNumber attno = attnum + FirstLowInvalidHeapAttributeNumber; + + if (pg_attribute_aclcheck(rte->relid, attno, userid, ACL_SELECT) != ACLCHECK_OK) return false; } diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out index 8f5fd546eb..5f9040ae48 100644 --- a/src/test/regress/expected/stats_ext.out +++ b/src/test/regress/expected/stats_ext.out @@ -3251,6 +3251,15 @@ DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak -- Tidy up DROP OPERATOR <<< (int, int); DROP FUNCTION op_leak(int, int); +-- Test for bug 17570. +RESET SESSION AUTHORIZATION; +CREATE TABLE priv_test_tbl1(a INT, b VARCHAR); +INSERT INTO priv_test_tbl1(a, b) SELECT i, i FROM generate_series(1,100) s(i); +CREATE STATISTICS priv_test_tbl1_stats (mcv) ON (a), (b) FROM priv_test_tbl1; +CREATE ROLE priv_test_user1; +SET SESSION AUTHORIZATION priv_test_user1; +SELECT * FROM priv_test_tbl1 WHERE a = 1 AND b = '1'; +ERROR: permission denied for table priv_test_tbl1 RESET SESSION AUTHORIZATION; DROP SCHEMA tststats CASCADE; NOTICE: drop cascades to 2 other objects diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql index 5fd865f509..8a65229c05 100644 --- a/src/test/regress/sql/stats_ext.sql +++ b/src/test/regress/sql/stats_ext.sql @@ -1642,6 +1642,16 @@ DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak -- Tidy up DROP OPERATOR <<< (int, int); DROP FUNCTION op_leak(int, int); + +-- Test for bug 17570. +RESET SESSION AUTHORIZATION; +CREATE TABLE priv_test_tbl1(a INT, b VARCHAR); +INSERT INTO priv_test_tbl1(a, b) SELECT i, i FROM generate_series(1,100) s(i); +CREATE STATISTICS priv_test_tbl1_stats (mcv) ON (a), (b) FROM priv_test_tbl1; +CREATE ROLE priv_test_user1; +SET SESSION AUTHORIZATION priv_test_user1; +SELECT * FROM priv_test_tbl1 WHERE a = 1 AND b = '1'; + RESET SESSION AUTHORIZATION; DROP SCHEMA tststats CASCADE; DROP USER regress_stats_user1; -- 2.17.1 --=-=-=--