> When the join is between attnos < 0 (such as oids), the selectivity is
> estimated as 0.5 (leading to very bad size estimates), since this code
> in function compute_clause_selec (clausesel.c):
> if (relid1 > 0 && relid2 > 0 && attno1 > 0 && attno2 > 0)
> ...
> else
> s1 = (Cost) (0.5);
> So what is the aim of the last two and conditions?
That's a bug, I guess. -1 is used to signal "couldn't find the
attribute", but there's no real need to check *both* relid and attno
to determine that. It should consider positive relid and negative
attno to be valid.
Since vacuum doesn't record statistics for the system attributes,
there probably also needs to be a hack in the code that looks in
pg_statistic so that it will produce reasonable estimates. We
should assume that OID has perfect disbursion, for sure. I don't
know if we can assume anything much about the other sys attributes...
regards, tom lane