[Rails] bug in postgresql 'now' time handling??

Ara.T.Howard Ara.T.Howard at noaa.gov
Thu Mar 3 18:46:15 GMT 2005


On Thu, 3 Mar 2005, Dave Steinberg wrote:

> Well, it does work, but as you mentioned, it does introduce the subtle
> difference you mentioned.

and, of course, the subtlty depends on how long your transactin takes : the
longer it takes the worse the error becomes...  basically it'll work in
testing but not production - slippery.

> The problem I had when I wrote this patch originally was that CURRENT_DATE,
> CURRENT_TIMESTAMP, 'now', and 'now()' - all which would accomplish the
> desired effect in PostgreSQL wouldn't get properly sent up the chain of the
> AR call stack.  Maybe I just missed the following:
>
> Looking over the code again, I think if we switched to using 'now' as the
> value and modified the string_to_time function in abstract_adapter.rb to be:
>
>        def string_to_time(string)
>          return string if string.is_a?(Time)
> 	 return Time.now if string == 'now'
>          time_array = ParseDate.parsedate(string).compact
>          # treat 0000-00-00 00:00:00 as nil
>          Time.send(Base.default_timezone, *time_array) rescue nil
>        end
>
> (The second line, return Time.now... is my addition here - sorry its not a
> proper diff.)
>
> Then we'd have the desired result.  string_to_date would need a similar
> modification I believe.

i don't think this will work - acknowledging here that i've only read about
10% of the rails source.  here's why; you can only skin this cat two ways:

   - sychronize the postgresql adapters notion of 'now' with that of the
     database.  this means knowing if you're in a transaction or now, and even
     this is doomed to be a 'little' wrong since there is always some time that
     has elapsed between the time the db returns 'now' and the mapping to a
     ruby value.  if you track transactions you can be sure it's the same
     during a transaction but the first one will be a *tiny* bit off from what
     the db would have done on it's own.  this is fine if you transactions only
     interact with other rails code but evil if you use the db, transaction,
     and the concept of 'now' for some logic from other apps - it's a race
     condition.

   - do no synchronization - let the db handle the concept for you.  after all,
     it already knows if it's in a transaction or not.  this means NEVER
     calling Time::now to get the code, but doing something like

       def current_timestamp
         require 'time'
         Time::parse(execute('select current_timestamp').first)
       end

       alias now current_timestamp

     instead and ALWAYS using this to obtain the string/timeobj for the current
     time.  i'd have to read more to understand how awful things like timezone
     work there way into this idea though...

in anycase, i like the second approach for the reason that i delegates
handling of 'now' to postgresql - so it should be consistent with what users
of that db see in other applications.  how does this fit into rails' time
handling in general?  do all the adapters handle 'now' - if so what is the
expectation?  it would argue for the first method above too...


> Ara, I do not have time to put together a patch and test it at the moment,
> could you?

perhaps - i don't really have any time now either - but will make an effort.
it should be easy to do, i just have to collect enough information from this
list to understand the big picture first.

-a
-- 
===============================================================================
| EMAIL   :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE   :: 303.497.6469
| When you do something, you should burn yourself completely, like a good
| bonfire, leaving no trace of yourself.  --Shunryu Suzuki
===============================================================================


More information about the Rails mailing list