Just curious, are you doing this in a trigger or in your application code? Either way, I'd think you could use the table record type to compare the temp vs real table values as an entire unit.
with cte_indexes as(
select * from pg_indexes limit 10
)
select i1.indexdef, i2.tablename
from cte_indexes AS i1
join cte_indexes AS i2 on i1.indexname = i2.indexname
where
i1 IS DISTINCT FROM i2;
select * from pg_indexes limit 10
)
select i1.indexdef, i2.tablename
from cte_indexes AS i1
join cte_indexes AS i2 on i1.indexname = i2.indexname
where
i1 IS DISTINCT FROM i2;
trigger-
I would probably delete records in the regular table that do not exist in the temp table, then delete from the temp table that already exists in the main table and then update the remaining rows.