I just remembered that one of the complaints was not wanting to worry about looking up the data types. In my previous example, you can also leave out the types and Postgres will do the right thing. I prefer the explicit data type version for clarity, but though I would provide this one for completeness:
prepare foo as with x as (update tab1 set mid=$2 where id=$1 returning 1)
insert into tab1 select $1,$2,$3 where not exists (select 1 from x);
Cheers,
Greg