You are correct.
Even though the standard says 'statement stability', I think that is less
useful than transaction stability. I personally think a reference to 'now'
should be stable throughout a transaction (a static value set when 'now' first
accessed in a transaction and cleared on a commit or rollback [of the outer
transaction only -- not changed on interim savepoint operations]) would be the
most useful and logically consistent implementation.
If transactions are disabled then no static value is saved for the transaction
and the behavior stays as it is.
This would require that the value of 'now' be cached in the transaction
structure I suppose ...
On the other hand, if one knows that the value of 'now' is not stable then one
can always bind a parameter with the appropriate value set from the host
language (which is what I usually do anyway, even with other SQL
implementations that do claim to have either statement or transaction stable
concepts of 'now' since that is usually what one wants anyway).
> Keith Medcalf wrote:
> >> In C there are local variables, where you can save result of impure
> >> functions when it is important. There are no local variables in SQL
> >> - with even more extreme example shown in E.Pasma message nearby -
> >> `SELECT strftime('%f') AS q FROM t WHERE q <> q`;
> >> oh, by the way, `SELECT CURRENT_TIME AS q FROM t WHERE q <> q`
> >> trigger that bug too, I've just checked (and it took less than 2
> >> seconds to trigger).
> >
> > That is version specific. What version of SQLite are you using? The
> current version optimizes out the clause q <> q thusly:
>
> No, it is NOT version specific.
>
> strftime vs. CURRENT_TIME triggers racing differently (strftime trigger
> in inner
> loop [and return *random* rows, easily triggered in shell with big
> enough
> table], CURRENT_TIME trigger in outer loop [and *randomly* return all
> rows; not
> easy to trigger in shell, but still it is triggered by my perl script
> without
> much problem]), but still triggers it.
>
> (By the way, better optimizer should've moved strftime out of inner loop
> as
> well; and even better optimizer should've eliminated all repeated calls
> for pure
> functions with constant arguments; but that's just "missing optimization
> opportunity/missing feature", not a "real bug"; and even if that
> optimization
> was implemented, it still would not have fixed racing between
> DATE('now',$foo)
> and DATE('now',$bar), as in OP's query).
>
> > sqlite> .explain
> > sqlite> explain select value, current_time as q from x where q <> q
> and value < 1000000000;
> > SELECT item[0] = {0:0}
> > item[1] = FUNCTION:current_time() AS q
> > FROM {0,*} = x
> > WHERE AND(REGISTER(1),LT({0:0},REGISTER(4)))
> > END
> > addr opcode p1 p2 p3 p4 p5 comment
> > ---- ------------- ---- ---- ---- ------------- -- ------------
> -
> > 0 Trace 0 0 0 00
> > 1 Function 0 0 2 current_time(0) 00
> > 2 Function 0 0 3 current_time(0) 00
>
> ...And as you see, current_time function evaluated *many* times (and
> there are
> no caching *inside* of current_time function, in *any* sqlite version).
>
> > 3 Ne 3 1 2 72
> > 4 Integer 1000000000 4 0 00
> > 5 Goto 0 18 0 00
> > 6 VOpen 0 0 0 vtab:6E06F0:50B800 00
> > 7 Copy 4 7 0 00
> > 8 Integer 4 5 0 00
> > 9 Integer 1 6 0 00
> > 10 VFilter 0 16 5 00
> > 11 IfNot 1 15 1 00
> > 12 VColumn 0 0 8 00
> > 13 Function 0 0 9 current_time(0) 00
> > 14 ResultRow 8 2 0 00
> > 15 VNext 0 11 0 00
> > 16 Close 0 0 0 00
> > 17 Halt 0 0 0 00
> > 18 Transaction 0 0 0 00
> > 19 VerifyCookie 0 1 0 00
> > 20 Goto 0 6 0 00
> >
> > So you will either get all rows or none.
>
> And? It should ALWAYS return NONE. It does not.
>
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users