Module: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::Quoting

Defined in:
activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb

Instance Method Summary collapse

Instance Method Details

#escape_bytea(value) ⇒ Object

Escapes binary strings for bytea input to the database.


6
7
8
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 6

def escape_bytea(value)
  PGconn.escape_bytea(value) if value
end

#quote(value, column = nil) ⇒ Object

Quotes PostgreSQL-specific data types for SQL input.


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 18

def quote(value, column = nil) #:nodoc:
  return super unless column && column.type

  sql_type = type_to_sql(column.type, column.limit, column.precision, column.scale)

  case value
  when Range
    if /range$/ =~ sql_type
      escaped = quote_string(PostgreSQLColumn.range_to_string(value))
      "'#{escaped}'::#{sql_type}"
    else
      super
    end
  when Array
    case sql_type
    when 'point' then super(PostgreSQLColumn.point_to_string(value))
    when 'json' then super(PostgreSQLColumn.json_to_string(value))
    else
      if column.array
        "'#{PostgreSQLColumn.array_to_string(value, column, self).gsub(/'/, "''")}'"
      else
        super
      end
    end
  when Hash
    case sql_type
    when 'hstore' then super(PostgreSQLColumn.hstore_to_string(value), column)
    when 'json' then super(PostgreSQLColumn.json_to_string(value), column)
    else super
    end
  when IPAddr
    case sql_type
    when 'inet', 'cidr' then super(PostgreSQLColumn.cidr_to_string(value), column)
    else super
    end
  when Float
    if value.infinite? && column.type == :datetime
      "'#{value.to_s.downcase}'"
    elsif value.infinite? || value.nan?
      "'#{value.to_s}'"
    else
      super
    end
  when Numeric
    if sql_type == 'money' || [:string, :text].include?(column.type)
      # Not truly string input, so doesn't require (or allow) escape string syntax.
      "'#{value}'"
    else
      super
    end
  when String
    case sql_type
    when 'bytea' then "'#{escape_bytea(value)}'"
    when 'xml'   then "xml '#{quote_string(value)}'"
    when /^bit/
      case value
      when /\A[01]*\Z/      then "B'#{value}'" # Bit-string notation
      when /\A[0-9A-F]*\Z/i then "X'#{value}'" # Hexadecimal notation
      end
    else
      super
    end
  else
    super
  end
end

#quote_column_name(name) ⇒ Object

Quotes column names for use in SQL queries.


169
170
171
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 169

def quote_column_name(name) #:nodoc:
  PGconn.quote_ident(name.to_s)
end

#quote_default_value(value, column) ⇒ Object

Does not quote function default values for UUID columns


188
189
190
191
192
193
194
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 188

def quote_default_value(value, column) #:nodoc:
  if column.type == :uuid && value =~ /\(\)/
    value
  else
    quote(value, column)
  end
end

#quote_string(s) ⇒ Object

Quotes strings for use in SQL input.


141
142
143
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 141

def quote_string(s) #:nodoc:
  @connection.escape(s)
end

#quote_table_name(name) ⇒ Object

Checks the following cases:

  • table_name

  • “table.name”

  • schema_name.table_name

  • schema_name.“table.name”

  • “schema.name”.table_name

  • “schema.name”.“table.name”


153
154
155
156
157
158
159
160
161
162
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 153

def quote_table_name(name)
  schema, name_part = extract_pg_identifier_from_name(name.to_s)

  unless name_part
    quote_column_name(schema)
  else
    table_name, name_part = extract_pg_identifier_from_name(name_part)
    "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
  end
end

#quote_table_name_for_assignment(table, attr) ⇒ Object


164
165
166
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 164

def quote_table_name_for_assignment(table, attr)
  quote_column_name(attr)
end

#quoted_date(value) ⇒ Object

Quote date/time values for use in SQL input. Includes microseconds if the value is a Time responding to usec.


175
176
177
178
179
180
181
182
183
184
185
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 175

def quoted_date(value) #:nodoc:
  result = super
  if value.acts_like?(:time) && value.respond_to?(:usec)
    result = "#{result}.#{sprintf("%06d", value.usec)}"
  end

  if value.year < 0
    result = result.sub(/^-/, "") + " BC"
  end
  result
end

#type_cast(value, column, array_member = false) ⇒ Object


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 85

def type_cast(value, column, array_member = false)
  return super(value, column) unless column

  case value
  when Range
    if /range$/ =~ column.sql_type
      PostgreSQLColumn.range_to_string(value)
    else
      super(value, column)
    end
  when NilClass
    if column.array && array_member
      'NULL'
    elsif column.array
      value
    else
      super(value, column)
    end
  when Array
    case column.sql_type
    when 'point' then PostgreSQLColumn.point_to_string(value)
    when 'json' then PostgreSQLColumn.json_to_string(value)
    else
      if column.array
        PostgreSQLColumn.array_to_string(value, column, self)
      else
        super(value, column)
      end
    end
  when String
    if 'bytea' == column.sql_type
      # Return a bind param hash with format as binary.
      # See http://deveiate.org/code/pg/PGconn.html#method-i-exec_prepared-doc
      # for more information
      { value: value, format: 1 }
    else
      super(value, column)
    end
  when Hash
    case column.sql_type
    when 'hstore' then PostgreSQLColumn.hstore_to_string(value, array_member)
    when 'json' then PostgreSQLColumn.json_to_string(value)
    else super(value, column)
    end
  when IPAddr
    if %w(inet cidr).include? column.sql_type
      PostgreSQLColumn.cidr_to_string(value)
    else
      super(value, column)
    end
  else
    super(value, column)
  end
end

#unescape_bytea(value) ⇒ Object

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.


13
14
15
# File 'activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb', line 13

def unescape_bytea(value)
  PGconn.unescape_bytea(value) if value
end