[Dbix-class] rfc, treating NULL as a value like any other
Christopher Laco
claco at chrislaco.com
Sun Jan 27 02:01:05 GMT 2008
Darren Duncan wrote:
> Hello,
> =
> This email is primarily concerned with the possible future internals of =
> DBIx-Class with respect to an intermediate AST based on Muldis D that =
> you can convert to/from SQL, but this email is secondarily concerned =
> with a possible future enhancement to the public interface of DBIx-Class.
> =
> In a nutshell, one issue that often trips up new (and experienced) SQL =
> users is its 3-valued logic such that you can't just say "foo =3D NULL" t=
o =
> match null values, requiring "IS NULL" instead, or that both "foo =3D 3" =
> and "foo <> 3" will not match foo that are NULL. And AFAIK in some =
> situations SQL treats 2 NULL as matching and other times non-matching.
> =
> My question for you is whether, from a typical or new or experienced =
> user's point of view, it would be preferable for the DBMS to treat NULL =
> like an actual single value, which is equal to itself while not equal to =
> every other normal value that is not NULL? Consequences of this include =
> that "foo =3D NULL" will DWIM (result in true when foo is NULL), and "foo =
> <> 3" will be true when foo is NULL (foo is anything but 3).
> =
> (Other consequences are that null-allowing columns with a single-column =
> unique key constraint will allow a NULL value to appear exactly once in =
> the column. In a naive case, a foreign key relationship would then =
> match a NULL in one table with one in another, or require one in the =
> parent. Though if this isn't desired, then the foreign key constraint =
> could be defined to only apply to child table values that do not equal =
> NULL. Both of which I think SQL already does and that doesn't =
> necessarily need to change.)
> =
> Regardless of whether any updates to the DBIx-Class public interface are =
> made, I believe it is preferrable to think in terms of NULL =3D NULL and =
> structure the AST along those principles, so you get more AST simplicity =
> or DWIM when you want that to be the case, while you may or may not get =
> more AST complexity when you don't want that to be the case. Or =
> regardless of whether that happens, the AST is simpler when dealing with =
> not-nullable data, and marginally more complex when dealing with =
> nullable data.
> =
> The latest release 0.18.0 of the Muldis D spec, =
> http://search.cpan.org/dist/Language-MuldisD/ , clarifies that any 2 =
> table ("relation") values are identical when they contain zero rows =
> ("tuples") and they have the same column ("attribute") names, regardless =
> of the declared types of those columns. Also, new subtypes Nothing,Just =
> of Maybe were added. Now, Muldis D is optimized towards not-nullable =
> data, so in SQL terms, if you simply say "foo Int" as a field type, that =
> is implicitly not nullable, and you have to explicitly say nullable to =
> make it so, as "foo Maybe{Int}". Defining a field nullable is actually =
> defining the field to contain a table value whose sole column name is =
> 'value' and which may contain only zero rows or 1 row; if it contains =
> zero, it is null, if it contains 1 row, namely the normal value, it is =
> not null. You could say that not-nullable means unboxed while nullable =
> means boxed. But those are details that users typically don't have to =
> know about. The single Nothing value matches the empty case, and Just =
> constructs a full case. Testing a not nullable field is simple as "foo =
> =3D 3" or "foo <> 3", while testing a nullable is "foo =3D Nothing" (SQL =
> "foo IS NULL") "foo =3D Just(3)" (SQL "foo =3D 3") or "foo <> Just(3)" (S=
QL =
> "foo <> 3 OR foo IS NULL") "foo <> Just(3) and foo <> Nothing" (SQL "foo =
> <> 3"). In this system, "Nothing =3D Nothing" is true, "Nothing =3D 3" a=
nd =
> "Nothing =3D Just(3)" are both false, "Nothing <> 3" and "Nothing <> =
> Just(3)" are both true, "3 =3D Just(3)" is false, "Just(3) =3D Just(3)" i=
s =
> true, "3 =3D Just(3).attr" is true. To do math with not-nullable, you =
> just say eg "row.x / row.y", with nullable but known not null you say =
> "row.x.attr / row.y.attr".
> =
> So, assuming it is clearly documented, do you forsee any problems in =
> using an AST that is 2-valued-logic and assumes NULL =3D NULL, where you =
> have to explicitly say when you don't want that behaviour? It should =
> still be possible to generate SQL with the desired semantics, so this is =
> more a useability question.
> =
> Thank you. -- Darren Duncan
In perl terms, I think it's great if {foo =3D> NULL} translates to foo IS =
NULL. DWIM++
Now, according to SQL92, any comparison of =3D or !=3D against NULL returns =
false. So, even a {foo =3D> 3} should not return rows that are NULL, =
because NULL is neither =3D or !=3D to 3.
http://msdn.microsoft.com/library/default.asp?url=3D/library/en-us/tsqlref/=
ts_set-set_9rec.asp
The SQL-92 standard requires that an equals (=3D) or not equal to (<>) =
comparison against a null value evaluates to FALSE. When SET ANSI_NULLS =
is ON, a SELECT statement using WHERE column_name =3D NULL returns zero =
rows even if there are null values in column_name. A SELECT statement =
using WHERE column_name <> NULL returns zero rows even if there are =
nonnull values in column_name.
I other words:
foo =3D NULL yields 'foo IS NULL'
foo =3D 3 should yield 'foo =3D 3' and NOT this 'foo =3D 3 and fo IS NU=
LL'
...assuming I understand the question.
-=3DChris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
Url : http://lists.scsys.co.uk/pipermail/dbix-class/attachments/20080126/11=
e272a8/signature.pgp
More information about the DBIx-Class
mailing list