<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -68,72 +68,6 @@ module ActiveRecord
           super
         end
   
-        # Escapes binary strings for bytea input to the database.
-        def self.string_to_binary(value)
-          if PGconn.respond_to?(:escape_bytea)
-            self.class.module_eval do
-              define_method(:string_to_binary) do |value|
-                PGconn.escape_bytea(value) if value
-              end
-            end
-          else
-            self.class.module_eval do
-              define_method(:string_to_binary) do |value|
-                if value
-                  result = ''
-                  value.each_byte { |c| result &lt;&lt; sprintf('\\\\%03o', c) }
-                  result
-                end
-              end
-            end
-          end
-          self.class.string_to_binary(value)
-        end
-  
-        # Unescapes bytea output from a database to the binary string it represents.
-        def self.binary_to_string(value)
-          # In each case, check if the value actually is escaped PostgreSQL bytea output
-          # or an unescaped Active Record attribute that was just written.
-          if PGconn.respond_to?(:unescape_bytea)
-            self.class.module_eval do
-              define_method(:binary_to_string) do |value|
-                if value =~ /\\\d{3}/
-                  PGconn.unescape_bytea(value)
-                else
-                  value
-                end
-              end
-            end
-          else
-            self.class.module_eval do
-              define_method(:binary_to_string) do |value|
-                if value =~ /\\\d{3}/
-                  result = ''
-                  i, max = 0, value.size
-                  while i &lt; max
-                    char = value[i]
-                    if char == ?\\
-                      if value[i+1] == ?\\
-                        char = ?\\
-                        i += 1
-                      else
-                        char = value[i+1..i+3].oct
-                        i += 3
-                      end
-                    end
-                    result &lt;&lt; char
-                    i += 1
-                  end
-                  result
-                else
-                  value
-                end
-              end
-            end
-          end
-          self.class.binary_to_string(value)
-        end  
-  
         # Maps PostgreSQL-specific data types to logical Rails types.
         def simplified_type(field_type)
           case field_type
@@ -347,10 +281,78 @@ module ActiveRecord
 
       # QUOTING ==================================================
 
+      # Escapes binary strings for bytea input to the database.
+      def escape_bytea(value)
+        if PGconn.respond_to?(:escape_bytea)
+          self.class.instance_eval do
+            define_method(:escape_bytea) do |value|
+              PGconn.escape_bytea(value) if value
+            end
+          end
+        else
+          self.class.instance_eval do
+            define_method(:escape_bytea) do |value|
+              if value
+                result = ''
+                value.each_byte { |c| result &lt;&lt; sprintf('\\\\%03o', c) }
+                result
+              end
+            end
+          end
+        end
+        escape_bytea(value)
+      end
+
+      # Unescapes bytea output from a database to the binary string it represents.
+      # NOTE: This is NOT an inverse of escape_bytea! This is only to be used
+      #       on escaped binary output from database drive.
+      def unescape_bytea(value)
+        # In each case, check if the value actually is escaped PostgreSQL bytea output
+        # or an unescaped Active Record attribute that was just written.
+        if PGconn.respond_to?(:unescape_bytea)
+          self.class.instance_eval do
+            define_method(:unescape_bytea) do |value|
+              if value =~ /\\\d{3}/
+                PGconn.unescape_bytea(value)
+              else
+                value
+              end
+            end
+          end
+        else
+          self.class.instance_eval do
+            define_method(:unescape_bytea) do |value|
+              if value =~ /\\\d{3}/
+                result = ''
+                i, max = 0, value.size
+                while i &lt; max
+                  char = value[i]
+                  if char == ?\\
+                    if value[i+1] == ?\\
+                      char = ?\\
+                      i += 1
+                    else
+                      char = value[i+1..i+3].oct
+                      i += 3
+                    end
+                  end
+                  result &lt;&lt; char
+                  i += 1
+                end
+                result
+              else
+                value
+              end
+            end
+          end
+        end
+        unescape_bytea(value)
+      end
+
       # Quotes PostgreSQL-specific data types for SQL input.
       def quote(value, column = nil) #:nodoc:
         if value.kind_of?(String) &amp;&amp; column &amp;&amp; column.type == :binary
-          &quot;#{quoted_string_prefix}'#{column.class.string_to_binary(value)}'&quot;
+          &quot;#{quoted_string_prefix}'#{escape_bytea(value)}'&quot;
         elsif value.kind_of?(String) &amp;&amp; column &amp;&amp; column.sql_type =~ /^xml$/
           &quot;xml '#{quote_string(value)}'&quot;
         elsif value.kind_of?(Numeric) &amp;&amp; column &amp;&amp; column.sql_type =~ /^money$/
@@ -463,11 +465,20 @@ module ActiveRecord
 
       # create a 2D array representing the result set
       def result_as_array(res) #:nodoc:
+        # check if we have any binary column and if they need escaping
+        unescape_col = []
+        for j in 0...res.nfields do
+          # unescape string passed BYTEA field (OID == 17)
+          unescape_col &lt;&lt; ( res.fformat(j)==0 and res.ftype(j)==17 )
+        end
+
         ary = []
         for i in 0...res.ntuples do
           ary &lt;&lt; []
           for j in 0...res.nfields do
-            ary[i] &lt;&lt; res.getvalue(i,j)
+            data = res.getvalue(i,j)
+            data = unescape_bytea(data) if unescape_col[j] and data.is_a?(String)
+            ary[i] &lt;&lt; data
           end
         end
         return ary</diff>
      <filename>activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>5c97d4ff29cfd944da751f01177a3024626d57bb</id>
    </parent>
  </parents>
  <author>
    <name>Adam Majer</name>
    <login></login>
    <email>adamm@zombino.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/932dffc559ef188eb31d0223116e9da361833488</url>
  <id>932dffc559ef188eb31d0223116e9da361833488</id>
  <committed-date>2008-10-25T03:54:48-07:00</committed-date>
  <authored-date>2008-09-19T19:38:39-07:00</authored-date>
  <message>Fix binary data corruption bug in PostgreSQL adaptor

  1. Move the binary escape/unescape from column to the driver - we should store binary data AR just like most other adaptors
  2. check to make sure we only unescape bytea data
     PGresult.ftype( column ) == 17
  that is passed to us in escaped format
     PGresult.fformat( column ) == 0

Signed-off-by: Michael Koziarski &lt;michael@koziarski.com&gt;
[#1063 state:committed]</message>
  <tree>3b0afabc3f70537b143b8c468182bcc329bbb4c9</tree>
  <committer>
    <name>Michael Koziarski</name>
    <login>NZKoz</login>
    <email>michael@koziarski.com</email>
  </committer>
</commit>
