Commit
6b7d585eb1c693e4ffb5b8e6ed9aa0f067fa1b89 invalidates query
cache if any ALTER ROLE/USER statement is used. Actually this is an
overkill. Because following queries do not affect the privilege of the
role.
- ALTER ROLE user WITH [ENCRYPTED] PASSWORD
- ALTER ROLE user WITH CONNECTION LIMIT
So do not invalidate query cache if those commands are used.
Backpatch-through: v4.1
Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2024-October/004532.html
以下のコマンドはクエリキャッシュとデータベース内容の整合性を失わせる可能性があるので、実行されるとクエリキャッシュをすべて削除します。
<programlisting>
ALTER DATABASE
- ALTER ROLE
+ ALTER ROLE or USER (WITH CONNECTION LIMITとWITH [ENCRYPTED] PASSWORDを除く)
ALTER TABLE
REVOKE
</programlisting>
they are executed:
<programlisting>
ALTER DATABASE
- ALTER ROLE
+ ALTER ROLE or USER (except WITH CONNECTION LIMIT and WITH [ENCRYPTED] PASSWORD)
ALTER TABLE
REVOKE
</programlisting>
static int forward_empty_query(POOL_CONNECTION * frontend, char *packet, int packetlen);
static int forward_packet_to_frontend(POOL_CONNECTION * frontend, char kind, char *packet, int packetlen);
static void process_clear_cache(POOL_CONNECTION_POOL * backend);
+static bool check_alter_role_statement(AlterRoleStmt *stmt);
POOL_STATUS
CommandComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, bool command_complete)
process_clear_cache(backend);
}
else if (IsA(node, AlterTableStmt) || IsA(node, AlterDatabaseStmt) ||
- IsA(node, AlterDatabaseSetStmt) || IsA(node, AlterRoleStmt))
+ IsA(node, AlterDatabaseSetStmt))
{
/* Clear query cache */
process_clear_cache(backend);
}
+ else if (IsA(node, AlterRoleStmt))
+ {
+ if (check_alter_role_statement(castNode(AlterRoleStmt, node)))
+ {
+ /* Clear query cache */
+ process_clear_cache(backend);
+ }
+ }
+}
+
+/*
+ * Check whether the ALTER ROLE statement needs query cache invalidation.
+ * stmt must be AlterRoleStmt.
+ */
+static bool
+check_alter_role_statement(AlterRoleStmt *stmt)
+{
+ ListCell *l;
+
+ foreach(l, stmt->options)
+ {
+ DefElem *elm = (DefElem *) lfirst(l);
+
+ /*
+ * We want to detect other than ALTER ROLE foo WITH PASSWORD or
+ * WITH CONNECTION LIMIT case. It does not change any privilege of the
+ * role.
+ */
+ if (strcmp(elm->defname, "password") &&
+ strcmp(elm->defname, "connectionlimit"))
+ return true;
+ }
+ return false;
}
/*
2 |
(1 row)
+--
+-- ALTER ROLE WITH ENCRYPTED PASSWORD and
+-- ALTER ROLE WITH CONNECTION LIMIT 10
+-- do not invalidate query cache
+SELECT 10;
+NOTICE: DB node id: 0 statement: SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+ALTER ROLE
+ALTER ROLE foo WITH CONNECTION LIMIT 10;
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH CONNECTION LIMIT 10;
+ALTER ROLE
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
2 |
(1 row)
+--
+-- ALTER ROLE WITH ENCRYPTED PASSWORD and
+-- ALTER ROLE WITH CONNECTION LIMIT 10
+-- do not invalidate query cache
+SELECT 10;
+NOTICE: DB node id: 0 statement: SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+NOTICE: DB node id: 1 statement: ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+ALTER ROLE
+ALTER ROLE foo WITH CONNECTION LIMIT 10;
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH CONNECTION LIMIT 10;
+NOTICE: DB node id: 1 statement: ALTER ROLE foo WITH CONNECTION LIMIT 10;
+ALTER ROLE
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
2 |
(1 row)
+--
+-- ALTER ROLE WITH ENCRYPTED PASSWORD and
+-- ALTER ROLE WITH CONNECTION LIMIT 10
+-- do not invalidate query cache
+SELECT 10;
+NOTICE: DB node id: 0 statement: SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
+ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+ALTER ROLE
+ALTER ROLE foo WITH CONNECTION LIMIT 10;
+NOTICE: DB node id: 0 statement: ALTER ROLE foo WITH CONNECTION LIMIT 10;
+ALTER ROLE
+SELECT 10;
+ ?column?
+----------
+ 10
+(1 row)
+
# $PGPROTO -d test -f ../alter_database2.data |& del_details_from_error >> result
# $PGPROTO -d test -f ../alter_database3.data |& del_details_from_error >> result
+ $PSQL -a test >> result 2>&1 <<EOF
+--
+-- ALTER ROLE WITH ENCRYPTED PASSWORD and
+-- ALTER ROLE WITH CONNECTION LIMIT 10
+-- do not invalidate query cache
+SELECT 10;
+SELECT 10;
+ALTER ROLE foo WITH ENCRYPTED PASSWORD 'foo';
+ALTER ROLE foo WITH CONNECTION LIMIT 10;
+SELECT 10;
+EOF
+
./shutdownall
cd ..