[Dbix-class] rfc, treating NULL as a value like any other
Darren Duncan
darren at DarrenDuncan.net
Mon Jan 28 21:51:20 GMT 2008
At 3:59 PM +0000 1/28/08, Matt S Trout wrote:
>On Sat, Jan 26, 2008 at 07:35:08PM -0800, Darren Duncan wrote:
>> Under my proposal, saying "foo != 3" would return foo that are NULL,
>> because they are not 3.
>
>If you're going to have something that behaves like that, please don't call
>it NULL.
Just as well that I actually called the corresponding concept Nothing, then.
I also realize that in practice users probably would rarely if ever
face the situation where saying "foo = 3" would do what they wanted
and saying "foo != 3" with the same foo would also return foo of
Nothing.
Any typical situation where they would simply say "foo = 3" is a
situation where foo is not nullable, and hence their saying "foo !=
3" would never return Nothing anyway. So this behaviour should be
intuitive to SQL users.
For a typical situation where foo is nullable, users would not simply
be treating foo like a normal value; instead they would be asking one
of these 3 questions, though usually not directly: "foo = Nothing",
"foo != Nothing and foo.attr = 3", "foo != Nothing and foo.attr !=
3"; this would be similar to how Perl code may test for foo being
undef before it tries using foo in a normal context.
In actual select-like queries, for a not-nullable foo, you'd say
something analagous to:
myrowset.where:{ .foo = 3 }
or
myrowset.where:{ .foo != 3 }
... whereas for a nullable foo, you'd say something analagous to:
myrowset.where:{ .foo = Nothing }
or
myrowset.ungroup_to_outer_name('foo').where:{ .foo = 3 }
or
myrowset.ungroup_to_outer_name('foo').where:{ .foo != 3 }
... in order to match not-nullable foo equal or not equal to 3.
To explain the above, the type of foo in the not-nullable case is
Int, while the type of foo in the nullable case is Maybe{Int}, and a
Maybe is a rowset having zero or 1 row, and 1 column. A relational
ungroup on a table-valued column will eliminate any main rowset rows
where the inner table value had zero rows (that equalled Nothing in
this case), and then for the remaining rows, the type of foo is now
just Int like the not nullable case (if the inner table had more than
1 row, not the case for Maybe, then extra rows are added to the
result for each, like when you do an inner join).
Now once again, the real syntax could be made more terse, but the
example is meant to be illustrative of the fact that you use
different syntax to work with nullable vs not-nullable, and none of
them look like a plain "foo != 3" that also returns null.
-- Darren Duncan
More information about the DBIx-Class
mailing list