On Sun, Mar 09, 2025 at 03:01:41AM +0530, Ayush Vatsa wrote:
> Maybe we can move ahead with the patch if we can see no other concerns.

I think we should allow some time in case others want to review the patch.
I do see a concern upthread about increased deadlock risk [0], but your
patch doesn't lock the table, but unless I'm wrong [1] (which is always
possible), it doesn't need to lock it.

Anyway, here is a tidied up patch.

[0] https://postgr.es/m/1246906.1739896202%40sss.pgh.pa.us
[1] https://postgr.es/m/Z8yxsm9ZWVkHlPbV%40nathan

-- 
nathan
>From 326b4bfbb67485f40d77eaf97ea78bfef49b02f3 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nat...@postgresql.org>
Date: Sat, 8 Mar 2025 15:45:32 -0600
Subject: [PATCH v2 1/1] pg_prewarm: For indexes, check privileges on table.

Author: Ayush Vatsa <ayushvatsa1...@gmail.com>
Discussion: 
https://postgr.es/m/CACX%2BKaMz2ZoOojh0nQ6QNBYx8Ak1Dkoko%3DD4FSb80BYW%2Bo8CHQ%40mail.gmail.com
Backpatch-through: 13
---
 contrib/pg_prewarm/pg_prewarm.c   | 13 +++++++++++--
 contrib/pg_prewarm/t/001_basic.pl | 29 ++++++++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c
index a2f0ac4af0c..57bd1527a50 100644
--- a/contrib/pg_prewarm/pg_prewarm.c
+++ b/contrib/pg_prewarm/pg_prewarm.c
@@ -16,6 +16,7 @@
 #include <unistd.h>
 
 #include "access/relation.h"
+#include "catalog/index.h"
 #include "fmgr.h"
 #include "miscadmin.h"
 #include "storage/bufmgr.h"
@@ -55,6 +56,7 @@ Datum
 pg_prewarm(PG_FUNCTION_ARGS)
 {
        Oid                     relOid;
+       Oid                     permOid;
        text       *forkName;
        text       *type;
        int64           first_block;
@@ -103,9 +105,16 @@ pg_prewarm(PG_FUNCTION_ARGS)
        forkString = text_to_cstring(forkName);
        forkNumber = forkname_to_number(forkString);
 
-       /* Open relation and check privileges. */
+       /*
+        * Open relation and check privileges.  Indexes don't have their own
+        * privileges, so we check privileges on the table instead in that case.
+        */
        rel = relation_open(relOid, AccessShareLock);
-       aclresult = pg_class_aclcheck(relOid, GetUserId(), ACL_SELECT);
+       if (rel->rd_rel->relkind == RELKIND_INDEX)
+               permOid = IndexGetRelation(relOid, false);
+       else
+               permOid = relOid;
+       aclresult = pg_class_aclcheck(permOid, GetUserId(), ACL_SELECT);
        if (aclresult != ACLCHECK_OK)
                aclcheck_error(aclresult, 
get_relkind_objtype(rel->rd_rel->relkind), get_rel_name(relOid));
 
diff --git a/contrib/pg_prewarm/t/001_basic.pl 
b/contrib/pg_prewarm/t/001_basic.pl
index 0a8259d3678..a77ab67d29e 100644
--- a/contrib/pg_prewarm/t/001_basic.pl
+++ b/contrib/pg_prewarm/t/001_basic.pl
@@ -23,7 +23,9 @@ $node->start;
 $node->safe_psql("postgres",
                "CREATE EXTENSION pg_prewarm;\n"
          . "CREATE TABLE test(c1 int);\n"
-         . "INSERT INTO test SELECT generate_series(1, 100);");
+         . "INSERT INTO test SELECT generate_series(1, 100);\n"
+         . "CREATE INDEX test_idx ON test(c1);\n"
+         . "CREATE ROLE test_user LOGIN;");
 
 # test read mode
 my $result =
@@ -42,6 +44,31 @@ ok( (        $stdout =~ qr/^[1-9][0-9]*$/
                  or $stderr =~ qr/prefetch is not supported by this build/),
        'prefetch mode succeeded');
 
+# test_user should be unable to prewarm table/index without privileges
+($cmdret, $stdout, $stderr) =
+  $node->psql(
+    "postgres", "SELECT pg_prewarm('test');",
+    extra_params => [ '--username' => 'test_user' ]);
+ok($stderr =~ /permission denied for table test/, 'pg_prewarm failed as 
expected');
+($cmdret, $stdout, $stderr) =
+  $node->psql(
+    "postgres", "SELECT pg_prewarm('test_idx');",
+    extra_params => [ '--username' => 'test_user' ]);
+ok($stderr =~ /permission denied for index test_idx/, 'pg_prewarm failed as 
expected');
+
+# test_user should be able to prewarm table/index with privileges
+$node->safe_psql("postgres", "GRANT SELECT ON test TO test_user;");
+$result =
+  $node->safe_psql(
+    "postgres", "SELECT pg_prewarm('test');",
+    extra_params => [ '--username' => 'test_user' ]);
+like($result, qr/^[1-9][0-9]*$/, 'pg_prewarm succeeded as expected');
+$result =
+  $node->safe_psql(
+    "postgres", "SELECT pg_prewarm('test_idx');",
+    extra_params => [ '--username' => 'test_user' ]);
+like($result, qr/^[1-9][0-9]*$/, 'pg_prewarm succeeded as expected');
+
 # test autoprewarm_dump_now()
 $result = $node->safe_psql("postgres", "SELECT autoprewarm_dump_now();");
 like($result, qr/^[1-9][0-9]*$/, 'autoprewarm_dump_now succeeded');
-- 
2.39.5 (Apple Git-154)

Reply via email to