Closed nomeata closed 11 months ago
% psql
psql (10.18 (Ubuntu 10.18-0ubuntu0.18.04.1))
Type "help" for help.
phadej=# select 1 where null = null;
?column?
----------
(0 rows)
phadej=# select 1 where null != null;
?column?
----------
(0 rows)
Hmm, I see. And the Haskell ==
has to match the SQL =
here? Is this a property that is guaranteed in general?
And the Haskell == has to match the SQL = here?
I don't know. I guess it's a bit like nan == (nan :: Double) = False
, even people argue for and against.
Is this a property that is guaranteed in general?
For other types? I'd consider it a potential bug if type's PostgreSQL equality and its canonical representation in Haskell disagree on equality, but I don't think we test that. (the types are not that complicated, but maybe time, json, ...)
Hmm, but as it stands it is an unlawful instance, and may cause surprising effects when passed to code that relies on (/=)
being the negation of (==)
.
Hmm, but as it stands it is an unlawful instance,
So is Double
s instance not reflexive.
If this is related to your single method Eq
instance proposal, the Eq Null
is not an issue. No test fails if I just derive Eq Null
, so I think Bryan just felt "smart" when writing the initial version of a library.
Thanks for testing that :-)
For reference, that's a commit which added it to mysql-simple
: https://github.com/paul-rouse/mysql-simple/commit/6260c7dbecc2bf4ed3673a087f566f9bfc135a32
Add basic documentation.
But no hint why Eq Null
is the way it is.
But no hint why
Eq Null
is the way it is.
SQL Null
is the way it is because SQL has 'three-value logic'. (I tend to call it "three-and-a-half value logic"; or not any sort of logic).
Note that unlike haskell's undefined
; SQL's Null
is a value you can assign/store in a variable/write out to a database/etc. It's distinct from zero or from a zero-length string. You're supposed to test for it using ... IS [NOT] NULL
, not using equality. (SQL doesn't have anything like a Maybe
type.)
It's just so darn convenient (= quick-and-dirty) that testing any non-Null value = Null
returns False (in effect, see below).
@nomeata And the Haskell == has to match the SQL = here?
I think not. I can see no reason why you'd have instance Eq Null
.
Is this a property that is guaranteed in general?
The general rule in SQL is that Null = <anything>
returns Null
. But if that result bubbles up to SELECT ... WHERE ...
statement level, the DB engine has to decide whether to include the row; then a Null
result means don't select the row; IOW treat the result as if False
.
I see that PostreSQL repo says:
-- | A placeholder for the SQL @NULL@ value.
Must be written by somebody who doesn't understand SQL: Null
is not a "value". It's a 'marker' for the absence of a value (in a field whose type contains 'proper' values like INT, CHAR, ...
). Hence its behaviour wrt equality testing. I see no reason that repo should even define data Null = ...
, let alone give an Eq
instance. SQL has no type Null
; fields of a genuine type can be marked NULLABLE
.
Thank you, I know what three value logic is. That doesn't explain why Eq Null
instance was added.
Instance is removed in #120 (postgresql-simple-0.7.0.0
)
I found this code in https://github.com/haskellari/postgresql-simple/blob/master/src/Database/PostgreSQL/Simple/Types.hs#L53-L55:
but no rationale for this definition. Why was this definition done? (It has been there since “Initial commit”, so
git blame
does not give any insights.)