Andy Fan <zhihui.fan1213@gmail.com> writes:
> notnulls discussion is forked from UniqueKey stuff, you can see the
> attachment
> for the UnqiueKey introduction. Tom raised his opinion to track the
> nullability
> inside Var[1][2][3], this thread would start from there based on my
> understanding.
I'm pretty certain that I never suggested this:
> struct Var
> {
> ...;
> int nullable; // -1 unknown, 0 - not nullable. 1 - nullable
> };
You're free to pursue it if you like, but I think it will be a dead end.
The fundamental problem as you note is that equalVar() cannot do anything
sane with a field defined that way. Also, we'd have to generate Vars
initially with nullable = unknown (else, for example, ALTER SET/DROP NOT
NULL breaks stored views referring to the column). It'd be on the planner
to run through the tree and replace that with "nullable" or "not
nullable". It's hard to see how that's more advantageous than just
keeping the info in the associated RelOptInfo.
Also, I think you're confusing two related but distinct issues. For
certain optimization issues, we'd like to keep track of whether a column
stored in a table is known NOT NULL. However, that's not the same thing
as the question that I've muttered about, which is how to treat a Var
that's been possibly forced to null due to null-extension of an outer
join. That is a different value from the Var as read from the table,
but we currently represent it the same within the planner, which causes
various sorts of undesirable complication. We cannot fix that by setting
Var.nullable = true in above-the-join instances, because it might also
be true in below-the-join instances. "Known not null in the table" is
not the inverse of "potentially nulled by an outer join". Moreover, we
probably need to know *which* join is the one potentially nulling the Var,
so a bool is not likely enough anyway.
The schemes I've been toying with tend to look more like putting a
PlaceHolderVar-ish wrapper around the Var or expression that represents
the below-the-join value. The wrapper node could carry any join ID
info that we find necessary. The thing that I'm kind of stalled on is
how to define this struct so that it's not a big headache for join
strength reduction (which could remove the need for a wrapper altogether)
or outer-join reordering (which makes it a bit harder to define which
join we think is the one nulling the value).
regards, tom lane