In PostgreSQL, how do I make it so that either column A or column B must be non-null?
You need a table-level check constraint:
alter table <name>
add constraint either_email
check (email is not null or p2pmail is not null);
If you're only allowed to enter one, but not both:
alter table <name>
add constraint either_email
check (email is null <> p2pmail is null);
The second form is possibly a little confusing at first glance: what it does is compare both columns' null status -- they aren't allowed to be the same.
The constraint can also be created simultaneously with the table:
create table <name> (
... columns ...
constraint either_email check (email is not null or p2pmail is not null)
);
I like using num_nonnulls
for this:
alter table the_table
add constraint check_at_least_one_email
check (num_nonnulls(email, p2pmail) > 0);
I prefer this because it can easily be extended to multiple columns.
If you also want to deal with empty strings:
alter table the_table
add constraint check_at_least_one_email
check (num_nonnulls(nullif(trim(email),''), nullif(trim(p2pmail),'')) > 0);
If you require exactly one non-null value change > 0
to = 1