aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-06-17 16:37:08 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-17 17:01:09 -0600
commitc462c2bd07548449131359b8e507ce11a44e6cb5 (patch)
tree695411cfb1a4dd05f9fb29f4357ec351dd85ea0b /activerecord/lib
parent838c3d25e7ee904d7a9b084c5900491211eda0e9 (diff)
downloadrails-c462c2bd07548449131359b8e507ce11a44e6cb5.tar.gz
rails-c462c2bd07548449131359b8e507ce11a44e6cb5.tar.bz2
rails-c462c2bd07548449131359b8e507ce11a44e6cb5.zip
Ensure `OID::Array#type_cast_for_database` matches PG's quoting behavior
Also takes a step towards supporting types which use a character other than ',' for the delimiter (`box` is the only built in type for which this is the case)
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb26
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb2
2 files changed, 21 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
index b686e1e5ad..63f3be45de 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb
@@ -3,11 +3,12 @@ module ActiveRecord
module PostgreSQL
module OID # :nodoc:
class Array < Type::Value
- attr_reader :subtype
+ attr_reader :subtype, :delimiter
delegate :type, to: :subtype
- def initialize(subtype)
+ def initialize(subtype, delimiter = ',')
@subtype = subtype
+ @delimiter = delimiter
end
def type_cast_from_database(value)
@@ -55,7 +56,7 @@ module ActiveRecord
def cast_value_for_database(value)
if value.is_a?(::Array)
casted_values = value.map { |item| cast_value_for_database(item) }
- "{#{casted_values.join(',')}}"
+ "{#{casted_values.join(delimiter)}}"
else
quote_and_escape(subtype.type_cast_for_database(value))
end
@@ -66,13 +67,26 @@ module ActiveRecord
def quote_and_escape(value)
case value
when ::String
- value = value.gsub(/\\/, ARRAY_ESCAPE)
- value.gsub!(/"/,"\\\"")
- %("#{value}")
+ if string_requires_quoting?(value)
+ value = value.gsub(/\\/, ARRAY_ESCAPE)
+ value.gsub!(/"/,"\\\"")
+ %("#{value}")
+ else
+ value
+ end
when nil then "NULL"
else value
end
end
+
+ # See http://www.postgresql.org/docs/9.2/static/arrays.html#ARRAYS-IO
+ # for a list of all cases in which strings will be quoted.
+ def string_requires_quoting?(string)
+ string.empty? ||
+ string == "NULL" ||
+ string =~ /[\{\}"\\\s]/ ||
+ string.include?(delimiter)
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
index 28f7a4eafb..e396ff4a1e 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb
@@ -40,7 +40,7 @@ module ActiveRecord
def register_array_type(row)
if subtype = @store.lookup(row['typelem'].to_i)
- register row['oid'], OID::Array.new(subtype)
+ register row['oid'], OID::Array.new(subtype, row['typdelim'])
end
end