Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 958 lines (822 sloc) 32.382 kb
db045db @dhh Initial
dhh authored
1 require 'active_record/connection_adapters/abstract_adapter'
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
2 require 'active_record/connection_adapters/statement_pool'
9fd3bde @tenderlove many of the OIDs mapped and implemented
tenderlove authored
3 require 'active_record/connection_adapters/postgresql/oid'
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
4 require 'active_record/connection_adapters/postgresql/cast'
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
5 require 'active_record/connection_adapters/postgresql/array_parser'
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
6 require 'active_record/connection_adapters/postgresql/quoting'
7 require 'active_record/connection_adapters/postgresql/schema_statements'
8 require 'active_record/connection_adapters/postgresql/database_statements'
9 require 'active_record/connection_adapters/postgresql/referential_integrity'
fd39847 @tenderlove prepared statements can be disabled
tenderlove authored
10 require 'arel/visitors/bind_visitor'
3d19b35 @tenderlove fetch result row arrays from pg in C and return early if there are no mo...
tenderlove authored
11
12 # Make sure we're using pg high enough for PGResult#values
13 gem 'pg', '~> 0.11'
df9abfa @tenderlove require pg when this adapter is loaded
tenderlove authored
14 require 'pg'
db045db @dhh Initial
dhh authored
15
0e1c651 @danmcclain Removes NetAddr dependency
danmcclain authored
16 require 'ipaddr'
17
db045db @dhh Initial
dhh authored
18 module ActiveRecord
79af9e9 @frodsan nodoc AR::ConnectionHandling for adapters [ci skip]
frodsan authored
19 module ConnectionHandling # :nodoc:
19b52d3 @rafaelfranca Use whitelist to pass valid connection parameters to PGConn.
rafaelfranca authored
20 VALID_CONN_PARAMS = [:host, :hostaddr, :port, :dbname, :user, :password, :connect_timeout,
21 :client_encoding, :options, :application_name, :fallback_application_name,
22 :keepalives, :keepalives_idle, :keepalives_interval, :keepalives_count,
950ef05 @larskanis Add parameter :sslcompression to PostgreSQL adapter.
larskanis authored
23 :tty, :sslmode, :requiressl, :sslcompression, :sslcert, :sslkey,
24 :sslrootcert, :sslcrl, :requirepeer, :krbsrvname, :gsslib, :service]
19b52d3 @rafaelfranca Use whitelist to pass valid connection parameters to PGConn.
rafaelfranca authored
25
db045db @dhh Initial
dhh authored
26 # Establishes a connection to the database that's used by all Active Record objects
79af9e9 @frodsan nodoc AR::ConnectionHandling for adapters [ci skip]
frodsan authored
27 def postgresql_connection(config)
f63fff6 @tenderlove delete reaping frequency from the db config
tenderlove authored
28 conn_params = config.symbolize_keys
db045db @dhh Initial
dhh authored
29
19b52d3 @rafaelfranca Use whitelist to pass valid connection parameters to PGConn.
rafaelfranca authored
30 conn_params.delete_if { |_, v| v.nil? }
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
31
32 # Map ActiveRecords param names to PGs.
33 conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
34 conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
db045db @dhh Initial
dhh authored
35
19b52d3 @rafaelfranca Use whitelist to pass valid connection parameters to PGConn.
rafaelfranca authored
36 # Forward only valid config params to PGconn.connect.
37 conn_params.keep_if { |k, _| VALID_CONN_PARAMS.include?(k) }
38
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
39 # The postgres drivers don't allow the creation of an unconnected PGconn object,
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
40 # so just pass a nil connection object for the time being.
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
41 ConnectionAdapters::PostgreSQLAdapter.new(nil, logger, conn_params, config)
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
42 end
43 end
c699a3e @dhh Added option :schema_order to the PostgreSQL adapter to support the use ...
dhh authored
44
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
45 module ConnectionAdapters
46 # PostgreSQL-specific extensions to column definitions in a table.
47 class PostgreSQLColumn < Column #:nodoc:
4734e4e @kennyj Migration dump UUID default functions to schema.rb. Fixes #10751.
kennyj authored
48 attr_accessor :array, :default_function
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
49 # Instantiates a new PostgreSQL column definition in a table.
c50cb4a @tenderlove PG column consults oid types when typecasting
tenderlove authored
50 def initialize(name, default, oid_type, sql_type = nil, null = true)
51 @oid_type = oid_type
4734e4e @kennyj Migration dump UUID default functions to schema.rb. Fixes #10751.
kennyj authored
52 default_value = self.class.extract_value_from_default(default)
53 @default_function = default if !default_value && default && default =~ /.+\(.*\)/
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
54 if sql_type =~ /\[\]$/
55 @array = true
4734e4e @kennyj Migration dump UUID default functions to schema.rb. Fixes #10751.
kennyj authored
56 super(name, default_value, sql_type[0..sql_type.length - 3], null)
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
57 else
58 @array = false
4734e4e @kennyj Migration dump UUID default functions to schema.rb. Fixes #10751.
kennyj authored
59 super(name, default_value, sql_type, null)
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
60 end
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
61 end
5821096 Multiple fixes and optimizations in PostgreSQL adapter, allowing ruby-po...
Tobias Lütke authored
62
61355c0 @tenderlove clearing up many warnings, removing unnecessary regular expresion compar...
tenderlove authored
63 # :stopdoc:
64 class << self
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
65 include ConnectionAdapters::PostgreSQLColumn::Cast
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
66 include ConnectionAdapters::PostgreSQLColumn::ArrayParser
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
67 attr_accessor :money_precision
61355c0 @tenderlove clearing up many warnings, removing unnecessary regular expresion compar...
tenderlove authored
68 end
69 # :startdoc:
70
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
71 # Extracts the value from a PostgreSQL column default definition.
72 def self.extract_value_from_default(default)
73 # This is a performance optimization for Ruby 1.9.2 in development.
74 # If the value is nil, we return nil straight away without checking
75 # the regular expressions. If we check each regular expression,
76 # Regexp#=== will call NilClass#to_str, which will trigger
77 # method_missing (defined by whiny nil in ActiveSupport) which
78 # makes this method very very slow.
79 return default unless default
80
81 case default
af1ef85 @slbug Add postgresql range types support
slbug authored
82 when /\A'(.*)'::(num|date|tstz|ts|int4|int8)range\z/m
83 $1
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
84 # Numeric types
661365e @subwindow Correctly parse bigint defaults in PostgreSQL
subwindow authored
85 when /\A\(?(-?\d+(\.\d*)?\)?(::bigint)?)\z/
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
86 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
87 # Character types
2da85ed @arturopie #7914 get default value when type uses schema name
arturopie authored
88 when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
78f6268 @dmarkow Handle single quotes in PostgreSQL default column values
dmarkow authored
89 $1.gsub(/''/, "'")
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
90 # Binary data types
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
91 when /\A'(.*)'::bytea\z/m
92 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
93 # Date/time types
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
94 when /\A'(.+)'::(?:time(?:stamp)? with(?:out)? time zone|date)\z/
95 $1
96 when /\A'(.*)'::interval\z/
97 $1
98 # Boolean type
99 when 'true'
100 true
101 when 'false'
102 false
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
103 # Geometric types
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
104 when /\A'(.*)'::(?:point|line|lseg|box|"?path"?|polygon|circle)\z/
105 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
106 # Network address types
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
107 when /\A'(.*)'::(?:cidr|inet|macaddr)\z/
108 $1
109 # Bit string types
110 when /\AB'(.*)'::"?bit(?: varying)?"?\z/
111 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
112 # XML type
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
113 when /\A'(.*)'::xml\z/m
114 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
115 # Arrays
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
116 when /\A'(.*)'::"?\D+"?\[\]\z/
117 $1
f7b915b @tenderlove Merge branch 'joelhoffman-postgres_schema_builder' into instance_reader
tenderlove authored
118 # Hstore
119 when /\A'(.*)'::hstore\z/
120 $1
3b516b5 @guedes ActiveRecord support to PostgreSQL 9.2 JSON type
guedes authored
121 # JSON
122 when /\A'(.*)'::json\z/
123 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
124 # Object identifier types
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
125 when /\A-?\d+\z/
126 $1
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
127 else
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
128 # Anything else is blank, some user type, or some function
129 # and we can't know the value of that, so return nil.
130 nil
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
131 end
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
132 end
8885b2d @miloops Refactor to calculations. Migration's versions are string not integer. A...
miloops authored
133
5ac2341 @senny cast hstore values on write to be consistent with reading from the db.
senny authored
134 def type_cast_for_write(value)
135 if @oid_type.respond_to?(:type_cast_for_write)
136 @oid_type.type_cast_for_write(value)
137 else
138 super
139 end
140 end
141
c50cb4a @tenderlove PG column consults oid types when typecasting
tenderlove authored
142 def type_cast(value)
143 return if value.nil?
144 return super if encoded?
145
146 @oid_type.type_cast value
147 end
148
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
149 private
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
150
151 def extract_limit(sql_type)
152 case sql_type
153 when /^bigint/i; 8
154 when /^smallint/i; 2
155 when /^timestamp/i; nil
156 else super
157 end
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
158 end
159
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
160 # Extracts the scale from PostgreSQL-specific data types.
161 def extract_scale(sql_type)
162 # Money type has a fixed scale of 2.
163 sql_type =~ /^money/ ? 2 : super
164 end
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
165
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
166 # Extracts the precision from PostgreSQL-specific data types.
167 def extract_precision(sql_type)
168 if sql_type == 'money'
169 self.class.money_precision
170 elsif sql_type =~ /timestamp/i
171 $1.to_i if sql_type =~ /\((\d+)\)/
172 else
173 super
174 end
a9a1270 @tenderlove fixing indentation, moving class methods together
tenderlove authored
175 end
176
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
177 # Maps PostgreSQL-specific data types to logical Rails types.
178 def simplified_type(field_type)
179 case field_type
180 # Numeric and monetary types
181 when /^(?:real|double precision)$/
182 :float
183 # Monetary types
184 when 'money'
185 :decimal
186 when 'hstore'
187 :hstore
e209107 @robworley Support for PostgreSQL's ltree data type.
robworley authored
188 when 'ltree'
189 :ltree
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
190 # Network address types
191 when 'inet'
192 :inet
193 when 'cidr'
194 :cidr
195 when 'macaddr'
196 :macaddr
197 # Character types
198 when /^(?:character varying|bpchar)(?:\(\d+\))?$/
199 :string
200 # Binary data types
201 when 'bytea'
202 :binary
203 # Date/time types
204 when /^timestamp with(?:out)? time zone$/
205 :datetime
319482d @senny postgres, map scaled intervals to string datatype (#7518)
senny authored
206 when /^interval(?:|\(\d+\))$/
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
207 :string
208 # Geometric types
209 when /^(?:point|line|lseg|box|"?path"?|polygon|circle)$/
210 :string
211 # Bit strings
212 when /^bit(?: varying)?(?:\(\d+\))?$/
213 :string
214 # XML type
215 when 'xml'
216 :xml
217 # tsvector type
218 when 'tsvector'
219 :tsvector
220 # Arrays
221 when /^\D+\[\]$/
222 :string
223 # Object identifier types
224 when 'oid'
225 :integer
226 # UUID type
227 when 'uuid'
228 :uuid
9a4a095 @le0pard AR supporting new intrange data type on PostgreSQL >= 9.2
le0pard authored
229 # JSON type
230 when 'json'
231 :json
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
232 # Small and big integer types
233 when /^(?:small|big)int$/
234 :integer
af1ef85 @slbug Add postgresql range types support
slbug authored
235 when /(num|date|tstz|ts|int4|int8)range$/
236 field_type.to_sym
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
237 # Pass through all types that are not specific to PostgreSQL.
238 else
239 super
240 end
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
241 end
db045db @dhh Initial
dhh authored
242 end
243
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
244 # The PostgreSQL adapter works with the native C (https://bitbucket.org/ged/ruby-pg) driver.
1dc0b2a @dhh Added documentation for database adapters to visible RDoc
dhh authored
245 #
246 # Options:
247 #
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
248 # * <tt>:host</tt> - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets,
249 # the default is to connect to localhost.
dc4eec1 @lifo Merge docrails:
lifo authored
250 # * <tt>:port</tt> - Defaults to 5432.
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
251 # * <tt>:username</tt> - Defaults to be the same as the operating system name of the user running the application.
252 # * <tt>:password</tt> - Password to be used if the server demands password authentication.
253 # * <tt>:database</tt> - Defaults to be the same as the user name.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
254 # * <tt>:schema_search_path</tt> - An optional schema search path for the connection given
0034b78 @smartinez87 Remove extra white spaces on ActiveRecord docs.
smartinez87 authored
255 # as a string of comma-separated schema names. This is backward-compatible with the <tt>:schema_order</tt> option.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
256 # * <tt>:encoding</tt> - An optional client encoding that is used in a <tt>SET client_encoding TO
1ce40ca @neerajdotname ensuring that description does not exceed 100 columns
neerajdotname authored
257 # <encoding></tt> call on the connection.
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
258 # * <tt>:min_messages</tt> - An optional client min messages that is used in a
1ce40ca @neerajdotname ensuring that description does not exceed 100 columns
neerajdotname authored
259 # <tt>SET client_min_messages TO <min_messages></tt> call on the connection.
97d06e8 @sodabrew Session variables for mysql, mysql2, and postgresql adapters can be set
sodabrew authored
260 # * <tt>:variables</tt> - An optional hash of additional parameters that
261 # will be used in <tt>SET SESSION key = val</tt> calls on the connection.
28fc893 @AvnerCohen Fixed unclosing tag
AvnerCohen authored
262 # * <tt>:insert_returning</tt> - An optional boolean to control the use or <tt>RETURNING</tt> for <tt>INSERT</tt> statements
cd6ddc8 @dougcole refactor configuration of insert_returning
dougcole authored
263 # defaults to true.
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
264 #
265 # Any further options are used as connection parameters to libpq. See
266 # http://www.postgresql.org/docs/9.1/static/libpq-connect.html for the
267 # list of parameters.
268 #
269 # In addition, default connection parameters of libpq can be set per environment variables.
270 # See http://www.postgresql.org/docs/9.1/static/libpq-envars.html .
1dc0b2a @dhh Added documentation for database adapters to visible RDoc
dhh authored
271 class PostgreSQLAdapter < AbstractAdapter
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
272 class ColumnDefinition < ActiveRecord::ConnectionAdapters::ColumnDefinition
273 attr_accessor :array
274 end
275
5d0ca74 @senny Support PostgreSQL specific column types when using `change_table`.
senny authored
276 module ColumnMethods
b297911 @tenderlove use inheritence to deal with custom methods
tenderlove authored
277 def xml(*args)
278 options = args.extract_options!
279 column(args[0], 'xml', options)
280 end
714b4a8 Added tsvector Datatype Support
Benjamin Fritsch authored
281
282 def tsvector(*args)
283 options = args.extract_options!
284 column(args[0], 'tsvector', options)
285 end
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
286
af1ef85 @slbug Add postgresql range types support
slbug authored
287 def int4range(name, options = {})
288 column(name, 'int4range', options)
289 end
290
291 def int8range(name, options = {})
292 column(name, 'int8range', options)
293 end
294
295 def tsrange(name, options = {})
296 column(name, 'tsrange', options)
297 end
298
299 def tstzrange(name, options = {})
300 column(name, 'tstzrange', options)
301 end
302
303 def numrange(name, options = {})
304 column(name, 'numrange', options)
305 end
306
307 def daterange(name, options = {})
308 column(name, 'daterange', options)
309 end
310
8cb7bc8 @tenderlove pg columns should understand the hstore type
tenderlove authored
311 def hstore(name, options = {})
312 column(name, 'hstore', options)
313 end
f7b8fbd @danmcclain Adds migration and schema dump support for INET, CIDR, and MACADDR
danmcclain authored
314
e209107 @robworley Support for PostgreSQL's ltree data type.
robworley authored
315 def ltree(name, options = {})
316 column(name, 'ltree', options)
317 end
318
f7b8fbd @danmcclain Adds migration and schema dump support for INET, CIDR, and MACADDR
danmcclain authored
319 def inet(name, options = {})
320 column(name, 'inet', options)
321 end
322
323 def cidr(name, options = {})
324 column(name, 'cidr', options)
325 end
326
327 def macaddr(name, options = {})
328 column(name, 'macaddr', options)
329 end
12e9a75 @etehtsea Add uuid type support to PostgreSQL adapter
etehtsea authored
330
331 def uuid(name, options = {})
332 column(name, 'uuid', options)
333 end
3b516b5 @guedes ActiveRecord support to PostgreSQL 9.2 JSON type
guedes authored
334
335 def json(name, options = {})
336 column(name, 'json', options)
337 end
5d0ca74 @senny Support PostgreSQL specific column types when using `change_table`.
senny authored
338 end
339
340 class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
341 include ColumnMethods
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
342
55c40c0 @chadmoone allow override of uuid_generate_v4() default by passing default: nil
chadmoone authored
343 # Defines the primary key field.
344 # Use of the native PostgreSQL UUID type is supported, and can be used
345 # by defining your tables as such:
346 #
347 # create_table :stuffs, id: :uuid do |t|
348 # t.string :content
349 # t.timestamps
350 # end
351 #
352 # By default, this will use the +uuid_generate_v4()+ function from the
14a75a5 @carlosantoniodasilva Improve docs for postgresql with uuid primary keys [ci skip]
carlosantoniodasilva authored
353 # +uuid-ossp+ extension, which MUST be enabled on your database. To enable
55c40c0 @chadmoone allow override of uuid_generate_v4() default by passing default: nil
chadmoone authored
354 # the +uuid-ossp+ extension, you can use the +enable_extension+ method in your
14a75a5 @carlosantoniodasilva Improve docs for postgresql with uuid primary keys [ci skip]
carlosantoniodasilva authored
355 # migrations. To use a UUID primary key without +uuid-ossp+ enabled, you can
356 # set the +:default+ option to +nil+:
55c40c0 @chadmoone allow override of uuid_generate_v4() default by passing default: nil
chadmoone authored
357 #
358 # create_table :stuffs, id: false do |t|
359 # t.primary_key :id, :uuid, default: nil
360 # t.uuid :foo_id
361 # t.timestamps
362 # end
363 #
364 # You may also pass a different UUID generation function from +uuid-ossp+
365 # or another library.
366 #
14a75a5 @carlosantoniodasilva Improve docs for postgresql with uuid primary keys [ci skip]
carlosantoniodasilva authored
367 # Note that setting the UUID primary key default value to +nil+ will
368 # require you to assure that you always provide a UUID value before saving
369 # a record (as primary keys cannot be +nil+). This might be done via the
370 # +SecureRandom.uuid+ method and a +before_save+ callback, for instance.
bc8ebef @tenderlove add uuid primary key support
tenderlove authored
371 def primary_key(name, type = :primary_key, options = {})
2b5e4f7 @tenderlove Revert "Merge pull request #10455 from patricksrobertson/bigserial_id_no...
tenderlove authored
372 return super unless type == :uuid
373 options[:default] = options.fetch(:default, 'uuid_generate_v4()')
bc8ebef @tenderlove add uuid primary key support
tenderlove authored
374 options[:primary_key] = true
375 column name, type, options
376 end
377
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
378 def column(name, type = nil, options = {})
379 super
380 column = self[name]
381 column.array = options[:array]
382
383 self
384 end
385
386 private
387
4371c5c @pftg Removed redundant xml override from pg adapter
pftg authored
388 def create_column_definition(name, type)
389 ColumnDefinition.new name, type
390 end
b297911 @tenderlove use inheritence to deal with custom methods
tenderlove authored
391 end
392
5d0ca74 @senny Support PostgreSQL specific column types when using `change_table`.
senny authored
393 class Table < ActiveRecord::ConnectionAdapters::Table
394 include ColumnMethods
395 end
396
df9abfa @tenderlove require pg when this adapter is loaded
tenderlove authored
397 ADAPTER_NAME = 'PostgreSQL'
def594b @jeremy Don't append limit to primary key column definition. Freeze some constan...
jeremy authored
398
399 NATIVE_DATABASE_TYPES = {
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
400 primary_key: "serial primary key",
401 string: { name: "character varying", limit: 255 },
402 text: { name: "text" },
403 integer: { name: "integer" },
404 float: { name: "float" },
405 decimal: { name: "decimal" },
406 datetime: { name: "timestamp" },
407 timestamp: { name: "timestamp" },
408 time: { name: "time" },
409 date: { name: "date" },
af1ef85 @slbug Add postgresql range types support
slbug authored
410 daterange: { name: "daterange" },
411 numrange: { name: "numrange" },
412 tsrange: { name: "tsrange" },
413 tstzrange: { name: "tstzrange" },
414 int4range: { name: "int4range" },
415 int8range: { name: "int8range" },
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
416 binary: { name: "bytea" },
417 boolean: { name: "boolean" },
418 xml: { name: "xml" },
419 tsvector: { name: "tsvector" },
420 hstore: { name: "hstore" },
421 inet: { name: "inet" },
422 cidr: { name: "cidr" },
423 macaddr: { name: "macaddr" },
3b516b5 @guedes ActiveRecord support to PostgreSQL 9.2 JSON type
guedes authored
424 uuid: { name: "uuid" },
9a4a095 @le0pard AR supporting new intrange data type on PostgreSQL >= 9.2
le0pard authored
425 json: { name: "json" },
e209107 @robworley Support for PostgreSQL's ltree data type.
robworley authored
426 ltree: { name: "ltree" }
def594b @jeremy Don't append limit to primary key column definition. Freeze some constan...
jeremy authored
427 }
428
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
429 include Quoting
430 include ReferentialIntegrity
431 include SchemaStatements
432 include DatabaseStatements
78fcc5f @senny extract adapter savepoint implementations into `abstract/savepoints.rb`.
senny authored
433 include Savepoints
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
434
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
435 # Returns 'PostgreSQL' as adapter name for identification purposes.
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
436 def adapter_name
def594b @jeremy Don't append limit to primary key column definition. Freeze some constan...
jeremy authored
437 ADAPTER_NAME
b3df959 @dhh Refactored the AbstractAdapter to be a lot less scary. Cleaned up the do...
dhh authored
438 end
439
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
440 # Adds `:array` option to the default set provided by the
441 # AbstractAdapter
442 def prepare_column_options(column, types)
443 spec = super
444 spec[:array] = 'true' if column.respond_to?(:array) && column.array
4734e4e @kennyj Migration dump UUID default functions to schema.rb. Fixes #10751.
kennyj authored
445 spec[:default] = "\"#{column.default_function}\"" if column.respond_to?(:default_function) && column.default_function
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
446 spec
447 end
448
449 # Adds `:array` as a valid migration key
450 def migration_keys
451 super + [:array]
452 end
453
00e9cbd @smartinez87 Have a more connection specific rdoc for +supports_statement_cache?+
smartinez87 authored
454 # Returns +true+, since this connection adapter supports prepared statement
455 # caching.
104d0b2 @tenderlove adding backwards compatibility for non-prepare statement handling driver...
tenderlove authored
456 def supports_statement_cache?
457 true
458 end
459
69dcd45 @vjebelev AR changes to support creating ordered (asc, desc) indexes
vjebelev authored
460 def supports_index_sort_order?
461 true
462 end
463
d70e023 @mhfs Added where option to add_index to support postgresql partial indices
mhfs authored
464 def supports_partial_index?
465 true
466 end
467
392eeec @jonleighton Support for specifying transaction isolation level
jonleighton authored
468 def supports_transaction_isolation?
469 true
470 end
471
e199dc1 @danmcclain Adds support for concurrent indexing in PostgreSQL adapter
danmcclain authored
472 def index_algorithms
473 { concurrently: 'CONCURRENTLY' }
474 end
475
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
476 class StatementPool < ConnectionAdapters::StatementPool
477 def initialize(connection, max)
478 super
479 @counter = 0
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
480 @cache = Hash.new { |h,pid| h[pid] = {} }
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
481 end
482
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
483 def each(&block); cache.each(&block); end
484 def key?(key); cache.key?(key); end
485 def [](key); cache[key]; end
486 def length; cache.length; end
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
487
488 def next_key
489 "a#{@counter + 1}"
490 end
491
492 def []=(sql, key)
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
493 while @max <= cache.size
494 dealloc(cache.shift.last)
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
495 end
496 @counter += 1
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
497 cache[sql] = key
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
498 end
499
500 def clear
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
501 cache.each_value do |stmt_key|
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
502 dealloc stmt_key
503 end
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
504 cache.clear
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
505 end
506
6a28c51 @tenderlove reset prepared statement when schema changes imapact statement results. ...
tenderlove authored
507 def delete(sql_key)
508 dealloc cache[sql_key]
509 cache.delete sql_key
510 end
511
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
512 private
834d429 @tenderlove LRU should cache per process in postgresql. fixes #1339
tenderlove authored
513
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
514 def cache
515 @cache[Process.pid]
516 end
ee9d9fb @tenderlove Merge pull request #3258 from ileitch/3-1-stable
tenderlove authored
517
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
518 def dealloc(key)
519 @connection.query "DEALLOCATE #{key}" if connection_active?
520 end
521
522 def connection_active?
523 @connection.status == PGconn::CONNECTION_OK
524 rescue PGError
525 false
526 end
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
527 end
528
fd39847 @tenderlove prepared statements can be disabled
tenderlove authored
529 class BindSubstitution < Arel::Visitors::PostgreSQL # :nodoc:
530 include Arel::Visitors::BindVisitor
531 end
532
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
533 # Initializes and connects a PostgreSQL adapter.
534 def initialize(connection, logger, connection_parameters, config)
e8f664d @jeremy MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwi...
jeremy authored
535 super(connection, logger)
fd39847 @tenderlove prepared statements can be disabled
tenderlove authored
536
e54acf1 @rafaelfranca Do not type cast all the database url values.
rafaelfranca authored
537 if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
f13b278 @rafaelfranca Check if the SQL is not a prepared statement
rafaelfranca authored
538 @prepared_statements = true
fd39847 @tenderlove prepared statements can be disabled
tenderlove authored
539 @visitor = Arel::Visitors::PostgreSQL.new self
540 else
9f54921 @cfabianski Unprepared Visitor + unprepared_statement
cfabianski authored
541 @visitor = unprepared_visitor
fd39847 @tenderlove prepared statements can be disabled
tenderlove authored
542 end
543
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
544 @connection_parameters, @config = connection_parameters, config
821f2d5 @jeremy PostgreSQL: don't use async_exec and async_query with postgres-pr. Close...
jeremy authored
545
7a7c608 @spastorino Your original TIME ZONE value on PostgreSQL is correctly restored now, a...
spastorino authored
546 # @local_tz is initialized as nil to avoid warnings when connect tries to use it
547 @local_tz = nil
36150c9 @tenderlove Let's initialize instance variables in the postgres adapter.
tenderlove authored
548 @table_alias_length = nil
549
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
550 connect
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
551 @statements = StatementPool.new @connection,
e54acf1 @rafaelfranca Do not type cast all the database url values.
rafaelfranca authored
552 self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
35dba50 @tenderlove community support for pg < 8.2 has ended, so we can drop support for tho...
tenderlove authored
553
554 if postgresql_version < 80200
555 raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
556 end
557
fa6cda5 @tenderlove dynamically populate casting objects via the pg_type table
tenderlove authored
558 initialize_type_map
90a3714 @tenderlove properly name schema queries for the logger
tenderlove authored
559 @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
e54acf1 @rafaelfranca Do not type cast all the database url values.
rafaelfranca authored
560 @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
e8f664d @jeremy MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwi...
jeremy authored
561 end
562
df70b9d @fxn copy-edits 0e2644c
fxn authored
563 # Clears the prepared statements cache.
ffb9991 @tenderlove initial exec() method is working in pg adapter
tenderlove authored
564 def clear_cache!
565 @statements.clear
566 end
567
44b6470 @jeremy r3032@asus: jeremy | 2005-11-12 23:16:52 -0800
jeremy authored
568 # Is this connection alive and ready for queries?
569 def active?
34c7e73 @tenderlove use `connect_poll` on pg so that reaping does not hurt the connection
tenderlove authored
570 @connection.connect_poll != PG::PGRES_POLLING_FAILED
0eea560 @tenderlove requring pg ~> 0.11, so remove conditional code for supporting older ver...
tenderlove authored
571 rescue PGError
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
572 false
44b6470 @jeremy r3032@asus: jeremy | 2005-11-12 23:16:52 -0800
jeremy authored
573 end
574
575 # Close then reopen the connection.
576 def reconnect!
02f5655 @jonleighton Ensure disconnecting or reconnecting resets the transaction state
jonleighton authored
577 super
0eea560 @tenderlove requring pg ~> 0.11, so remove conditional code for supporting older ver...
tenderlove authored
578 @connection.reset
579 configure_connection
44b6470 @jeremy r3032@asus: jeremy | 2005-11-12 23:16:52 -0800
jeremy authored
580 end
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
581
ffb9991 @tenderlove initial exec() method is working in pg adapter
tenderlove authored
582 def reset!
583 clear_cache!
584 super
585 end
586
02ee200 @smartinez87 Added docs for #disconnect! on adapters
smartinez87 authored
587 # Disconnects from the database if already connected. Otherwise, this
588 # method does nothing.
6bd8e35 @jeremy ActiveRecord::Base.remove_connection explicitly closes database connecti...
jeremy authored
589 def disconnect!
02f5655 @jonleighton Ensure disconnecting or reconnecting resets the transaction state
jonleighton authored
590 super
6bd8e35 @jeremy ActiveRecord::Base.remove_connection explicitly closes database connecti...
jeremy authored
591 @connection.close rescue nil
592 end
44b6470 @jeremy r3032@asus: jeremy | 2005-11-12 23:16:52 -0800
jeremy authored
593
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
594 def native_database_types #:nodoc:
def594b @jeremy Don't append limit to primary key column definition. Freeze some constan...
jeremy authored
595 NATIVE_DATABASE_TYPES
4160b51 @dhh Added new Migrations framework for describing schema transformations in ...
dhh authored
596 end
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
597
868fb38 @smartinez87 Make this docs more consistent with the rest of the docs present
smartinez87 authored
598 # Returns true, since this connection adapter supports migrations.
4160b51 @dhh Added new Migrations framework for describing schema transformations in ...
dhh authored
599 def supports_migrations?
600 true
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
601 end
602
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Recor...
fxn authored
603 # Does PostgreSQL support finding primary key on non-Active Record tables?
f060221 @bellmyer raises exception (ActiveRecord::ConfigurationError with message) on habt...
bellmyer authored
604 def supports_primary_key? #:nodoc:
605 true
606 end
607
dac80f7 @jeremy PostgreSQL: use standard-conforming strings if possible
jeremy authored
608 # Enable standard-conforming strings if available.
609 def set_standard_conforming_strings
610 old, self.client_min_messages = client_min_messages, 'panic'
90a3714 @tenderlove properly name schema queries for the logger
tenderlove authored
611 execute('SET standard_conforming_strings = on', 'SCHEMA') rescue nil
dac80f7 @jeremy PostgreSQL: use standard-conforming strings if possible
jeremy authored
612 ensure
613 self.client_min_messages = old
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
614 end
615
03bf727 @jeremy PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later.
jeremy authored
616 def supports_insert_with_returning?
35dba50 @tenderlove community support for pg < 8.2 has ended, so we can drop support for tho...
tenderlove authored
617 true
03bf727 @jeremy PostgreSQL: use 'INSERT ... RETURNING id' for 8.2 and later.
jeremy authored
618 end
619
707ee0e @tarmo Made migrations transactional for PostgreSQL [#834 state:resolved]
tarmo authored
620 def supports_ddl_transactions?
621 true
622 end
8885b2d @miloops Refactor to calculations. Migration's versions are string not integer. A...
miloops authored
623
0306f82 @fxn implements automatic EXPLAIN logging for slow queries
fxn authored
624 # Returns true.
625 def supports_explain?
626 true
627 end
628
349fc90 @kennyj Also support extensions in PostgreSQL 9.1, because this has been support...
kennyj authored
629 # Returns true if pg > 9.1
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
630 def supports_extensions?
349fc90 @kennyj Also support extensions in PostgreSQL 9.1, because this has been support...
kennyj authored
631 postgresql_version >= 90100
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
632 end
633
c5989cc @pixeltrix Fix PostgreSQL tests on Travis
pixeltrix authored
634 # Range datatypes weren't introduced until PostgreSQL 9.2
635 def supports_ranges?
636 postgresql_version >= 90200
637 end
638
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
639 def enable_extension(name)
511c5ec fixes enable_extension bug in postgresql_adapter
Darren Woodley authored
640 exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
efd2be3 @tenderlove reloading type map on extension changing
tenderlove authored
641 reload_type_map
642 }
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
643 end
644
645 def disable_extension(name)
2076a93 @stouset Also quote extension name in disable_extension
stouset authored
646 exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
efd2be3 @tenderlove reloading type map on extension changing
tenderlove authored
647 reload_type_map
648 }
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
649 end
650
651 def extension_enabled?(name)
88e4ec6 @rafaelfranca Fix typo
rafaelfranca authored
652 if supports_extensions?
349fc90 @kennyj Also support extensions in PostgreSQL 9.1, because this has been support...
kennyj authored
653 res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled",
610958a @rafaelfranca Only search for enabled extension if the PostgreSQL version supports
rafaelfranca authored
654 'SCHEMA'
349fc90 @kennyj Also support extensions in PostgreSQL 9.1, because this has been support...
kennyj authored
655 res.column_types['enabled'].type_cast res.rows.first.first
610958a @rafaelfranca Only search for enabled extension if the PostgreSQL version supports
rafaelfranca authored
656 end
439ac72 @tenderlove add API to pg for enabling / disabling hstore
tenderlove authored
657 end
658
fba496f @jaggederest add ActiveRecord::AbstractAdapter#extensions and ActiveRecord::Connectio...
jaggederest authored
659 def extensions
660 if supports_extensions?
661 res = exec_query "SELECT extname from pg_extension", "SCHEMA"
662 res.rows.map { |r| res.column_types['extname'].type_cast r.first }
663 else
f88c336 @carlosantoniodasilva Call super to use the abstract adapter implementation instead
carlosantoniodasilva authored
664 super
fba496f @jaggederest add ActiveRecord::AbstractAdapter#extensions and ActiveRecord::Connectio...
jaggederest authored
665 end
666 end
667
35dba50 @tenderlove community support for pg < 8.2 has ended, so we can drop support for tho...
tenderlove authored
668 # Returns the configured supported identifier length supported by PostgreSQL
263479b @technoweenie Add AbstractAdapter#table_alias_for to create table aliases according to...
technoweenie authored
669 def table_alias_length
576d700 @kennyj Fix logs name consistency.
kennyj authored
670 @table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
263479b @technoweenie Add AbstractAdapter#table_alias_for to create table aliases according to...
technoweenie authored
671 end
2c6b6e2 @technoweenie automatically add primary key to #select_limited_ids_list order by claus...
technoweenie authored
672
9d9aed4 @tenderlove add a session authorization setter to the pg connection
tenderlove authored
673 # Set the authorized user for this session
674 def session_auth=(user)
02128d6 @tenderlove setting the authorized session clears the statement cache
tenderlove authored
675 clear_cache!
0f45f23 @tenderlove renaming exec in the PG adapter
tenderlove authored
676 exec_query "SET SESSION AUTHORIZATION #{user}"
9d9aed4 @tenderlove add a session authorization setter to the pg connection
tenderlove authored
677 end
678
9991f0f @dasch Refactor PostgreSQLAdapter a bit
dasch authored
679 module Utils
a982443 @dasch Make #extract_schema_and_table an instance method in Utils
dasch authored
680 extend self
681
9991f0f @dasch Refactor PostgreSQLAdapter a bit
dasch authored
682 # Returns an array of <tt>[schema_name, table_name]</tt> extracted from +name+.
683 # +schema_name+ is nil if not specified in +name+.
684 # +schema_name+ and +table_name+ exclude surrounding quotes (regardless of whether provided in +name+)
685 # +name+ supports the range of schema/table references understood by PostgreSQL, for example:
686 #
687 # * <tt>table_name</tt>
688 # * <tt>"table.name"</tt>
689 # * <tt>schema_name.table_name</tt>
690 # * <tt>schema_name."table.name"</tt>
691 # * <tt>"schema.name"."table name"</tt>
a982443 @dasch Make #extract_schema_and_table an instance method in Utils
dasch authored
692 def extract_schema_and_table(name)
9991f0f @dasch Refactor PostgreSQLAdapter a bit
dasch authored
693 table, schema = name.scan(/[^".\s]+|"[^"]*"/)[0..1].collect{|m| m.gsub(/(^"|"$)/,'') }.reverse
694 [schema, table]
695 end
696 end
697
3a0d081 @dougcole pick better names and add a little documentation
dougcole authored
698 def use_insert_returning?
699 @use_insert_returning
f09bb33 @dougcole add use_returning as a postgresql connection config
dougcole authored
700 end
701
c2e2031 @ranjaykrishna Created a layer of abstraction for the valid type checking in schema dum...
ranjaykrishna authored
702 def valid_type?(type)
703 !native_database_types[type].nil?
704 end
705
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
706 protected
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
707
4d04641 @smartinez87 Fix #postgresql_version docs
smartinez87 authored
708 # Returns the version of the connected PostgreSQL server.
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
709 def postgresql_version
0eea560 @tenderlove requring pg ~> 0.11, so remove conditional code for supporting older ver...
tenderlove authored
710 @connection.server_version
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
711 end
712
2fe2813 @kennyj Fix a problem of translate_exception method in Japanese.
kennyj authored
713 # See http://www.postgresql.org/docs/9.1/static/errcodes-appendix.html
714 FOREIGN_KEY_VIOLATION = "23503"
715 UNIQUE_VIOLATION = "23505"
716
53a3eaa @mschuerig Translate adapter errors that indicate a violated uniqueness constraint ...
mschuerig authored
717 def translate_exception(exception, message)
e2a4b7a @kennyj Wrong exception is occured when raising no translatable exception
kennyj authored
718 return exception unless exception.respond_to?(:result)
719
0d63cda Don't crash exception translation w/ nil result attribute.
Steve Jorgensen authored
720 case exception.result.try(:error_field, PGresult::PG_DIAG_SQLSTATE)
2fe2813 @kennyj Fix a problem of translate_exception method in Japanese.
kennyj authored
721 when UNIQUE_VIOLATION
b5dfdc7 @NZKoz Make sure the wrapped exceptions also have the original exception availa...
NZKoz authored
722 RecordNotUnique.new(message, exception)
2fe2813 @kennyj Fix a problem of translate_exception method in Japanese.
kennyj authored
723 when FOREIGN_KEY_VIOLATION
b5dfdc7 @NZKoz Make sure the wrapped exceptions also have the original exception availa...
NZKoz authored
724 InvalidForeignKey.new(message, exception)
53a3eaa @mschuerig Translate adapter errors that indicate a violated uniqueness constraint ...
mschuerig authored
725 else
726 super
727 end
728 end
729
db045db @dhh Initial
dhh authored
730 private
fa6cda5 @tenderlove dynamically populate casting objects via the pg_type table
tenderlove authored
731
efd2be3 @tenderlove reloading type map on extension changing
tenderlove authored
732 def reload_type_map
733 OID::TYPE_MAP.clear
734 initialize_type_map
735 end
736
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
737 def initialize_type_map
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
738 result = execute('SELECT oid, typname, typelem, typdelim, typinput FROM pg_type', 'SCHEMA')
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
739 leaves, nodes = result.partition { |row| row['typelem'] == '0' }
fa6cda5 @tenderlove dynamically populate casting objects via the pg_type table
tenderlove authored
740
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
741 # populate the leaf nodes
742 leaves.find_all { |row| OID.registered_type? row['typname'] }.each do |row|
743 OID::TYPE_MAP[row['oid'].to_i] = OID::NAMES[row['typname']]
744 end
745
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
746 arrays, nodes = nodes.partition { |row| row['typinput'] == 'array_in' }
747
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
748 # populate composite types
749 nodes.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row|
336b376 @MSch Make Postgres point type correspond to ruby array with two floats inside
MSch authored
750 if OID.registered_type? row['typname']
751 # this composite type is explicitly registered
752 vector = OID::NAMES[row['typname']]
753 else
754 # use the default for composite types
755 vector = OID::Vector.new row['typdelim'], OID::TYPE_MAP[row['typelem'].to_i]
756 end
757
232d222 @etehtsea Modularize postgresql adapter
etehtsea authored
758 OID::TYPE_MAP[row['oid'].to_i] = vector
759 end
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
760
761 # populate array types
762 arrays.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row|
763 array = OID::Array.new OID::TYPE_MAP[row['typelem'].to_i]
764 OID::TYPE_MAP[row['oid'].to_i] = array
765 end
fa6cda5 @tenderlove dynamically populate casting objects via the pg_type table
tenderlove authored
766 end
767
6a28c51 @tenderlove reset prepared statement when schema changes imapact statement results. ...
tenderlove authored
768 FEATURE_NOT_SUPPORTED = "0A000" # :nodoc:
769
ffbefc7 @tenderlove wrap logging around the actual query call itself.
tenderlove authored
770 def exec_no_cache(sql, name, binds)
771 log(sql, name, binds) { @connection.async_exec(sql) }
1741bbe @tenderlove avoiding statement cache if there are no bind values
tenderlove authored
772 end
f1df6b2 @tenderlove postgresql supports prepare statement deletes
tenderlove authored
773
ffbefc7 @tenderlove wrap logging around the actual query call itself.
tenderlove authored
774 def exec_cache(sql, name, binds)
98e0016 @tenderlove log every sql statement, even when they error
tenderlove authored
775 stmt_key = prepare_statement(sql)
776
2ae9166 @tenderlove log the statement name along with the SQL
tenderlove authored
777 log(sql, name, binds, stmt_key) do
98e0016 @tenderlove log every sql statement, even when they error
tenderlove authored
778 @connection.send_query_prepared(stmt_key, binds.map { |col, val|
779 type_cast(val, col)
780 })
781 @connection.block
782 @connection.get_last_result
783 end
784 rescue ActiveRecord::StatementInvalid => e
785 pgerror = e.original_exception
786
787 # Get the PG code for the failure. Annoyingly, the code for
788 # prepared statements whose return value may have changed is
789 # FEATURE_NOT_SUPPORTED. Check here for more details:
790 # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
791 begin
792 code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
793 rescue
794 raise e
795 end
796 if FEATURE_NOT_SUPPORTED == code
797 @statements.delete sql_key(sql)
798 retry
799 else
800 raise e
6a28c51 @tenderlove reset prepared statement when schema changes imapact statement results. ...
tenderlove authored
801 end
802 end
803
804 # Returns the statement identifier for the client side cache
805 # of statements
806 def sql_key(sql)
807 "#{schema_search_path}-#{sql}"
808 end
809
810 # Prepare the statement if it hasn't been prepared, return
811 # the statement key.
812 def prepare_statement(sql)
813 sql_key = sql_key(sql)
cfc95d8 @Juanmcuello Use the schema_search_path in prepared statements.
Juanmcuello authored
814 unless @statements.key? sql_key
54b7e78 @tenderlove Database adapters use a statement pool.
tenderlove authored
815 nextkey = @statements.next_key
019c263 @tardate apply private method indentation convention
tardate authored
816 @connection.prepare nextkey, sql
19fc886 @tenderlove prepare the statement inside the begin / rescue block
tenderlove authored
817 # Clear the queue
818 @connection.get_last_result
cfc95d8 @Juanmcuello Use the schema_search_path in prepared statements.
Juanmcuello authored
819 @statements[sql_key] = nextkey
019c263 @tardate apply private method indentation convention
tardate authored
820 end
6a28c51 @tenderlove reset prepared statement when schema changes imapact statement results. ...
tenderlove authored
821 @statements[sql_key]
019c263 @tardate apply private method indentation convention
tardate authored
822 end
1741bbe @tenderlove avoiding statement cache if there are no bind values
tenderlove authored
823
0432d15 @lifo Merge with docrails.
lifo authored
824 # The internal PostgreSQL identifier of the money data type.
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
825 MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
bc35631 @tenderlove use constants instead of magic numbers. meow
tenderlove authored
826 # The internal PostgreSQL identifier of the BYTEA data type.
827 BYTEA_COLUMN_TYPE_OID = 17 #:nodoc:
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
828
829 # Connects to a PostgreSQL server and sets up the adapter depending on the
830 # connected server's characteristics.
831 def connect
8ee6406 @larskanis Postgresql: Allow setting of any libpq connection parameters
larskanis authored
832 @connection = PGconn.connect(@connection_parameters)
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
833
834 # Money type has a fixed precision of 10 in PostgreSQL 8.2 and below, and as of
835 # PostgreSQL 8.3 it has a fixed precision of 19. PostgreSQLColumn.extract_precision
836 # should know about this but can't detect it there, so deal with it here.
dac80f7 @jeremy PostgreSQL: use standard-conforming strings if possible
jeremy authored
837 PostgreSQLColumn.money_precision = (postgresql_version >= 80300) ? 19 : 10
838
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
839 configure_connection
840 end
841
c5b652f @jackc PostgreSQLAdapter: set time_zone to UTC when Base.default_timezone == :u...
jackc authored
842 # Configures the encoding, verbosity, schema search path, and time zone of the connection.
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
843 # This is called by #connect and should not be called manually.
e8f664d @jeremy MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwi...
jeremy authored
844 def configure_connection
845 if @config[:encoding]
0eea560 @tenderlove requring pg ~> 0.11, so remove conditional code for supporting older ver...
tenderlove authored
846 @connection.set_client_encoding(@config[:encoding])
e8f664d @jeremy MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwi...
jeremy authored
847 end
052e415 @kennyj Change minimum (default) log level in PostgreSQL to warning.
kennyj authored
848 self.client_min_messages = @config[:min_messages] || 'warning'
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
849 self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
dac80f7 @jeremy PostgreSQL: use standard-conforming strings if possible
jeremy authored
850
851 # Use standard-conforming strings if available so we don't have to do the E'...' dance.
852 set_standard_conforming_strings
853
f17159b @fxn edit pass: the names of Rails components have a space, ie, "Active Recor...
fxn authored
854 # If using Active Record's time zone support configure the connection to return
c5b652f @jackc PostgreSQLAdapter: set time_zone to UTC when Base.default_timezone == :u...
jackc authored
855 # TIMESTAMP WITH ZONE types in UTC.
97d06e8 @sodabrew Session variables for mysql, mysql2, and postgresql adapters can be set
sodabrew authored
856 # (SET TIME ZONE does not use an equals sign like other SET variables)
bf6661c @tenderlove setting the timezone in postgres to whatever ruby thinks the timezone is...
tenderlove authored
857 if ActiveRecord::Base.default_timezone == :utc
90a3714 @tenderlove properly name schema queries for the logger
tenderlove authored
858 execute("SET time zone 'UTC'", 'SCHEMA')
7a7c608 @spastorino Your original TIME ZONE value on PostgreSQL is correctly restored now, a...
spastorino authored
859 elsif @local_tz
90a3714 @tenderlove properly name schema queries for the logger
tenderlove authored
860 execute("SET time zone '#{@local_tz}'", 'SCHEMA')
bf6661c @tenderlove setting the timezone in postgres to whatever ruby thinks the timezone is...
tenderlove authored
861 end
97d06e8 @sodabrew Session variables for mysql, mysql2, and postgresql adapters can be set
sodabrew authored
862
863 # SET statements from :variables config hash
864 # http://www.postgresql.org/docs/8.3/static/sql-set.html
865 variables = @config[:variables] || {}
866 variables.map do |k, v|
867 if v == ':default' || v == :default
868 # Sets the value to the global or compile default
869 execute("SET SESSION #{k.to_s} TO DEFAULT", 'SCHEMA')
870 elsif !v.nil?
871 execute("SET SESSION #{k.to_s} TO #{quote(v)}", 'SCHEMA')
872 end
873 end
e8f664d @jeremy MySQL, PostgreSQL: reconnect! also reconfigures the connection. Otherwi...
jeremy authored
874 end
875
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
876 # Returns the current ID of a table's sequence.
3378d77 @tenderlove use prepared statements to fetch the last insert id
tenderlove authored
877 def last_insert_id(sequence_name) #:nodoc:
f09bb33 @dougcole add use_returning as a postgresql connection config
dougcole authored
878 Integer(last_insert_id_value(sequence_name))
879 end
880
20615e7 @dougcole refactor
dougcole authored
881 def last_insert_id_value(sequence_name)
882 last_insert_id_result(sequence_name).rows.first.first
883 end
884
885 def last_insert_id_result(sequence_name) #:nodoc:
6f3489c @evtuhovich Remove prepared statement from system query in postgresql adapter
evtuhovich authored
886 exec_query("SELECT currval('#{sequence_name}')", 'SQL')
db045db @dhh Initial
dhh authored
887 end
888
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
889 # Executes a SELECT query and returns the results, performing any data type
7143d80 Smattering of grammatical fixes to documentation. Closes #10083 [BobSilv...
Marcel Molina authored
890 # conversions that are required to be performed here instead of in PostgreSQLColumn.
43bbb25 @tenderlove bind substitution is working properly
tenderlove authored
891 def select(sql, name = nil, binds = [])
40ce682 @tenderlove made the result set object act more like an array
tenderlove authored
892 exec_query(sql, name, binds)
30fb7b8 @jeremy connection.select_rows 'sql' returns an array (rows) of arrays (field va...
jeremy authored
893 end
894
895 def select_raw(sql, name = nil)
d0bd3b5 @jeremy Return PostgreSQL columns in the order they are declared #1374 (perlguy@...
jeremy authored
896 res = execute(sql, name)
9a947af @jeremy PostgreSQL: support server versions 7.4 through 8.0 and the ruby-pg driv...
jeremy authored
897 results = result_as_array(res)
8521cdf @tenderlove PostgreSQLAdapter#select_raw fields and results are empty even if ntuple...
tenderlove authored
898 fields = res.fields
15aa6e0 @jeremy r4644@asus: jeremy | 2006-06-16 14:57:03 -0700
jeremy authored
899 res.clear
2aed63e @tenderlove our method is modifying the original array, so refactor to use destructi...
tenderlove authored
900 return fields, results
e2da98e Back out of [2548].
Marcel Molina authored
901 end
902
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
903 # Returns the list of a table's column names, data types, and default values.
1fde44b @jeremy r1278@iwill: jeremy | 2005-06-12 05:11:48 -0700
jeremy authored
904 #
905 # The underlying query is roughly:
906 # SELECT column.name, column.type, default.value
907 # FROM column LEFT JOIN default
908 # ON column.table_id = default.table_id
909 # AND column.num = default.column_num
910 # WHERE column.table_id = get_table_id('table_name')
911 # AND column.num > 0
912 # AND NOT column.is_dropped
913 # ORDER BY column.num
914 #
915 # If the table name is not prefixed with a schema, the database will
916 # take the first match from the schema search path.
917 #
918 # Query implementation notes:
919 # - format_type includes the column size constraint, e.g. varchar(50)
920 # - ::regclass is a function that gives the id for a table name
29b0707 @NZKoz Improve performance and functionality of the postgresql adapter. Closes...
NZKoz authored
921 def column_definitions(table_name) #:nodoc:
90a3714 @tenderlove properly name schema queries for the logger
tenderlove authored
922 exec_query(<<-end_sql, 'SCHEMA').rows
40475cf @arturopie #7914 Using a better way to get the defaults from db.
arturopie authored
923 SELECT a.attname, format_type(a.atttypid, a.atttypmod),
924 pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
4544d2b @danmcclain Moves column dump specific code to a module included in AbstractAdapter
danmcclain authored
925 FROM pg_attribute a LEFT JOIN pg_attrdef d
926 ON a.attrelid = d.adrelid AND a.attnum = d.adnum
927 WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
928 AND a.attnum > 0 AND NOT a.attisdropped
929 ORDER BY a.attnum
1fde44b @jeremy r1278@iwill: jeremy | 2005-06-12 05:11:48 -0700
jeremy authored
930 end_sql
db045db @dhh Initial
dhh authored
931 end
70de8e6 @maxlapshin Support multiple schemas in table names for postgresql [#390 state:resol...
maxlapshin authored
932
933 def extract_pg_identifier_from_name(name)
e7d860c @tenderlove create fewer objects, call fewer methods in extract_pg_identifier_from_n...
tenderlove authored
934 match_data = name.start_with?('"') ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)
70de8e6 @maxlapshin Support multiple schemas in table names for postgresql [#390 state:resol...
maxlapshin authored
935
936 if match_data
e7d860c @tenderlove create fewer objects, call fewer methods in extract_pg_identifier_from_n...
tenderlove authored
937 rest = name[match_data[0].length, name.length]
938 rest = rest[1, rest.length] if rest.start_with? "."
89925e8 @josevalim Revert "Use any instead of length"
josevalim authored
939 [match_data[1], (rest.length > 0 ? rest : nil)]
70de8e6 @maxlapshin Support multiple schemas in table names for postgresql [#390 state:resol...
maxlapshin authored
940 end
941 end
b297911 @tenderlove use inheritence to deal with custom methods
tenderlove authored
942
5c7f8c9 @tardate Improve PostgreSQL adapter schema-awareness
tardate authored
943 def extract_table_ref_from_insert_sql(sql)
944 sql[/into\s+([^\(]*).*values\s*\(/i]
945 $1.strip if $1
946 end
947
14d7dc0 @tenderlove push SQL generation inside the schema creation object
tenderlove authored
948 def create_table_definition(name, temporary, options)
949 TableDefinition.new native_database_types, name, temporary, options
019c263 @tardate apply private method indentation convention
tardate authored
950 end
5d0ca74 @senny Support PostgreSQL specific column types when using `change_table`.
senny authored
951
952 def update_table_definition(table_name, base)
953 Table.new(table_name, base)
954 end
db045db @dhh Initial
dhh authored
955 end
956 end
957 end
Something went wrong with that request. Please try again.