Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • T torque-postgresql
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 6
    • Issues 6
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Carlos
  • torque-postgresql
  • Issues
  • #32
Closed
Open
Issue created Apr 01, 2019 by Mikhail Titov@mltContributor

Type casting support is missing

It would be nice to have native ranges with support for infinity with a minimum efforts.

>> rng = ActiveRecord::Base.connection.select_one("select tstzrange('2019-01-01', 'Infinity', '[)')")['tstzrange']
=> "[\"2019-01-01 00:00:00+00\",infinity)"
>> rng.class
=> String
>> rng = ActiveRecord::Base.connection.select_all("select tstzrange('2019-01-01', 'Infinity', '[)')")
=> #<ActiveRecord::Result:0x0000000012ffde00 @columns=["tstzrange"], @rows=[["[\"2019-01-01 00:00:00+00\",infinity)"]], @hash_rows=nil, @column_types={"tstzrange"=>#<ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Range:0x0000000013936850 @subtype=#<ActiveRecord::ConnectionAdapters::PostgreSQL::OID::DateTime:0x00000000139368a0 @precision=nil, @scale=nil, @limit=nil>, @type=:tstzrange>}>
>> rng.column_types['tstzrange'].cast rng.first['tstzrange']
=> 2019-01-01 00:00:00 UTC...#<Date::Infinity:0x0000000010e19f00 @d=1>

Something along these lines could be worked into a concern or something

module ActiveRecordResultCast

  extend ActiveSupport::Concern

  def cast
    if Rails::VERSION::MAJOR >= 5
      self.map{|o| o.each{|k, v| o[k] = column_types[k].cast v}}
    else
      ...
    end
  end
end

ActiveRecord::Result.send(:include, ActiveRecordResultCast)

Then

>> rng.cast
=> [{"tstzrange"=>2019-01-01 00:00:00 UTC...#<Date::Infinity:0x000000000b314600 @d=1>}]
>> rng.cast.first['tstzrange']
=> 2019-01-01 00:00:00 UTC...#<Date::Infinity:0x000000000b314600 @d=1>

I don't know whether there is a way to make it work with like select_one without explicit #cast call. Would be nice though…

Edit

I also have

module DatetimeInfinity
  extend ActiveSupport::Concern

  def infinity(options = {})
    options[:negative] ? -::DateTime::Infinity.new : ::DateTime::Infinity.new
  end
end

ActiveRecord::ConnectionAdapters::PostgreSQL::OID::DateTime.send(:include, DatetimeInfinity)

Otherwise you end up with

>> rng.cast.first['tstzrange'].last.class
=> Float
Assignee
Assign to
Time tracking