D. Richard Hipp wrote:
> 
> If I understand Peter correctly, he is saying that NULL should mean  
> "unknown" in the context of the RHS of a NOT IN operator.  SQLite does  
> not currently operate this way.  SQLite currently interprets a NULL in  
> the RHS of a NOT IN operator to mean "nothing".
> 
> Can you or anybody else point to text in any  
> SQL spec that would suggest that SQLites behavior in this case is wrong?


I believe that your interpretation is correct, and that SQLite's current 
behavior is incorrect according to the standard, at least the SQL:1999 
standard.

The IN predicate is a synonym for the quantified predicate = ANY, or = 
SOME which is equivalent. The inversion of this predicate, NOT IN, is 
therefore the inversion of the quantified predicate. The rules defined 
in section 8.4 <in predicate> Syntax Rules 3 and 4 show how this is 
transformed.

   col NOT IN subquery

becomes

   NOT col IN subquery

which becomes

   NOT (col = SOME subquery)

And the inversion of the quantified predicate is

   col <> ALL subquery

In the standard the rules for evaluating this quantified subquery are in 
   section 8.8 <quantified comparison predicate> General Rules 1 through 
2e copied below.

     1) Let R be the result of the <row value expression> and let T be 
the result of the <table subquery>.
     2) The result of ‘‘R <comp op> <quantifier> T’’ is derived by the 
application of the implied <comparison predicate> ‘‘R <comp op> RT’’ to 
every row RT in T:
     Case:
         a) If T is empty or if the implied <comparison predicate> is 
true for every row RT in T, then ‘‘R <comp op> <all> T’’ is true.
         b) If the implied <comparison predicate> is false for at least 
one row RT in T, then ‘‘R <comp op> <all> T’’ is false.
         c) If the implied <comparison predicate> is true for at least 
one row RT in T, then ‘‘R <comp op> <some> T’’ is true.
         d) If T is empty or if the implied <comparison predicate> is 
false for every row RT in T, then ‘‘R <comp op> <some> T’’ is false.
         e) If ‘‘R <comp op> <quantifier> T’’ is neither true nor false, 
then it is unknown .

For the example given, the engine evaluates the following predicates.

   1 <> ALL (NULL, 3, 4, 5)
   2 <> ALL (NULL, 3, 4, 5)
   3 <> ALL (NULL, 3, 4, 5)

In each case the first comparison is

   X <> NULL

And from 8.2 <comparison predicate> General Rules 1a we have

     a)  If either XV or YV is the null value, then
             X <comp op> Y
         is unknown.

The results of the comparisons are therefore:

   (unknown, true, true, true)
   (unknown, true, true, true)
   (unknown, false, true, true)

So all three rows result in an unknown result for the first, NULL, 
element. The last row is handled buy case b in section 8.8 General Rule 
2 above since one subquery result is false. The other rows all fall 
through to case e in section 8.8 General Rule 2 above. The result of 
each quantified comparison is therefore unknown.

The where clause only returns rows where the condition is true according 
to section 7.8 <where clause> General Rule 1.

     1) The <search condition> is applied to each row of T. The result 
of the <where clause> is a table of those rows of T for which the result 
of the <search condition> is true.

It looks like this should be changed to match the other database engines 
for improved standard compliance.

Dennis Cote
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to