Rails PG adapter: Properly quote Infinity and NaN

refs CNVS-1368

This backports a Rails 3.1 fix as a monkey patch to our Rails 2.3.X
installation. It should address unquoted instances of Infinity we are
seeing occasionally in web conference queries.

The test plan for this is not UI-based, since I was unable to reproduce
by poking around the BigBlueButton web conferences UI.

Test Plan:
 - Inside a ./script/console, choose a model with a column of type
   "float", like WebConference
 - Try to create it with 0.0/0 and 1.0/0 as the value of that column,
   like BigBlueButtonConference.new(:duration => 0.0/0).save(false)
 - Verify that no database exceptions are thrown

The official Rails commit with this fix is here:

06c23c4c7f

Change-Id: I41141054aa06c88ed121a33e6e2da578ff9be82d
Reviewed-on: https://gerrit.instructure.com/17317
Reviewed-by: Cody Cutrer <cody@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Clare Hetherington <clare@instructure.com>
This commit is contained in:
Paul Hinze 2013-01-30 17:10:49 -07:00
parent 67d06f0cda
commit 4de8992575
2 changed files with 66 additions and 0 deletions

View File

@ -203,4 +203,43 @@ else
end
end
end
# Handle quoting properly for Infinity and NaN. This fix exists in Rails 3.1
# and can be safely removed once we upgrade.
#
# Adapted from: https://github.com/rails/rails/commit/06c23c4c7ff842f7c6237f3ac43fc9d19509a947
#
# This patch is covered by tests in spec/initializers/active_record_quoting_spec.rb
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do
# Quotes PostgreSQL-specific data types for SQL input.
def quote(value, column = nil) #:nodoc:
if value.kind_of?(String) && column && column.type == :binary
"'#{escape_bytea(value)}'"
elsif value.kind_of?(String) && column && column.sql_type == 'xml'
"xml '#{quote_string(value)}'"
elsif value.kind_of?(Float)
if value.infinite? && column && column.type == :datetime
"'#{value.to_s.downcase}'"
elsif value.infinite? || value.nan?
"'#{value.to_s}'"
else
super
end
elsif value.kind_of?(Numeric) && column && column.sql_type == 'money'
# Not truly string input, so doesn't require (or allow) escape string syntax.
"'#{value.to_s}'"
elsif value.kind_of?(String) && column && column.sql_type =~ /^bit/
case value
when /^[01]*$/
"B'#{value}'" # Bit-string notation
when /^[0-9A-F]*$/i
"X'#{value}'" # Hexadecimal notation
end
else
super
end
end
end
end
end

View File

@ -0,0 +1,27 @@
require File.expand_path('../spec_helper', File.dirname( __FILE__ ))
module ActiveRecord
module ConnectionAdapters
describe PostgreSQLAdapter do
describe 'quoting' do
# These tests are adapted from the ActiveRecord tests located here:
# https://github.com/rails/rails/blob/06c23c4c7ff842f7c6237f3ac43fc9d19509a947/activerecord/test/cases/adapters/postgresql/quoting_test.rb
before do
@conn = ActiveRecord::Base.connection
end
it 'properly quotes NaN' do
nan = 0.0/0
c = Column.new(nil, 1, 'float')
assert_equal "'NaN'", @conn.quote(nan, c)
end
it 'properly quotes Infinity' do
infinity = 1.0/0
c = Column.new(nil, 1, 'float')
assert_equal "'Infinity'", @conn.quote(infinity, c)
end
end
end
end
end