[PATCH v5 5/5] Improve tab completion for ALTER SYSTEM RESET for non-superusers
Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
From: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
To:
Date: 2025-08-08T23:29:39Z
Lists: pgsql-hackers
Non-superusers can only use ALTER SYSTEM on variables they've
explicitly been GRANTed access to, and can't read the data_directory
setting or pg_settings.sourceline column, so the existing tab
completion for ALTER SYSTEM isn't very useful for them.
Instead, query pg_parameter_acl to show the variables they do have
permission to set via ALTER SYSTEM.
---
src/bin/psql/tab-complete.in.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
index 60bba212f5e..aee939e98be 100644
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -1049,6 +1049,13 @@ static const SchemaQuery Query_for_trigger_of_table = {
" '[_%%\\\\]', '\\\\\\&') || '_postgresql.auto.conf' " \
" AND pg_catalog.lower(name) LIKE pg_catalog.lower('%s')"
+#define Query_for_list_of_alter_system_granted_vars \
+"SELECT pg_catalog.lower(parname) FROM pg_catalog.pg_parameter_acl " \
+" WHERE EXISTS (SELECT FROM pg_catalog.aclexplode(paracl) " \
+" WHERE pg_has_role(current_role, grantee, 'usage') " \
+" AND privilege_type = 'ALTER SYSTEM') " \
+" AND pg_catalog.lower(parname) LIKE pg_catalog.lower('%s')"
+
#define Query_for_list_of_set_vars \
"SELECT pg_catalog.lower(name) FROM pg_catalog.pg_settings "\
" WHERE context IN ('user', 'superuser') "\
@@ -2632,10 +2639,16 @@ match_previous_words(int pattern_id,
else if (Matches("ALTER", "SYSTEM"))
COMPLETE_WITH("SET", "RESET");
else if (Matches("ALTER", "SYSTEM", "SET"))
- COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_set_vars);
+ if (is_superuser())
+ COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_set_vars);
+ else
+ COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_granted_vars);
else if (Matches("ALTER", "SYSTEM", "RESET"))
- COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_alter_system_reset_vars,
- "ALL");
+ if (is_superuser())
+ COMPLETE_WITH_QUERY_VERBATIM_PLUS(Query_for_list_of_alter_system_reset_vars,
+ "ALL");
+ else
+ COMPLETE_WITH_QUERY_VERBATIM(Query_for_list_of_alter_system_granted_vars);
else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
COMPLETE_WITH("TO");
/* ALTER VIEW <name> */
--
2.50.1
--=-=-=--