[Rails] bug in postgresql 'now' time handling??
Ara.T.Howard
Ara.T.Howard at noaa.gov
Thu Mar 3 17:10:05 GMT 2005
line 212 of postgresql_adapter.rb is
return Time.now.to_s if value =~ /^\('now'::text\)::(date|timestamp)/
i don't think this will work. in postgresql the field 'now' is pinned to the
SAME TIME for the duration of a transaction. eg. if you do
begin transaction;
insert into t values(42, 'now');
# sleep one minute
insert into t values(42, 'now');
# sleep one minute
insert into t values(42, 'now');
commit;
and fields will have the same timestamp. for example:
[ahoward at localhost ~]$ cat a.rb
require 'open3'
stdin, stdout, stderr = Open3::popen3 'psql'
stdin.puts 'drop table t;'
stdin.puts 'begin transaction;'
stdin.puts 'create table t(ts timestamp);'
4.times{ stdin.puts "insert into t values('now');"; sleep 1}
stdin.puts 'end transaction;'
stdin.puts 'select * from t;'
stdin.close
puts stdout.read
[ahoward at localhost ~]$ ruby a.rb
...
...
...
ts
----------------------------
2005-03-03 09:53:54.290717
2005-03-03 09:53:54.290717
2005-03-03 09:53:54.290717
2005-03-03 09:53:54.290717
(4 rows)
it looks like (from only reading the code) that table_structure will map the
default values of each field in
column_defaults.collect do |row|
field = row[0]
type = type_as_string(row[3], row[2])
default = default_value(row[1])
length = row[2]
[field, type, default, length]
end
so, each time default_value sees 'now' it will call Time::now.to_s - and this
will be different each time. it may not be obvious right away since, if the
code runs quickly and you are storing only to second resolution you might not
notice, but this could lead to subtle errors.
in any case, i may be way off base here : but what i've done in the past with
my own postgresql orms is to have a class variable @@now, which gets reset
each time a transaction is started using
select current_timestamp;
and is then used during transaction for any 'now' -> ruby translations. of
course, if you are not using transactions this must be reset for each
statement. basically some sort of lazy evaluation which depends on the
transaction context is needed to do the mapping of the 'now' string to a time
object...
can anyone comment on this?
kind regards.
-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