diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile
index 414a30856e..c19ccad77e 100644
--- a/contrib/pg_stat_statements/Makefile
+++ b/contrib/pg_stat_statements/Makefile
@@ -19,7 +19,8 @@ LDFLAGS_SL += $(filter -lm, $(LIBS))
 
 REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/pg_stat_statements/pg_stat_statements.conf
 REGRESS = select dml cursors utility level_tracking planning \
-	user_activity wal entry_timestamp cleanup oldextversions
+	user_activity wal entry_timestamp privileges cleanup \
+	oldextversions
 # Disabled because these tests require "shared_preload_libraries=pg_stat_statements",
 # which typical installcheck users do not have (e.g. buildfarm clients).
 NO_INSTALLCHECK = 1
diff --git a/contrib/pg_stat_statements/expected/privileges.out b/contrib/pg_stat_statements/expected/privileges.out
new file mode 100644
index 0000000000..383895c87d
--- /dev/null
+++ b/contrib/pg_stat_statements/expected/privileges.out
@@ -0,0 +1,102 @@
+--
+-- Superusers or roles with the privileges of pg_read_all_stats members
+-- can read query text and queryid
+--
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+ t 
+---
+ t
+(1 row)
+
+CREATE ROLE regress_stats_user1;
+CREATE ROLE regress_stats_user2;
+GRANT pg_read_all_stats TO regress_stats_user2;
+SET ROLE regress_stats_user1;
+SELECT 1 AS "ONE";
+ ONE 
+-----
+   1
+(1 row)
+
+-- Superuser can read query text and queryid
+RESET ROLE;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ queryid_bool |                       query                        
+--------------+----------------------------------------------------
+ t            | CREATE ROLE regress_stats_user1
+ t            | CREATE ROLE regress_stats_user2
+ t            | GRANT pg_read_all_stats TO regress_stats_user2
+ t            | RESET ROLE
+ t            | SELECT $1 AS "ONE"
+ t            | SELECT pg_stat_statements_reset() IS NOT NULL AS t
+ t            | SET ROLE regress_stats_user1
+(7 rows)
+
+--
+-- regress_stats_user1 can not read query text and queryid
+-- executed by other users
+--
+SET ROLE regress_stats_user1;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ queryid_bool |            query             
+--------------+------------------------------
+ f            | <insufficient privilege>
+ f            | <insufficient privilege>
+ f            | <insufficient privilege>
+ f            | <insufficient privilege>
+ f            | <insufficient privilege>
+ f            | <insufficient privilege>
+ t            | SELECT $1 AS "ONE"
+ t            | SET ROLE regress_stats_user1
+(8 rows)
+
+RESET ROLE;
+-- regress_stats_user2 can read query text and queryid
+SET ROLE regress_stats_user2;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+ queryid_bool |                            query                            
+--------------+-------------------------------------------------------------
+ t            | CREATE ROLE regress_stats_user1
+ t            | CREATE ROLE regress_stats_user2
+ t            | GRANT pg_read_all_stats TO regress_stats_user2
+ t            | RESET ROLE
+ t            | SELECT                                                     +
+              |   CASE                                                     +
+              |     WHEN queryid <> $1 THEN $2 ELSE $3                     +
+              |   END AS queryid_bool                                      +
+              |   ,query FROM pg_stat_statements ORDER BY query COLLATE "C"
+ t            | SELECT                                                     +
+              |   CASE                                                     +
+              |     WHEN queryid <> $1 THEN $2 ELSE $3                     +
+              |   END AS queryid_bool                                      +
+              |   ,query FROM pg_stat_statements ORDER BY query COLLATE "C"
+ t            | SELECT $1 AS "ONE"
+ t            | SELECT pg_stat_statements_reset() IS NOT NULL AS t
+ t            | SET ROLE regress_stats_user1
+ t            | SET ROLE regress_stats_user2
+(10 rows)
+
+--
+-- cleanup
+--
+RESET ROLE;
+DROP ROLE regress_stats_user1;
+DROP ROLE regress_stats_user2;
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+ t 
+---
+ t
+(1 row)
+
diff --git a/contrib/pg_stat_statements/sql/privileges.sql b/contrib/pg_stat_statements/sql/privileges.sql
new file mode 100644
index 0000000000..69f4abf234
--- /dev/null
+++ b/contrib/pg_stat_statements/sql/privileges.sql
@@ -0,0 +1,52 @@
+--
+-- Superusers or roles with the privileges of pg_read_all_stats members
+-- can read query text and queryid
+--
+
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
+CREATE ROLE regress_stats_user1;
+CREATE ROLE regress_stats_user2;
+GRANT pg_read_all_stats TO regress_stats_user2;
+
+SET ROLE regress_stats_user1;
+SELECT 1 AS "ONE";
+
+-- Superuser can read query text and queryid
+
+RESET ROLE;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+
+--
+-- regress_stats_user1 can not read query text and queryid
+-- executed by other users
+--
+
+SET ROLE regress_stats_user1;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+RESET ROLE;
+
+-- regress_stats_user2 can read query text and queryid
+
+SET ROLE regress_stats_user2;
+SELECT
+  CASE
+    WHEN queryid <> 0 THEN TRUE ELSE FALSE
+  END AS queryid_bool
+  ,query FROM pg_stat_statements ORDER BY query COLLATE "C";
+
+--
+-- cleanup
+--
+
+RESET ROLE;
+DROP ROLE regress_stats_user1;
+DROP ROLE regress_stats_user2;
+SELECT pg_stat_statements_reset() IS NOT NULL AS t;
