List primary replicas and non-HA databases - excluding forwarder replicas When asking which databases are writable on any given server, I've been using the below snippet to list PRIMARY replica databases and databases that do not participate in an AG. 

Now that I've deployed a Distributed Availability Group, it's not working anymoar! Since the local forwarder reports as a PRIMARY replica on the sys.dm_hadr_availability_replica_states DMV, my old query is telling me a database is writable when it is not. 


  How do I change this query to exclude databases in a local forwarder replica?


select 
    ars.role_desc
   ,ag_name = ag.[name]
   ,adc.[database_name]
from sys.availability_groups ag 
join sys.dm_hadr_availability_replica_states ars on ars.group_id = ag.group_id
join sys.availability_databases_cluster adc on adc.group_id = ag.group_id
where ars.is_local = 1
    and ars.role_desc = 'PRIMARY'
union all 
select 
    'LOCAL_ONLY'
   ,@@servername
   ,[name]
from sys.databases d 
where not exists (
    select 1 
    from sys.availability_databases_cluster adc
    where adc.[database_name] = d.[name]
);


...or more simply...


  How do I list all local forwarder databases?
To list all databases in an forwarder replica on the current server...

select 
     dag.group_id
    ,dag.[name]
    ,dag.is_distributed
    ,fwd.replica_id
    ,fwd.replica_server_name
    ,adc.[database_name]
from sys.availability_groups dag 
join sys.availability_replicas fwd on fwd.group_id = dag.group_id
join sys.availability_groups ag on ag.name = fwd.replica_server_name
join sys.availability_databases_cluster adc on adc.group_id = ag.group_id
where dag.is_distributed = 1;


To list all databases that are PRIMARY or local only and exclude forwarder databases...

select 
    ars.role_desc
   ,ag_name = ag.[name]
   ,adc.[database_name]
from sys.availability_groups ag 
join sys.dm_hadr_availability_replica_states ars on ars.group_id = ag.group_id
join sys.availability_databases_cluster adc on adc.group_id = ag.group_id
where ars.is_local = 1
    and ars.role_desc = 'PRIMARY'
    and not exists (
        select 1
        from sys.availability_groups dag 
        join sys.availability_replicas fwd on fwd.group_id = dag.group_id
        join sys.availability_groups ag2 on ag2.name = fwd.replica_server_name
        join sys.availability_databases_cluster db on db.group_id = ag2.group_id
        where dag.is_distributed = 1
            and db.[database_name] = adc.[database_name]
)
union all 
select 
    'LOCAL_ONLY'
   ,@@servername
   ,[name]
from sys.databases d 
where not exists (
    select 1 
    from sys.availability_databases_cluster adc
    where adc.[database_name] = d.[name]
);