JOIN catalog_schemas cs ON ct.schema_id = cs.id JOIN catalog_databases cd ON cs.database_id = cd.id JOIN catalogs c ON cd.catalog_id = c.id JOIN users u ON u.id = :user_id -- ユーザー所属チーム JOIN team_users tu ON tu.user_id = u.id JOIN teams t ON tu.team_id = t.id -- 左結合で各階層のアクセス権取得(allow/deny 両方見る) LEFT JOIN team_table_permissions ttp_allow ON ttp_allow.team_id = t.id AND ttp_allow.table_id = ct.id AND ttp_allow.can_view = TRUE LEFT JOIN team_table_permissions ttp_deny ON ttp_deny.team_id = t.id AND ttp_deny.table_id = ct.id AND ttp_deny.can_view = FALSE LEFT JOIN team_schema_permissions tsp_allow ON tsp_allow.team_id = t.id AND tsp_allow.schema_id = cs.id AND tsp_allow.can_view = TRUE LEFT JOIN team_schema_permissions tsp_deny ON tsp_deny.team_id = t.id AND tsp_deny.schema_id = cs.id AND tsp_deny.can_view = FALSE LEFT JOIN team_database_permissions tdp_allow ON tdp_allow.team_id = t.id AND tdp_allow.database_id = cd.id AND tdp_allow.can_view = TRUE LEFT JOIN team_database_permissions tdp_deny ON tdp_deny.team_id = t.id AND tdp_deny.database_id = cd.id AND tdp_deny.can_view = FALSE LEFT JOIN team_catalog_permissions tcp_allow ON tcp_allow.team_id = t.id AND tcp_allow.catalog_id = c.id AND tcp_allow.can_view = TRUE LEFT JOIN team_catalog_permissions tcp_deny ON tcp_deny.team_id = t.id AND tcp_deny.catalog_id = c.id AND tcp_deny.can_view = FALSE WHERE -- 明示的な拒否がない(deny優先) ttp_deny.team_id IS NULL AND tsp_deny.team_id IS NULL AND tdp_deny.team_id IS NULL AND tcp_deny.team_id IS NULL AND ( -- スーパーユーザー u.account_role = 'super_admin' -- オーナー OR c.owner_id = u.id -- チーム経由で allow が1つでもあれば OK OR ttp_allow.team_id IS NOT NULL OR tsp_allow.team_id IS NOT NULL OR tdp_allow.team_id IS NOT NULL OR tcp_allow.team_id IS NOT NULL ) ;