Uh oh!
There was an error while loading. Please reload this page.
fix time encoding to work with Cassandra 4 - #269
Conversation
Hey @Roguelazer, thanks (again) for the PR! Do you happen to have some sample code that you can share which exercises this issue? I ask because it looks like you're trying to call Cassandra::Utils.encode_time with a Ruby Time object with the expectation that you'll get something out that can be inserted into a column of timestamp type. The problem is that the driver tries to encode Time objects via encode_timestamp while encode_time is reserved for Cassandra::Time (https://github.com/datastax/ruby-driver/blob/master/lib/cassandra/util.rb#L94-L115). So you wind up with the following behaviour here: [mersault@linuxruby]$ irb2.5.1:001 > require'cassandra'=>true2.5.1:002 > Cassandra::Util.encode_timestamp(Time.now)=>"1634273394"2.5.1:003 > Cassandra::Util.encode_time(Time.now)=>"'2021-10-14 23:49:54 -0500'"2.5.1:004 > Cassandra::Util.encode_object(Time.now)=>"1634273394"2.5.1:005 > Cassandra::Util.encode_timestamp(Cassandra::Time.new(1000000000 * 300))Traceback(mostrecentcalllast):
3: from/home/mersault/.rvm/rubies/ruby-2.5.1/bin/irb:11:in`<main>' 2: from (irb):5 1: from /home/mersault/.rvm/gems/ruby-2.5.1@countapp/gems/cassandra-driver-3.2.5/lib/cassandra/util.rb:127:in `encode_timestamp'NoMethodError (undefined method `to_i'for#<Cassandra::Time:0x00000000031dcf88 @nanoseconds=300000000000>)Didyou mean? to_s2.5.1:006 > Cassandra::Util.encode_time(Cassandra::Time.new(1000000000 * 300))=>"'00:05:00.000'"2.5.1:007 > Cassandra::Util.encode_object(Cassandra::Time.new(1000000000 * 300))=>"'00:05:00.000'"Given that a Ruby top-level Time object maps to a "timestamp" CQL type while Cassandra::Time maps to a "time" type I'd expect that given the following: this code should work without issue: require'cassandra'require'cassandra/util'require'time'cluster=Cassandra.clustersession=cluster.connectstmt=session.prepare"insert into foo.bar (key,ts) values (?,?)"session.executestmt,arguments: [1,Time.now]And indeed that's exactly what I get; the code runs without an error of any kind and after execution I observe the following: That's with Ruby 2.5.1 (using cassandra-driver 3.2.5) against Cassandra 4.0.0. Please let me know if I've misunderstood something about your use case @Roguelazer. |
The default Ruby
.to_smethod for a Time results in output of%Y-%m-%d %H:%M:%S %z; note the space between the seconds and the time offset.In Cassandra 4.0, the validator for the
TIMESTAMPcolumn type is stricter and there cannot be a space between the fractional part and the timezone offset and it must match the formatyyyy-mm-dd[(T| )HH:MM:SS[.fff]][(+|-)NNNN].