Optimize query cache invalidation for ALTER ROLE.
authorTatsuo Ishii <ishii@postgresql.org>
Tue, 22 Oct 2024 22:47:37 +0000 (07:47 +0900)
committerTatsuo Ishii <ishii@postgresql.org>
Tue, 22 Oct 2024 23:48:51 +0000 (08:48 +0900)
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

doc.ja/src/sgml/memcache.sgml
doc/src/sgml/memcache.sgml
src/protocol/CommandComplete.c
src/test/regression/tests/006.memqcache/expected.n
src/test/regression/tests/006.memqcache/expected.r
src/test/regression/tests/006.memqcache/expected.s
src/test/regression/tests/006.memqcache/test.sh

index 1e981c8e5bacb6efb083bb78cf2e0cdcfa20d980..2145e88c5d515e87eb768886f6f019a1d1c91dd5 100644 (file)
    以下のコマンドはクエリキャッシュとデータベース内容の整合性を失わせる可能性があるので、実行されるとクエリキャッシュをすべて削除します。
    <programlisting>
     ALTER DATABASE
-    ALTER ROLE
+    ALTER ROLE or USER (WITH CONNECTION LIMITとWITH [ENCRYPTED] PASSWORDを除く)
     ALTER TABLE
     REVOKE
    </programlisting>
index 9ee211b44f01a67e0dc3d0764b8e499927684b01..e87573c51b1ed5c455eb9a44e795908efca372a6 100644 (file)
@@ -79,7 +79,7 @@
    they are executed:
    <programlisting>
     ALTER DATABASE
-    ALTER ROLE
+    ALTER ROLE or USER (except WITH CONNECTION LIMIT and WITH [ENCRYPTED] PASSWORD)
     ALTER TABLE
     REVOKE
    </programlisting>
index 4b02b793d26aef6afb11f3a1ab069b3e8e20db51..a8350969381604bf443d2f9f4c80b0951e478346 100644 (file)
@@ -45,6 +45,7 @@ static int    forward_command_complete(POOL_CONNECTION * frontend, char *packet, in
 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)
@@ -475,11 +476,44 @@ handle_query_context(POOL_CONNECTION_POOL * backend)
                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;
 }
 
 /*
index 00e3bc9d8807932f36702f0fc0ce040f97154559..df85bcee94da3c80ad090d155fba81eb7d6fb17a 100644 (file)
@@ -567,3 +567,32 @@ NOTICE:  DB node id: 0 statement: SELECT * FROM t1;
  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)
+
index fc7f3303706c1760b5c183a4b3891836fe3fc582..ebf84694cd2ce43bca8e8d50861a1cf5fdcea99b 100644 (file)
@@ -625,3 +625,34 @@ NOTICE:  DB node id: 0 statement: SELECT * FROM t1;
  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)
+
index 00e3bc9d8807932f36702f0fc0ce040f97154559..df85bcee94da3c80ad090d155fba81eb7d6fb17a 100644 (file)
@@ -567,3 +567,32 @@ NOTICE:  DB node id: 0 statement: SELECT * FROM t1;
  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)
+
index 4b218e197c3474bb436ba05beef8a4ceb2f1bae4..00eb1dfe3a39d64561c667ce9bee4aa618db995d 100755 (executable)
@@ -446,6 +446,18 @@ EOF
 #      $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 ..