James K. Lowden wrote:
> On Fri, 14 Feb 2014 08:32:02 +0400
> Max Vlasov <max.vla...@gmail.com> wrote:
> 
>> From: Max Vlasov <max.vla...@gmail.com>
>> To: General Discussion of SQLite Database <sqlite-users@sqlite.org>
>> Reply-To: General Discussion of SQLite Database
>> <sqlite-users@sqlite.org> Date: Fri, 14 Feb 2014 08:32:02 +0400
>> Subject: Re: [sqlite] Once again about random values appearance
>>
>> On Fri, Feb 14, 2014 at 6:35 AM, James K. Lowden
>> <jklow...@schemamania.org>wrote:
>>
>>>>> select id, (select id from TestTable where id = abs(random() %
>>>>> 100)) as rndid from TestTable where id=rndid
>>> On Thu, 13 Feb 2014 07:26:55 -0500
>>> Richard Hipp <d...@sqlite.org> wrote:
>>>
>>>> It is undefined behavior, subject to change depending the specific
>>>> version of SQLite, compile-time options, optimization settings,
>>>> and the whim of the query planner.
>>> It should be defined.
>>>
>>> In the above query, random() should be evaluated once.  In the SQL
>>> model the user provides inputs once, and the system evaluates them
>>> once.
>>>
>>>
>> Once for the query or once for the row?
> 
> Once for the query.  
> 
> As a user you have no control how the system evaluates your query.
> The evaluation may change over time with different implementations, but
> the semantics of the query do not.  
> 
> Not long ago on this list we discussed 
> 
>       SELECT *, datetime('now') from T;
> 
> and the behavior was that the datetime function was called per-row,
> resulting in different times on different rows.  It was changed, the
> rationale IIRC to be compatible with the SQL standard and other DBMSs.  
> 
> Like datetime, random() is a nondeterministic function taking constant
> (but void) input.  It should be evaluated once, as provided. Where it
> appears in your query should not matter.  That would make it consistent
> with how other functions work, and with the SQL standard.  

Good in theory, bad in practice.
CURRENT_TIME = CURRENT_TIME was /almost always/ true before change (when it
happened to be false, it was /surprising/ and /counter-intuitive/ exception),
and just become /always/ true after change (no surprising change in behavior!).

RANDOM() = RANDOM() is /always false/ now, it will become /always true/ after
your suggested change.
It have much higher potential to break existing code, e.g.
   SELECT * FROM t ORDER BY RANDOM() LIMIT 1
will be completely broken (well, sure, it is not best way to select random
row(s) from table - it is overly expensive and unportable - but still much more
likely to be used - and relied on - in existing code).

Besides, datetime function behavior is specified by SQL standard - and RANDOM()
is not.

Then again, I, too, don't quite like how OP's queries - such as
   SELECT r <> r FROM (SELECT RANDOM() AS r FROM t)
behavior depends on whether query flattening was used or not (even though one
can write it off as "documented undefined behavior").
Or, that `SELECT RANDOM() AS r FROM t ORDER BY r` gives quite unexpected result.
I just don't think that same approach as with datetime function would be good in
this case.

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

Reply via email to