From 2a5840a1659d3a3126706f1f1ac50be94d89f15e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:19:51 +0000 Subject: [PATCH 1/2] Initial plan From d6c795d5879e3bd2ab44857e40f39732f6d0fdfb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:30:56 +0000 Subject: [PATCH 2/2] Optimize list_groups_info query using LATERAL JOIN with UNION Replace the OR condition in the join predicate with a LATERAL JOIN that uses a UNION subquery. This separates the two cases: 1. Networks explicitly allowed for a group (via wnag table) 2. Networks where allow_all_groups = true This avoids the intermediate result set explosion caused by the OR predicate matching every allow_all_groups network for every group row. Update the sqlx offline query cache accordingly. Co-authored-by: moubctez <12608048+moubctez@users.noreply.github.com> --- ...5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb.json} | 6 +++--- crates/defguard_core/src/handlers/group.rs | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) rename .sqlx/{query-df601202e8bf0cb5978581ebea3b5799549a3a4bf9735f7fd160b359653e5fe5.json => query-4df55e50b2f092cbb5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb.json} (70%) diff --git a/.sqlx/query-df601202e8bf0cb5978581ebea3b5799549a3a4bf9735f7fd160b359653e5fe5.json b/.sqlx/query-4df55e50b2f092cbb5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb.json similarity index 70% rename from .sqlx/query-df601202e8bf0cb5978581ebea3b5799549a3a4bf9735f7fd160b359653e5fe5.json rename to .sqlx/query-4df55e50b2f092cbb5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb.json index b9cfb04d79..9991e38c55 100644 --- a/.sqlx/query-df601202e8bf0cb5978581ebea3b5799549a3a4bf9735f7fd160b359653e5fe5.json +++ b/.sqlx/query-4df55e50b2f092cbb5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT g.id, g.name, COALESCE(ARRAY_AGG(DISTINCT u.username) FILTER (WHERE u.username IS NOT NULL), '{}') \"members!\", COALESCE(ARRAY_AGG(DISTINCT wn.name) FILTER (WHERE wn.name IS NOT NULL), '{}') \"vpn_locations!\", is_admin FROM \"group\" g LEFT JOIN \"group_user\" gu ON gu.group_id = g.id LEFT JOIN \"user\" u ON u.id = gu.user_id LEFT JOIN \"wireguard_network_allowed_group\" wnag ON wnag.group_id = g.id LEFT JOIN \"wireguard_network\" wn ON wn.allow_all_groups OR wn.id = wnag.network_id GROUP BY g.name, g.id", + "query": "SELECT g.id, g.name, COALESCE(ARRAY_AGG(DISTINCT u.username) FILTER (WHERE u.username IS NOT NULL), '{}') \"members!\", COALESCE(ARRAY_AGG(DISTINCT wn.name) FILTER (WHERE wn.name IS NOT NULL), '{}') \"vpn_locations!\", is_admin FROM \"group\" g LEFT JOIN \"group_user\" gu ON gu.group_id = g.id LEFT JOIN \"user\" u ON u.id = gu.user_id LEFT JOIN LATERAL (SELECT wn_inner.name FROM \"wireguard_network\" wn_inner JOIN \"wireguard_network_allowed_group\" wnag ON wnag.network_id = wn_inner.id AND wnag.group_id = g.id UNION SELECT wn_all.name FROM \"wireguard_network\" wn_all WHERE wn_all.allow_all_groups) wn ON true GROUP BY g.name, g.id", "describe": { "columns": [ { @@ -40,5 +40,5 @@ false ] }, - "hash": "df601202e8bf0cb5978581ebea3b5799549a3a4bf9735f7fd160b359653e5fe5" -} + "hash": "4df55e50b2f092cbb5d22fa2a99ddf5f13b6d71296c7e9b7859a6ecbb495dbfb" +} \ No newline at end of file diff --git a/crates/defguard_core/src/handlers/group.rs b/crates/defguard_core/src/handlers/group.rs index e672decf40..480d99790f 100644 --- a/crates/defguard_core/src/handlers/group.rs +++ b/crates/defguard_core/src/handlers/group.rs @@ -188,8 +188,13 @@ pub(crate) async fn list_groups_info( FROM \"group\" g \ LEFT JOIN \"group_user\" gu ON gu.group_id = g.id \ LEFT JOIN \"user\" u ON u.id = gu.user_id \ - LEFT JOIN \"wireguard_network_allowed_group\" wnag ON wnag.group_id = g.id \ - LEFT JOIN \"wireguard_network\" wn ON wn.allow_all_groups OR wn.id = wnag.network_id \ + LEFT JOIN LATERAL (\ + SELECT wn_inner.name FROM \"wireguard_network\" wn_inner \ + JOIN \"wireguard_network_allowed_group\" wnag ON wnag.network_id = wn_inner.id AND wnag.group_id = g.id \ + UNION \ + SELECT wn_all.name FROM \"wireguard_network\" wn_all \ + WHERE wn_all.allow_all_groups\ + ) wn ON true \ GROUP BY g.name, g.id" ) .fetch_all(&appstate.pool)